@agent-score/commerce 2.4.0 → 2.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.
Files changed (80) hide show
  1. package/README.md +19 -17
  2. package/dist/challenge/index.d.mts +31 -3
  3. package/dist/challenge/index.d.ts +31 -3
  4. package/dist/challenge/index.js +25 -9
  5. package/dist/challenge/index.js.map +1 -1
  6. package/dist/challenge/index.mjs +25 -9
  7. package/dist/challenge/index.mjs.map +1 -1
  8. package/dist/{checkout-B-MIzYzW.d.ts → checkout-C4RD7M0Z.d.ts} +117 -13
  9. package/dist/{checkout-Bn7ZKIBD.d.mts → checkout-CzB9f_jf.d.mts} +117 -13
  10. package/dist/core.d.mts +40 -7
  11. package/dist/core.d.ts +40 -7
  12. package/dist/core.js +52 -27
  13. package/dist/core.js.map +1 -1
  14. package/dist/core.mjs +52 -27
  15. package/dist/core.mjs.map +1 -1
  16. package/dist/discovery/index.d.mts +33 -3
  17. package/dist/discovery/index.d.ts +33 -3
  18. package/dist/discovery/index.js +50 -16
  19. package/dist/discovery/index.js.map +1 -1
  20. package/dist/discovery/index.mjs +49 -16
  21. package/dist/discovery/index.mjs.map +1 -1
  22. package/dist/gate-D2RP6bZg.d.ts +307 -0
  23. package/dist/gate-GCXy4FHI.d.mts +307 -0
  24. package/dist/identity/express.d.mts +28 -1
  25. package/dist/identity/express.d.ts +28 -1
  26. package/dist/identity/express.js +714 -31
  27. package/dist/identity/express.js.map +1 -1
  28. package/dist/identity/express.mjs +710 -30
  29. package/dist/identity/express.mjs.map +1 -1
  30. package/dist/identity/fastify.d.mts +14 -2
  31. package/dist/identity/fastify.d.ts +14 -2
  32. package/dist/identity/fastify.js +727 -31
  33. package/dist/identity/fastify.js.map +1 -1
  34. package/dist/identity/fastify.mjs +723 -30
  35. package/dist/identity/fastify.mjs.map +1 -1
  36. package/dist/identity/hono.d.mts +28 -1
  37. package/dist/identity/hono.d.ts +28 -1
  38. package/dist/identity/hono.js +696 -33
  39. package/dist/identity/hono.js.map +1 -1
  40. package/dist/identity/hono.mjs +692 -32
  41. package/dist/identity/hono.mjs.map +1 -1
  42. package/dist/identity/nextjs.d.mts +5 -0
  43. package/dist/identity/nextjs.d.ts +5 -0
  44. package/dist/identity/nextjs.js +695 -30
  45. package/dist/identity/nextjs.js.map +1 -1
  46. package/dist/identity/nextjs.mjs +691 -29
  47. package/dist/identity/nextjs.mjs.map +1 -1
  48. package/dist/identity/policy.d.mts +21 -2
  49. package/dist/identity/policy.d.ts +21 -2
  50. package/dist/identity/policy.js +22 -1
  51. package/dist/identity/policy.js.map +1 -1
  52. package/dist/identity/policy.mjs +21 -1
  53. package/dist/identity/policy.mjs.map +1 -1
  54. package/dist/identity/web.d.mts +26 -1
  55. package/dist/identity/web.d.ts +26 -1
  56. package/dist/identity/web.js +695 -30
  57. package/dist/identity/web.js.map +1 -1
  58. package/dist/identity/web.mjs +691 -29
  59. package/dist/identity/web.mjs.map +1 -1
  60. package/dist/index.d.mts +165 -4
  61. package/dist/index.d.ts +165 -4
  62. package/dist/index.js +3103 -534
  63. package/dist/index.js.map +1 -1
  64. package/dist/index.mjs +3086 -545
  65. package/dist/index.mjs.map +1 -1
  66. package/dist/payment/index.d.mts +1 -1
  67. package/dist/payment/index.d.ts +1 -1
  68. package/dist/payment/index.js +10 -2
  69. package/dist/payment/index.js.map +1 -1
  70. package/dist/payment/index.mjs +10 -2
  71. package/dist/payment/index.mjs.map +1 -1
  72. package/dist/stripe-multichain/index.js +1614 -266
  73. package/dist/stripe-multichain/index.js.map +1 -1
  74. package/dist/stripe-multichain/index.mjs +1614 -266
  75. package/dist/stripe-multichain/index.mjs.map +1 -1
  76. package/dist/types-D1slMt0H.d.mts +137 -0
  77. package/dist/types-D1slMt0H.d.ts +137 -0
  78. package/dist/{wwwauthenticate-CVaGUMjU.d.mts → wwwauthenticate-Dgm-_af9.d.mts} +11 -1
  79. package/dist/{wwwauthenticate-CVaGUMjU.d.ts → wwwauthenticate-Dgm-_af9.d.ts} +11 -1
  80. package/package.json +26 -21
