@agent-score/commerce 1.5.1 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +22 -8
  2. package/dist/challenge/index.js.map +1 -1
  3. package/dist/challenge/index.mjs.map +1 -1
  4. package/dist/core.d.mts +36 -27
  5. package/dist/core.d.ts +36 -27
  6. package/dist/core.js +1 -1
  7. package/dist/core.js.map +1 -1
  8. package/dist/core.mjs +1 -1
  9. package/dist/core.mjs.map +1 -1
  10. package/dist/identity/express.d.mts +2 -2
  11. package/dist/identity/express.d.ts +2 -2
  12. package/dist/identity/express.js +1 -1
  13. package/dist/identity/express.js.map +1 -1
  14. package/dist/identity/express.mjs +1 -1
  15. package/dist/identity/express.mjs.map +1 -1
  16. package/dist/identity/fastify.d.mts +2 -2
  17. package/dist/identity/fastify.d.ts +2 -2
  18. package/dist/identity/fastify.js +1 -1
  19. package/dist/identity/fastify.js.map +1 -1
  20. package/dist/identity/fastify.mjs +1 -1
  21. package/dist/identity/fastify.mjs.map +1 -1
  22. package/dist/identity/hono.d.mts +2 -2
  23. package/dist/identity/hono.d.ts +2 -2
  24. package/dist/identity/hono.js +1 -1
  25. package/dist/identity/hono.js.map +1 -1
  26. package/dist/identity/hono.mjs +1 -1
  27. package/dist/identity/hono.mjs.map +1 -1
  28. package/dist/identity/nextjs.d.mts +2 -2
  29. package/dist/identity/nextjs.d.ts +2 -2
  30. package/dist/identity/nextjs.js +1 -1
  31. package/dist/identity/nextjs.js.map +1 -1
  32. package/dist/identity/nextjs.mjs +1 -1
  33. package/dist/identity/nextjs.mjs.map +1 -1
  34. package/dist/identity/policy.d.mts +3 -3
  35. package/dist/identity/policy.d.ts +3 -3
  36. package/dist/identity/policy.js +3 -3
  37. package/dist/identity/policy.js.map +1 -1
  38. package/dist/identity/policy.mjs +2 -2
  39. package/dist/identity/policy.mjs.map +1 -1
  40. package/dist/identity/web.d.mts +3 -3
  41. package/dist/identity/web.d.ts +3 -3
  42. package/dist/identity/web.js +1 -1
  43. package/dist/identity/web.js.map +1 -1
  44. package/dist/identity/web.mjs +1 -1
  45. package/dist/identity/web.mjs.map +1 -1
  46. package/dist/index.d.mts +217 -123
  47. package/dist/index.d.ts +217 -123
  48. package/dist/index.js +86 -70
  49. package/dist/index.js.map +1 -1
  50. package/dist/index.mjs +84 -68
  51. package/dist/index.mjs.map +1 -1
  52. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -32,11 +32,13 @@ var index_exports = {};
