@agent-score/commerce 2.5.0 → 2.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +19 -17
  2. package/dist/challenge/index.d.mts +26 -2
  3. package/dist/challenge/index.d.ts +26 -2
  4. package/dist/challenge/index.js +14 -5
  5. package/dist/challenge/index.js.map +1 -1
  6. package/dist/challenge/index.mjs +14 -5
  7. package/dist/challenge/index.mjs.map +1 -1
  8. package/dist/{checkout-McfNpZJf.d.ts → checkout-C4RD7M0Z.d.ts} +46 -13
  9. package/dist/{checkout-o17dIxHi.d.mts → checkout-CzB9f_jf.d.mts} +46 -13
  10. package/dist/core.d.mts +20 -9
  11. package/dist/core.d.ts +20 -9
  12. package/dist/core.js +35 -24
  13. package/dist/core.js.map +1 -1
  14. package/dist/core.mjs +35 -24
  15. package/dist/core.mjs.map +1 -1
  16. package/dist/discovery/index.d.mts +17 -2
  17. package/dist/discovery/index.d.ts +17 -2
  18. package/dist/discovery/index.js +36 -12
  19. package/dist/discovery/index.js.map +1 -1
  20. package/dist/discovery/index.mjs +35 -12
  21. package/dist/discovery/index.mjs.map +1 -1
  22. package/dist/{gate-CWP10xPQ.d.mts → gate-D2RP6bZg.d.ts} +109 -141
  23. package/dist/{gate-CWP10xPQ.d.ts → gate-GCXy4FHI.d.mts} +109 -141
  24. package/dist/identity/express.d.mts +3 -1
  25. package/dist/identity/express.d.ts +3 -1
  26. package/dist/identity/express.js +164 -55
  27. package/dist/identity/express.js.map +1 -1
  28. package/dist/identity/express.mjs +164 -55
  29. package/dist/identity/express.mjs.map +1 -1
  30. package/dist/identity/fastify.d.mts +3 -1
  31. package/dist/identity/fastify.d.ts +3 -1
  32. package/dist/identity/fastify.js +171 -57
  33. package/dist/identity/fastify.js.map +1 -1
  34. package/dist/identity/fastify.mjs +171 -57
  35. package/dist/identity/fastify.mjs.map +1 -1
  36. package/dist/identity/hono.d.mts +3 -1
  37. package/dist/identity/hono.d.ts +3 -1
  38. package/dist/identity/hono.js +159 -59
  39. package/dist/identity/hono.js.map +1 -1
  40. package/dist/identity/hono.mjs +159 -59
  41. package/dist/identity/hono.mjs.map +1 -1
  42. package/dist/identity/nextjs.d.mts +3 -1
  43. package/dist/identity/nextjs.d.ts +3 -1
  44. package/dist/identity/nextjs.js +153 -56
  45. package/dist/identity/nextjs.js.map +1 -1
  46. package/dist/identity/nextjs.mjs +153 -56
  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 +3 -1
  55. package/dist/identity/web.d.ts +3 -1
  56. package/dist/identity/web.js +153 -56
  57. package/dist/identity/web.js.map +1 -1
  58. package/dist/identity/web.mjs +153 -56
  59. package/dist/identity/web.mjs.map +1 -1
  60. package/dist/index.d.mts +55 -10
  61. package/dist/index.d.ts +55 -10
  62. package/dist/index.js +2227 -501
  63. package/dist/index.js.map +1 -1
  64. package/dist/index.mjs +2219 -501
  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 +1621 -266
  73. package/dist/stripe-multichain/index.js.map +1 -1
  74. package/dist/stripe-multichain/index.mjs +1621 -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 +23 -18
@@ -1,8 +1,10 @@
1
1
  import { createAgentScoreGate } from './web.mjs';
2
2
  export { AipGateWebOptions, AipGuardResult, createAipGate, withAipGate, withConditionalAipGate } from './web.mjs';
3
3
  import { AssessResult, SignerVerdict, FailOpenInfraReason, GateQuotaInfo } from '../core.mjs';