@@ -44,7 +44,7 @@ var IDENTITY_VERIFICATION_REQUIRED_FALLBACK_INSTRUCTIONS = JSON.stringify({
44
44
  var API_ERROR_INSTRUCTIONS = JSON.stringify({
45
45
  action: "retry_with_backoff",
46
46
  steps: [
47
- "Verification is temporarily unavailable. Retry the request after 5\u201330 seconds with exponential backoff.",
47
+ "Verification is temporarily unavailable. Retry the request after 5-30 seconds with exponential backoff.",
48
48
  "This is NOT a compliance denial \u2014 the user does not need to re-verify their identity. Send the same identity headers (X-Wallet-Address or X-Operator-Token) on retry.",
49
49
  "If the request continues to fail after 3+ retries (~60 seconds total), surface the error to the user with the merchant's support contact."
50
50
  ],
@@ -131,7 +131,624 @@ function denialReasonToBody(reason) {
131
131
  return body;
132
132
  }
133
133
 
134
+ // src/aip/verify.ts
135
+ import { decodeJwt, decodeProtectedHeader, importJWK as importJWK2, jwtVerify } from "jose";
136
+
137
+ // src/aip/http-signature.ts
138
+ import { calculateJwkThumbprint, importJWK } from "jose";
139
+ var { subtle } = globalThis.crypto;
140
+ var b64ToBytes = (b64) => {
141
+ const bin = atob(b64);
142
+ const out = new Uint8Array(bin.length);
143
+ for (let i = 0; i < bin.length; i++) {
144
+ out[i] = bin.charCodeAt(i);
145
+ }
146
+ return out;
147
+ };
148
+ var AIP_COVERED_COMPONENTS = ["@method", "@authority", "@path", "agent-identity"];
149
+ var AIP_SIGNATURE_TAG = "agent-identity";
150
+ var DEFAULT_MAX_SKEW_SECONDS = 60;
151
+ var MAX_POP_WINDOW_SECONDS = 120;
152
+ var normalizeAuthority = (authority) => {
153
+ const lower = authority.trim().toLowerCase();
154
+ const colon = lower.lastIndexOf(":");
155
+ if (colon === -1) {
156
+ return lower;
157
+ }
158
+ if (lower.includes("]") && colon < lower.indexOf("]")) {
159
+ return lower;
160
+ }
161
+ const host = lower.slice(0, colon);
162
+ const port = lower.slice(colon + 1);
163
+ if (port === "80" || port === "443") {
164
+ return host;
165
+ }
166
+ return lower;
167
+ };
168
+ var componentValue = (name, input) => {
169
+ switch (name) {
170
+ case "@method":
171
+ return input.method.toUpperCase();
172
+ case "@authority":
173
+ return normalizeAuthority(input.authority);
174
+ case "@path":
175
+ return input.path;
176
+ case "agent-identity":
177
+ return input.agentIdentity.trim();
178
+ default:
179
+ return input.extra?.[name] ?? null;
180
+ }
181
+ };
182
+ var serializeComponentList = (components) => `(${components.map((c) => `"${c}"`).join(" ")})`;
183
+ var serializeParams = (p) => {
184
+ const parts = [];
185
+ if (p.created !== void 0) {
186
+ parts.push(`created=${p.created}`);
187
+ }
188
+ if (p.expires !== void 0) {
189
+ parts.push(`expires=${p.expires}`);
190
+ }
191
+ if (p.keyid !== void 0) {
192
+ parts.push(`keyid="${p.keyid}"`);
193
+ }
194
+ if (p.alg !== void 0) {
195
+ parts.push(`alg="${p.alg}"`);
196
+ }
197
+ if (p.tag !== void 0) {
198
+ parts.push(`tag="${p.tag}"`);
199
+ }
200
+ return parts.map((s) => `;${s}`).join("");
201
+ };
202
+ var buildSignatureBase = (params, input, rawSignatureParams) => {
203
+ const lines = [];
204
+ for (const name of params.components) {
205
+ const value = componentValue(name, input);
206
+ if (value === null) {
207
+ throw new MissingComponentError(name);
208
+ }
209
+ lines.push(`"${name}": ${value}`);
210
+ }
211
+ const paramsValue = rawSignatureParams ?? serializeComponentList(params.components) + serializeParams(params);
212
+ lines.push(`"@signature-params": ${paramsValue}`);
213
+ return lines.join("\n");
214
+ };
215
+ var MissingComponentError = class extends Error {
216
+ constructor(component) {
217
+ super(`signature base missing covered component: ${component}`);
218
+ this.component = component;
219
+ this.name = "MissingComponentError";
220
+ }
221
+ component;
222
+ };
223
+ var parseSignatureInput = (header, tag = AIP_SIGNATURE_TAG) => {
224
+ const members = splitDictionary(header);
225
+ if (members.length === 0) {
226
+ return null;
227
+ }
228
+ const parsed = members.map((m) => {
229
+ const params = parseInnerListMember(m.value);
230
+ return params ? { label: m.label, params, rawParams: m.value } : null;
231
+ }).filter((x) => x !== null);
232
+ if (parsed.length === 0) {
233
+ return null;
234
+ }
235
+ return parsed.find((p) => p.params.tag === tag) ?? null;
236
+ };
237
+ var parseSignatureValue = (header, label) => {
238
+ const members = splitDictionary(header);
239
+ const member = members.find((m) => m.label === label);
240
+ if (!member) {
241
+ return null;
242
+ }
243
+ const v = member.value.trim();
244
+ if (!v.startsWith(":") || !v.endsWith(":") || v.length < 2) {
245
+ return null;
246
+ }
247
+ const b64 = v.slice(1, -1);
248
+ try {
249
+ return b64ToBytes(b64);
250
+ } catch {
251
+ return null;
252
+ }
253
+ };
254
+ var splitDictionary = (header) => {
255
+ const out = [];
256
+ let depth = 0;
257
+ let inBytes = false;
258
+ let inString = false;
259
+ let current = "";
260
+ for (let i = 0; i < header.length; i++) {
261
+ const ch = header[i];
262
+ if (inString) {
263
+ current += ch;
264
+ if (ch === '"' && header[i - 1] !== "\\") {
265
+ inString = false;
266
+ }
267
+ continue;
268
+ }
269
+ if (ch === '"') {
270
+ inString = true;
271
+ current += ch;
272
+ continue;
273
+ }
274
+ if (ch === ":") {
275
+ inBytes = !inBytes;
276
+ current += ch;
277
+ continue;
278
+ }
279
+ if (!inBytes && ch === "(") {
280
+ depth++;
281
+ current += ch;
282
+ continue;
283
+ }
284
+ if (!inBytes && ch === ")") {
285
+ depth = Math.max(0, depth - 1);
286
+ current += ch;
287
+ continue;
288
+ }
289
+ if (!inBytes && depth === 0 && ch === ",") {
290
+ pushMember(out, current);
291
+ current = "";
292
+ continue;
293
+ }
294
+ current += ch;
295
+ }
296
+ pushMember(out, current);
297
+ return out;
298
+ };
299
+ var pushMember = (out, raw) => {
300
+ const trimmed = raw.trim();
301
+ if (!trimmed) {
302
+ return;
303
+ }
304
+ const eq = trimmed.indexOf("=");
305
+ if (eq === -1) {
306
+ return;
307
+ }
308
+ const label = trimmed.slice(0, eq).trim();
309
+ const value = trimmed.slice(eq + 1).trim();
310
+ if (label) {
311
+ out.push({ label, value });
312
+ }
313
+ };
314
+ var parseInnerListMember = (value) => {
315
+ const open = value.indexOf("(");
316
+ const close = value.indexOf(")", open + 1);
317
+ if (open === -1 || close === -1) {
318
+ return null;
319
+ }
320
+ const listBody = value.slice(open + 1, close).trim();
321
+ const components = listBody.length === 0 ? [] : (listBody.match(/"[^"]*"/g) ?? []).map((s) => s.slice(1, -1));
322
+ const params = { components };
323
+ const paramStr = value.slice(close + 1);
324
+ const re = /;\s*([a-zA-Z][a-zA-Z0-9_-]*)\s*=\s*("(?:[^"\\]|\\.)*"|-?\d+)/g;
325
+ let match;
326
+ while ((match = re.exec(paramStr)) !== null) {
327
+ const key = match[1];
328
+ const raw = match[2];
329
+ const val = raw.startsWith('"') ? raw.slice(1, -1) : Number(raw);
330
+ if (key === "created") {
331
+ params.created = val;
332
+ } else if (key === "expires") {
333
+ params.expires = val;
334
+ } else if (key === "keyid") {
335
+ params.keyid = val;
336
+ } else if (key === "tag") {
337
+ params.tag = val;
338
+ } else if (key === "alg") {
339
+ params.alg = val;
340
+ }
341
+ }
342
+ return params;
343
+ };
344
+ var verifyMessageSignature = async (input) => {
345
+ const selected = parseSignatureInput(input.signatureInput);
346
+ if (!selected) {
347
+ return { ok: false, reason: "no_aip_signature" };
348
+ }
349
+ const { label, params, rawParams } = selected;
350
+ if (params.alg !== void 0 && !["ed25519", "eddsa"].includes(params.alg.toLowerCase())) {
351
+ return { ok: false, reason: "unsupported_alg" };
352
+ }
353
+ for (const required of AIP_COVERED_COMPONENTS) {
354
+ if (!params.components.includes(required)) {
355
+ return { ok: false, reason: "missing_covered_component" };
356
+ }
357
+ }
358
+ if (params.created === void 0) {
359
+ return { ok: false, reason: "created_missing" };
360
+ }
361
+ if (params.expires === void 0) {
362
+ return { ok: false, reason: "expires_missing" };
363
+ }
364
+ if (params.expires < params.created || params.expires - params.created > MAX_POP_WINDOW_SECONDS) {
365
+ return { ok: false, reason: "pop_window_too_long" };
366
+ }
367
+ const now = input.now ?? Math.floor(Date.now() / 1e3);
368
+ const skew = input.maxSkewSeconds ?? DEFAULT_MAX_SKEW_SECONDS;
369
+ if (params.created > now + skew) {
370
+ return { ok: false, reason: "created_in_future" };
371
+ }
372
+ if (params.expires < now - skew) {
373
+ return { ok: false, reason: "expired" };
374
+ }
375
+ if (!params.keyid) {
376
+ return { ok: false, reason: "missing_keyid" };
377
+ }
378
+ const cnf = input.cnfJwk;
379
+ if (cnf.kty !== "OKP" || cnf.crv !== "Ed25519" || typeof cnf.x !== "string" || cnf.x.length === 0) {
380
+ return { ok: false, reason: "unsupported_cnf_key" };
381
+ }
382
+ let thumbprint;
383
+ try {
384
+ thumbprint = await calculateJwkThumbprint(input.cnfJwk, "sha256");
385
+ } catch {
386
+ return { ok: false, reason: "unsupported_cnf_key" };
387
+ }
388
+ if (params.keyid !== thumbprint) {
389
+ return { ok: false, reason: "keyid_mismatch" };
390
+ }
391
+ const sig = parseSignatureValue(input.signature, label);
392
+ if (!sig) {
393
+ return { ok: false, reason: "malformed_signature" };
394
+ }
395
+ let base;
396
+ try {
397
+ base = buildSignatureBase(params, {
398
+ method: input.method,
399
+ authority: input.authority,
400
+ path: input.path,
401
+ agentIdentity: input.agentIdentity,
402
+ extra: input.extraComponents
403
+ }, rawParams);
404
+ } catch (err) {
405
+ if (err instanceof MissingComponentError) {
406
+ return { ok: false, reason: "missing_covered_component" };
407
+ }
408
+ throw err;
409
+ }
410
+ let valid;
411
+ try {
412
+ const key = await importJWK(input.cnfJwk, "EdDSA");
413
+ if (!(key instanceof CryptoKey)) {
414
+ return { ok: false, reason: "signature_invalid" };
415
+ }
416
+ valid = await subtle.verify(
417
+ { name: "Ed25519" },
418
+ key,
419
+ sig,
420
+ new TextEncoder().encode(base)
421
+ );
422
+ } catch {
423
+ return { ok: false, reason: "signature_invalid" };
424
+ }
425
+ return valid ? { ok: true, params } : { ok: false, reason: "signature_invalid" };
426
+ };
427
+
428
+ // src/aip/types.ts
429
+ var isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
430
+ var isNonEmptyString = (v) => typeof v === "string" && v.length > 0;
431
+ var isAitShape = (payload) => isObject(payload) && isObject(payload.cnf) && isObject(payload.agent);
432
+ var validateAitPayload = (payload) => {
433
+ if (!isObject(payload)) {
434
+ return { ok: false, reason: "not_an_object" };
435
+ }
436
+ if (!isNonEmptyString(payload.aip_version)) {
437
+ return { ok: false, reason: "missing_aip_version" };
438
+ }
439
+ if (!isNonEmptyString(payload.iss)) {
440
+ return { ok: false, reason: "missing_iss" };
441
+ }
442
+ if (!isNonEmptyString(payload.sub)) {
443
+ return { ok: false, reason: "missing_sub" };
444
+ }
445
+ if (typeof payload.iat !== "number") {
446
+ return { ok: false, reason: "missing_iat" };
447
+ }
448
+ if (typeof payload.exp !== "number") {
449
+ return { ok: false, reason: "missing_exp" };
450
+ }
451
+ if (!isObject(payload.cnf) || !isObject(payload.cnf.jwk)) {
452
+ return { ok: false, reason: "missing_cnf" };
453
+ }
454
+ if (!isObject(payload.agent) || !isNonEmptyString(payload.agent.provider)) {
455
+ return { ok: false, reason: "missing_agent_provider" };
456
+ }
457
+ if (payload.trust_level === "human_confirmed") {
458
+ const auth = payload.auth;
459
+ const amr = isObject(auth) ? auth.amr : void 0;
460
+ if (!Array.isArray(amr) || amr.length === 0) {
461
+ return { ok: false, reason: "human_confirmed_without_amr" };
462
+ }
463
+ }
464
+ return { ok: true, payload };
465
+ };
466
+
467
+ // src/aip/verify.ts
468
+ var verifyAit = async (ctx, opts) => {
469
+ if (ctx.agentIdentityHeaders.length === 0) {
470
+ return { ok: false, reason: "no_token" };
471
+ }
472
+ if (!ctx.signatureInput || !ctx.signature) {
473
+ return { ok: false, reason: "pop_signature_missing" };
474
+ }
475
+ const signatureInput = ctx.signatureInput;
476
+ const signature = ctx.signature;
477
+ let lastFailure = "malformed_token";
478
+ for (const raw of ctx.agentIdentityHeaders) {
479
+ const token = stripBearer(raw);
480
+ let header;
481
+ let payload;
482
+ try {
483
+ header = decodeProtectedHeader(token);
484
+ payload = decodeJwt(token);
485
+ } catch {
486
+ lastFailure = "malformed_token";
487
+ continue;
488
+ }
489
+ if (header.alg === void 0 || header.alg.toLowerCase() === "none") {
490
+ lastFailure = "malformed_token";
491
+ continue;
492
+ }
493
+ if (!isAitShape(payload)) {
494
+ lastFailure = "malformed_token";
495
+ continue;
496
+ }
497
+ const validated = validateAitPayload(payload);
498
+ if (!validated.ok) {
499
+ lastFailure = "invalid_claims";
500
+ continue;
501
+ }
502
+ const claims = validated.payload;
503
+ const keyLookup = await opts.jwks.getKey(claims.iss, header.kid);
504
+ if (!keyLookup.ok) {
505
+ lastFailure = keyLookup.reason === "untrusted_issuer" || keyLookup.reason === "insecure_issuer" ? "untrusted_issuer" : "key_unavailable";
506
+ continue;
507
+ }
508
+ const jwtClockTolerance = opts.maxSkewSeconds ?? 60;
509
+ try {
510
+ const idpKey = await importJWK2(keyLookup.key, normalizeAlg(header.alg));
511
+ await jwtVerify(token, idpKey, {
512
+ // Pin the signature algorithm allowlist (RFC 8725 §3.1) — also rejects `alg:none`. Without
513
+ // this, jose accepts whatever alg the resolved JWK supports, so a trusted IdP publishing a
514
+ // non-Ed25519 (e.g. RSA/EC) `use:sig` key would let an attacker present an RS256/ES256
515
+ // token that verifies. Matches the server-side allowlist in the AgentScore API verifier.
516
+ algorithms: AIT_SIGNING_ALGS,
517
+ clockTolerance: jwtClockTolerance,
518
+ currentDate: opts.now !== void 0 ? new Date(opts.now * 1e3) : void 0
519
+ });
520
+ } catch (err) {
521
+ lastFailure = isExpiry(err) ? "expired_token" : "idp_signature_invalid";
522
+ continue;
523
+ }
524
+ const nowSec = opts.now ?? Math.floor(Date.now() / 1e3);
525
+ if (claims.iat > nowSec + jwtClockTolerance) {
526
+ lastFailure = "expired_token";
527
+ continue;
528
+ }
529
+ if (claims.exp - claims.iat > (opts.maxLifetimeSeconds ?? 300)) {
530
+ lastFailure = "expired_token";
531
+ continue;
532
+ }
533
+ const popResult = await verifyMessageSignature({
534
+ method: ctx.method,
535
+ authority: ctx.authority,
536
+ path: ctx.path,
537
+ // The agent-identity covered component is the BARE AIT (a Bearer prefix, if present, is
538
+ // transport that `stripBearer` removed above). Verify over `token`, not `raw`, so the edge and
539
+ // the API — which verifies over the forwarded bare aip_token — reconstruct the identical base.
540
+ agentIdentity: token,
541
+ signatureInput,
542
+ signature,
543
+ cnfJwk: claims.cnf.jwk,
544
+ now: opts.now,
545
+ maxSkewSeconds: opts.maxSkewSeconds
546
+ });
547
+ if (!popResult.ok) {
548
+ lastFailure = "pop_signature_invalid";
549
+ continue;
550
+ }
551
+ return {
552
+ ok: true,
553
+ ait: {
554
+ payload: claims,
555
+ iss: claims.iss,
556
+ cnfJwk: claims.cnf.jwk,
557
+ token,
558
+ signatureMaterial: {
559
+ method: ctx.method,
560
+ authority: ctx.authority,
561
+ path: ctx.path,
562
+ signature_input: signatureInput,
563
+ signature
564
+ }
565
+ }
566
+ };
567
+ }
568
+ return { ok: false, reason: lastFailure };
569
+ };
570
+ var stripBearer = (value) => {
571
+ const trimmed = value.trim();
572
+ return /^bearer\s+/i.test(trimmed) ? trimmed.replace(/^bearer\s+/i, "") : trimmed;
573
+ };
574
+ var AIT_SIGNING_ALGS = ["EdDSA", "ES256"];
575
+ var normalizeAlg = (alg) => alg.toLowerCase() === "eddsa" ? "EdDSA" : alg;
576
+ var isExpiry = (err) => typeof err === "object" && err !== null && err.code === "ERR_JWT_EXPIRED";
577
+
578
+ // src/aip/request.ts
579
+ var readNodeHeader = (headers, name) => {
580
+ const v = headers[name] ?? headers[name.toLowerCase()];
581
+ if (v === void 0) {
582
+ return void 0;
583
+ }
584
+ return Array.isArray(v) ? v.join(", ") : v;
585
+ };
586
+ var hasAgentIdentityHeaderNode = (headers) => {
587
+ const raw = readNodeHeader(headers, "agent-identity");
588
+ return raw !== void 0 && raw.split(",").some((s) => s.trim().length > 0);
589
+ };
590
+ var buildVerifyContextFromParts = (parts) => {
591
+ const agentIdentityRaw = readNodeHeader(parts.headers, "agent-identity");
592
+ const agentIdentityHeaders = agentIdentityRaw ? agentIdentityRaw.split(",").map((s) => s.trim()).filter((s) => s.length > 0) : [];
593
+ const host = parts.authority ?? readNodeHeader(parts.headers, "host") ?? "";
594
+ let path;
595
+ try {
596
+ if (/^[a-z][a-z0-9+.-]*:\/\//i.test(parts.url)) {
597
+ path = new URL(parts.url).pathname;
598
+ } else {
599
+ const target = parts.url.startsWith("/") ? parts.url : `/${parts.url}`;
600
+ path = new URL(`http://${host || "localhost"}${target}`).pathname;
601
+ }
602
+ } catch {
603
+ const q = parts.url.indexOf("?");
604
+ path = q === -1 ? parts.url : parts.url.slice(0, q);
605
+ }
606
+ return {
607
+ method: parts.method,
608
+ authority: host,
609
+ path,
610
+ agentIdentityHeaders,
611
+ signatureInput: readNodeHeader(parts.headers, "signature-input") ?? null,
612
+ signature: readNodeHeader(parts.headers, "signature") ?? null
613
+ };
614
+ };
615
+
616
+ // src/aip/gate.ts
617
+ var partsWithAuthority = (parts, opts) => {
618
+ const authority = parts.authority ?? opts.authority;
619
+ return authority !== void 0 ? { ...parts, authority } : parts;
620
+ };
621
+ var aipErrorCode = (failure) => {
622
+ switch (failure) {
623
+ case "no_token":
624
+ case "pop_signature_missing":
625
+ return "agent_identity_required";
626
+ case "untrusted_issuer":
627
+ return "untrusted_issuer";
628
+ case "expired_token":
629
+ return "expired_token";
630
+ case "invalid_claims":
631
+ return "insufficient_claims";
632
+ case "key_unavailable":
633
+ return "idp_unavailable";
634
+ case "malformed_token":
635
+ case "idp_signature_invalid":
636
+ case "pop_signature_invalid":
637
+ return "invalid_signature";
638
+ default:
639
+ return "invalid_signature";
640
+ }
641
+ };
642
+ var aipErrorStatus = (failure) => {
643
+ switch (failure) {
644
+ case "key_unavailable":
645
+ return 503;
646
+ case "untrusted_issuer":
647
+ case "invalid_claims":
648
+ return 403;
649
+ default:
650
+ return 401;
651
+ }
652
+ };
653
+ var aipErrorDetail = (failure) => {
654
+ switch (failure) {
655
+ case "no_token":
656
+ return "No Agent-Identity token was presented.";
657
+ case "pop_signature_missing":
658
+ return "The request is missing the RFC 9421 HTTP Message Signature that proves possession of the token-bound key.";
659
+ case "untrusted_issuer":
660
+ return "The token's issuer is not in this service's trusted-issuer list.";
661
+ case "expired_token":
662
+ return "The Agent Identity Token has expired.";
663
+ case "invalid_claims":
664
+ return "The token is missing required claims for this endpoint.";
665
+ case "malformed_token":
666
+ return "The Agent-Identity header could not be parsed as an Agent Identity Token.";
667
+ case "idp_signature_invalid":
668
+ return "The identity provider's signature on the token failed verification.";
669
+ case "pop_signature_invalid":
670
+ return "The request signature did not match the key bound to the token.";
671
+ case "key_unavailable":
672
+ return "The identity provider's signing key could not be resolved.";
673
+ default:
674
+ return "Token verification failed.";
675
+ }
676
+ };
677
+ var buildAipErrorBody = (failure, requirements) => {
678
+ const code = aipErrorCode(failure);
679
+ const body = {
680
+ type: `urn:aip:error:${code}`,
681
+ title: code.replace(/_/g, " "),
682
+ status: aipErrorStatus(failure),
683
+ detail: aipErrorDetail(failure)
684
+ };
685
+ if (requirements) {
686
+ if (code === "untrusted_issuer" && requirements.trustedIssuers?.length) {
687
+ body.trusted_issuers = requirements.trustedIssuers;
688
+ }
689
+ if (code === "insufficient_claims") {
690
+ if (requirements.requiredClaims?.length) body.required_claims = requirements.requiredClaims;
691
+ if (requirements.requiredTrustLevel !== void 0) body.required_trust_level = requirements.requiredTrustLevel;
692
+ if (requirements.requiredAmr?.length) body.required_amr = requirements.requiredAmr;
693
+ }
694
+ }
695
+ return body;
696
+ };
697
+ var TRUST_RANK = { autonomous: 0, human_present: 1, human_confirmed: 2 };
698
+ var checkTrustRequirements = (payload, requiredTrustLevel, requiredAmr) => {
699
+ if (requiredTrustLevel !== void 0) {
700
+ const have = TRUST_RANK[payload.trust_level ?? "autonomous"] ?? 0;
701
+ const need = TRUST_RANK[requiredTrustLevel] ?? 0;
702
+ if (have < need) {
703
+ return `This endpoint requires trust_level '${requiredTrustLevel}'; the token asserts '${payload.trust_level ?? "autonomous"}'. Re-mint an AIT at the required trust level (human confirmation).`;
704
+ }
705
+ }
706
+ if (requiredAmr !== void 0 && requiredAmr.length > 0) {
707
+ const amr = Array.isArray(payload.auth?.amr) ? payload.auth.amr : [];
708
+ if (!amr.some((m) => requiredAmr.includes(m))) {
709
+ return `This endpoint requires an authentication method in [${requiredAmr.join(", ")}]; the token carries [${amr.join(", ") || "none"}].`;
710
+ }
711
+ }
712
+ return null;
713
+ };
714
+ var buildAipWeakAuthBody = (opts) => ({
715
+ type: "urn:aip:error:weak_auth",
716
+ title: "weak auth",
717
+ status: 403,
718
+ detail: opts.detail,
719
+ ...opts.requiredTrustLevel !== void 0 && { required_trust_level: opts.requiredTrustLevel },
720
+ ...opts.requiredAmr !== void 0 && opts.requiredAmr.length > 0 && { required_amr: opts.requiredAmr },
721
+ ...opts.trustedIssuers !== void 0 && opts.trustedIssuers.length > 0 && { trusted_issuers: opts.trustedIssuers }
722
+ });
723
+ var requirementsFromOptions = (opts) => ({
724
+ ...opts.trustedIssuers !== void 0 && { trustedIssuers: opts.trustedIssuers },
725
+ ...opts.requiredClaims !== void 0 && { requiredClaims: opts.requiredClaims },
726
+ ...opts.requireTrustLevel !== void 0 && { requiredTrustLevel: opts.requireTrustLevel },
727
+ ...opts.requireAmr !== void 0 && { requiredAmr: opts.requireAmr }
728
+ });
729
+ var evaluateFromContext = async (ctx, opts) => {
730
+ const result = await verifyAit(ctx, { jwks: opts.jwks, now: opts.now, maxSkewSeconds: opts.maxSkewSeconds });
731
+ if (!result.ok) {
732
+ return { ok: false, body: buildAipErrorBody(result.reason, requirementsFromOptions(opts)) };
733
+ }
734
+ const weak = checkTrustRequirements(result.ait.payload, opts.requireTrustLevel, opts.requireAmr);
735
+ if (weak !== null) {
736
+ return {
737
+ ok: false,
738
+ body: buildAipWeakAuthBody({
739
+ detail: weak,
740
+ ...opts.requireTrustLevel !== void 0 && { requiredTrustLevel: opts.requireTrustLevel },
741
+ ...opts.requireAmr !== void 0 && { requiredAmr: opts.requireAmr },
742
+ ...opts.trustedIssuers !== void 0 && { trustedIssuers: opts.trustedIssuers }
743
+ })
744
+ };
745
+ }
746
+ return { ok: true, ait: result.ait };
747
+ };
748
+ var evaluateAipParts = (parts, opts) => evaluateFromContext(buildVerifyContextFromParts(partsWithAuthority(parts, opts)), opts);
749
+
134
750
  // src/core.ts
751
+ import { createHash } from "crypto";
135
752
  import {
136
753
  AgentScore,
137
754
  InvalidCredentialError,
@@ -207,7 +824,7 @@ function stripTrailingSlashes(s) {
207
824
  while (end > 0 && s.charCodeAt(end - 1) === 47) end--;
208
825
  return end === s.length ? s : s.slice(0, end);
209
826
  }
210
- var CANONICAL_AGENTSCORE_API = "https://api.agentscore.sh";
827
+ var CANONICAL_AGENTSCORE_API = "https://api.agentscore.com";
211
828
  var WALLET_SIGNER_MISMATCH_INSTRUCTIONS = JSON.stringify({
212
829
  action: "resign_or_switch_to_operator_token",
213
830
  steps: [
@@ -233,17 +850,22 @@ var INVALID_CREDENTIAL_INSTRUCTIONS = JSON.stringify({
233
850
  ],
234
851
  user_message: "The operator_token is not recognized. Use a different stored token, or restart the verification session flow to mint a new one."
235
852
  });
236
- function buildAgentMemoryHint() {
853
+ function buildAgentMemoryHint(aipTrustedIssuers) {
237
854
  const api = CANONICAL_AGENTSCORE_API;
855
+ const acceptsAip = aipTrustedIssuers !== void 0 && aipTrustedIssuers.length > 0;
238
856
  return {
239
857
  save_for_future_agentscore_gates: true,
240
858
  pattern_summary: "AgentScore is a cross-merchant identity substrate for agent commerce. Any endpoint that returns 403 missing_identity / identity_verification_required or 402 challenges referencing AgentScore uses the same identity system. One KYC works across all AgentScore merchants \u2014 no re-verification per site. Save this pattern (and the endpoints below) to persistent memory so future AgentScore encounters skip the cold-start session flow.",
241
- quickstart: "https://docs.agentscore.sh/guides/agent-identity",
859
+ quickstart: "https://docs.agentscore.com/guides/agent-identity",
242
860
  identity_check_endpoint: `${api}/v1/credentials`,
243
861
  identity_paths: {
244
862
  wallet: "If paying from a crypto wallet you have used before on any AgentScore merchant, send `X-Wallet-Address: 0x...`. Shortest path; no token lifecycle to manage.",
245
- operator_token: "For any rail (Stripe SPT, card, or a wallet you have not linked yet), send `X-Operator-Token: opc_...`. Reusable across merchants until the token expires."
863
+ operator_token: "For any rail (Stripe SPT, card, or a wallet you have not linked yet), send `X-Operator-Token: opc_...`. Reusable across merchants until the token expires.",
864
+ ...acceptsAip && {
865
+ agent_identity: 'If you hold an AIP Agent Identity Token from a trusted issuer (see aip_trusted_issuers), present it: send the JWT in an `Agent-Identity` header plus an RFC 9421 HTTP Message Signature (Signature-Input + Signature over @method @authority @path agent-identity, tag="agent-identity") signed with the token-bound cnf key. The merchant verifies it and applies its policy \u2014 no separate AgentScore credential needed.'
866
+ }
246
867
  },
868
+ ...acceptsAip && { aip_trusted_issuers: aipTrustedIssuers },
247
869
  bootstrap: "If you have neither a linked wallet nor a valid operator_token, follow the session/verify flow in the per-request `agent_instructions` block. This happens at most once per agent identity \u2014 after first verification, the operator_token and any subsequently used wallet are reusable everywhere.",
248
870
  do_not_persist_in_memory: ["operator_token", "poll_secret"],
249
871
  persist_in_credential_store: ["operator_token"]
@@ -251,7 +873,7 @@ function buildAgentMemoryHint() {
251
873
  }
252
874
  function createAgentScoreCore(options) {
253
875
  if (!options.apiKey) {
254
- throw new Error("AgentScore API key is required. Get one at https://agentscore.sh/sign-up");
876
+ throw new Error("AgentScore API key is required. Get one at https://www.agentscore.com/sign-up");
255
877
  }
256
878
  const {
257
879
  apiKey,
@@ -262,14 +884,15 @@ function createAgentScoreCore(options) {
262
884
  allowedJurisdictions,
263
885
  failOpen = false,
264
886
  cacheSeconds = 300,
265
- baseUrl: rawBaseUrl = "https://api.agentscore.sh",
887
+ baseUrl: rawBaseUrl = "https://api.agentscore.com",
266
888
  chain: gateChain,
267
889
  userAgent,
268
- createSessionOnMissing
890
+ createSessionOnMissing,
891
+ aipTrustedIssuers
269
892
  } = options;
270
893
  const baseUrl = stripTrailingSlashes(rawBaseUrl);
271
- const agentMemoryHint = buildAgentMemoryHint();
272
- const defaultUa = `@agent-score/commerce@${"2.4.0"}`;
894
+ const agentMemoryHint = buildAgentMemoryHint(aipTrustedIssuers);
895
+ const defaultUa = `@agent-score/commerce@${"2.6.0"}`;
273
896
  const userAgentHeader = userAgent ? `${userAgent} (${defaultUa})` : defaultUa;
274
897
  const sdk = new AgentScore({ apiKey, baseUrl, userAgent: userAgentHeader });
275
898
  const sessionSdkCache = /* @__PURE__ */ new Map();
@@ -344,16 +967,21 @@ function createAgentScoreCore(options) {
344
967
  }
345
968
  }
346
969
  async function evaluate(identity, ctx, signer) {
347
- if (!identity || !identity.address && !identity.operatorToken) {
970
+ if (!identity || !identity.address?.trim() && !identity.operatorToken?.trim() && !identity.aipToken?.trim()) {
348
971
  if (failOpen) return { kind: "allow" };
349
972
  const sessionReason = await tryMintSessionDenial(ctx);
350
973
  if (sessionReason) return { kind: "deny", reason: sessionReason };
974
+ const acceptsAip = aipTrustedIssuers !== void 0 && aipTrustedIssuers.length > 0;
975
+ const aipStep = acceptsAip ? [
976
+ `If you hold an AIP Agent Identity Token from a trusted issuer (${aipTrustedIssuers.join(", ")}): present it \u2014 send the JWT in an Agent-Identity header plus an RFC 9421 HTTP Message Signature (Signature-Input + Signature over @method @authority @path agent-identity, tag="agent-identity") signed with the token-bound cnf key. This satisfies identity in one round trip without an AgentScore credential.`
977
+ ] : [];
351
978
  const missingIdentityInstructions = JSON.stringify({
352
979
  action: "probe_identity_then_session",
353
980
  steps: [
981
+ ...aipStep,
354
982
  "If you have a wallet AND this merchant accepts a wallet-signing rail (Tempo MPP or x402 \u2014 see openapi.json x-payment-info): send X-Wallet-Address and retry. If the wallet is already linked to an AgentScore operator (via prior SIWE claim or prior captureWallet), this passes in one round trip. If the wallet is unlinked or the account has no KYC, the 403 will include a verify_url \u2014 share it with the user to claim the wallet + complete KYC, then retry.",
355
983
  "If step 1 is denied or you already have a stored operator_token (valid + not expired): send X-Operator-Token: opc_... and retry.",
356
- "If neither applies: retry with NO identity header. Merchants that auto-create verification sessions (most AgentScore merchants do) return verify_url + session_id + poll_secret in the 403 body \u2014 share verify_url with the user, then poll poll_url every 5s with the X-Poll-Secret header until status=verified (the poll returns a one-time operator_token). If the retry returns the same bare 403, this merchant does not support self-service session bootstrapping \u2014 direct the user to https://agentscore.sh/sign-up to create an AgentScore identity and mint an operator_token from their dashboard (https://agentscore.sh/dashboard/verify). The user hands the opc_... to you, and you retry with X-Operator-Token."
984
+ "If neither applies: retry with NO identity header. Merchants that auto-create verification sessions (most AgentScore merchants do) return verify_url + session_id + poll_secret in the 403 body \u2014 share verify_url with the user, then poll poll_url every 5s with the X-Poll-Secret header until status=verified (the poll returns a one-time operator_token). If the retry returns the same bare 403, this merchant does not support self-service session bootstrapping \u2014 direct the user to https://www.agentscore.com/sign-up to create an AgentScore identity and mint an operator_token from their dashboard (https://www.agentscore.com/dashboard/verify). The user hands the opc_... to you, and you retry with X-Operator-Token."
357
985
  ],
358
986
  user_message: "Try X-Wallet-Address first if you have a wallet and the merchant accepts Tempo/x402; fall back to a stored X-Operator-Token, then to the session/verify flow described in agent_memory.bootstrap."
359
987
  });
@@ -366,21 +994,26 @@ function createAgentScoreCore(options) {
366
994
  }
367
995
  };
368
996
  }
369
- const cacheKey = identity.operatorToken?.toLowerCase() ?? (identity.address ? normalizeAddress(identity.address) : "");
997
+ const identityKey = identity.aipToken ? `aip:${createHash("sha256").update(identity.aipToken).digest("hex")}` : identity.operatorToken?.toLowerCase() ?? (identity.address ? normalizeAddress(identity.address) : "");
998
+ const cacheKey = signer ? JSON.stringify([identityKey, signer.network, normalizeAddress(signer.address)]) : JSON.stringify([identityKey]);
370
999
  const cached = cache.get(cacheKey);
371
1000
  if (cached) {
1001
+ const cachedVerdict = cached.raw ? buildSignerVerdict(identity, cached.raw) : void 0;
372
1002
  if (cached.allow) {
373
1003
  const cachedRaw = cached.raw;
374
1004
  const cachedQuota = cachedRaw?.quota;
375
1005
  return {
376
1006
  kind: "allow",
377
1007
  data: cachedRaw,
378
- ...cachedQuota !== void 0 && { quota: cachedQuota }
1008
+ ...cachedQuota !== void 0 && { quota: cachedQuota },
1009
+ ...cachedVerdict !== void 0 && { signerVerdict: cachedVerdict }
379
1010
  };
380
1011
  }
381
1012
  if (isFixableDenial(cached.reasons)) {
382
1013
  const sessionReason = await tryMintSessionDenial(ctx);
383
- if (sessionReason) return { kind: "deny", reason: sessionReason };
1014
+ if (sessionReason) {
1015
+ return { kind: "deny", reason: sessionReason, ...cachedVerdict !== void 0 && { signerVerdict: cachedVerdict } };
1016
+ }
384
1017
  }
385
1018
  return {
386
1019
  kind: "deny",
@@ -390,7 +1023,8 @@ function createAgentScoreCore(options) {
390
1023
  reasons: cached.reasons,
391
1024
  verify_url: cached.raw?.verify_url,
392
1025
  data: cached.raw
393
- }
1026
+ },
1027
+ ...cachedVerdict !== void 0 && { signerVerdict: cachedVerdict }
394
1028
  };
395
1029
  }
396
1030
  const policy = {};
@@ -411,7 +1045,10 @@ function createAgentScoreCore(options) {
411
1045
  // regardless of policy.require_sanctions_clear (which gates the separate NAME screen).
412
1046
  ...signer && { signer: { address: signer.address, network: signer.network } }
413
1047
  };
414
- const result = identity.address ? await sdk.assess(identity.address, { ...opts, operatorToken: identity.operatorToken }) : await sdk.assess(null, { ...opts, operatorToken: identity.operatorToken });
1048
+ if (identity.aipToken !== void 0 && identity.aipSignature === void 0) {
1049
+ throw new Error("AgentScoreCore.evaluate: aipToken requires aipSignature (RFC 9421 proof-of-possession material).");
1050
+ }
1051
+ const result = identity.aipToken !== void 0 && identity.aipSignature !== void 0 ? await sdk.assess(null, { ...opts, aipToken: identity.aipToken, aipSignature: identity.aipSignature }) : identity.address ? await sdk.assess(identity.address, { ...opts, operatorToken: identity.operatorToken }) : await sdk.assess(null, { ...opts, operatorToken: identity.operatorToken });
415
1052
  data = result;
416
1053
  } catch (err) {
417
1054
  if (err instanceof PaymentRequiredError) {
@@ -482,17 +1119,21 @@ function createAgentScoreCore(options) {
482
1119
  const decisionReasons = data.decision_reasons ?? [];
483
1120
  const allow = decision === "allow" || decision == null;
484
1121
  cache.set(cacheKey, { allow, decision: decision ?? void 0, reasons: decisionReasons, raw: data });
1122
+ const signerVerdict = buildSignerVerdict(identity, data);
485
1123
  if (allow) {
486
1124
  const quota = data.quota;
487
1125
  return {
488
1126
  kind: "allow",
489
1127
  data,
490
- ...quota !== void 0 && { quota }
1128
+ ...quota !== void 0 && { quota },
1129
+ ...signerVerdict !== void 0 && { signerVerdict }
491
1130
  };
492
1131
  }
493
1132
  if (isFixableDenial(decisionReasons)) {
494
1133
  const sessionReason = await tryMintSessionDenial(ctx);
495
- if (sessionReason) return { kind: "deny", reason: sessionReason };
1134
+ if (sessionReason) {
1135
+ return { kind: "deny", reason: sessionReason, ...signerVerdict !== void 0 && { signerVerdict } };
1136
+ }
496
1137
  }
497
1138
  return {
498
1139
  kind: "deny",
@@ -502,7 +1143,8 @@ function createAgentScoreCore(options) {
502
1143
  reasons: decisionReasons,
503
1144
  verify_url: data.verify_url,
504
1145
  data
505
- }
1146
+ },
1147
+ ...signerVerdict !== void 0 && { signerVerdict }
506
1148
  };
507
1149
  }
508
1150
  async function captureWallet2(options2) {
@@ -544,22 +1186,21 @@ function createAgentScoreCore(options) {
544
1186
  agentInstructions: sm.agent_instructions ?? WALLET_SIGNER_MISMATCH_INSTRUCTIONS
545
1187
  };
546
1188
  }
547
- function getSignerVerdict2(claimedAddress) {
548
- const claimedNorm = normalizeAddress(claimedAddress);
549
- const cached = cache.get(claimedNorm);
550
- if (!cached) return void 0;
551
- const raw = cached.raw;
552
- if (!raw) return void 0;
1189
+ function buildSignerVerdict(identity, raw) {
1190
+ if (identity.address === void 0 || identity.operatorToken !== void 0 || identity.aipToken !== void 0) {
1191
+ return void 0;
1192
+ }
553
1193
  const rawMatch = raw.signer_match;
554
1194
  const rawSanctions = raw.signer_sanctions;
555
1195
  if (!rawMatch && !rawSanctions) return void 0;
1196
+ const claimedNorm = normalizeAddress(identity.address);
556
1197
  const signerNorm = rawMatch?.actual_signer ?? claimedNorm;
557
1198
  return {
558
1199
  signer_match: rawMatch ? projectSignerMatch(rawMatch, claimedNorm, signerNorm) : null,
559
1200
  signer_sanctions: rawSanctions ?? null
560
1201
  };
561
1202
  }
562
- return { evaluate, captureWallet: captureWallet2, getSignerVerdict: getSignerVerdict2 };
1203
+ return { evaluate, captureWallet: captureWallet2 };
563
1204
  }
564
1205
 
565
1206
  // src/payment/payment_header.ts
@@ -702,11 +1343,16 @@ function agentscoreGate(options) {
702
1343
  state.infraReason = outcome.infraReason;
703
1344
  }
704
1345
  if (outcome.quota) state.quota = outcome.quota;
1346
+ if (outcome.signerVerdict) state.signerVerdict = outcome.signerVerdict;
705
1347
  }
706
1348
  if (outcome.data) req.agentscore = outcome.data;
707
1349
  next();
708
1350
  return;
709
1351
  }
1352
+ if (outcome.signerVerdict) {
1353
+ const state = req[GATE_STATE_KEY];
1354
+ if (state) state.signerVerdict = outcome.signerVerdict;
1355
+ }
710
1356
  onDenied(req, res, outcome.reason);
711
1357
  };
712
1358
  }
@@ -733,8 +1379,7 @@ async function captureWallet(req, options) {
733
1379
  }
734
1380
  function getSignerVerdict(req) {
735
1381
  const state = req[GATE_STATE_KEY];
736
- if (!state?.walletAddress) return void 0;
737
- return state.core.getSignerVerdict(state.walletAddress);
1382
+ return state?.signerVerdict;
738
1383
  }
739
1384
  function conditionalAgentscoreGate(options) {
740
1385
  const gate = agentscoreGate(options);
@@ -746,13 +1391,48 @@ function conditionalAgentscoreGate(options) {
746
1391
  return gate(req, res, next);
747
1392
  };
748
1393
  }
1394
+ var AIT_STATE_KEY = "__agentscoreAit";
1395
+ function defaultAipOnDenied(_req, res, body) {
1396
+ res.status(body.status).type("application/problem+json").json(body);
1397
+ }
1398
+ function aipGate(options) {
1399
+ const { onDenied = defaultAipOnDenied, ...gateOpts } = options;
1400
+ return async function aipGateMiddleware(req, res, next) {
1401
+ const result = await evaluateAipParts(
1402
+ { method: req.method, url: req.url, headers: req.headers },
1403
+ gateOpts
1404
+ );
1405
+ if (!result.ok) {
1406
+ onDenied(req, res, result.body);
1407
+ return;
1408
+ }
1409
+ req[AIT_STATE_KEY] = result.ait;
1410
+ next();
1411
+ };
1412
+ }
1413
+ function conditionalAipGate(options) {
1414
+ const gate = aipGate(options);
1415
+ return async function conditionalAipMiddleware(req, res, next) {
1416
+ if (!hasAgentIdentityHeaderNode(req.headers)) {
1417
+ next();
1418
+ return;
1419
+ }
1420
+ return gate(req, res, next);
1421
+ };
1422
+ }
1423
+ function getVerifiedAit(req) {
1424
+ return req[AIT_STATE_KEY];
1425
+ }
749
1426
  export {
750
1427
  agentscoreGate,
1428
+ aipGate,
751
1429
  captureWallet,
752
1430
  conditionalAgentscoreGate,
1431
+ conditionalAipGate,
753
1432
  getAgentScoreData,
754
1433
  getGateDegradedState,
755
1434
  getGateQuotaInfo,
756
- getSignerVerdict
1435
+ getSignerVerdict,
1436
+ getVerifiedAit
757
1437
  };
758
1438
  //# sourceMappingURL=express.mjs.map