32
32
  __export(index_exports, {
33
33
  AGENTSCORE_UCP_CAPABILITY: () => AGENTSCORE_UCP_CAPABILITY,
34
34
  FIXABLE_DENIAL_REASONS: () => FIXABLE_DENIAL_REASONS,
35
+ UCPSigningKey: () => UCPSigningKey,
35
36
  UCPVerificationError: () => UCPVerificationError,
36
37
  UCP_A2A_EXTENSION_URI: () => UCP_A2A_EXTENSION_URI,
37
38
  buildA2AAgentCard: () => buildA2AAgentCard,
38
39
  buildAgentMemoryHint: () => buildAgentMemoryHint,
39
40
  buildContactSupportNextSteps: () => buildContactSupportNextSteps,
41
+ buildGateOptionsFromPolicy: () => buildGateOptionsFromPolicy,
40
42
  buildJWKSResponse: () => buildJWKSResponse,
41
43
  buildSignerMismatchBody: () => buildSignerMismatchBody,
42
44
  buildUCPProfile: () => buildUCPProfile,
@@ -46,14 +48,12 @@ __export(index_exports, {
46
48
  extractPaymentSignerAddress: () => extractPaymentSignerAddress,
47
49
  generateUCPSigningKey: () => generateUCPSigningKey,
48
50
  isFixableDenial: () => isFixableDenial,
49
- policyToGateOptions: () => policyToGateOptions,
50
51
  readX402PaymentHeader: () => readX402PaymentHeader,
51
52
  runGateWithEnforcement: () => runGateWithEnforcement,
52
53
  shippingCountryAllowed: () => shippingCountryAllowed,
53
54
  shippingStateAllowed: () => shippingStateAllowed,
54
55
  signUCPProfile: () => signUCPProfile,
55
56
  ucpA2AExtension: () => ucpA2AExtension,
56
- ucpSigningKeyFromJWK: () => ucpSigningKeyFromJWK,
57
57
  verificationAgentInstructions: () => verificationAgentInstructions,
58
58
  verifyUCPProfile: () => verifyUCPProfile
59
59
  });
@@ -384,73 +384,86 @@ function readX402PaymentHeader(request) {
384
384
  }
385
385
 
386
386
  // src/identity/a2a.ts
387
+ var PROTOCOL_VERSION = "1.0";
388
+ var DEFAULT_PROTOCOL_BINDING = "HTTP+JSON";
389
+ var DEFAULT_INPUT_MODE = "application/json";
390
+ var DEFAULT_OUTPUT_MODE = "application/json";
387
391
  var UCP_A2A_EXTENSION_URI = "https://ucp.dev/2026-04-08/specification/reference";
388
- function ucpA2AExtension(capabilities = {}) {
392
+ function ucpA2AExtension(capabilities = {}, options = {}) {
389
393
  return {
390
394
  uri: UCP_A2A_EXTENSION_URI,
395
+ description: "UCP support: this agent serves Universal Commerce Protocol bindings via the A2A transport.",
396
+ required: options.required ?? false,
391
397
  params: { capabilities }
392
398
  };
393
399
  }
394
- var PROTOCOL_VERSION = "1.0";
395
- var CARD_VERSION = 1;
396
400
  function buildA2AAgentCard(input) {
397
- const issuer = input.issuer ?? "https://agentscore.sh";
398
- let identity = null;
399
- if (input.data) {
400
- const operatorId = input.data.resolved_operator ?? null;
401
- if (operatorId) {
402
- const operatorVerification = input.data.operator_verification;
403
- const accountVerification = input.data.account_verification;
404
- identity = {
405
- issuer,
406
- operator_id: operatorId,
407
- kyc_level: accountVerification?.kyc_level ?? operatorVerification?.level ?? "none",
408
- sanctions_clear: accountVerification?.sanctions_clear === true,
409
- age_bracket: accountVerification?.age_bracket ?? "unknown",
410
- jurisdiction: accountVerification?.jurisdiction ?? "",
411
- verified_at: accountVerification?.verified_at ?? operatorVerification?.verified_at ?? null,
412
- verify_url: input.verifyUrl ?? input.data.verify_url ?? `${issuer}/verify`
413
- };
414
- }
401
+ if (!input.skills || input.skills.length === 0) {
402
+ throw new Error(
403
+ "buildA2AAgentCard: `skills` MUST be a non-empty list. Per spec \xA74.4.1 (proto field 12 [field_behavior=REQUIRED]), every Agent Card must declare at least one AgentSkill. Construct A2AAgentCard directly to bypass."
404
+ );
415
405
  }
406
+ const capabilities = {};
407
+ if (input.streaming !== void 0) capabilities.streaming = input.streaming;
408
+ if (input.push_notifications !== void 0) capabilities.push_notifications = input.push_notifications;
409
+ if (input.extensions && input.extensions.length > 0) capabilities.extensions = input.extensions;
410
+ if (input.extended_agent_card !== void 0) capabilities.extended_agent_card = input.extended_agent_card;
411
+ const primaryInterface = {
412
+ url: input.url,
413
+ protocol_binding: input.protocol_binding ?? DEFAULT_PROTOCOL_BINDING,
414
+ protocol_version: input.a2a_protocol_version ?? PROTOCOL_VERSION
415
+ };
416
416
  const card = {
417
- protocol_version: PROTOCOL_VERSION,
418
- card_version: CARD_VERSION,
419
417
  name: input.name,
420
- identity
418
+ description: input.description,
419
+ supported_interfaces: [primaryInterface],
420
+ version: input.version ?? "1.0.0",
421
+ capabilities,
422
+ default_input_modes: input.default_input_modes ?? [DEFAULT_INPUT_MODE],
423
+ default_output_modes: input.default_output_modes ?? [DEFAULT_OUTPUT_MODE],
424
+ skills: input.skills
421
425
  };
422
- if (input.description !== void 0) card.description = input.description;
423
- if (input.url !== void 0) card.url = input.url;
424
- if (input.capabilities !== void 0) card.capabilities = input.capabilities;
425
- if (input.extensions && input.extensions.length > 0) card.extensions = input.extensions;
426
- if (input.extras !== void 0) card.extras = input.extras;
426
+ if (input.provider !== void 0) card.provider = input.provider;
427
+ if (input.documentation_url !== void 0) card.documentation_url = input.documentation_url;
428
+ if (input.icon_url !== void 0) card.icon_url = input.icon_url;
429
+ if (input.signatures !== void 0 && input.signatures.length > 0) card.signatures = input.signatures;
430
+ if (input.security_schemes !== void 0) card.security_schemes = input.security_schemes;
431
+ if (input.security_requirements !== void 0) card.security_requirements = input.security_requirements;
432
+ if (input.extras) {
433
+ for (const [k, v] of Object.entries(input.extras)) {
434
+ card[k] = v;
435
+ }
436
+ }
427
437
  return card;
428
438
  }
429
439
 
430
440
  // src/identity/ucp.ts
431
- function ucpSigningKeyFromJWK(jwk) {
441
+ function ucpSigningKeyFromJWKImpl(jwk) {
432
442
  if (!jwk || typeof jwk !== "object") {
433
- throw new Error(`ucpSigningKeyFromJWK expected a non-null object; got ${typeof jwk}.`);
443
+ throw new Error(`UCPSigningKey.fromJWK expected a non-null object; got ${typeof jwk}.`);
434
444
  }
435
445
  if (typeof jwk.kid !== "string" || !jwk.kid) {
436
- throw new Error("ucpSigningKeyFromJWK: JWK missing required field `kid` (or non-string).");
446
+ throw new Error("UCPSigningKey.fromJWK: JWK missing required field `kid` (or non-string).");
437
447
  }
438
448
  if (typeof jwk.kty !== "string" || !jwk.kty) {
439
- throw new Error("ucpSigningKeyFromJWK: JWK missing required field `kty` (or non-string).");
449
+ throw new Error("UCPSigningKey.fromJWK: JWK missing required field `kty` (or non-string).");
440
450
  }
441
451
  if (jwk.kty !== "OKP" && jwk.kty !== "EC" && jwk.kty !== "RSA") {
442
452
  throw new Error(
443
- `ucpSigningKeyFromJWK: kty=${JSON.stringify(jwk.kty)} is not a supported asymmetric key type (expected OKP, EC, or RSA). Symmetric \`oct\` keys are rejected because they cannot publicly verify a JWS in the trust-mode UCP flow.`
453
+ `UCPSigningKey.fromJWK: kty=${JSON.stringify(jwk.kty)} is not a supported asymmetric key type (expected OKP, EC, or RSA). Symmetric \`oct\` keys are rejected because they cannot publicly verify a JWS in the trust-mode UCP flow.`
444
454
  );
445
455
  }
446
456
  if ((jwk.kty === "EC" || jwk.kty === "OKP") && (typeof jwk.crv !== "string" || !jwk.crv)) {
447
- throw new Error(`ucpSigningKeyFromJWK: kty=${jwk.kty} requires a non-empty \`crv\` field (e.g., "P-256" for EC, "Ed25519" for OKP).`);
457
+ throw new Error(`UCPSigningKey.fromJWK: kty=${jwk.kty} requires a non-empty \`crv\` field (e.g., "P-256" for EC, "Ed25519" for OKP).`);
448
458
  }
449
459
  return jwk;
450
460
  }
461
+ var UCPSigningKey = {
462
+ fromJWK: ucpSigningKeyFromJWKImpl
463
+ };
451
464
  var DEFAULT_VERSION = "2026-04-08";
452
465
  var AGENTSCORE_CAPABILITY_NAME = "sh.agentscore.identity";
453
- var AGENTSCORE_CAPABILITY_VERSION = "1";
466
+ var AGENTSCORE_CAPABILITY_VERSION = "2026-04-08";
454
467
  var AGENTSCORE_DEFAULT_SPEC_URL = "https://agentscore.sh/specification/identity";
455
468
  var AGENTSCORE_DEFAULT_SCHEMA_URL = "https://agentscore.sh/schemas/ucp/sh-agentscore-identity-v1.json";
456
469
  var AGENTSCORE_EXTENDS = ["dev.ucp.shopping.checkout", "dev.ucp.shopping.cart"];
@@ -474,44 +487,47 @@ var RESERVED_UCP_FIELDS = /* @__PURE__ */ new Set([
474
487
  "prototype"
475
488
  ]);
476
489
  function buildUCPProfile(input) {
490
+ for (const [name, bindings] of Object.entries(input.services ?? {})) {
491
+ for (const binding of bindings) {
492
+ if ((binding.transport === "rest" || binding.transport === "mcp" || binding.transport === "a2a") && (binding.endpoint === void 0 || binding.endpoint === null || binding.endpoint === "")) {
493
+ throw new Error(
494
+ `buildUCPProfile: service "${name}" transport=${binding.transport} requires \`endpoint\`. Per UCP spec service.json business_schema, rest/mcp/a2a bindings MUST carry an endpoint URL.`
495
+ );
496
+ }
497
+ }
498
+ }
499
+ const paymentHandlers = {};
500
+ for (const [name, bindings] of Object.entries(input.payment_handlers ?? {})) {
501
+ paymentHandlers[name] = bindings.map((binding) => {
502
+ if (Array.isArray(binding.available_instruments) && binding.available_instruments.length === 0) {
503
+ const { available_instruments: _drop, ...rest } = binding;
504
+ return rest;
505
+ }
506
+ return binding;
507
+ });
508
+ }
477
509
  const capabilities = {};
478
510
  for (const [name, bindings] of Object.entries(input.capabilities ?? {})) {
479
511
  capabilities[name] = [...bindings];
480
512
  }
481
- if (input.data) {
482
- const operatorId = input.data.resolved_operator;
483
- if (operatorId) {
484
- const operatorVerification = input.data.operator_verification;
485
- const accountVerification = input.data.account_verification;
486
- const claims = {
487
- operator_id: operatorId,
488
- kyc_level: accountVerification?.kyc_level || operatorVerification?.level || "none",
489
- sanctions_clear: accountVerification?.sanctions_clear === true,
490
- age_bracket: accountVerification?.age_bracket || "unknown",
491
- jurisdiction: accountVerification?.jurisdiction || "",
492
- verified_at: accountVerification?.verified_at || operatorVerification?.verified_at || null,
493
- verify_url: input.data.verify_url ?? null,
494
- issuer: "https://agentscore.sh"
495
- };
496
- const agentscoreBinding = {
497
- version: AGENTSCORE_CAPABILITY_VERSION,
498
- spec: input.agentscore_spec_url ?? AGENTSCORE_DEFAULT_SPEC_URL,
499
- schema: input.agentscore_schema_url ?? AGENTSCORE_DEFAULT_SCHEMA_URL,
500
- extends: AGENTSCORE_EXTENDS,
501
- // `claims` is our vendor extra on the binding; allowed per spec via the
502
- // `[k: string]: unknown` index signature on UCPCapabilityBinding.
503
- claims
504
- };
505
- const existing = capabilities[AGENTSCORE_CAPABILITY_NAME];
506
- if (existing) existing.push(agentscoreBinding);
507
- else capabilities[AGENTSCORE_CAPABILITY_NAME] = [agentscoreBinding];
508
- }
513
+ if (input.agentscore_gate) {
514
+ const gateConfig = { ...input.agentscore_gate };
515
+ const agentscoreBinding = {
516
+ version: AGENTSCORE_CAPABILITY_VERSION,
517
+ spec: input.agentscore_spec_url ?? AGENTSCORE_DEFAULT_SPEC_URL,
518
+ schema: input.agentscore_schema_url ?? AGENTSCORE_DEFAULT_SCHEMA_URL,
519
+ extends: AGENTSCORE_EXTENDS
520
+ };
521
+ if (Object.keys(gateConfig).length > 0) agentscoreBinding.config = gateConfig;
522
+ const existing = capabilities[AGENTSCORE_CAPABILITY_NAME];
523
+ if (existing) existing.push(agentscoreBinding);
524
+ else capabilities[AGENTSCORE_CAPABILITY_NAME] = [agentscoreBinding];
509
525
  }
510
526
  const ucp = {
511
527
  version: input.version ?? DEFAULT_VERSION,
512
528
  services: input.services ?? {},
513
529
  capabilities,
514
- payment_handlers: input.payment_handlers ?? {}
530
+ payment_handlers: paymentHandlers
515
531
  };
516
532
  if (input.name !== void 0) ucp.name = input.name;
517
533
  if (input.supported_versions !== void 0) ucp.supported_versions = input.supported_versions;
@@ -812,7 +828,7 @@ function buildJWKSResponse(keys) {
812
828
  }
813
829
 
814
830
  // src/identity/policy.ts
815
- function policyToGateOptions(policy, base) {
831
+ function buildGateOptionsFromPolicy(policy, base) {
816
832
  if (!policy || !policy.enforcement) return null;
817
833
  return {
818
834
  apiKey: base.apiKey,
@@ -861,11 +877,13 @@ function shippingStateAllowed(state, country, policy) {
861
877
  0 && (module.exports = {
862
878
  AGENTSCORE_UCP_CAPABILITY,
863
879
  FIXABLE_DENIAL_REASONS,
880
+ UCPSigningKey,
864
881
  UCPVerificationError,
865
882
  UCP_A2A_EXTENSION_URI,
866
883
  buildA2AAgentCard,
867
884
  buildAgentMemoryHint,
868
885
  buildContactSupportNextSteps,
886
+ buildGateOptionsFromPolicy,
869
887
  buildJWKSResponse,
870
888
  buildSignerMismatchBody,
871
889
  buildUCPProfile,
@@ -875,14 +893,12 @@ function shippingStateAllowed(state, country, policy) {
875
893
  extractPaymentSignerAddress,
876
894
  generateUCPSigningKey,
877
895
  isFixableDenial,
878
- policyToGateOptions,
879
896
  readX402PaymentHeader,
880
897
  runGateWithEnforcement,
881
898
  shippingCountryAllowed,
882
899
  shippingStateAllowed,
883
900
  signUCPProfile,
884
901
  ucpA2AExtension,
885
- ucpSigningKeyFromJWK,
886
902
  verificationAgentInstructions,
887
903
  verifyUCPProfile
888
904
  });