4
- import '../gate-CWP10xPQ.mjs';
4
+ import '../gate-GCXy4FHI.mjs';
5
+ import '../types-D1slMt0H.mjs';
5
6
  import 'jose';
7
+ import '@agent-score/sdk';
6
8
  import '../signer-3FAit11j.mjs';
7
9
 
8
10
  /**
@@ -1,8 +1,10 @@
1
1
  import { createAgentScoreGate } from './web.js';
2
2
  export { AipGateWebOptions, AipGuardResult, createAipGate, withAipGate, withConditionalAipGate } from './web.js';
3
3
  import { AssessResult, SignerVerdict, FailOpenInfraReason, GateQuotaInfo } from '../core.js';
4
- import '../gate-CWP10xPQ.js';
4
+ import '../gate-D2RP6bZg.js';
5
+ import '../types-D1slMt0H.js';
5
6
  import 'jose';
7
+ import '@agent-score/sdk';
6
8
  import '../signer-3FAit11j.js';
7
9
 
8
10
  /**
@@ -100,7 +100,7 @@ var IDENTITY_VERIFICATION_REQUIRED_FALLBACK_INSTRUCTIONS = JSON.stringify({
100
100
  var API_ERROR_INSTRUCTIONS = JSON.stringify({
101
101
  action: "retry_with_backoff",
102
102
  steps: [
103
- "Verification is temporarily unavailable. Retry the request after 5\u201330 seconds with exponential backoff.",
103
+ "Verification is temporarily unavailable. Retry the request after 5-30 seconds with exponential backoff.",
104
104
  "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.",
105
105
  "If the request continues to fail after 3+ retries (~60 seconds total), surface the error to the user with the merchant's support contact."
106
106
  ],
@@ -204,6 +204,7 @@ var b64ToBytes = (b64) => {
204
204
  var AIP_COVERED_COMPONENTS = ["@method", "@authority", "@path", "agent-identity"];
205
205
  var AIP_SIGNATURE_TAG = "agent-identity";
206
206
  var DEFAULT_MAX_SKEW_SECONDS = 60;
207
+ var MAX_POP_WINDOW_SECONDS = 120;
207
208
  var normalizeAuthority = (authority) => {
208
209
  const lower = authority.trim().toLowerCase();
209
210
  const colon = lower.lastIndexOf(":");
@@ -254,7 +255,7 @@ var serializeParams = (p) => {
254
255
  }
255
256
  return parts.map((s) => `;${s}`).join("");
256
257
  };
257
- var buildSignatureBase = (params, input) => {
258
+ var buildSignatureBase = (params, input, rawSignatureParams) => {
258
259
  const lines = [];
259
260
  for (const name of params.components) {
260
261
  const value = componentValue(name, input);
@@ -263,7 +264,7 @@ var buildSignatureBase = (params, input) => {
263
264
  }
264
265
  lines.push(`"${name}": ${value}`);
265
266
  }
266
- const paramsValue = serializeComponentList(params.components) + serializeParams(params);
267
+ const paramsValue = rawSignatureParams ?? serializeComponentList(params.components) + serializeParams(params);
267
268
  lines.push(`"@signature-params": ${paramsValue}`);
268
269
  return lines.join("\n");
269
270
  };
@@ -282,19 +283,12 @@ var parseSignatureInput = (header, tag = AIP_SIGNATURE_TAG) => {
282
283
  }
283
284
  const parsed = members.map((m) => {
284
285
  const params = parseInnerListMember(m.value);
285
- return params ? { label: m.label, params } : null;
286
+ return params ? { label: m.label, params, rawParams: m.value } : null;
286
287
  }).filter((x) => x !== null);
287
288
  if (parsed.length === 0) {
288
289
  return null;
289
290
  }
290
- const tagged = parsed.find((p) => p.params.tag === tag);
291
- if (tagged) {
292
- return tagged;
293
- }
294
- if (parsed.length === 1 && parsed[0].params.tag === void 0) {
295
- return parsed[0];
296
- }
297
- return null;
291
+ return parsed.find((p) => p.params.tag === tag) ?? null;
298
292
  };
299
293
  var parseSignatureValue = (header, label) => {
300
294
  const members = splitDictionary(header);
@@ -408,7 +402,7 @@ var verifyMessageSignature = async (input) => {
408
402
  if (!selected) {
409
403
  return { ok: false, reason: "no_aip_signature" };
410
404
  }
411
- const { label, params } = selected;
405
+ const { label, params, rawParams } = selected;
412
406
  if (params.alg !== void 0 && !["ed25519", "eddsa"].includes(params.alg.toLowerCase())) {
413
407
  return { ok: false, reason: "unsupported_alg" };
414
408
  }
@@ -417,12 +411,21 @@ var verifyMessageSignature = async (input) => {
417
411
  return { ok: false, reason: "missing_covered_component" };
418
412
  }
419
413
  }
414
+ if (params.created === void 0) {
415
+ return { ok: false, reason: "created_missing" };
416
+ }
417
+ if (params.expires === void 0) {
418
+ return { ok: false, reason: "expires_missing" };
419
+ }
420
+ if (params.expires < params.created || params.expires - params.created > MAX_POP_WINDOW_SECONDS) {
421
+ return { ok: false, reason: "pop_window_too_long" };
422
+ }
420
423
  const now = input.now ?? Math.floor(Date.now() / 1e3);
421
424
  const skew = input.maxSkewSeconds ?? DEFAULT_MAX_SKEW_SECONDS;
422
- if (params.created !== void 0 && params.created > now + skew) {
425
+ if (params.created > now + skew) {
423
426
  return { ok: false, reason: "created_in_future" };
424
427
  }
425
- if (params.expires !== void 0 && params.expires < now - skew) {
428
+ if (params.expires < now - skew) {
426
429
  return { ok: false, reason: "expired" };
427
430
  }
428
431
  if (!params.keyid) {
@@ -453,7 +456,7 @@ var verifyMessageSignature = async (input) => {
453
456
  path: input.path,
454
457
  agentIdentity: input.agentIdentity,
455
458
  extra: input.extraComponents
456
- });
459
+ }, rawParams);
457
460
  } catch (err) {
458
461
  if (err instanceof MissingComponentError) {
459
462
  return { ok: false, reason: "missing_covered_component" };
@@ -526,6 +529,8 @@ var verifyAit = async (ctx, opts) => {
526
529
  if (!ctx.signatureInput || !ctx.signature) {
527
530
  return { ok: false, reason: "pop_signature_missing" };
528
531
  }
532
+ const signatureInput = ctx.signatureInput;
533
+ const signature = ctx.signature;
529
534
  let lastFailure = "malformed_token";
530
535
  for (const raw of ctx.agentIdentityHeaders) {
531
536
  const token = stripBearer(raw);
@@ -564,7 +569,7 @@ var verifyAit = async (ctx, opts) => {
564
569
  // Pin the signature algorithm allowlist (RFC 8725 §3.1) — also rejects `alg:none`. Without
565
570
  // this, jose accepts whatever alg the resolved JWK supports, so a trusted IdP publishing a
566
571
  // non-Ed25519 (e.g. RSA/EC) `use:sig` key would let an attacker present an RS256/ES256
567
- // token that verifies. Matches the server-side allowlist in core/api aip-verify.
572
+ // token that verifies. Matches the server-side allowlist in the AgentScore API verifier.
568
573
  algorithms: AIT_SIGNING_ALGS,
569
574
  clockTolerance: jwtClockTolerance,
570
575
  currentDate: opts.now !== void 0 ? new Date(opts.now * 1e3) : void 0
@@ -578,13 +583,20 @@ var verifyAit = async (ctx, opts) => {
578
583
  lastFailure = "expired_token";
579
584
  continue;
580
585
  }
586
+ if (claims.exp - claims.iat > (opts.maxLifetimeSeconds ?? 300)) {
587
+ lastFailure = "expired_token";
588
+ continue;
589
+ }
581
590
  const popResult = await verifyMessageSignature({
582
591
  method: ctx.method,
583
592
  authority: ctx.authority,
584
593
  path: ctx.path,
585
- agentIdentity: raw,
586
- signatureInput: ctx.signatureInput,
587
- signature: ctx.signature,
594
+ // The agent-identity covered component is the BARE AIT (a Bearer prefix, if present, is
595
+ // transport that `stripBearer` removed above). Verify over `token`, not `raw`, so the edge and
596
+ // the API — which verifies over the forwarded bare aip_token — reconstruct the identical base.
597
+ agentIdentity: token,
598
+ signatureInput,
599
+ signature,
588
600
  cnfJwk: claims.cnf.jwk,
589
601
  now: opts.now,
590
602
  maxSkewSeconds: opts.maxSkewSeconds
@@ -593,7 +605,22 @@ var verifyAit = async (ctx, opts) => {
593
605
  lastFailure = "pop_signature_invalid";
594
606
  continue;
595
607
  }
596
- return { ok: true, ait: { payload: claims, iss: claims.iss, cnfJwk: claims.cnf.jwk, token } };
608
+ return {
609
+ ok: true,
610
+ ait: {
611
+ payload: claims,
612
+ iss: claims.iss,
613
+ cnfJwk: claims.cnf.jwk,
614
+ token,
615
+ signatureMaterial: {
616
+ method: ctx.method,
617
+ authority: ctx.authority,
618
+ path: ctx.path,
619
+ signature_input: signatureInput,
620
+ signature
621
+ }
622
+ }
623
+ };
597
624
  }
598
625
  return { ok: false, reason: lastFailure };
599
626
  };
@@ -614,11 +641,11 @@ var readAgentIdentityHeaders = (headers) => {
614
641
  return raw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
615
642
  };
616
643
  var deriveAuthority = (req, url) => req.headers.get("host") ?? url.host;
617
- var buildVerifyContextFromRequest = (req) => {
644
+ var buildVerifyContextFromRequest = (req, authority) => {
618
645
  const url = new URL(req.url);
619
646
  return {
620
647
  method: req.method,
621
- authority: deriveAuthority(req, url),
648
+ authority: authority ?? deriveAuthority(req, url),
622
649
  path: url.pathname,
623
650
  agentIdentityHeaders: readAgentIdentityHeaders(req.headers),
624
651
  signatureInput: req.headers.get("signature-input"),
@@ -628,11 +655,6 @@ var buildVerifyContextFromRequest = (req) => {
628
655
  var hasAgentIdentityHeader = (req) => readAgentIdentityHeaders(req.headers).length > 0;
629
656
 
630
657
  // src/aip/gate.ts
631
- var verifyFromContext = async (ctx, opts) => {
632
- const result = await verifyAit(ctx, { jwks: opts.jwks, now: opts.now, maxSkewSeconds: opts.maxSkewSeconds });
633
- return result.ok ? { ok: true, ait: result.ait } : { ok: false, failure: result.reason };
634
- };
635
- var verifyAitRequest = (req, opts) => verifyFromContext(buildVerifyContextFromRequest(req), opts);
636
658
  var aipErrorCode = (failure) => {
637
659
  switch (failure) {
638
660
  case "no_token":
@@ -689,15 +711,78 @@ var aipErrorDetail = (failure) => {
689
711
  return "Token verification failed.";
690
712
  }
691
713
  };
692
- var buildAipErrorBody = (failure) => {
714
+ var buildAipErrorBody = (failure, requirements) => {
693
715
  const code = aipErrorCode(failure);
694
- return {
716
+ const body = {
695
717
  type: `urn:aip:error:${code}`,
696
718
  title: code.replace(/_/g, " "),
697
719
  status: aipErrorStatus(failure),
698
720
  detail: aipErrorDetail(failure)
699
721
  };
722
+ if (requirements) {
723
+ if (code === "untrusted_issuer" && requirements.trustedIssuers?.length) {
724
+ body.trusted_issuers = requirements.trustedIssuers;
725
+ }
726
+ if (code === "insufficient_claims") {
727
+ if (requirements.requiredClaims?.length) body.required_claims = requirements.requiredClaims;
728
+ if (requirements.requiredTrustLevel !== void 0) body.required_trust_level = requirements.requiredTrustLevel;
729
+ if (requirements.requiredAmr?.length) body.required_amr = requirements.requiredAmr;
730
+ }
731
+ }
732
+ return body;
700
733
  };
734
+ var TRUST_RANK = { autonomous: 0, human_present: 1, human_confirmed: 2 };
735
+ var checkTrustRequirements = (payload, requiredTrustLevel, requiredAmr) => {
736
+ if (requiredTrustLevel !== void 0) {
737
+ const have = TRUST_RANK[payload.trust_level ?? "autonomous"] ?? 0;
738
+ const need = TRUST_RANK[requiredTrustLevel] ?? 0;
739
+ if (have < need) {
740
+ 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).`;
741
+ }
742
+ }
743
+ if (requiredAmr !== void 0 && requiredAmr.length > 0) {
744
+ const amr = Array.isArray(payload.auth?.amr) ? payload.auth.amr : [];
745
+ if (!amr.some((m) => requiredAmr.includes(m))) {
746
+ return `This endpoint requires an authentication method in [${requiredAmr.join(", ")}]; the token carries [${amr.join(", ") || "none"}].`;
747
+ }
748
+ }
749
+ return null;
750
+ };
751
+ var buildAipWeakAuthBody = (opts) => ({
752
+ type: "urn:aip:error:weak_auth",
753
+ title: "weak auth",
754
+ status: 403,
755
+ detail: opts.detail,
756
+ ...opts.requiredTrustLevel !== void 0 && { required_trust_level: opts.requiredTrustLevel },
757
+ ...opts.requiredAmr !== void 0 && opts.requiredAmr.length > 0 && { required_amr: opts.requiredAmr },
758
+ ...opts.trustedIssuers !== void 0 && opts.trustedIssuers.length > 0 && { trusted_issuers: opts.trustedIssuers }
759
+ });
760
+ var requirementsFromOptions = (opts) => ({
761
+ ...opts.trustedIssuers !== void 0 && { trustedIssuers: opts.trustedIssuers },
762
+ ...opts.requiredClaims !== void 0 && { requiredClaims: opts.requiredClaims },
763
+ ...opts.requireTrustLevel !== void 0 && { requiredTrustLevel: opts.requireTrustLevel },
764
+ ...opts.requireAmr !== void 0 && { requiredAmr: opts.requireAmr }
765
+ });
766
+ var evaluateFromContext = async (ctx, opts) => {
767
+ const result = await verifyAit(ctx, { jwks: opts.jwks, now: opts.now, maxSkewSeconds: opts.maxSkewSeconds });
768
+ if (!result.ok) {
769
+ return { ok: false, body: buildAipErrorBody(result.reason, requirementsFromOptions(opts)) };
770
+ }
771
+ const weak = checkTrustRequirements(result.ait.payload, opts.requireTrustLevel, opts.requireAmr);
772
+ if (weak !== null) {
773
+ return {
774
+ ok: false,
775
+ body: buildAipWeakAuthBody({
776
+ detail: weak,
777
+ ...opts.requireTrustLevel !== void 0 && { requiredTrustLevel: opts.requireTrustLevel },
778
+ ...opts.requireAmr !== void 0 && { requiredAmr: opts.requireAmr },
779
+ ...opts.trustedIssuers !== void 0 && { trustedIssuers: opts.trustedIssuers }
780
+ })
781
+ };
782
+ }
783
+ return { ok: true, ait: result.ait };
784
+ };
785
+ var evaluateAipRequest = (req, opts) => evaluateFromContext(buildVerifyContextFromRequest(req, opts.authority), opts);
701
786
 
702
787
  // src/core.ts
703
788
  var import_node_crypto = require("crypto");
@@ -769,7 +854,7 @@ function stripTrailingSlashes(s) {
769
854
  while (end > 0 && s.charCodeAt(end - 1) === 47) end--;
770
855
  return end === s.length ? s : s.slice(0, end);
771
856
  }
772
- var CANONICAL_AGENTSCORE_API = "https://api.agentscore.sh";
857
+ var CANONICAL_AGENTSCORE_API = "https://api.agentscore.com";
773
858
  var WALLET_SIGNER_MISMATCH_INSTRUCTIONS = JSON.stringify({
774
859
  action: "resign_or_switch_to_operator_token",
775
860
  steps: [
@@ -801,7 +886,7 @@ function buildAgentMemoryHint(aipTrustedIssuers) {
801
886
  return {
802
887
  save_for_future_agentscore_gates: true,
803
888
  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.",
804
- quickstart: "https://docs.agentscore.sh/guides/agent-identity",
889
+ quickstart: "https://docs.agentscore.com/guides/agent-identity",
805
890
  identity_check_endpoint: `${api}/v1/credentials`,
806
891
  identity_paths: {
807
892
  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.",
@@ -818,7 +903,7 @@ function buildAgentMemoryHint(aipTrustedIssuers) {
818
903
  }
819
904
  function createAgentScoreCore(options) {
820
905
  if (!options.apiKey) {
821
- throw new Error("AgentScore API key is required. Get one at https://agentscore.sh/sign-up");
906
+ throw new Error("AgentScore API key is required. Get one at https://www.agentscore.com/sign-up");
822
907
  }
823
908
  const {
824
909
  apiKey,
@@ -829,7 +914,7 @@ function createAgentScoreCore(options) {
829
914
  allowedJurisdictions,
830
915
  failOpen = false,
831
916
  cacheSeconds = 300,
832
- baseUrl: rawBaseUrl = "https://api.agentscore.sh",
917
+ baseUrl: rawBaseUrl = "https://api.agentscore.com",
833
918
  chain: gateChain,
834
919
  userAgent,
835
920
  createSessionOnMissing,
@@ -837,7 +922,7 @@ function createAgentScoreCore(options) {
837
922
  } = options;
838
923
  const baseUrl = stripTrailingSlashes(rawBaseUrl);
839
924
  const agentMemoryHint = buildAgentMemoryHint(aipTrustedIssuers);
840
- const defaultUa = `@agent-score/commerce@${"2.5.0"}`;
925
+ const defaultUa = `@agent-score/commerce@${"2.6.1"}`;
841
926
  const userAgentHeader = userAgent ? `${userAgent} (${defaultUa})` : defaultUa;
842
927
  const sdk = new import_sdk.AgentScore({ apiKey, baseUrl, userAgent: userAgentHeader });
843
928
  const sessionSdkCache = /* @__PURE__ */ new Map();
