@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
@@ -21,13 +21,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var fastify_exports = {};
22
22
  __export(fastify_exports, {
23
23
  agentscoreGate: () => agentscoreGate,
24
+ aipGate: () => aipGate,
24
25
  captureWallet: () => captureWallet,
25
26
  conditionalAgentscoreGate: () => conditionalAgentscoreGate,
27
+ conditionalAipGate: () => conditionalAipGate,
26
28
  default: () => fastify_default,
27
29
  getAgentScoreData: () => getAgentScoreData,
28
30
  getGateDegradedState: () => getGateDegradedState,
29
31
  getGateQuotaInfo: () => getGateQuotaInfo,
30
- getSignerVerdict: () => getSignerVerdict
32
+ getSignerVerdict: () => getSignerVerdict,
33
+ getVerifiedAit: () => getVerifiedAit
31
34
  });
32
35
  module.exports = __toCommonJS(fastify_exports);
33
36
 
@@ -77,7 +80,7 @@ var IDENTITY_VERIFICATION_REQUIRED_FALLBACK_INSTRUCTIONS = JSON.stringify({
77
80
  var API_ERROR_INSTRUCTIONS = JSON.stringify({
78
81
  action: "retry_with_backoff",
79
82
  steps: [
80
- "Verification is temporarily unavailable. Retry the request after 5\u201330 seconds with exponential backoff.",
83
+ "Verification is temporarily unavailable. Retry the request after 5-30 seconds with exponential backoff.",
81
84
  "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.",
82
85
  "If the request continues to fail after 3+ retries (~60 seconds total), surface the error to the user with the merchant's support contact."
83
86
  ],
@@ -164,7 +167,624 @@ function denialReasonToBody(reason) {
164
167
  return body;
165
168
  }
166
169
 
170
+ // src/aip/verify.ts
171
+ var import_jose2 = require("jose");
172
+
173
+ // src/aip/http-signature.ts
174
+ var import_jose = require("jose");
175
+ var { subtle } = globalThis.crypto;
176
+ var b64ToBytes = (b64) => {
177
+ const bin = atob(b64);
178
+ const out = new Uint8Array(bin.length);
179
+ for (let i = 0; i < bin.length; i++) {
180
+ out[i] = bin.charCodeAt(i);
181
+ }
182
+ return out;
183
+ };
184
+ var AIP_COVERED_COMPONENTS = ["@method", "@authority", "@path", "agent-identity"];
185
+ var AIP_SIGNATURE_TAG = "agent-identity";
186
+ var DEFAULT_MAX_SKEW_SECONDS = 60;
187
+ var MAX_POP_WINDOW_SECONDS = 120;
188
+ var normalizeAuthority = (authority) => {
189
+ const lower = authority.trim().toLowerCase();
190
+ const colon = lower.lastIndexOf(":");
191
+ if (colon === -1) {
192
+ return lower;
193
+ }
194
+ if (lower.includes("]") && colon < lower.indexOf("]")) {
195
+ return lower;
196
+ }
197
+ const host = lower.slice(0, colon);
198
+ const port = lower.slice(colon + 1);
199
+ if (port === "80" || port === "443") {
200
+ return host;
201
+ }
202
+ return lower;
203
+ };
204
+ var componentValue = (name, input) => {
205
+ switch (name) {
206
+ case "@method":
207
+ return input.method.toUpperCase();
208
+ case "@authority":
209
+ return normalizeAuthority(input.authority);
210
+ case "@path":
211
+ return input.path;
212
+ case "agent-identity":
213
+ return input.agentIdentity.trim();
214
+ default:
215
+ return input.extra?.[name] ?? null;
216
+ }
217
+ };
218
+ var serializeComponentList = (components) => `(${components.map((c) => `"${c}"`).join(" ")})`;
219
+ var serializeParams = (p) => {
220
+ const parts = [];
221
+ if (p.created !== void 0) {
222
+ parts.push(`created=${p.created}`);
223
+ }
224
+ if (p.expires !== void 0) {
225
+ parts.push(`expires=${p.expires}`);
226
+ }
227
+ if (p.keyid !== void 0) {
228
+ parts.push(`keyid="${p.keyid}"`);
229
+ }
230
+ if (p.alg !== void 0) {
231
+ parts.push(`alg="${p.alg}"`);
232
+ }
233
+ if (p.tag !== void 0) {
234
+ parts.push(`tag="${p.tag}"`);
235
+ }
236
+ return parts.map((s) => `;${s}`).join("");
237
+ };
238
+ var buildSignatureBase = (params, input, rawSignatureParams) => {
239
+ const lines = [];
240
+ for (const name of params.components) {
241
+ const value = componentValue(name, input);
242
+ if (value === null) {
243
+ throw new MissingComponentError(name);
244
+ }
245
+ lines.push(`"${name}": ${value}`);
246
+ }
247
+ const paramsValue = rawSignatureParams ?? serializeComponentList(params.components) + serializeParams(params);
248
+ lines.push(`"@signature-params": ${paramsValue}`);
249
+ return lines.join("\n");
250
+ };
251
+ var MissingComponentError = class extends Error {
252
+ constructor(component) {
253
+ super(`signature base missing covered component: ${component}`);
254
+ this.component = component;
255
+ this.name = "MissingComponentError";
256
+ }
257
+ component;
258
+ };
259
+ var parseSignatureInput = (header, tag = AIP_SIGNATURE_TAG) => {
260
+ const members = splitDictionary(header);
261
+ if (members.length === 0) {
262
+ return null;
263
+ }
264
+ const parsed = members.map((m) => {
265
+ const params = parseInnerListMember(m.value);
266
+ return params ? { label: m.label, params, rawParams: m.value } : null;
267
+ }).filter((x) => x !== null);
268
+ if (parsed.length === 0) {
269
+ return null;
270
+ }
271
+ return parsed.find((p) => p.params.tag === tag) ?? null;
272
+ };
273
+ var parseSignatureValue = (header, label) => {
274
+ const members = splitDictionary(header);
275
+ const member = members.find((m) => m.label === label);
276
+ if (!member) {
277
+ return null;
278
+ }
279
+ const v = member.value.trim();
280
+ if (!v.startsWith(":") || !v.endsWith(":") || v.length < 2) {
281
+ return null;
282
+ }
283
+ const b64 = v.slice(1, -1);
284
+ try {
285
+ return b64ToBytes(b64);
286
+ } catch {
287
+ return null;
288
+ }
289
+ };
290
+ var splitDictionary = (header) => {
291
+ const out = [];
292
+ let depth = 0;
293
+ let inBytes = false;
294
+ let inString = false;
295
+ let current = "";
296
+ for (let i = 0; i < header.length; i++) {
297
+ const ch = header[i];
298
+ if (inString) {
299
+ current += ch;
300
+ if (ch === '"' && header[i - 1] !== "\\") {
301
+ inString = false;
302
+ }
303
+ continue;
304
+ }
305
+ if (ch === '"') {
306
+ inString = true;
307
+ current += ch;
308
+ continue;
309
+ }
310
+ if (ch === ":") {
311
+ inBytes = !inBytes;
312
+ current += ch;
313
+ continue;
314
+ }
315
+ if (!inBytes && ch === "(") {
316
+ depth++;
317
+ current += ch;
318
+ continue;
319
+ }
320
+ if (!inBytes && ch === ")") {
321
+ depth = Math.max(0, depth - 1);
322
+ current += ch;
323
+ continue;
324
+ }
325
+ if (!inBytes && depth === 0 && ch === ",") {
326
+ pushMember(out, current);
327
+ current = "";
328
+ continue;
329
+ }
330
+ current += ch;
331
+ }
332
+ pushMember(out, current);
333
+ return out;
334
+ };
335
+ var pushMember = (out, raw) => {
336
+ const trimmed = raw.trim();
337
+ if (!trimmed) {
338
+ return;
339
+ }
340
+ const eq = trimmed.indexOf("=");
341
+ if (eq === -1) {
342
+ return;
343
+ }
344
+ const label = trimmed.slice(0, eq).trim();
345
+ const value = trimmed.slice(eq + 1).trim();
346
+ if (label) {
347
+ out.push({ label, value });
348
+ }
349
+ };
350
+ var parseInnerListMember = (value) => {
351
+ const open = value.indexOf("(");
352
+ const close = value.indexOf(")", open + 1);
353
+ if (open === -1 || close === -1) {
354
+ return null;
355
+ }
356
+ const listBody = value.slice(open + 1, close).trim();
357
+ const components = listBody.length === 0 ? [] : (listBody.match(/"[^"]*"/g) ?? []).map((s) => s.slice(1, -1));
358
+ const params = { components };
359
+ const paramStr = value.slice(close + 1);
360
+ const re = /;\s*([a-zA-Z][a-zA-Z0-9_-]*)\s*=\s*("(?:[^"\\]|\\.)*"|-?\d+)/g;
361
+ let match;
362
+ while ((match = re.exec(paramStr)) !== null) {
363
+ const key = match[1];
364
+ const raw = match[2];
365
+ const val = raw.startsWith('"') ? raw.slice(1, -1) : Number(raw);
366
+ if (key === "created") {
367
+ params.created = val;
368
+ } else if (key === "expires") {
369
+ params.expires = val;
370
+ } else if (key === "keyid") {
371
+ params.keyid = val;
372
+ } else if (key === "tag") {
373
+ params.tag = val;
374
+ } else if (key === "alg") {
375
+ params.alg = val;
376
+ }
377
+ }
378
+ return params;
379
+ };
380
+ var verifyMessageSignature = async (input) => {
381
+ const selected = parseSignatureInput(input.signatureInput);
382
+ if (!selected) {
383
+ return { ok: false, reason: "no_aip_signature" };
384
+ }
385
+ const { label, params, rawParams } = selected;
386
+ if (params.alg !== void 0 && !["ed25519", "eddsa"].includes(params.alg.toLowerCase())) {
387
+ return { ok: false, reason: "unsupported_alg" };
388
+ }
389
+ for (const required of AIP_COVERED_COMPONENTS) {
390
+ if (!params.components.includes(required)) {
391
+ return { ok: false, reason: "missing_covered_component" };
392
+ }
393
+ }
394
+ if (params.created === void 0) {
395
+ return { ok: false, reason: "created_missing" };
396
+ }
397
+ if (params.expires === void 0) {
398
+ return { ok: false, reason: "expires_missing" };
399
+ }
400
+ if (params.expires < params.created || params.expires - params.created > MAX_POP_WINDOW_SECONDS) {
401
+ return { ok: false, reason: "pop_window_too_long" };
402
+ }
403
+ const now = input.now ?? Math.floor(Date.now() / 1e3);
404
+ const skew = input.maxSkewSeconds ?? DEFAULT_MAX_SKEW_SECONDS;
405
+ if (params.created > now + skew) {
406
+ return { ok: false, reason: "created_in_future" };
407
+ }
408
+ if (params.expires < now - skew) {
409
+ return { ok: false, reason: "expired" };
410
+ }
411
+ if (!params.keyid) {
412
+ return { ok: false, reason: "missing_keyid" };
413
+ }
414
+ const cnf = input.cnfJwk;
415
+ if (cnf.kty !== "OKP" || cnf.crv !== "Ed25519" || typeof cnf.x !== "string" || cnf.x.length === 0) {
416
+ return { ok: false, reason: "unsupported_cnf_key" };
417
+ }
418
+ let thumbprint;
419
+ try {
420
+ thumbprint = await (0, import_jose.calculateJwkThumbprint)(input.cnfJwk, "sha256");
421
+ } catch {
422
+ return { ok: false, reason: "unsupported_cnf_key" };
423
+ }
424
+ if (params.keyid !== thumbprint) {
425
+ return { ok: false, reason: "keyid_mismatch" };
426
+ }
427
+ const sig = parseSignatureValue(input.signature, label);
428
+ if (!sig) {
429
+ return { ok: false, reason: "malformed_signature" };
430
+ }
431
+ let base;
432
+ try {
433
+ base = buildSignatureBase(params, {
434
+ method: input.method,
435
+ authority: input.authority,
436
+ path: input.path,
437
+ agentIdentity: input.agentIdentity,
438
+ extra: input.extraComponents
439
+ }, rawParams);
440
+ } catch (err) {
441
+ if (err instanceof MissingComponentError) {
442
+ return { ok: false, reason: "missing_covered_component" };
443
+ }
444
+ throw err;
445
+ }
446
+ let valid;
447
+ try {
448
+ const key = await (0, import_jose.importJWK)(input.cnfJwk, "EdDSA");
449
+ if (!(key instanceof CryptoKey)) {
450
+ return { ok: false, reason: "signature_invalid" };
451
+ }
452
+ valid = await subtle.verify(
453
+ { name: "Ed25519" },
454
+ key,
455
+ sig,
456
+ new TextEncoder().encode(base)
457
+ );
458
+ } catch {
459
+ return { ok: false, reason: "signature_invalid" };
460
+ }
461
+ return valid ? { ok: true, params } : { ok: false, reason: "signature_invalid" };
462
+ };
463
+
464
+ // src/aip/types.ts
465
+ var isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
466
+ var isNonEmptyString = (v) => typeof v === "string" && v.length > 0;
467
+ var isAitShape = (payload) => isObject(payload) && isObject(payload.cnf) && isObject(payload.agent);
468
+ var validateAitPayload = (payload) => {
469
+ if (!isObject(payload)) {
470
+ return { ok: false, reason: "not_an_object" };
471
+ }
472
+ if (!isNonEmptyString(payload.aip_version)) {
473
+ return { ok: false, reason: "missing_aip_version" };
474
+ }
475
+ if (!isNonEmptyString(payload.iss)) {
476
+ return { ok: false, reason: "missing_iss" };
477
+ }
478
+ if (!isNonEmptyString(payload.sub)) {
479
+ return { ok: false, reason: "missing_sub" };
480
+ }
481
+ if (typeof payload.iat !== "number") {
482
+ return { ok: false, reason: "missing_iat" };
483
+ }
484
+ if (typeof payload.exp !== "number") {
485
+ return { ok: false, reason: "missing_exp" };
486
+ }
487
+ if (!isObject(payload.cnf) || !isObject(payload.cnf.jwk)) {
488
+ return { ok: false, reason: "missing_cnf" };
489
+ }
490
+ if (!isObject(payload.agent) || !isNonEmptyString(payload.agent.provider)) {
491
+ return { ok: false, reason: "missing_agent_provider" };
492
+ }
493
+ if (payload.trust_level === "human_confirmed") {
494
+ const auth = payload.auth;
495
+ const amr = isObject(auth) ? auth.amr : void 0;
496
+ if (!Array.isArray(amr) || amr.length === 0) {
497
+ return { ok: false, reason: "human_confirmed_without_amr" };
498
+ }
499
+ }
500
+ return { ok: true, payload };
501
+ };
502
+
503
+ // src/aip/verify.ts
504
+ var verifyAit = async (ctx, opts) => {
505
+ if (ctx.agentIdentityHeaders.length === 0) {
506
+ return { ok: false, reason: "no_token" };
507
+ }
508
+ if (!ctx.signatureInput || !ctx.signature) {
509
+ return { ok: false, reason: "pop_signature_missing" };
510
+ }
511
+ const signatureInput = ctx.signatureInput;
512
+ const signature = ctx.signature;
513
+ let lastFailure = "malformed_token";
514
+ for (const raw of ctx.agentIdentityHeaders) {
515
+ const token = stripBearer(raw);
516
+ let header;
517
+ let payload;
518
+ try {
519
+ header = (0, import_jose2.decodeProtectedHeader)(token);
520
+ payload = (0, import_jose2.decodeJwt)(token);
521
+ } catch {
522
+ lastFailure = "malformed_token";
523
+ continue;
524
+ }
525
+ if (header.alg === void 0 || header.alg.toLowerCase() === "none") {
526
+ lastFailure = "malformed_token";
527
+ continue;
528
+ }
529
+ if (!isAitShape(payload)) {
530
+ lastFailure = "malformed_token";
531
+ continue;
532
+ }
533
+ const validated = validateAitPayload(payload);
534
+ if (!validated.ok) {
535
+ lastFailure = "invalid_claims";
536
+ continue;
537
+ }
538
+ const claims = validated.payload;
539
+ const keyLookup = await opts.jwks.getKey(claims.iss, header.kid);
540
+ if (!keyLookup.ok) {
541
+ lastFailure = keyLookup.reason === "untrusted_issuer" || keyLookup.reason === "insecure_issuer" ? "untrusted_issuer" : "key_unavailable";
542
+ continue;
543
+ }
544
+ const jwtClockTolerance = opts.maxSkewSeconds ?? 60;
545
+ try {
546
+ const idpKey = await (0, import_jose2.importJWK)(keyLookup.key, normalizeAlg(header.alg));
547
+ await (0, import_jose2.jwtVerify)(token, idpKey, {
548
+ // Pin the signature algorithm allowlist (RFC 8725 §3.1) — also rejects `alg:none`. Without
549
+ // this, jose accepts whatever alg the resolved JWK supports, so a trusted IdP publishing a
550
+ // non-Ed25519 (e.g. RSA/EC) `use:sig` key would let an attacker present an RS256/ES256
551
+ // token that verifies. Matches the server-side allowlist in the AgentScore API verifier.
552
+ algorithms: AIT_SIGNING_ALGS,
553
+ clockTolerance: jwtClockTolerance,
554
+ currentDate: opts.now !== void 0 ? new Date(opts.now * 1e3) : void 0
555
+ });
556
+ } catch (err) {
557
+ lastFailure = isExpiry(err) ? "expired_token" : "idp_signature_invalid";
558
+ continue;
559
+ }
560
+ const nowSec = opts.now ?? Math.floor(Date.now() / 1e3);
561
+ if (claims.iat > nowSec + jwtClockTolerance) {
562
+ lastFailure = "expired_token";
563
+ continue;
564
+ }
565
+ if (claims.exp - claims.iat > (opts.maxLifetimeSeconds ?? 300)) {
566
+ lastFailure = "expired_token";
567
+ continue;
568
+ }
569
+ const popResult = await verifyMessageSignature({
570
+ method: ctx.method,
571
+ authority: ctx.authority,
572
+ path: ctx.path,
573
+ // The agent-identity covered component is the BARE AIT (a Bearer prefix, if present, is
574
+ // transport that `stripBearer` removed above). Verify over `token`, not `raw`, so the edge and
575
+ // the API — which verifies over the forwarded bare aip_token — reconstruct the identical base.
576
+ agentIdentity: token,
577
+ signatureInput,
578
+ signature,
579
+ cnfJwk: claims.cnf.jwk,
580
+ now: opts.now,
581
+ maxSkewSeconds: opts.maxSkewSeconds
582
+ });
583
+ if (!popResult.ok) {
584
+ lastFailure = "pop_signature_invalid";
585
+ continue;
586
+ }
587
+ return {
588
+ ok: true,
589
+ ait: {
590
+ payload: claims,
591
+ iss: claims.iss,
592
+ cnfJwk: claims.cnf.jwk,
593
+ token,
594
+ signatureMaterial: {
595
+ method: ctx.method,
596
+ authority: ctx.authority,
597
+ path: ctx.path,
598
+ signature_input: signatureInput,
599
+ signature
600
+ }
601
+ }
602
+ };
603
+ }
604
+ return { ok: false, reason: lastFailure };
605
+ };
606
+ var stripBearer = (value) => {
607
+ const trimmed = value.trim();
608
+ return /^bearer\s+/i.test(trimmed) ? trimmed.replace(/^bearer\s+/i, "") : trimmed;
609
+ };
610
+ var AIT_SIGNING_ALGS = ["EdDSA", "ES256"];
611
+ var normalizeAlg = (alg) => alg.toLowerCase() === "eddsa" ? "EdDSA" : alg;
612
+ var isExpiry = (err) => typeof err === "object" && err !== null && err.code === "ERR_JWT_EXPIRED";
613
+
614
+ // src/aip/request.ts
615
+ var readNodeHeader = (headers, name) => {
616
+ const v = headers[name] ?? headers[name.toLowerCase()];
617
+ if (v === void 0) {
618
+ return void 0;
619
+ }
620
+ return Array.isArray(v) ? v.join(", ") : v;
621
+ };
622
+ var hasAgentIdentityHeaderNode = (headers) => {
623
+ const raw = readNodeHeader(headers, "agent-identity");
624
+ return raw !== void 0 && raw.split(",").some((s) => s.trim().length > 0);
625
+ };
626
+ var buildVerifyContextFromParts = (parts) => {
627
+ const agentIdentityRaw = readNodeHeader(parts.headers, "agent-identity");
628
+ const agentIdentityHeaders = agentIdentityRaw ? agentIdentityRaw.split(",").map((s) => s.trim()).filter((s) => s.length > 0) : [];
629
+ const host = parts.authority ?? readNodeHeader(parts.headers, "host") ?? "";
630
+ let path;
631
+ try {
632
+ if (/^[a-z][a-z0-9+.-]*:\/\//i.test(parts.url)) {
633
+ path = new URL(parts.url).pathname;
634
+ } else {
635
+ const target = parts.url.startsWith("/") ? parts.url : `/${parts.url}`;
636
+ path = new URL(`http://${host || "localhost"}${target}`).pathname;
637
+ }
638
+ } catch {
639
+ const q = parts.url.indexOf("?");
640
+ path = q === -1 ? parts.url : parts.url.slice(0, q);
641
+ }
642
+ return {
643
+ method: parts.method,
644
+ authority: host,
645
+ path,
646
+ agentIdentityHeaders,
647
+ signatureInput: readNodeHeader(parts.headers, "signature-input") ?? null,
648
+ signature: readNodeHeader(parts.headers, "signature") ?? null
649
+ };
650
+ };
651
+
652
+ // src/aip/gate.ts
653
+ var partsWithAuthority = (parts, opts) => {
654
+ const authority = parts.authority ?? opts.authority;
655
+ return authority !== void 0 ? { ...parts, authority } : parts;
656
+ };
657
+ var aipErrorCode = (failure) => {
658
+ switch (failure) {
659
+ case "no_token":
660
+ case "pop_signature_missing":
661
+ return "agent_identity_required";
662
+ case "untrusted_issuer":
663
+ return "untrusted_issuer";
664
+ case "expired_token":
665
+ return "expired_token";
666
+ case "invalid_claims":
667
+ return "insufficient_claims";
668
+ case "key_unavailable":
669
+ return "idp_unavailable";
670
+ case "malformed_token":
671
+ case "idp_signature_invalid":
672
+ case "pop_signature_invalid":
673
+ return "invalid_signature";
674
+ default:
675
+ return "invalid_signature";
676
+ }
677
+ };
678
+ var aipErrorStatus = (failure) => {
679
+ switch (failure) {
680
+ case "key_unavailable":
681
+ return 503;
682
+ case "untrusted_issuer":
683
+ case "invalid_claims":
684
+ return 403;
685
+ default:
686
+ return 401;
687
+ }
688
+ };
689
+ var aipErrorDetail = (failure) => {
690
+ switch (failure) {
691
+ case "no_token":
692
+ return "No Agent-Identity token was presented.";
693
+ case "pop_signature_missing":
694
+ return "The request is missing the RFC 9421 HTTP Message Signature that proves possession of the token-bound key.";
695
+ case "untrusted_issuer":
696
+ return "The token's issuer is not in this service's trusted-issuer list.";
697
+ case "expired_token":
698
+ return "The Agent Identity Token has expired.";
699
+ case "invalid_claims":
700
+ return "The token is missing required claims for this endpoint.";
701
+ case "malformed_token":
702
+ return "The Agent-Identity header could not be parsed as an Agent Identity Token.";
703
+ case "idp_signature_invalid":
704
+ return "The identity provider's signature on the token failed verification.";
705
+ case "pop_signature_invalid":
706
+ return "The request signature did not match the key bound to the token.";
707
+ case "key_unavailable":
708
+ return "The identity provider's signing key could not be resolved.";
709
+ default:
710
+ return "Token verification failed.";
711
+ }
712
+ };
713
+ var buildAipErrorBody = (failure, requirements) => {
714
+ const code = aipErrorCode(failure);
715
+ const body = {
716
+ type: `urn:aip:error:${code}`,
717
+ title: code.replace(/_/g, " "),
718
+ status: aipErrorStatus(failure),
719
+ detail: aipErrorDetail(failure)
720
+ };
721
+ if (requirements) {
722
+ if (code === "untrusted_issuer" && requirements.trustedIssuers?.length) {
723
+ body.trusted_issuers = requirements.trustedIssuers;
724
+ }
725
+ if (code === "insufficient_claims") {
726
+ if (requirements.requiredClaims?.length) body.required_claims = requirements.requiredClaims;
727
+ if (requirements.requiredTrustLevel !== void 0) body.required_trust_level = requirements.requiredTrustLevel;
728
+ if (requirements.requiredAmr?.length) body.required_amr = requirements.requiredAmr;
729
+ }
730
+ }
731
+ return body;
732
+ };
733
+ var TRUST_RANK = { autonomous: 0, human_present: 1, human_confirmed: 2 };
734
+ var checkTrustRequirements = (payload, requiredTrustLevel, requiredAmr) => {
735
+ if (requiredTrustLevel !== void 0) {
736
+ const have = TRUST_RANK[payload.trust_level ?? "autonomous"] ?? 0;
737
+ const need = TRUST_RANK[requiredTrustLevel] ?? 0;
738
+ if (have < need) {
739
+ 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).`;
740
+ }
741
+ }
742
+ if (requiredAmr !== void 0 && requiredAmr.length > 0) {
743
+ const amr = Array.isArray(payload.auth?.amr) ? payload.auth.amr : [];
744
+ if (!amr.some((m) => requiredAmr.includes(m))) {
745
+ return `This endpoint requires an authentication method in [${requiredAmr.join(", ")}]; the token carries [${amr.join(", ") || "none"}].`;
746
+ }
747
+ }
748
+ return null;
749
+ };
750
+ var buildAipWeakAuthBody = (opts) => ({
751
+ type: "urn:aip:error:weak_auth",
752
+ title: "weak auth",
753
+ status: 403,
754
+ detail: opts.detail,
755
+ ...opts.requiredTrustLevel !== void 0 && { required_trust_level: opts.requiredTrustLevel },
756
+ ...opts.requiredAmr !== void 0 && opts.requiredAmr.length > 0 && { required_amr: opts.requiredAmr },
757
+ ...opts.trustedIssuers !== void 0 && opts.trustedIssuers.length > 0 && { trusted_issuers: opts.trustedIssuers }
758
+ });
759
+ var requirementsFromOptions = (opts) => ({
760
+ ...opts.trustedIssuers !== void 0 && { trustedIssuers: opts.trustedIssuers },
761
+ ...opts.requiredClaims !== void 0 && { requiredClaims: opts.requiredClaims },
762
+ ...opts.requireTrustLevel !== void 0 && { requiredTrustLevel: opts.requireTrustLevel },
763
+ ...opts.requireAmr !== void 0 && { requiredAmr: opts.requireAmr }
764
+ });
765
+ var evaluateFromContext = async (ctx, opts) => {
766
+ const result = await verifyAit(ctx, { jwks: opts.jwks, now: opts.now, maxSkewSeconds: opts.maxSkewSeconds });
767
+ if (!result.ok) {
768
+ return { ok: false, body: buildAipErrorBody(result.reason, requirementsFromOptions(opts)) };
769
+ }
770
+ const weak = checkTrustRequirements(result.ait.payload, opts.requireTrustLevel, opts.requireAmr);
771
+ if (weak !== null) {
772
+ return {
773
+ ok: false,
774
+ body: buildAipWeakAuthBody({
775
+ detail: weak,
776
+ ...opts.requireTrustLevel !== void 0 && { requiredTrustLevel: opts.requireTrustLevel },
777
+ ...opts.requireAmr !== void 0 && { requiredAmr: opts.requireAmr },
778
+ ...opts.trustedIssuers !== void 0 && { trustedIssuers: opts.trustedIssuers }
779
+ })
780
+ };
781
+ }
782
+ return { ok: true, ait: result.ait };
783
+ };
784
+ var evaluateAipParts = (parts, opts) => evaluateFromContext(buildVerifyContextFromParts(partsWithAuthority(parts, opts)), opts);
785
+
167
786
  // src/core.ts
787
+ var import_node_crypto = require("crypto");
168
788
  var import_sdk = require("@agent-score/sdk");
169
789
 
170
790
  // src/address.ts
@@ -233,7 +853,7 @@ function stripTrailingSlashes(s) {
233
853
  while (end > 0 && s.charCodeAt(end - 1) === 47) end--;
234
854
  return end === s.length ? s : s.slice(0, end);
235
855
  }
236
- var CANONICAL_AGENTSCORE_API = "https://api.agentscore.sh";
856
+ var CANONICAL_AGENTSCORE_API = "https://api.agentscore.com";
237
857
  var WALLET_SIGNER_MISMATCH_INSTRUCTIONS = JSON.stringify({
238
858
  action: "resign_or_switch_to_operator_token",
239
859
  steps: [
@@ -259,17 +879,22 @@ var INVALID_CREDENTIAL_INSTRUCTIONS = JSON.stringify({
259
879
  ],
260
880
  user_message: "The operator_token is not recognized. Use a different stored token, or restart the verification session flow to mint a new one."
261
881
  });
262
- function buildAgentMemoryHint() {
882
+ function buildAgentMemoryHint(aipTrustedIssuers) {
263
883
  const api = CANONICAL_AGENTSCORE_API;
884
+ const acceptsAip = aipTrustedIssuers !== void 0 && aipTrustedIssuers.length > 0;
264
885
  return {
265
886
  save_for_future_agentscore_gates: true,
266
887
  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.",
267
- quickstart: "https://docs.agentscore.sh/guides/agent-identity",
888
+ quickstart: "https://docs.agentscore.com/guides/agent-identity",
268
889
  identity_check_endpoint: `${api}/v1/credentials`,
269
890
  identity_paths: {
270
891
  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.",
271
- 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."
892
+ 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.",
893
+ ...acceptsAip && {
894
+ 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.'
895
+ }
272
896
  },
897
+ ...acceptsAip && { aip_trusted_issuers: aipTrustedIssuers },
273
898
  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.",
274
899
  do_not_persist_in_memory: ["operator_token", "poll_secret"],
275
900
  persist_in_credential_store: ["operator_token"]
@@ -277,7 +902,7 @@ function buildAgentMemoryHint() {
277
902
  }
278
903
  function createAgentScoreCore(options) {
279
904
  if (!options.apiKey) {
280
- throw new Error("AgentScore API key is required. Get one at https://agentscore.sh/sign-up");
905
+ throw new Error("AgentScore API key is required. Get one at https://www.agentscore.com/sign-up");
281
906
  }
282
907
  const {
283
908
  apiKey,
@@ -288,14 +913,15 @@ function createAgentScoreCore(options) {
288
913
  allowedJurisdictions,
289
914
  failOpen = false,
290
915
  cacheSeconds = 300,
291
- baseUrl: rawBaseUrl = "https://api.agentscore.sh",
916
+ baseUrl: rawBaseUrl = "https://api.agentscore.com",
292
917
  chain: gateChain,
293
918
  userAgent,
294
- createSessionOnMissing
919
+ createSessionOnMissing,
920
+ aipTrustedIssuers
295
921
  } = options;
296
922
  const baseUrl = stripTrailingSlashes(rawBaseUrl);
297
- const agentMemoryHint = buildAgentMemoryHint();
298
- const defaultUa = `@agent-score/commerce@${"2.4.0"}`;
923
+ const agentMemoryHint = buildAgentMemoryHint(aipTrustedIssuers);
924
+ const defaultUa = `@agent-score/commerce@${"2.6.0"}`;
299
925
  const userAgentHeader = userAgent ? `${userAgent} (${defaultUa})` : defaultUa;
300
926
  const sdk = new import_sdk.AgentScore({ apiKey, baseUrl, userAgent: userAgentHeader });
301
927
  const sessionSdkCache = /* @__PURE__ */ new Map();
@@ -370,16 +996,21 @@ function createAgentScoreCore(options) {
370
996
  }
371
997
  }
372
998
  async function evaluate(identity, ctx, signer) {
373
- if (!identity || !identity.address && !identity.operatorToken) {
999
+ if (!identity || !identity.address?.trim() && !identity.operatorToken?.trim() && !identity.aipToken?.trim()) {
374
1000
  if (failOpen) return { kind: "allow" };
375
1001
  const sessionReason = await tryMintSessionDenial(ctx);
376
1002
  if (sessionReason) return { kind: "deny", reason: sessionReason };
1003
+ const acceptsAip = aipTrustedIssuers !== void 0 && aipTrustedIssuers.length > 0;
1004
+ const aipStep = acceptsAip ? [
1005
+ `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.`
1006
+ ] : [];
377
1007
  const missingIdentityInstructions = JSON.stringify({
378
1008
  action: "probe_identity_then_session",
379
1009
  steps: [
1010
+ ...aipStep,
380
1011
  "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.",
381
1012
  "If step 1 is denied or you already have a stored operator_token (valid + not expired): send X-Operator-Token: opc_... and retry.",
382
- "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."
1013
+ "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."
383
1014
  ],
384
1015
  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."
385
1016
  });
@@ -392,21 +1023,26 @@ function createAgentScoreCore(options) {
392
1023
  }
393
1024
  };
394
1025
  }
395
- const cacheKey = identity.operatorToken?.toLowerCase() ?? (identity.address ? normalizeAddress(identity.address) : "");
1026
+ const identityKey = identity.aipToken ? `aip:${(0, import_node_crypto.createHash)("sha256").update(identity.aipToken).digest("hex")}` : identity.operatorToken?.toLowerCase() ?? (identity.address ? normalizeAddress(identity.address) : "");
1027
+ const cacheKey = signer ? JSON.stringify([identityKey, signer.network, normalizeAddress(signer.address)]) : JSON.stringify([identityKey]);
396
1028
  const cached = cache.get(cacheKey);
397
1029
  if (cached) {
1030
+ const cachedVerdict = cached.raw ? buildSignerVerdict(identity, cached.raw) : void 0;
398
1031
  if (cached.allow) {
399
1032
  const cachedRaw = cached.raw;
400
1033
  const cachedQuota = cachedRaw?.quota;
401
1034
  return {
402
1035
  kind: "allow",
403
1036
  data: cachedRaw,
404
- ...cachedQuota !== void 0 && { quota: cachedQuota }
1037
+ ...cachedQuota !== void 0 && { quota: cachedQuota },
1038
+ ...cachedVerdict !== void 0 && { signerVerdict: cachedVerdict }
405
1039
  };
406
1040
  }
407
1041
  if (isFixableDenial(cached.reasons)) {
408
1042
  const sessionReason = await tryMintSessionDenial(ctx);
409
- if (sessionReason) return { kind: "deny", reason: sessionReason };
1043
+ if (sessionReason) {
1044
+ return { kind: "deny", reason: sessionReason, ...cachedVerdict !== void 0 && { signerVerdict: cachedVerdict } };
1045
+ }
410
1046
  }
411
1047
  return {
412
1048
  kind: "deny",
@@ -416,7 +1052,8 @@ function createAgentScoreCore(options) {
416
1052
  reasons: cached.reasons,
417
1053
  verify_url: cached.raw?.verify_url,
418
1054
  data: cached.raw
419
- }
1055
+ },
1056
+ ...cachedVerdict !== void 0 && { signerVerdict: cachedVerdict }
420
1057
  };
421
1058
  }
422
1059
  const policy = {};
@@ -437,7 +1074,10 @@ function createAgentScoreCore(options) {
437
1074
  // regardless of policy.require_sanctions_clear (which gates the separate NAME screen).
438
1075
  ...signer && { signer: { address: signer.address, network: signer.network } }
439
1076
  };
440
- const result = identity.address ? await sdk.assess(identity.address, { ...opts, operatorToken: identity.operatorToken }) : await sdk.assess(null, { ...opts, operatorToken: identity.operatorToken });
1077
+ if (identity.aipToken !== void 0 && identity.aipSignature === void 0) {
1078
+ throw new Error("AgentScoreCore.evaluate: aipToken requires aipSignature (RFC 9421 proof-of-possession material).");
1079
+ }
1080
+ 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 });
441
1081
  data = result;
442
1082
  } catch (err) {
443
1083
  if (err instanceof import_sdk.PaymentRequiredError) {
@@ -508,17 +1148,21 @@ function createAgentScoreCore(options) {
508
1148
  const decisionReasons = data.decision_reasons ?? [];
509
1149
  const allow = decision === "allow" || decision == null;
510
1150
  cache.set(cacheKey, { allow, decision: decision ?? void 0, reasons: decisionReasons, raw: data });
1151
+ const signerVerdict = buildSignerVerdict(identity, data);
511
1152
  if (allow) {
512
1153
  const quota = data.quota;
513
1154
  return {
514
1155
  kind: "allow",
515
1156
  data,
516
- ...quota !== void 0 && { quota }
1157
+ ...quota !== void 0 && { quota },
1158
+ ...signerVerdict !== void 0 && { signerVerdict }
517
1159
  };
518
1160
  }
519
1161
  if (isFixableDenial(decisionReasons)) {
520
1162
  const sessionReason = await tryMintSessionDenial(ctx);
521
- if (sessionReason) return { kind: "deny", reason: sessionReason };
1163
+ if (sessionReason) {
1164
+ return { kind: "deny", reason: sessionReason, ...signerVerdict !== void 0 && { signerVerdict } };
1165
+ }
522
1166
  }
523
1167
  return {
524
1168
  kind: "deny",
@@ -528,7 +1172,8 @@ function createAgentScoreCore(options) {
528
1172
  reasons: decisionReasons,
529
1173
  verify_url: data.verify_url,
530
1174
  data
531
- }
1175
+ },
1176
+ ...signerVerdict !== void 0 && { signerVerdict }
532
1177
  };
533
1178
  }
534
1179
  async function captureWallet2(options2) {
@@ -570,22 +1215,21 @@ function createAgentScoreCore(options) {
570
1215
  agentInstructions: sm.agent_instructions ?? WALLET_SIGNER_MISMATCH_INSTRUCTIONS
571
1216
  };
572
1217
  }
573
- function getSignerVerdict2(claimedAddress) {
574
- const claimedNorm = normalizeAddress(claimedAddress);
575
- const cached = cache.get(claimedNorm);
576
- if (!cached) return void 0;
577
- const raw = cached.raw;
578
- if (!raw) return void 0;
1218
+ function buildSignerVerdict(identity, raw) {
1219
+ if (identity.address === void 0 || identity.operatorToken !== void 0 || identity.aipToken !== void 0) {
1220
+ return void 0;
1221
+ }
579
1222
  const rawMatch = raw.signer_match;
580
1223
  const rawSanctions = raw.signer_sanctions;
581
1224
  if (!rawMatch && !rawSanctions) return void 0;
1225
+ const claimedNorm = normalizeAddress(identity.address);
582
1226
  const signerNorm = rawMatch?.actual_signer ?? claimedNorm;
583
1227
  return {
584
1228
  signer_match: rawMatch ? projectSignerMatch(rawMatch, claimedNorm, signerNorm) : null,
585
1229
  signer_sanctions: rawSanctions ?? null
586
1230
  };
587
1231
  }
588
- return { evaluate, captureWallet: captureWallet2, getSignerVerdict: getSignerVerdict2 };
1232
+ return { evaluate, captureWallet: captureWallet2 };
589
1233
  }
590
1234
 
591
1235
  // src/payment/payment_header.ts
@@ -728,10 +1372,15 @@ var agentscoreGatePlugin = async (fastify, options) => {
728
1372
  state.infraReason = outcome.infraReason;
729
1373
  }
730
1374
  if (outcome.quota) state.quota = outcome.quota;
1375
+ if (outcome.signerVerdict) state.signerVerdict = outcome.signerVerdict;
731
1376
  }
732
1377
  if (outcome.data) request.agentscore = outcome.data;
733
1378
  return;
734
1379
  }
1380
+ if (outcome.signerVerdict) {
1381
+ const state = request[GATE_STATE_KEY];
1382
+ if (state) state.signerVerdict = outcome.signerVerdict;
1383
+ }
735
1384
  await onDenied(request, reply, outcome.reason);
736
1385
  });
737
1386
  };
@@ -758,8 +1407,7 @@ async function captureWallet(request, options) {
758
1407
  }
759
1408
  function getSignerVerdict(request) {
760
1409
  const state = request[GATE_STATE_KEY];
761
- if (!state?.walletAddress) return void 0;
762
- return state.core.getSignerVerdict(state.walletAddress);
1410
+ return state?.signerVerdict;
763
1411
  }
764
1412
  agentscoreGatePlugin[/* @__PURE__ */ Symbol.for("skip-override")] = true;
765
1413
  var agentscoreGate = agentscoreGatePlugin;
@@ -787,22 +1435,70 @@ var conditionalAgentscoreGatePlugin = async (fastify, options) => {
787
1435
  state.infraReason = outcome.infraReason;
788
1436
  }
789
1437
  if (outcome.quota) state.quota = outcome.quota;
1438
+ if (outcome.signerVerdict) state.signerVerdict = outcome.signerVerdict;
790
1439
  }
791
1440
  return;
792
1441
  }
1442
+ if (outcome.signerVerdict) {
1443
+ const state = request[GATE_STATE_KEY];
1444
+ if (state) state.signerVerdict = outcome.signerVerdict;
1445
+ }
793
1446
  return onDenied(request, reply, outcome.reason);
794
1447
  });
795
1448
  };
796
1449
  conditionalAgentscoreGatePlugin[/* @__PURE__ */ Symbol.for("skip-override")] = true;
797
1450
  var conditionalAgentscoreGate = conditionalAgentscoreGatePlugin;
1451
+ var AIT_STATE_KEY = "__agentscoreAit";
1452
+ function defaultAipOnDenied(_req, reply, body) {
1453
+ reply.code(body.status).header("content-type", "application/problem+json").send(body);
1454
+ }
1455
+ var aipGatePlugin = async (fastify, options) => {
1456
+ const { onDenied = defaultAipOnDenied, ...gateOpts } = options;
1457
+ fastify.addHook("preHandler", async (request, reply) => {
1458
+ const result = await evaluateAipParts(
1459
+ { method: request.method, url: request.url, headers: request.headers },
1460
+ gateOpts
1461
+ );
1462
+ if (!result.ok) {
1463
+ await onDenied(request, reply, result.body);
1464
+ return;
1465
+ }
1466
+ request[AIT_STATE_KEY] = result.ait;
1467
+ });
1468
+ };
1469
+ aipGatePlugin[/* @__PURE__ */ Symbol.for("skip-override")] = true;
1470
+ var aipGate = aipGatePlugin;
1471
+ var conditionalAipGatePlugin = async (fastify, options) => {
1472
+ const { onDenied = defaultAipOnDenied, ...gateOpts } = options;
1473
+ fastify.addHook("preHandler", async (request, reply) => {
1474
+ if (!hasAgentIdentityHeaderNode(request.headers)) return;
1475
+ const result = await evaluateAipParts(
1476
+ { method: request.method, url: request.url, headers: request.headers },
1477
+ gateOpts
1478
+ );
1479
+ if (!result.ok) {
1480
+ await onDenied(request, reply, result.body);
1481
+ return;
1482
+ }
1483
+ request[AIT_STATE_KEY] = result.ait;
1484
+ });
1485
+ };
1486
+ conditionalAipGatePlugin[/* @__PURE__ */ Symbol.for("skip-override")] = true;
1487
+ var conditionalAipGate = conditionalAipGatePlugin;
1488
+ function getVerifiedAit(request) {
1489
+ return request[AIT_STATE_KEY];
1490
+ }
798
1491
  // Annotate the CommonJS export names for ESM import in node:
799
1492
  0 && (module.exports = {
800
1493
  agentscoreGate,
1494
+ aipGate,
801
1495
  captureWallet,
802
1496
  conditionalAgentscoreGate,
1497
+ conditionalAipGate,
803
1498
  getAgentScoreData,
804
1499
  getGateDegradedState,
805
1500
  getGateQuotaInfo,
806
- getSignerVerdict
1501
+ getSignerVerdict,
1502
+ getVerifiedAit
807
1503
  });
808
1504
  //# sourceMappingURL=fastify.js.map