@@ -855,7 +940,6 @@ function createAgentScoreCore(options) {
855
940
  return s;
856
941
  }
857
942
  const cache = new TTLCache(cacheSeconds * 1e3);
858
- const lastSignerRaw = /* @__PURE__ */ new Map();
859
943
  async function tryMintSessionDenial(ctx) {
860
944
  if (!createSessionOnMissing) return void 0;
861
945
  try {
@@ -927,7 +1011,7 @@ function createAgentScoreCore(options) {
927
1011
  ...aipStep,
928
1012
  "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.",
929
1013
  "If step 1 is denied or you already have a stored operator_token (valid + not expired): send X-Operator-Token: opc_... and retry.",
930
- "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."
1014
+ "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."
931
1015
  ],
932
1016
  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."
933
1017
  });
@@ -940,21 +1024,26 @@ function createAgentScoreCore(options) {
940
1024
  }
941
1025
  };
942
1026
  }
943
- const cacheKey = identity.aipToken ? `aip:${(0, import_node_crypto.createHash)("sha256").update(identity.aipToken).digest("hex")}` : identity.operatorToken?.toLowerCase() ?? (identity.address ? normalizeAddress(identity.address) : "");
1027
+ const identityKey = identity.aipToken ? `aip:${(0, import_node_crypto.createHash)("sha256").update(identity.aipToken).digest("hex")}` : identity.operatorToken?.toLowerCase() ?? (identity.address ? normalizeAddress(identity.address) : "");
1028
+ const cacheKey = signer ? JSON.stringify([identityKey, signer.network, normalizeAddress(signer.address)]) : JSON.stringify([identityKey]);
944
1029
  const cached = cache.get(cacheKey);
945
1030
  if (cached) {
1031
+ const cachedVerdict = cached.raw ? buildSignerVerdict(identity, cached.raw) : void 0;
946
1032
  if (cached.allow) {
947
1033
  const cachedRaw = cached.raw;
948
1034
  const cachedQuota = cachedRaw?.quota;
949
1035
  return {
950
1036
  kind: "allow",
951
1037
  data: cachedRaw,
952
- ...cachedQuota !== void 0 && { quota: cachedQuota }
1038
+ ...cachedQuota !== void 0 && { quota: cachedQuota },
1039
+ ...cachedVerdict !== void 0 && { signerVerdict: cachedVerdict }
953
1040
  };
954
1041
  }
955
1042
  if (isFixableDenial(cached.reasons)) {
956
1043
  const sessionReason = await tryMintSessionDenial(ctx);
957
- if (sessionReason) return { kind: "deny", reason: sessionReason };
1044
+ if (sessionReason) {
1045
+ return { kind: "deny", reason: sessionReason, ...cachedVerdict !== void 0 && { signerVerdict: cachedVerdict } };
1046
+ }
958
1047
  }
959
1048
  return {
960
1049
  kind: "deny",
@@ -964,7 +1053,8 @@ function createAgentScoreCore(options) {
964
1053
  reasons: cached.reasons,
965
1054
  verify_url: cached.raw?.verify_url,
966
1055
  data: cached.raw
967
- }
1056
+ },
1057
+ ...cachedVerdict !== void 0 && { signerVerdict: cachedVerdict }
968
1058
  };
969
1059
  }
970
1060
  const policy = {};
@@ -985,7 +1075,10 @@ function createAgentScoreCore(options) {
985
1075
  // regardless of policy.require_sanctions_clear (which gates the separate NAME screen).
986
1076
  ...signer && { signer: { address: signer.address, network: signer.network } }
987
1077
  };
988
- const result = identity.aipToken ? await sdk.assess(null, { ...opts, aipToken: identity.aipToken }) : identity.address ? await sdk.assess(identity.address, { ...opts, operatorToken: identity.operatorToken }) : await sdk.assess(null, { ...opts, operatorToken: identity.operatorToken });
1078
+ if (identity.aipToken !== void 0 && identity.aipSignature === void 0) {
1079
+ throw new Error("AgentScoreCore.evaluate: aipToken requires aipSignature (RFC 9421 proof-of-possession material).");
1080
+ }
1081
+ 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 });
989
1082
  data = result;
990
1083
  } catch (err) {
991
1084
  if (err instanceof import_sdk.PaymentRequiredError) {
@@ -1056,20 +1149,21 @@ function createAgentScoreCore(options) {
1056
1149
  const decisionReasons = data.decision_reasons ?? [];
1057
1150
  const allow = decision === "allow" || decision == null;
1058
1151
  cache.set(cacheKey, { allow, decision: decision ?? void 0, reasons: decisionReasons, raw: data });
1059
- if (identity.address !== void 0 && identity.operatorToken === void 0 && identity.aipToken === void 0 && (data.signer_match !== void 0 || data.signer_sanctions !== void 0)) {
1060
- lastSignerRaw.set(normalizeAddress(identity.address), data);
1061
- }
1152
+ const signerVerdict = buildSignerVerdict(identity, data);
1062
1153
  if (allow) {
1063
1154
  const quota = data.quota;
1064
1155
  return {
1065
1156
  kind: "allow",
1066
1157
  data,
1067
- ...quota !== void 0 && { quota }
1158
+ ...quota !== void 0 && { quota },
1159
+ ...signerVerdict !== void 0 && { signerVerdict }
1068
1160
  };
1069
1161
  }
1070
1162
  if (isFixableDenial(decisionReasons)) {
1071
1163
  const sessionReason = await tryMintSessionDenial(ctx);
1072
- if (sessionReason) return { kind: "deny", reason: sessionReason };
1164
+ if (sessionReason) {
1165
+ return { kind: "deny", reason: sessionReason, ...signerVerdict !== void 0 && { signerVerdict } };
1166
+ }
1073
1167
  }
1074
1168
  return {
1075
1169
  kind: "deny",
@@ -1079,7 +1173,8 @@ function createAgentScoreCore(options) {
1079
1173
  reasons: decisionReasons,
1080
1174
  verify_url: data.verify_url,
1081
1175
  data
1082
- }
1176
+ },
1177
+ ...signerVerdict !== void 0 && { signerVerdict }
1083
1178
  };
1084
1179
  }
1085
1180
  async function captureWallet(options2) {
@@ -1121,20 +1216,21 @@ function createAgentScoreCore(options) {
1121
1216
  agentInstructions: sm.agent_instructions ?? WALLET_SIGNER_MISMATCH_INSTRUCTIONS
1122
1217
  };
1123
1218
  }
1124
- function getSignerVerdict(claimedAddress) {
1125
- const claimedNorm = normalizeAddress(claimedAddress);
1126
- const raw = lastSignerRaw.get(claimedNorm) ?? cache.get(claimedNorm)?.raw;
1127
- if (!raw) return void 0;
1219
+ function buildSignerVerdict(identity, raw) {
1220
+ if (identity.address === void 0 || identity.operatorToken !== void 0 || identity.aipToken !== void 0) {
1221
+ return void 0;
1222
+ }
1128
1223
  const rawMatch = raw.signer_match;
1129
1224
  const rawSanctions = raw.signer_sanctions;
1130
1225
  if (!rawMatch && !rawSanctions) return void 0;
1226
+ const claimedNorm = normalizeAddress(identity.address);
1131
1227
  const signerNorm = rawMatch?.actual_signer ?? claimedNorm;
1132
1228
  return {
1133
1229
  signer_match: rawMatch ? projectSignerMatch(rawMatch, claimedNorm, signerNorm) : null,
1134
1230
  signer_sanctions: rawSanctions ?? null
1135
1231
  };
1136
1232
  }
1137
- return { evaluate, captureWallet, getSignerVerdict };
1233
+ return { evaluate, captureWallet };
1138
1234
  }
1139
1235
 
1140
1236
  // src/signer.ts
@@ -1239,7 +1335,8 @@ function createAgentScoreGate(options) {
1239
1335
  const outcome = await core.evaluate(identity, req, signer);
1240
1336
  if (outcome.kind === "allow") {
1241
1337
  const captureWallet = identity?.operatorToken ? (opts) => core.captureWallet({ operatorToken: identity.operatorToken, ...opts }) : void 0;
1242
- const getSignerVerdictBound = identity?.address && !identity?.operatorToken ? () => core.getSignerVerdict(identity.address) : void 0;
1338
+ const signerVerdict = outcome.signerVerdict;
1339
+ const getSignerVerdictBound = identity?.address && !identity?.operatorToken ? () => signerVerdict : void 0;
1243
1340
  return {
1244
1341
  allowed: true,
1245
1342
  data: outcome.data,
@@ -1257,11 +1354,11 @@ var defaultAipResponse = (body) => new Response(JSON.stringify(body), { status:
1257
1354
  function createAipGate(options) {
1258
1355
  const { onDenied, ...gateOpts } = options;
1259
1356
  return async (req) => {
1260
- const result = await verifyAitRequest(req, gateOpts);
1357
+ const result = await evaluateAipRequest(req, gateOpts);
1261
1358
  if (result.ok) {
1262
1359
  return { allowed: true, ait: result.ait };
1263
1360
  }
1264
- const body = buildAipErrorBody(result.failure);
1361
+ const body = result.body;
1265
1362
  const response = onDenied ? await onDenied(req, body) : defaultAipResponse(body);
1266
1363
  return { allowed: false, response };
1267
1364
  };