agentscore-commerce 3.0.0__tar.gz → 3.2.0__tar.gz

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 (253) hide show
  1. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/CLAUDE.md +11 -11
  2. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/PKG-INFO +9 -9
  3. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/README.md +7 -7
  4. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/SECURITY.md +2 -2
  5. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/__init__.py +4 -8
  6. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/_headers.py +1 -1
  7. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/_mppx_receipt.py +3 -3
  8. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/_redis.py +2 -2
  9. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/_warnings.py +1 -1
  10. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/api/__init__.py +1 -1
  11. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/challenge/agent_instructions.py +3 -3
  12. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/challenge/agent_memory.py +2 -7
  13. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/challenge/body.py +1 -1
  14. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/challenge/how_to_pay.py +3 -3
  15. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/challenge/pricing.py +2 -2
  16. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/challenge/respond_402.py +5 -5
  17. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/challenge/validation_error.py +1 -1
  18. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/checkout.py +46 -533
  19. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/checkout_compute_first.py +9 -9
  20. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/discovery/__init__.py +1 -1
  21. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/discovery/agentscore_content.py +6 -6
  22. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/discovery/llms_txt.py +5 -20
  23. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/discovery/openapi.py +4 -22
  24. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/discovery/probe.py +6 -6
  25. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/discovery/robots_tag.py +2 -2
  26. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/discovery/skill_md.py +8 -23
  27. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/discovery/well_known.py +1 -1
  28. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/forwarded_proto.py +2 -2
  29. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/identity/__init__.py +2 -49
  30. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/identity/_denial.py +11 -11
  31. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/identity/_response.py +39 -58
  32. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/identity/a2a.py +7 -51
  33. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/identity/address.py +2 -2
  34. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/identity/aiohttp.py +11 -119
  35. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/identity/core.py +36 -102
  36. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/identity/default_denied.py +1 -1
  37. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/identity/django.py +15 -153
  38. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/identity/fastapi.py +17 -147
  39. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/identity/flask.py +15 -165
  40. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/identity/middleware.py +13 -135
  41. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/identity/policy.py +13 -15
  42. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/identity/sanic.py +10 -114
  43. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/identity/sessions.py +7 -7
  44. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/identity/signer.py +1 -1
  45. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/identity/types.py +11 -51
  46. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/identity/ucp.py +7 -7
  47. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/identity/ucp_jwks.py +15 -15
  48. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/middleware/asgi.py +5 -5
  49. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/__init__.py +1 -1
  50. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/amounts.py +1 -1
  51. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/compose_rails.py +2 -2
  52. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/default_rails.py +2 -2
  53. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/dispatch.py +2 -2
  54. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/headers.py +10 -10
  55. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/idempotency.py +4 -4
  56. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/mppx_server.py +8 -8
  57. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/network_kind.py +1 -1
  58. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/payment_header.py +7 -13
  59. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/settlement_override.py +1 -1
  60. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/solana.py +4 -4
  61. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/wwwauthenticate.py +1 -1
  62. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/x402_server.py +14 -14
  63. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/x402_settle.py +5 -5
  64. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/x402_validation.py +6 -6
  65. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/zero_settle.py +2 -2
  66. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/quote_cache.py +3 -3
  67. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/stripe_multichain/__init__.py +1 -1
  68. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/stripe_multichain/mppx_stripe.py +4 -4
  69. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/stripe_multichain/pay_to_address.py +4 -4
  70. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/stripe_multichain/pi_cache.py +9 -9
  71. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/stripe_multichain/simulate_deposit.py +6 -6
  72. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/examples/README.md +2 -2
  73. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/examples/compliance_merchant.py +1 -1
  74. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/examples/compute_first_merchant.py +4 -4
  75. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/examples/identity_only.py +3 -3
  76. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/examples/multi_rail_merchant.py +1 -1
  77. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/examples/per_product_policy_merchant.py +2 -2
  78. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/examples/stripe_multichain_merchant.py +3 -3
  79. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/osv-scanner.toml +3 -3
  80. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/pyproject.toml +13 -9
  81. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/scripts/regenerate_cross_lang_fixtures.py +12 -12
  82. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_a2a.py +8 -0
  83. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_address.py +3 -3
  84. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_agent_memory_emitter.py +2 -2
  85. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_aiohttp.py +4 -3
  86. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_challenge.py +1 -1
  87. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_checkout.py +10 -10
  88. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_checkout_compute_first.py +3 -3
  89. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_checkout_compute_first_settle.py +3 -3
  90. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_checkout_signer_match.py +4 -4
  91. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_checkout_wallet_ofac_default.py +2 -2
  92. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_classify_orchestration_error.py +2 -2
  93. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_core.py +5 -5
  94. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_default_read_only_on_denied.py +1 -1
  95. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_denial.py +2 -2
  96. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_django.py +1 -1
  97. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_extract_owner_scope.py +3 -3
  98. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_fastapi.py +8 -7
  99. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_flask.py +1 -1
  100. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_gate_quota_info.py +1 -1
  101. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_get_signer_verdict.py +2 -2
  102. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_idempotency_helper.py +1 -1
  103. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_lifted_helpers.py +1 -1
  104. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_load_ucp_signing_key_from_env.py +1 -1
  105. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_middleware.py +7 -6
  106. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_network_kind.py +1 -1
  107. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_pay_to_address.py +2 -2
  108. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_payment_directive.py +1 -1
  109. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_payment_header.py +1 -1
  110. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_payment_servers.py +3 -3
  111. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_payment_signer.py +5 -5
  112. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_policy.py +3 -3
  113. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_quote_cache_redis.py +1 -1
  114. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_rail_spec.py +2 -2
  115. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_redis_internal.py +1 -1
  116. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_response.py +17 -3
  117. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_robots_tag.py +1 -1
  118. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_sanic.py +1 -1
  119. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_seamless_helpers.py +13 -13
  120. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_signer_match.py +7 -44
  121. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_signer_verdict_request_scoped.py +4 -4
  122. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_solana.py +3 -3
  123. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_tokens.py +2 -2
  124. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_ucp.py +2 -2
  125. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_ucp_jwks.py +1 -1
  126. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_verification_session.py +5 -4
  127. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_zero_settle.py +1 -1
  128. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/uv.lock +426 -254
  129. agentscore_commerce-3.0.0/agentscore_commerce/aip/__init__.py +0 -168
  130. agentscore_commerce-3.0.0/agentscore_commerce/aip/gate.py +0 -429
  131. agentscore_commerce-3.0.0/agentscore_commerce/aip/http_signature.py +0 -654
  132. agentscore_commerce-3.0.0/agentscore_commerce/aip/jwks.py +0 -448
  133. agentscore_commerce-3.0.0/agentscore_commerce/aip/request.py +0 -253
  134. agentscore_commerce-3.0.0/agentscore_commerce/aip/types.py +0 -268
  135. agentscore_commerce-3.0.0/agentscore_commerce/aip/verify.py +0 -408
  136. agentscore_commerce-3.0.0/tests/test_aip_adapters.py +0 -303
  137. agentscore_commerce-3.0.0/tests/test_aip_agent_memory.py +0 -36
  138. agentscore_commerce-3.0.0/tests/test_aip_checkout.py +0 -815
  139. agentscore_commerce-3.0.0/tests/test_aip_gate.py +0 -254
  140. agentscore_commerce-3.0.0/tests/test_aip_http_signature.py +0 -597
  141. agentscore_commerce-3.0.0/tests/test_aip_jwks.py +0 -499
  142. agentscore_commerce-3.0.0/tests/test_aip_presentation.py +0 -120
  143. agentscore_commerce-3.0.0/tests/test_aip_request.py +0 -129
  144. agentscore_commerce-3.0.0/tests/test_aip_types.py +0 -135
  145. agentscore_commerce-3.0.0/tests/test_aip_verify.py +0 -372
  146. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  147. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  148. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  149. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/.github/dependabot.yml +0 -0
  150. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/.github/workflows/ci.yml +0 -0
  151. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/.github/workflows/publish.yml +0 -0
  152. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/.github/workflows/security.yml +0 -0
  153. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/.gitignore +0 -0
  154. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/CODE_OF_CONDUCT.md +0 -0
  155. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/CONTRIBUTING.md +0 -0
  156. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/LICENSE +0 -0
  157. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/challenge/__init__.py +0 -0
  158. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/challenge/accepted_methods.py +0 -0
  159. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/challenge/identity.py +0 -0
  160. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/challenge/receipt.py +0 -0
  161. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/checkout_hooks.py +0 -0
  162. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/discovery/bazaar.py +0 -0
  163. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/discovery/redemption_md.py +0 -0
  164. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/discovery/well_known_mpp.py +0 -0
  165. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/discovery/well_known_x402.py +0 -0
  166. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/errors.py +0 -0
  167. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/identity/cache.py +0 -0
  168. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/identity/py.typed +0 -0
  169. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/identity/tokens.py +0 -0
  170. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/middleware/__init__.py +0 -0
  171. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/middleware/_core.py +0 -0
  172. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/middleware/aiohttp.py +0 -0
  173. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/middleware/django.py +0 -0
  174. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/middleware/fastapi.py +0 -0
  175. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/middleware/flask.py +0 -0
  176. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/middleware/sanic.py +0 -0
  177. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/constants.py +0 -0
  178. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/directive.py +0 -0
  179. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/lazy.py +0 -0
  180. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/mppx_failures.py +0 -0
  181. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/networks.py +0 -0
  182. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/rail_spec.py +0 -0
  183. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/rails.py +0 -0
  184. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/signer.py +0 -0
  185. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/usdc.py +0 -0
  186. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/payment/x402.py +0 -0
  187. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/py.typed +0 -0
  188. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/stripe_multichain/payment_intent.py +0 -0
  189. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/agentscore_commerce/stripe_multichain/simulate_dispatch.py +0 -0
  190. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/examples/api_provider.py +0 -0
  191. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/examples/signed_ucp_merchant.py +0 -0
  192. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/lefthook.yml +0 -0
  193. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/ruff.toml +0 -0
  194. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/__init__.py +0 -0
  195. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/conftest.py +0 -0
  196. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/fixtures/cross-lang/node-agentscore-gate-blocked.json +0 -0
  197. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/fixtures/cross-lang/node-agentscore-gate-full.json +0 -0
  198. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/fixtures/cross-lang/node-capability.json +0 -0
  199. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/fixtures/cross-lang/node-emoji-keys.json +0 -0
  200. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/fixtures/cross-lang/node-es256-rails.json +0 -0
  201. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/fixtures/cross-lang/node-extras-int.json +0 -0
  202. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/fixtures/cross-lang/node-int-boundary.json +0 -0
  203. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/fixtures/cross-lang/node-minimal.json +0 -0
  204. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/fixtures/cross-lang/node-multikey.json +0 -0
  205. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/fixtures/cross-lang/node-unicode.json +0 -0
  206. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/fixtures/cross-lang/py-agentscore-gate-blocked.json +0 -0
  207. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/fixtures/cross-lang/py-agentscore-gate-full.json +0 -0
  208. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/fixtures/cross-lang/py-capability.json +0 -0
  209. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/fixtures/cross-lang/py-emoji-keys.json +0 -0
  210. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/fixtures/cross-lang/py-es256-rails.json +0 -0
  211. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/fixtures/cross-lang/py-extras-int.json +0 -0
  212. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/fixtures/cross-lang/py-int-boundary.json +0 -0
  213. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/fixtures/cross-lang/py-minimal.json +0 -0
  214. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/fixtures/cross-lang/py-multikey.json +0 -0
  215. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/fixtures/cross-lang/py-unicode.json +0 -0
  216. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_a2a_canonical.py +0 -0
  217. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_a2a_jws_roundtrip.py +0 -0
  218. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_amounts.py +0 -0
  219. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_api_reexport.py +0 -0
  220. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_cache.py +0 -0
  221. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_checkout_compute_first_adapters.py +0 -0
  222. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_checkout_compute_first_ofac.py +0 -0
  223. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_checkout_coverage_gaps.py +0 -0
  224. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_checkout_verification_bootstrap.py +0 -0
  225. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_compose_rails.py +0 -0
  226. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_coverage_fillers.py +0 -0
  227. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_credential_precheck.py +0 -0
  228. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_default_denied.py +0 -0
  229. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_default_rails.py +0 -0
  230. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_discovery.py +0 -0
  231. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_dispatch.py +0 -0
  232. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_forwarded_proto.py +0 -0
  233. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_integration.py +0 -0
  234. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_internal_helpers.py +0 -0
  235. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_mppx_failures.py +0 -0
  236. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_mppx_receipt.py +0 -0
  237. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_operator_handle.py +0 -0
  238. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_payment_dispatch.py +0 -0
  239. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_payment_handlers.py +0 -0
  240. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_payment_headers.py +0 -0
  241. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_payment_misc.py +0 -0
  242. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_pricing.py +0 -0
  243. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_public_surface.py +0 -0
  244. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_quote_cache.py +0 -0
  245. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_rate_limit.py +0 -0
  246. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_sessions.py +0 -0
  247. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_simulate_dispatch.py +0 -0
  248. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_skill_md.py +0 -0
  249. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_solana_mpp_rail_spec_post_init.py +0 -0
  250. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_stripe_multichain.py +0 -0
  251. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_ucp_cross_lang.py +0 -0
  252. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_validation_error.py +0 -0
  253. {agentscore_commerce-3.0.0 → agentscore_commerce-3.2.0}/tests/test_x402_settle_extra.py +0 -0
@@ -8,14 +8,14 @@ Every helper is extracted from a real consumer, not speculated.
8
8
 
9
9
  | Submodule | What it is |
10
10
  |---|---|
11
- | `agentscore_commerce` (top-level) | `Checkout` orchestrator (the 2.0 high-level surface): one config object + hooks (pre_validate, compute_pricing, mint_recipients, compose_mppx, on_settled, gate), auto-derived x402+pympp servers, per-framework adapters `handle_fastapi`/`handle_flask`/`handle_django`/`handle_aiohttp`/`handle_sanic`, signed UCP routes via `mount_ucp_routes_{fastapi,flask,django,aiohttp,sanic}`, optional `discovery_probe` config for x402-crawler auto-routing. Plus `compute_first_checkout` — variable-cost pay-per-result helper (compute-first + exact-x402). Scope is exact-mode rails only (x402-exact Base, tempo/charge, solana/charge, Stripe SPT); does NOT use x402-upto (Permit2) or Settlement-Overrides — variable cost is captured by running the work pre-settle and emitting a 402 at the exact computed price. `create_quote_cache` — content-hash quote cache used by the compute-first helper (in-memory by default; pass `redis_url` for distributed deployments). `create_result_cache` — the neutral primitive under it: keyed JSON-value cache with the same body-hash key builder; use it to cache any probe-leg result a Checkout-class merchant replays on the settle leg (e.g. a paid upstream call made in `pre_validate`). `create_default_on_denied` — canonical `on_denied(reason)` factory matching `Checkout`'s gate hook (handles `wallet_signer_mismatch`, `wallet_not_trusted` unfixable fallback, `payment_required`, `token_expired`/`invalid_credential`/`api_error`); merchants pass `merchant_name` + `support_email` and override `wallet_not_trusted_message` / `payment_required_message` / `support_context` for vendor-specific copy. `should_run_conditional_gate` / `requests_verification_session` / `has_identity_header` / `VERIFICATION_SESSION_HEADER`: the conditional-gate predicate (payment credential or an opt-in pre-payment verification-session request) and its parts; `build_identity_bootstrap`: the matching `identity_bootstrap` 402 block. `has_payment_header` — discriminator that splits discovery legs (no payment credential → 402) from settle legs (`payment-signature` / `x-payment` / `Authorization: Payment <jwt>`); `has_x402_header` / `has_mppx_header` — granular dispatch helpers (x402 vs MPP credential present) for routes that branch on rail. `malformed_payment_credential` — wire-shape gate for payment credentials (not base64 JSON, not token-shaped → reject); `Checkout` runs it before any merchant hook by default (`credential_pre_check=False` opts out). `default_read_only_on_denied(reason)` — canonical `on_denied` for read-only resource gates (`GET /orders/:id`): collapses every denial to 401 `unauthorized` + `Cache-Control: no-store` while still spreading `denial_reason_to_body` so `agent_instructions` / `verify_url` ride through. Returns a `DefaultOnDeniedResult(body, status, headers)` dataclass; FastAPI / Flask / aiohttp / Sanic `on_denied` callbacks accept an optional 3-tuple `(body, status, headers)` — convert with `lambda req, reason: (r := default_read_only_on_denied(reason), (r.body, r.status, r.headers or {}))[1]` or a named wrapper. Django + ASGI middleware adapters return Response objects directly; construct `JsonResponse(r.body, status=r.status, headers=r.headers)` / `JSONResponse(content=r.body, status_code=r.status, headers=r.headers)`. `extract_owner_scope(headers) -> OwnerScope` — pull canonical owner identity from `X-Wallet-Address` / `X-Operator-Token` with safe token hashing; pair with a wallet-or-token-scoped resource query so plaintext tokens never leave the request. Plus factories: `pricing_result` (cents → typed `PricingResult`), `validation_response_{fastapi,flask,django,aiohttp,sanic}` (4xx envelope per framework) |
11
+ | `agentscore_commerce` (top-level) | `Checkout` orchestrator: one config object + hooks (pre_validate, compute_pricing, mint_recipients, compose_mppx, on_settled, gate), auto-derived x402+pympp servers, per-framework adapters `handle_fastapi`/`handle_flask`/`handle_django`/`handle_aiohttp`/`handle_sanic`, signed UCP routes via `mount_ucp_routes_{fastapi,flask,django,aiohttp,sanic}`, optional `discovery_probe` config for x402-crawler auto-routing. Plus `compute_first_checkout`: variable-cost pay-per-result helper (compute-first + exact-x402). Scope is exact-mode rails only (x402-exact Base, tempo/charge, solana/charge, Stripe SPT); does NOT use x402-upto (Permit2) or Settlement-Overrides: variable cost is captured by running the work pre-settle and emitting a 402 at the exact computed price. `create_quote_cache`: content-hash quote cache used by the compute-first helper (in-memory by default; pass `redis_url` for distributed deployments). `create_result_cache`: the neutral primitive under it: keyed JSON-value cache with the same body-hash key builder; use it to cache any probe-leg result a Checkout-class merchant replays on the settle leg (e.g. a paid upstream call made in `pre_validate`). `create_default_on_denied`: canonical `on_denied(reason)` factory matching `Checkout`'s gate hook (handles `wallet_signer_mismatch`, `wallet_not_trusted` unfixable fallback, `payment_required`, `token_expired`/`invalid_credential`/`api_error`); merchants pass `merchant_name` + `support_email` and override `wallet_not_trusted_message` / `payment_required_message` / `support_context` for vendor-specific copy. `should_run_conditional_gate` / `requests_verification_session` / `has_identity_header` / `VERIFICATION_SESSION_HEADER`: the conditional-gate predicate (payment credential or an opt-in pre-payment verification-session request) and its parts; `build_identity_bootstrap`: the matching `identity_bootstrap` 402 block. `has_payment_header`: discriminator that splits discovery legs (no payment credential → 402) from settle legs (`payment-signature` / `x-payment` / `Authorization: Payment <jwt>`); `has_x402_header` / `has_mppx_header`: granular dispatch helpers (x402 vs MPP credential present) for routes that branch on rail. `malformed_payment_credential`: wire-shape gate for payment credentials (not base64 JSON, not token-shaped → reject); `Checkout` runs it before any merchant hook by default (`credential_pre_check=False` opts out). `default_read_only_on_denied(reason)`: canonical `on_denied` for read-only resource gates (`GET /orders/:id`): collapses every denial to 401 `unauthorized` + `Cache-Control: no-store` while still spreading `denial_reason_to_body` so `agent_instructions` / `verify_url` ride through. Returns a `DefaultOnDeniedResult(body, status, headers)` dataclass; FastAPI / Flask / aiohttp / Sanic `on_denied` callbacks accept an optional 3-tuple `(body, status, headers)`: convert with `lambda req, reason: (r := default_read_only_on_denied(reason), (r.body, r.status, r.headers or {}))[1]` or a named wrapper. Django + ASGI middleware adapters return Response objects directly; construct `JsonResponse(r.body, status=r.status, headers=r.headers)` / `JSONResponse(content=r.body, status_code=r.status, headers=r.headers)`. `extract_owner_scope(headers) -> OwnerScope`: pull canonical owner identity from `X-Wallet-Address` / `X-Operator-Token` with safe token hashing; pair with a wallet-or-token-scoped resource query so plaintext tokens never leave the request. Plus factories: `pricing_result` (cents → typed `PricingResult`), `validation_response_{fastapi,flask,django,aiohttp,sanic}` (4xx envelope per framework) |
12
12
  | `agentscore_commerce.identity.{fastapi,flask,django,aiohttp,sanic,middleware}` | Trust gate middleware (KYC, age, sanctions on both account name and signer wallet, jurisdiction). Each adapter exports a conditional variant that wraps the gate so it fires only on settle legs (anonymous discovery flows through and gets a 402 with all rails): FastAPI / ASGI expose `ConditionalAgentScoreGate`, Django exposes `ConditionalAgentScoreMiddleware`, Flask + Sanic expose `conditional_agentscore_gate(app, ...)`, aiohttp exposes `conditional_agentscore_gate_middleware(...)`. Adapters export ONLY framework-specific surface (gate classes / fns, accessors, `capture_wallet`); shared helpers like `has_payment_header` / `denial_reason_to_body` import from their canonical home (`agentscore_commerce.payment` and `agentscore_commerce.identity` respectively). The Flask / Sanic `agentscore_gate(app, ...)` function accepts an optional `condition=` callable for inline gating (`AgentScoreGate.__init__` does not). |
13
13
  | `agentscore_commerce.identity.policy` | Per-product compliance helpers: `PolicyBlock`, `build_gate_from_policy`, `run_gate_with_enforcement`, `shipping_country_allowed`, `shipping_state_allowed`, `validate_shipping_against_policy` (one-call country+state validator that raises `CheckoutValidationError` with the canonical envelope on miss) |
14
- | `agentscore_commerce.payment` | Networks/USDC/rails registries, paymentauth.org directive builders, `create_x402_server` (wraps `x402[evm]>=2.9` + `cdp-sdk` for `facilitator="coinbase"`; install via the `coinbase` extra), `build_x402_accepts_for_402` (build the 402's `accepts[]` from the registered scheme; derives the right `extra.name` per network), `build_default_checkout_rails(tempo=, x402_base=, solana_mpp=, stripe=)` (canonical 4-rail `rails` dict factory: merchants pass per-rail overrides instead of redeclaring the recipient sentinel + network/chain_id/token boilerplate. When a caller flips `network` without pinning `token` / `chain_id`, the underlying dataclass derives them from the network: Base Sepolia → Sepolia USDC + chain_id 84532, Solana devnet → devnet USDC mint. Explicit overrides always win. Solana's `network` field accepts both CAIP-2 (`solana:5eykt4UsFv8…` / `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1`) AND the raw `@solana/mpp` form (`mainnet-beta` / `devnet` / `localnet`)), `build_mppx_compose_rails(amount_usd=, tempo_recipient=, solana_recipient=, ...)` (per-call intent factory replacing the hand-rolled `[("tempo/charge", {...}), ("solana/charge", {...}), ("stripe/charge", {...})]` list; auto-handles USD→atomic conversion for Solana; auto-drops the `stripe/charge` rail with a one-time `logging.warning` when `amount_usd < 0.50` since Stripe's fixed ~$0.30 fee makes sub-50-cent charges unprofitable — many Stripe accounts also reject PI creation below the floor with `amount_too_small`; sub-50-cent APIs pass `include_stripe=False` explicitly to silence the warning), `process_x402_settle` (verify+settle in one call), `create_mppx_server` (wraps `pympp[server,tempo,stripe]>=0.6`), `is_evm_network`/`is_solana_network` (CAIP-2 discriminators that hide the `startswith("eip155:")` / `startswith("solana:")` prefix matching), `has_payment_header` (settle-leg vs discovery-leg discriminator), `parse_did_pkh_address` (parses ``did:pkh:<family>:<chain>:<addr>`` into a `PaymentSigner`), dispatch-by-network, signer extraction, WWW-Authenticate header, Settlement-Overrides header |
14
+ | `agentscore_commerce.payment` | Networks/USDC/rails registries, paymentauth.org directive builders, `create_x402_server` (wraps `x402[evm]>=2.9` + `cdp-sdk` for `facilitator="coinbase"`; install via the `coinbase` extra), `build_x402_accepts_for_402` (build the 402's `accepts[]` from the registered scheme; derives the right `extra.name` per network), `build_default_checkout_rails(tempo=, x402_base=, solana_mpp=, stripe=)` (canonical 4-rail `rails` dict factory: merchants pass per-rail overrides instead of redeclaring the recipient sentinel + network/chain_id/token boilerplate. When a caller flips `network` without pinning `token` / `chain_id`, the underlying dataclass derives them from the network: Base Sepolia → Sepolia USDC + chain_id 84532, Solana devnet → devnet USDC mint. Explicit overrides always win. Solana's `network` field accepts both CAIP-2 (`solana:5eykt4UsFv8…` / `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1`) AND the raw `@solana/mpp` form (`mainnet-beta` / `devnet` / `localnet`)), `build_mppx_compose_rails(amount_usd=, tempo_recipient=, solana_recipient=, ...)` (per-call intent factory replacing the hand-rolled `[("tempo/charge", {...}), ("solana/charge", {...}), ("stripe/charge", {...})]` list; auto-handles USD→atomic conversion for Solana; auto-drops the `stripe/charge` rail with a one-time `logging.warning` when `amount_usd < 0.50` since Stripe's fixed ~$0.30 fee makes sub-50-cent charges unprofitable: many Stripe accounts also reject PI creation below the floor with `amount_too_small`; sub-50-cent APIs pass `include_stripe=False` explicitly to silence the warning), `process_x402_settle` (verify+settle in one call), `create_mppx_server` (wraps `pympp[server,tempo,stripe]>=0.6`), `is_evm_network`/`is_solana_network` (CAIP-2 discriminators that hide the `startswith("eip155:")` / `startswith("solana:")` prefix matching), `has_payment_header` (settle-leg vs discovery-leg discriminator), `parse_did_pkh_address` (parses ``did:pkh:<family>:<chain>:<addr>`` into a `PaymentSigner`), dispatch-by-network, signer extraction, WWW-Authenticate header, Settlement-Overrides header |
15
15
  | `agentscore_commerce.discovery` | Discovery probe (`is_discovery_probe_request`, `build_discovery_probe_response`; the x402 sample envelope always carries a v2 `resource` and threads optional `extensions`, and `Checkout` fills both from its own `url`/`resource_info`/`discovery_extensions`, because envelope validators (mppx, x402scan's shared engine) hard-require `resource` and read the Bazaar example input to build valid probe bodies), Bazaar wrapper, `/.well-known/mpp.json`, `llms.txt` builder, `skill.md` builder (Claude-Skill-compatible agent-discovery manifest), `build_redemption_skill_md` (delivery-neutral; printed/emailed/API-trial codes all covered via `delivery_intro`/`body_shape`/`body_rules`/`extra_recovery_rows` overrides), `build_merchant_index_json` + `standard_endpoint_descriptions(kind=)` (canonical `/` discovery body for goods or API merchants), `build_success_next_steps` (universal Passport-active success block), `build_agentscore_onboarding_steps`, OpenAPI snippets, `NoindexNonDiscoveryMiddleware` ASGI middleware. Plus the UCP/JWKS publish surface: `build_signed_ucp_response`, `build_signed_jwks_response`, `well_known_preflight_response`, `default_a2a_services`, `bootstrap_ucp_signing_key`, framework-neutral `SignedDiscoveryResponse` + per-framework wrappers `signed_response_{fastapi,flask,django,aiohttp,sanic}` |
16
16
  | `agentscore_commerce.challenge` | 402-body builders: accepted_methods, identity_metadata (auto-attached by `Checkout` when wallet header present), how_to_pay, agent_instructions, build_402_body, pricing, agent_memory, `build_validation_error` (4xx body builder), `Receipt`/`ReceiptNextSteps`/`ProductInfo`/`ShippingAddress` (canonical 200-receipt dataclasses) |
17
- | `agentscore_commerce.stripe_multichain` | Multichain PaymentIntent helper (`create_multichain_payment_intent` returns `MultichainPaymentIntentResult`; read `result.deposit_addresses[network]` directly), `create_pay_to_address_from_stripe_pi(authorization_header=, amount_cents=, stripe=, pi_cache=, networks=, static_recipients=, metadata=, order_id=, preferred_network=)` — one-call per-order payTo resolver matching `Checkout.mint_recipients`: on the settle leg, reuses the buyer's signed-against payTo from the MPP credential (after `pi_cache.has_address` check OR a `static_recipients` match — the static address is always-accepted because the merchant owns it); on the discovery leg, mints a fresh PI for the rails NOT covered by `static_recipients`, caches the merged map, registers static addresses with `pi_cache.cache_address`. `mint_multichain_recipients(...same kwargs) -> MintMultichainRecipientsResult(recipients, payment_intent_id, reused_from_credential)` — structured variant returning the full per-rail map; prefer this when the merchant's `mint_recipients` hook needs all rail addresses (typical multi-rail merchant), and to avoid the "returned-string-is-ambiguous" trap on the settle leg when `static_recipients` is configured. Use `static_recipients={"solana": "<wallet>"}` for low-margin endpoints where rotating per-PI Solana addresses can't absorb MPP spec §13.6's ~$0.50 ATA rent per call — the SDK skips Stripe minting on that network and reuses the static recipient forever; pair with a one-time external USDC pre-funding of the recipient's ATA and every settle pays only the per-tx fee. Testnet simulator (`simulate_crypto_deposit`, `simulate_deposit_if_test_mode`), `simulate_deposit_for_outcome(outcome=, deposit_address=, get_payment_intent_id=, stripe_secret_key=, stripe_version=)` (dispatches the simulator based on a Checkout / compute_first_checkout settle outcome; replaces the per-merchant rail-switch + thin `simulate_deposit_if_testnet(addr, network)` wrapper), `network_for_outcome` (outcome → simulator network arg, handles both Checkout-shaped `rail_key` and compute-first-shaped `mpp_method`, accepts bare scheme names AND `<scheme>/charge` forms), `create_pi_cache`, `create_mppx_stripe` |
18
- | `agentscore_commerce.api` | Re-exports `AgentScore` from `agentscore` SDK |
17
+ | `agentscore_commerce.stripe_multichain` | Multichain PaymentIntent helper (`create_multichain_payment_intent` returns `MultichainPaymentIntentResult`; read `result.deposit_addresses[network]` directly), `create_pay_to_address_from_stripe_pi(authorization_header=, amount_cents=, stripe=, pi_cache=, networks=, static_recipients=, metadata=, order_id=, preferred_network=)`: one-call per-order payTo resolver matching `Checkout.mint_recipients`: on the settle leg, reuses the buyer's signed-against payTo from the MPP credential (after `pi_cache.has_address` check OR a `static_recipients` match: the static address is always-accepted because the merchant owns it); on the discovery leg, mints a fresh PI for the rails NOT covered by `static_recipients`, caches the merged map, registers static addresses with `pi_cache.cache_address`. `mint_multichain_recipients(...same kwargs) -> MintMultichainRecipientsResult(recipients, payment_intent_id, reused_from_credential)`: structured variant returning the full per-rail map; prefer this when the merchant's `mint_recipients` hook needs all rail addresses (typical multi-rail merchant), and to avoid the "returned-string-is-ambiguous" trap on the settle leg when `static_recipients` is configured. Use `static_recipients={"solana": "<wallet>"}` for low-margin endpoints where rotating per-PI Solana addresses can't absorb MPP spec §13.6's ~$0.50 ATA rent per call: the SDK skips Stripe minting on that network and reuses the static recipient forever; pair with a one-time external USDC pre-funding of the recipient's ATA and every settle pays only the per-tx fee. Testnet simulator (`simulate_crypto_deposit`, `simulate_deposit_if_test_mode`), `simulate_deposit_for_outcome(outcome=, deposit_address=, get_payment_intent_id=, stripe_secret_key=, stripe_version=)` (dispatches the simulator based on a Checkout / compute_first_checkout settle outcome; replaces the per-merchant rail-switch + thin `simulate_deposit_if_testnet(addr, network)` wrapper), `network_for_outcome` (outcome → simulator network arg, handles both Checkout-shaped `rail_key` and compute-first-shaped `mpp_method`, accepts bare scheme names AND `<scheme>/charge` forms), `create_pi_cache`, `create_mppx_stripe` |
18
+ | `agentscore_commerce.api` | Re-exports `AgentScore`, `AgentScoreError`, `AGENTSCORE_TEST_ADDRESSES` and `is_agentscore_test_address` from the `agentscore` SDK |
19
19
  | `agentscore_commerce.middleware.{fastapi,flask,django,aiohttp,sanic,asgi}` | Framework-specific rate-limit middleware. FastAPI exposes `rate_limit_fastapi(...)` (FastAPI dependency) plus the ASGI `RateLimitMiddleware` re-export; Flask exposes `rate_limit_flask(app, ...)` (installs a `before_request` hook); Django exposes a class-based async `RateLimitMiddleware` configured via `settings.AGENTSCORE_RATE_LIMIT`; aiohttp exposes `rate_limit_aiohttp(...)` middleware factory; Sanic exposes `rate_limit_sanic(app, ...)` installer; `asgi.RateLimitMiddleware` is a generic ASGI middleware that works with any starlette-compatible app. Shared options: `window_seconds` (default 60), `max_requests` (default 60), `key_resolver` (default first hop of `x-forwarded-for`), `redis_url` (lazy-imports `redis.asyncio` when set, in-memory `dict` fallback otherwise), `key_prefix`. `redis` is an optional peer dep (install via the `redis` extra). |
20
20
 
21
21
  ## Architecture
@@ -48,11 +48,11 @@ Peer-dep pattern: payment/x402/mppx/stripe modules import lazily at runtime; ven
48
48
  | `compute_first_merchant.py` | Pay-per-result variable-cost merchant via the compute-first + exact-x402 helper (`compute_first_checkout`). Exact-mode rails only (x402-exact Base, tempo/charge, solana/charge, Stripe SPT); deliberately scoped out of x402-upto (Permit2) and Settlement-Overrides. Probe runs the work + caches by body content-hash; settle replays the cached result at the computed exact price. Pairs with `rate_limit_fastapi` since the probe leg runs work pre-payment. |
49
49
  | `compliance_merchant.py` | Regulated-goods merchant: full compliance gate + custom `on_denied` composing the denial helpers (`verification_agent_instructions`, `is_fixable_denial`, `build_contact_support_next_steps`, `denial_reason_to_body`/`denial_reason_status`) |
50
50
  | `per_product_policy_merchant.py` | Multi-product merchant where each row carries its own compliance policy. One product hard-gates KYC + age + state; another is anonymous; a third uses `enforcement="soft"` (request KYC but don't block sale). Demonstrates `PolicyBlock`, `build_gate_from_policy`, `run_gate_with_enforcement`, `shipping_country_allowed`, `shipping_state_allowed`. |
51
- | `signed_ucp_merchant.py` | Signed UCP profile (`/.well-known/ucp`) + JWKS endpoint (`/.well-known/jwks.json`). AgentScore's `agentscore-profile+jws` is a vendor extension on top of UCP for trust-mode verifiers (regulated-commerce, AP2-aware) that opt into auditable cryptographic provenance — UCP §6 itself does NOT mandate signing; production UCP merchants commonly ship unsigned. Wires ephemeral-for-dev / env-JWK-for-prod signing, kid rotation, and `Cache-Control` posture. Uses `generate_ucp_signing_key`, `sign_ucp_profile`, `build_jwks_response`, `UCPSigningKey.from_jwk`, `UCPVerificationError`. Demonstrates the payment-handler builders (`mpp_payment_handler`, `x402_payment_handler`, `stripe_spt_payment_handler` — see "Payment-handler builders" below). |
51
+ | `signed_ucp_merchant.py` | Signed UCP profile (`/.well-known/ucp`) + JWKS endpoint (`/.well-known/jwks.json`). AgentScore's `agentscore-profile+jws` is a vendor extension on top of UCP for trust-mode verifiers (regulated-commerce, AP2-aware) that opt into auditable cryptographic provenance: UCP §6 itself does NOT mandate signing; production UCP merchants commonly ship unsigned. Wires ephemeral-for-dev / env-JWK-for-prod signing, kid rotation, and `Cache-Control` posture. Uses `generate_ucp_signing_key`, `sign_ucp_profile`, `build_jwks_response`, `UCPSigningKey.from_jwk`, `UCPVerificationError`. Demonstrates the payment-handler builders (`mpp_payment_handler`, `x402_payment_handler`, `stripe_spt_payment_handler`: see "Payment-handler builders" below). |
52
52
 
53
53
  ## Payment-handler builders
54
54
 
55
- The SDK ships protocol-rooted builders for the AgentScore-published payment handlers — vendors compose UCP `payment_handlers` blocks by spreading these helpers instead of hand-writing the verbose binding wrapper:
55
+ The SDK ships protocol-rooted builders for the AgentScore-published payment handlers: vendors compose UCP `payment_handlers` blocks by spreading these helpers instead of hand-writing the verbose binding wrapper:
56
56
 
57
57
  ```python
58
58
  from agentscore_commerce import StripeRailSpec, TempoRailSpec, X402BaseRailSpec
@@ -73,7 +73,7 @@ build_ucp_profile(
73
73
  )
74
74
  ```
75
75
 
76
- Each helper returns `{ <reverse-DNS-key>: [binding] }` so spreading composes the parent map. The handler `version`, spec URL, and schema URL are owned by the helpers (`agentscore_commerce/identity/ucp.py`) — bumping a handler spec version is a one-line change there. `mpp` takes `TempoRailSpec` / `SolanaMppRailSpec` instances and `x402` takes `X402BaseRailSpec`; each carries a `recipient` — a static address string, or `""` / a factory callable to signal per-order minting (e.g. Stripe-derived deposit addresses), in which case the authoritative recipient ships in the 402 body rather than the static UCP profile.
76
+ Each helper returns `{ <reverse-DNS-key>: [binding] }` so spreading composes the parent map. The handler `version`, spec URL, and schema URL are owned by the helpers (`agentscore_commerce/identity/ucp.py`): bumping a handler spec version is a one-line change there. `mpp` takes `TempoRailSpec` / `SolanaMppRailSpec` instances and `x402` takes `X402BaseRailSpec`; each carries a `recipient`: a static address string, or `""` / a factory callable to signal per-order minting (e.g. Stripe-derived deposit addresses), in which case the authoritative recipient ships in the 402 body rather than the static UCP profile.
77
77
 
78
78
  ## Identity model
79
79
 
@@ -81,11 +81,11 @@ Two identity types: wallet (`X-Wallet-Address`) and operator-token (`X-Operator-
81
81
 
82
82
  `DenialReason` codes (`missing_identity`, `identity_verification_required`, `token_expired`, `invalid_credential`, `wallet_signer_mismatch`, `wallet_auth_requires_wallet_signing`, `wallet_not_trusted`, `api_error`, `payment_required`) each carry a structured `agent_instructions` JSON block describing concrete recovery actions. See `agentscore_commerce/identity/_response.py` for the canned action copy.
83
83
 
84
- `create_session_on_missing` auto-mints a verification session when no identity is present AND when `wallet_not_trusted` carries fixable reasons (`kyc_required` / `kyc_pending` / `kyc_failed`) — both paths rewrite the denial to `identity_verification_required` before reaching `on_denied`. When the merchant omits `create_session_on_missing` from `CheckoutGateConfig`, `Checkout` auto-defaults it from `gate.api_key` + `gate.base_url` + `gate.context` + `gate.merchant_name`. Merchants that need `on_before_session` side effects (e.g. pre-minting an order_id) supply their own config to override.
84
+ `create_session_on_missing` auto-mints a verification session when no identity is present AND when `wallet_not_trusted` carries fixable reasons (`kyc_required` / `kyc_pending` / `kyc_failed`): both paths rewrite the denial to `identity_verification_required` before reaching `on_denied`. When the merchant omits `create_session_on_missing` from `CheckoutGateConfig`, `Checkout` auto-defaults it from `gate.api_key` + `gate.base_url` + `gate.context` + `gate.merchant_name`. Merchants that need `on_before_session` side effects (e.g. pre-minting an order_id) supply their own config to override.
85
85
 
86
86
  **Getting a verify_url before paying.** On an identity-gated `Checkout`, the gate runs only on a settle leg, so a buyer with no identity reached the session 403 only by sending a payment credential first (an SPT buyer had to mint one). The discovery 402 carries an `identity_bootstrap` block (`build_identity_bootstrap()`) naming `X-Verification-Session: create` whenever the request has no identity header (`has_identity_header`), and a request carrying that header, no identity and no payment credential runs the gate, which answers with the same session-bearing 403. It is opt-in on purpose: scanners replay the Bazaar example body on a schedule, so minting on every identity-less 402 would create a session and (on goods stores) a pending order per probe. Gateless merchants neither advertise nor honor it.
87
87
 
88
- `build_verification_required_body(reason, message=?, agent_instructions=?, extra=?)` — canonical body builder for the `identity_verification_required` denial. Spreads `verify_url` / `session_id` / `poll_secret` / `poll_url` / `agent_instructions` from the gate-minted reason into a 4xx envelope with merchant-specific message + optional extras. Saves the per-merchant mapping boilerplate.
88
+ `build_verification_required_body(reason, message=?, agent_instructions=?, extra=?)`: canonical body builder for the `identity_verification_required` denial. Spreads `verify_url` / `session_id` / `poll_secret` / `poll_url` / `agent_instructions` from the gate-minted reason into a 4xx envelope with merchant-specific message + optional extras. Saves the per-merchant mapping boilerplate.
89
89
 
90
90
  `get_signer_verdict(request)` (per-adapter) returns the cached `signer_match` + `signer_sanctions` verdicts the gate composed on its primary `/v1/assess` call (single round trip; merchants build a 403 with `build_signer_mismatch_body(result=verdict.signer_match)` when `kind != "pass"`).
91
91
 
@@ -103,11 +103,11 @@ Anything that is not a well-formed `oph_` string reads as absent rather than bei
103
103
 
104
104
  Captured wallets: `capture_wallet(...)` is fire-and-forget. Reads `operator_token` stashed during gating and POSTs to `/v1/credentials/wallets`. No-ops for wallet-authenticated requests.
105
105
 
106
- Wallet-signer-match + signer-sanctions: the gate adapter calls `extract_payment_signer(x402_header)` pre-evaluate and passes `signer={address, network}` to the SDK's `assess`. The API returns both `signer_match` (wallet-binding) and `signer_sanctions` (OFAC SDN wallet-address) on the same response; commerce caches the raw body alongside the projected verdicts so `get_signer_verdict` is a pure cache read. **Wallet-OFAC SDN enforcement on the `signer` block is unconditional** whenever a signer is present — no `policy.require_sanctions_clear` opt-in required. An SDN hit (or `sanctions_check_unavailable`) flips `decision -> deny` and the gate returns 403 before the handler runs.
106
+ Wallet-signer-match + signer-sanctions: the gate adapter calls `extract_payment_signer(x402_header)` pre-evaluate and passes `signer={address, network}` to the SDK's `assess`. The API returns both `signer_match` (wallet-binding) and `signer_sanctions` (OFAC SDN wallet-address) on the same response; commerce caches the raw body alongside the projected verdicts so `get_signer_verdict` is a pure cache read. **Wallet-OFAC SDN enforcement on the `signer` block is unconditional** whenever a signer is present: no `policy.require_sanctions_clear` opt-in required. An SDN hit (or `sanctions_check_unavailable`) flips `decision -> deny` and the gate returns 403 before the handler runs.
107
107
 
108
108
  ### Always-on wallet OFAC default for gateless merchants
109
109
 
110
- Merchants who do NOT configure a `gate` on `Checkout` (or `compute_first_checkout`) still get wallet OFAC SDN enforcement on every settle leg. The SDK resolves the API key from `AGENTSCORE_API_KEY` (or `gate.api_key` if a partial gate config is present), reads `AGENTSCORE_BASE_URL` for staging/dev overrides, extracts the payment signer, and calls `/v1/assess` with the signer block. SDN hit → 403 with `wallet_not_trusted` + `decision_reasons: ["sanctions_flagged"]`. No key → one-time `[checkout]` / `[<name>.compute_first]` warning + skip (dev/testnet pattern; see `agentscore_commerce/_warnings.py`). Stripe SPT (no extractable wallet signer) skips silently — Stripe runs its own OFAC screen at customer creation. `_has_identity_gate()` detects identity-bearing flags (`require_kyc`, `require_sanctions_clear`, `min_age`, `allowed/blocked_jurisdictions`); when none are set, the 402 body omits `agent_memory` and per-rail commands strip the `-H 'X-Operator-Token: ...'` flag (gateless merchants have no operator to identify). Gate configured WITHOUT `api_key` falls through to the wallet-OFAC-only path so the merchant gets the strict-liability floor instead of silently allowing.
110
+ Merchants who do NOT configure a `gate` on `Checkout` (or `compute_first_checkout`) still get wallet OFAC SDN enforcement on every settle leg. The SDK resolves the API key from `AGENTSCORE_API_KEY` (or `gate.api_key` if a partial gate config is present), reads `AGENTSCORE_BASE_URL` for staging/dev overrides, extracts the payment signer, and calls `/v1/assess` with the signer block. SDN hit → 403 with `wallet_not_trusted` + `decision_reasons: ["sanctions_flagged"]`. No key → one-time `[checkout]` / `[<name>.compute_first]` warning + skip (dev/testnet pattern; see `agentscore_commerce/_warnings.py`). Stripe SPT (no extractable wallet signer) skips silently: Stripe runs its own OFAC screen at customer creation. `_has_identity_gate()` detects identity-bearing flags (`require_kyc`, `require_sanctions_clear`, `min_age`, `allowed/blocked_jurisdictions`); when none are set, the 402 body omits `agent_memory` and per-rail commands strip the `-H 'X-Operator-Token: ...'` flag (gateless merchants have no operator to identify). Gate configured WITHOUT `api_key` falls through to the wallet-OFAC-only path so the merchant gets the strict-liability floor instead of silently allowing.
111
111
 
112
112
  ### Fail-open (opt-in)
113
113
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: agentscore-commerce
3
- Version: 3.0.0
3
+ Version: 3.2.0
4
4
  Summary: Agentic commerce SDK for Python: identity middleware (FastAPI, Flask, Django, AIOHTTP, Sanic, ASGI) + payment helpers + 402 builders + discovery + Stripe multichain. The full merchant-side toolkit for AgentScore-powered agentic commerce.
5
5
  Project-URL: Homepage, https://www.agentscore.com
6
6
  Project-URL: Repository, https://github.com/agentscore/python-commerce
@@ -23,7 +23,7 @@ Classifier: Programming Language :: Python :: 3.14
23
23
  Classifier: Programming Language :: Python :: 3.15
24
24
  Classifier: Topic :: Software Development :: Libraries
25
25
  Requires-Python: >=3.11
26
- Requires-Dist: agentscore-py>=2.7.0
26
+ Requires-Dist: agentscore-py>=2.8.0
27
27
  Requires-Dist: httpx<1.0.0,>=0.25.0
28
28
  Provides-Extra: aiohttp
29
29
  Requires-Dist: aiohttp>=3.8.0; extra == 'aiohttp'
@@ -77,7 +77,7 @@ pip install 'agentscore-commerce[fastapi,x402,coinbase]'
77
77
 
78
78
  | Submodule | What it provides |
79
79
  |---|---|
80
- | `agentscore_commerce` (top-level) | `Checkout` orchestrator + `CheckoutContext` + `CheckoutGateConfig` + `CheckoutValidationError` + `DiscoveryProbeConfig` + `SettleOutcome` + `MppxComposeOutcome` + `PricingResult` (the 2.0 high-level surface: one config object, hooks for pre_validate/compute_pricing/on_settled/mint_recipients/compose_mppx, auto-derived x402+mppx servers, per-framework adapters `handle_fastapi`/`handle_flask`/`handle_django`/`handle_aiohttp`/`handle_sanic`, signed UCP routes via `mount_ucp_routes_{fastapi,flask,django,aiohttp,sanic}`); `create_result_cache` (neutral keyed JSON-value cache with a stable body-hash key builder; cache a probe-leg result, e.g. a paid upstream call made in `pre_validate`, and replay it on the settle leg) plus the compute-first-shaped `create_quote_cache` built on it; `pricing_result` (factory: cents-denominated → typed `PricingResult` with embedded `PricingBlock`); `validation_response_{fastapi,flask,django,aiohttp,sanic}` (per-framework 4xx envelope wrappers); `make_mppx_compose_hook` (canonical pympp compose adapter). |
80
+ | `agentscore_commerce` (top-level) | `Checkout` orchestrator + `CheckoutContext` + `CheckoutGateConfig` + `CheckoutValidationError` + `DiscoveryProbeConfig` + `SettleOutcome` + `MppxComposeOutcome` + `PricingResult` (one config object, hooks for pre_validate/compute_pricing/on_settled/mint_recipients/compose_mppx, auto-derived x402+mppx servers, per-framework adapters `handle_fastapi`/`handle_flask`/`handle_django`/`handle_aiohttp`/`handle_sanic`, signed UCP routes via `mount_ucp_routes_{fastapi,flask,django,aiohttp,sanic}`); `create_result_cache` (neutral keyed JSON-value cache with a stable body-hash key builder; cache a probe-leg result, e.g. a paid upstream call made in `pre_validate`, and replay it on the settle leg) plus the compute-first-shaped `create_quote_cache` built on it; `pricing_result` (factory: cents-denominated → typed `PricingResult` with embedded `PricingBlock`); `validation_response_{fastapi,flask,django,aiohttp,sanic}` (per-framework 4xx envelope wrappers); `make_mppx_compose_hook` (canonical pympp compose adapter). |
81
81
  | `agentscore_commerce.identity.{fastapi,flask,django,aiohttp,sanic,middleware}` | Trust gate middleware: KYC, sanctions (account name + signer wallet), age, jurisdiction. `AgentScoreGate(...)` (or `agentscore_gate(app, ...)` on Flask/Sanic), `get_agentscore_data(...)`, `capture_wallet(...)`, `get_signer_verdict(...)`. The gate extracts the payment signer pre-evaluate and passes it to `/v1/assess`, so the API composes both wallet-binding (`signer_match`) and OFAC SDN wallet-address (`signer_sanctions`) verdicts on one round trip. |
82
82
  | `agentscore_commerce.identity` (package level) | Re-exports the denial helpers: `denial_reason_status`, `denial_reason_to_body`, `build_signer_mismatch_body`, `build_contact_support_next_steps`, `verification_agent_instructions`, `is_fixable_denial`, `FIXABLE_DENIAL_REASONS`. The per-framework adapter modules also expose `get_gate_quota_info(request)` for surfacing X-RateLimit info from gate state. Also re-exports the per-product policy helpers: `PolicyBlock`, `GateResult`, `EnforcementMode`, `IdentityStatus`, `build_gate_from_policy`, `run_gate_with_enforcement`, `shipping_country_allowed`, `shipping_state_allowed`, `validate_shipping_against_policy` (one-call country+state validator that raises `CheckoutValidationError` with the canonical envelope on miss), for multi-product merchants where each product carries its own compliance config: hard gate vs soft vs none, per-product shipping allowlists. Key + token helpers: `load_ucp_signing_key_from_env` (cached env-driven loader for the UCP signing key, reads `UCP_SIGNING_KEY_JWK_PRIVATE` JSON JWK, detects alg from shape, falls back to ephemeral when unset, sanitizes errors so key bytes never reach logs, concurrent-safe via `threading.Lock`; env-var names and `default_kid` / `default_alg` are overridable as kwargs); `hash_operator_token` (sha256 hex of plaintext `opc_...`, for merchants persisting `operator_token_id` to their own DB without ever storing the plaintext); `extract_owner_scope(headers) -> OwnerScope` (canonical owner-identity extractor for caller-scoped resource queries, reads `X-Wallet-Address` / `X-Operator-Token`, hashes the token so plaintext never leaves the request); `default_read_only_on_denied(reason)` (canonical `on_denied` for read-only resource gates: 401 + `Cache-Control: no-store` while still spreading `denial_reason_to_body`. Returns a `DefaultOnDeniedResult(body, status, headers)`; FastAPI / Flask / aiohttp / Sanic `on_denied` callbacks accept an optional 3-tuple `(body, status, headers)` to carry headers through; wrap with `lambda req, reason: (lambda r: (r.body, r.status, r.headers or {}))(default_read_only_on_denied(reason))`). |
83
83
  | `agentscore_commerce.payment` | `networks`, `USDC`, `rails` registries; `payment_directive`, `build_payment_directive`, `www_authenticate_header`, `payment_required_header`, `alias_amount_fields` (opt-in v1↔v2 amount-field shim that adds both `amount` and `maxAmountRequired` to an entry. The 402 builders do NOT apply it by default, strict x402 v2 settlement matches the agent's echoed requirement by exact comparison, so an extra field the server's rebuilt requirement lacks breaks settle; use only when you know a client is hardcoded to read `maxAmountRequired`), `settlement_override_header`, `dispatch_settlement_by_network`, `extract_payment_signer` (accepts positional `x402_payment_header` AND/OR `authorization_header=` kwarg; recovers signer from x402 EIP-3009 `payload.authorization.from` OR MPP `Authorization: Payment <base64>` `did:pkh:eip155:<chain>:<addr>` / `did:pkh:solana:<genesis>:<addr>` source DID), `detect_rail_from_headers` (returns `"x402"` / `"mpp"` / `None` from inbound headers), `register_x402_schemes_v1_v2`; drop-in x402 helpers: `validate_x402_network_config` (boot-time guard), `verify_x402_request` (parse + validate inbound X-Payment), `process_x402_settle` (verify-then-settle with one call), `classify_x402_settle_result` (maps the tagged settle result to a recommended HTTP status / code / next_steps so merchants get a controlled envelope without coupling to facilitator-specific error text), `classify_orchestration_error` (same `ClassifiedX402Error` shape but for uncaught exceptions thrown elsewhere in the orchestration; returns `None` for unknown errors so merchants rethrow instead of swallowing); `zero_amount_carve_out` (skip CDP / pympp upstream verify+settle for $0 settles where the upstream rejects value=0 payloads, including credentials signed against a nonzero quote the merchant re-priced to $0 at settle; parses the credential, lifts signer + network, returns a `ZeroSettleResult` shaped identically to the success path so callers branch on rail, not on result shape), `malformed_payment_credential` (wire-shape gate: payment headers that are not base64 JSON and not token-shaped are rejected before merchant hooks run; `Checkout` applies it by default, opt out with `credential_pre_check=False`); `usd_to_atomic` (Decimal-based USD → atomic int, ROUND_HALF_UP, for Tempo / Solana / Base USDC amount construction). |
@@ -146,7 +146,7 @@ async def purchase(request: Request, assess=Depends(get_agentscore_data)):
146
146
  return {"ok": True}
147
147
  ```
148
148
 
149
- ## Checkout orchestrator (the 2.0 high-level surface)
149
+ ## Checkout orchestrator
150
150
 
151
151
  `Checkout` is the canonical merchant surface: one config object, hooks for the merchant-specific pieces, and the SDK handles 402 emit, identity gating, x402 verify+settle, mppx compose, $0 carve-out, and the per-framework adapter. Most merchants reach for `Checkout` first and drop to lower-level helpers only when they need custom flows.
152
152
 
@@ -368,12 +368,12 @@ from agentscore_commerce.identity import (
368
368
  ucp_a2a_extension,
369
369
  )
370
370
 
371
- # Google A2A v1.0 Signed Agent Card. Publish at /.well-known/agent-card.json.
371
+ # A2A v1.0 Agent Card. Publish at /.well-known/agent-card.json.
372
372
  # Per UCP §A2A binding the card MUST declare the canonical UCP extension URI in
373
373
  # `capabilities.extensions[]`; pass `ucp_a2a_extension()` with empty capabilities
374
374
  # until you bind formal UCP capabilities (dev.ucp.shopping.checkout, etc.).
375
- # Skills are top-level AgentSkill objects; identity claims live in a separate
376
- # AgentCardSignature (RFC 7515 JWS) wrapping the serialized card.
375
+ # Skills are top-level AgentSkill objects. The card is returned unsigned: to sign it,
376
+ # compute RFC 7515 JWS entries over the card body and pass them as `signatures`.
377
377
  card = build_a2a_agent_card(
378
378
  name="My Service",
379
379
  description="Buy products via agent payments.",
@@ -393,7 +393,7 @@ card = build_a2a_agent_card(
393
393
  # Google Universal Commerce Protocol. Publish at /.well-known/ucp.
394
394
  # Output shape: {"ucp": {"version", "services", "capabilities",
395
395
  # "payment_handlers", "name?", "supported_versions?"}, "keys": [...]}
396
- # , services / capabilities / payment_handlers are MAPS keyed by reverse-DNS
396
+ # services / capabilities / payment_handlers are MAPS keyed by reverse-DNS
397
397
  # service / capability / handler name (UCP spec §3 + §6).
398
398
  profile = build_ucp_profile(
399
399
  name="My Service",
@@ -461,7 +461,7 @@ jwks = build_jwks_response([key.public_jwk])
461
461
 
462
462
  **Key rotation.** Mint a new key with a new `kid`, add the public JWK to your JWKS endpoint alongside the old one, then sign new profiles with the new key. Set `Cache-Control: public, max-age=300` on `/.well-known/jwks.json` and wait at least that long after publishing the new key before removing the old JWK.
463
463
 
464
- **Inline JWK in the profile vs separate JWKS endpoint.** UCP §6 mandates the separate `/.well-known/jwks.json` endpoint as the canonical trust source. The profile's `signing_keys[]` is informational; verifiers MUST resolve the kid against the JWKS to prevent a swap-after-sign attack.
464
+ **Inline JWK in the profile vs separate JWKS endpoint.** UCP §6 mandates the separate `/.well-known/jwks.json` endpoint as the canonical trust source. The profile's `keys[]` is informational; verifiers MUST resolve the kid against the JWKS to prevent a swap-after-sign attack.
465
465
 
466
466
  ACP (Stripe + OpenAI Agentic Commerce Protocol) is a transactional checkout protocol with no identity-publishing surface; ACP merchants integrate via the existing `build_402_body` + `build_payment_headers` + Stripe SPT rail.
467
467
 
@@ -24,7 +24,7 @@ pip install 'agentscore-commerce[fastapi,x402,coinbase]'
24
24
 
25
25
  | Submodule | What it provides |
26
26
  |---|---|
27
- | `agentscore_commerce` (top-level) | `Checkout` orchestrator + `CheckoutContext` + `CheckoutGateConfig` + `CheckoutValidationError` + `DiscoveryProbeConfig` + `SettleOutcome` + `MppxComposeOutcome` + `PricingResult` (the 2.0 high-level surface: one config object, hooks for pre_validate/compute_pricing/on_settled/mint_recipients/compose_mppx, auto-derived x402+mppx servers, per-framework adapters `handle_fastapi`/`handle_flask`/`handle_django`/`handle_aiohttp`/`handle_sanic`, signed UCP routes via `mount_ucp_routes_{fastapi,flask,django,aiohttp,sanic}`); `create_result_cache` (neutral keyed JSON-value cache with a stable body-hash key builder; cache a probe-leg result, e.g. a paid upstream call made in `pre_validate`, and replay it on the settle leg) plus the compute-first-shaped `create_quote_cache` built on it; `pricing_result` (factory: cents-denominated → typed `PricingResult` with embedded `PricingBlock`); `validation_response_{fastapi,flask,django,aiohttp,sanic}` (per-framework 4xx envelope wrappers); `make_mppx_compose_hook` (canonical pympp compose adapter). |
27
+ | `agentscore_commerce` (top-level) | `Checkout` orchestrator + `CheckoutContext` + `CheckoutGateConfig` + `CheckoutValidationError` + `DiscoveryProbeConfig` + `SettleOutcome` + `MppxComposeOutcome` + `PricingResult` (one config object, hooks for pre_validate/compute_pricing/on_settled/mint_recipients/compose_mppx, auto-derived x402+mppx servers, per-framework adapters `handle_fastapi`/`handle_flask`/`handle_django`/`handle_aiohttp`/`handle_sanic`, signed UCP routes via `mount_ucp_routes_{fastapi,flask,django,aiohttp,sanic}`); `create_result_cache` (neutral keyed JSON-value cache with a stable body-hash key builder; cache a probe-leg result, e.g. a paid upstream call made in `pre_validate`, and replay it on the settle leg) plus the compute-first-shaped `create_quote_cache` built on it; `pricing_result` (factory: cents-denominated → typed `PricingResult` with embedded `PricingBlock`); `validation_response_{fastapi,flask,django,aiohttp,sanic}` (per-framework 4xx envelope wrappers); `make_mppx_compose_hook` (canonical pympp compose adapter). |
28
28
  | `agentscore_commerce.identity.{fastapi,flask,django,aiohttp,sanic,middleware}` | Trust gate middleware: KYC, sanctions (account name + signer wallet), age, jurisdiction. `AgentScoreGate(...)` (or `agentscore_gate(app, ...)` on Flask/Sanic), `get_agentscore_data(...)`, `capture_wallet(...)`, `get_signer_verdict(...)`. The gate extracts the payment signer pre-evaluate and passes it to `/v1/assess`, so the API composes both wallet-binding (`signer_match`) and OFAC SDN wallet-address (`signer_sanctions`) verdicts on one round trip. |
29
29
  | `agentscore_commerce.identity` (package level) | Re-exports the denial helpers: `denial_reason_status`, `denial_reason_to_body`, `build_signer_mismatch_body`, `build_contact_support_next_steps`, `verification_agent_instructions`, `is_fixable_denial`, `FIXABLE_DENIAL_REASONS`. The per-framework adapter modules also expose `get_gate_quota_info(request)` for surfacing X-RateLimit info from gate state. Also re-exports the per-product policy helpers: `PolicyBlock`, `GateResult`, `EnforcementMode`, `IdentityStatus`, `build_gate_from_policy`, `run_gate_with_enforcement`, `shipping_country_allowed`, `shipping_state_allowed`, `validate_shipping_against_policy` (one-call country+state validator that raises `CheckoutValidationError` with the canonical envelope on miss), for multi-product merchants where each product carries its own compliance config: hard gate vs soft vs none, per-product shipping allowlists. Key + token helpers: `load_ucp_signing_key_from_env` (cached env-driven loader for the UCP signing key, reads `UCP_SIGNING_KEY_JWK_PRIVATE` JSON JWK, detects alg from shape, falls back to ephemeral when unset, sanitizes errors so key bytes never reach logs, concurrent-safe via `threading.Lock`; env-var names and `default_kid` / `default_alg` are overridable as kwargs); `hash_operator_token` (sha256 hex of plaintext `opc_...`, for merchants persisting `operator_token_id` to their own DB without ever storing the plaintext); `extract_owner_scope(headers) -> OwnerScope` (canonical owner-identity extractor for caller-scoped resource queries, reads `X-Wallet-Address` / `X-Operator-Token`, hashes the token so plaintext never leaves the request); `default_read_only_on_denied(reason)` (canonical `on_denied` for read-only resource gates: 401 + `Cache-Control: no-store` while still spreading `denial_reason_to_body`. Returns a `DefaultOnDeniedResult(body, status, headers)`; FastAPI / Flask / aiohttp / Sanic `on_denied` callbacks accept an optional 3-tuple `(body, status, headers)` to carry headers through; wrap with `lambda req, reason: (lambda r: (r.body, r.status, r.headers or {}))(default_read_only_on_denied(reason))`). |
30
30
  | `agentscore_commerce.payment` | `networks`, `USDC`, `rails` registries; `payment_directive`, `build_payment_directive`, `www_authenticate_header`, `payment_required_header`, `alias_amount_fields` (opt-in v1↔v2 amount-field shim that adds both `amount` and `maxAmountRequired` to an entry. The 402 builders do NOT apply it by default, strict x402 v2 settlement matches the agent's echoed requirement by exact comparison, so an extra field the server's rebuilt requirement lacks breaks settle; use only when you know a client is hardcoded to read `maxAmountRequired`), `settlement_override_header`, `dispatch_settlement_by_network`, `extract_payment_signer` (accepts positional `x402_payment_header` AND/OR `authorization_header=` kwarg; recovers signer from x402 EIP-3009 `payload.authorization.from` OR MPP `Authorization: Payment <base64>` `did:pkh:eip155:<chain>:<addr>` / `did:pkh:solana:<genesis>:<addr>` source DID), `detect_rail_from_headers` (returns `"x402"` / `"mpp"` / `None` from inbound headers), `register_x402_schemes_v1_v2`; drop-in x402 helpers: `validate_x402_network_config` (boot-time guard), `verify_x402_request` (parse + validate inbound X-Payment), `process_x402_settle` (verify-then-settle with one call), `classify_x402_settle_result` (maps the tagged settle result to a recommended HTTP status / code / next_steps so merchants get a controlled envelope without coupling to facilitator-specific error text), `classify_orchestration_error` (same `ClassifiedX402Error` shape but for uncaught exceptions thrown elsewhere in the orchestration; returns `None` for unknown errors so merchants rethrow instead of swallowing); `zero_amount_carve_out` (skip CDP / pympp upstream verify+settle for $0 settles where the upstream rejects value=0 payloads, including credentials signed against a nonzero quote the merchant re-priced to $0 at settle; parses the credential, lifts signer + network, returns a `ZeroSettleResult` shaped identically to the success path so callers branch on rail, not on result shape), `malformed_payment_credential` (wire-shape gate: payment headers that are not base64 JSON and not token-shaped are rejected before merchant hooks run; `Checkout` applies it by default, opt out with `credential_pre_check=False`); `usd_to_atomic` (Decimal-based USD → atomic int, ROUND_HALF_UP, for Tempo / Solana / Base USDC amount construction). |
@@ -93,7 +93,7 @@ async def purchase(request: Request, assess=Depends(get_agentscore_data)):
93
93
  return {"ok": True}
94
94
  ```
95
95
 
96
- ## Checkout orchestrator (the 2.0 high-level surface)
96
+ ## Checkout orchestrator
97
97
 
98
98
  `Checkout` is the canonical merchant surface: one config object, hooks for the merchant-specific pieces, and the SDK handles 402 emit, identity gating, x402 verify+settle, mppx compose, $0 carve-out, and the per-framework adapter. Most merchants reach for `Checkout` first and drop to lower-level helpers only when they need custom flows.
99
99
 
@@ -315,12 +315,12 @@ from agentscore_commerce.identity import (
315
315
  ucp_a2a_extension,
316
316
  )
317
317
 
318
- # Google A2A v1.0 Signed Agent Card. Publish at /.well-known/agent-card.json.
318
+ # A2A v1.0 Agent Card. Publish at /.well-known/agent-card.json.
319
319
  # Per UCP §A2A binding the card MUST declare the canonical UCP extension URI in
320
320
  # `capabilities.extensions[]`; pass `ucp_a2a_extension()` with empty capabilities
321
321
  # until you bind formal UCP capabilities (dev.ucp.shopping.checkout, etc.).
322
- # Skills are top-level AgentSkill objects; identity claims live in a separate
323
- # AgentCardSignature (RFC 7515 JWS) wrapping the serialized card.
322
+ # Skills are top-level AgentSkill objects. The card is returned unsigned: to sign it,
323
+ # compute RFC 7515 JWS entries over the card body and pass them as `signatures`.
324
324
  card = build_a2a_agent_card(
325
325
  name="My Service",
326
326
  description="Buy products via agent payments.",
@@ -340,7 +340,7 @@ card = build_a2a_agent_card(
340
340
  # Google Universal Commerce Protocol. Publish at /.well-known/ucp.
341
341
  # Output shape: {"ucp": {"version", "services", "capabilities",
342
342
  # "payment_handlers", "name?", "supported_versions?"}, "keys": [...]}
343
- # , services / capabilities / payment_handlers are MAPS keyed by reverse-DNS
343
+ # services / capabilities / payment_handlers are MAPS keyed by reverse-DNS
344
344
  # service / capability / handler name (UCP spec §3 + §6).
345
345
  profile = build_ucp_profile(
346
346
  name="My Service",
@@ -408,7 +408,7 @@ jwks = build_jwks_response([key.public_jwk])
408
408
 
409
409
  **Key rotation.** Mint a new key with a new `kid`, add the public JWK to your JWKS endpoint alongside the old one, then sign new profiles with the new key. Set `Cache-Control: public, max-age=300` on `/.well-known/jwks.json` and wait at least that long after publishing the new key before removing the old JWK.
410
410
 
411
- **Inline JWK in the profile vs separate JWKS endpoint.** UCP §6 mandates the separate `/.well-known/jwks.json` endpoint as the canonical trust source. The profile's `signing_keys[]` is informational; verifiers MUST resolve the kid against the JWKS to prevent a swap-after-sign attack.
411
+ **Inline JWK in the profile vs separate JWKS endpoint.** UCP §6 mandates the separate `/.well-known/jwks.json` endpoint as the canonical trust source. The profile's `keys[]` is informational; verifiers MUST resolve the kid against the JWKS to prevent a swap-after-sign attack.
412
412
 
413
413
  ACP (Stripe + OpenAI Agentic Commerce Protocol) is a transactional checkout protocol with no identity-publishing surface; ACP merchants integrate via the existing `build_402_body` + `build_payment_headers` + Stripe SPT rail.
414
414
 
@@ -19,5 +19,5 @@ We will acknowledge receipt within 48 hours and aim to release a fix within 7 da
19
19
 
20
20
  | Version | Supported |
21
21
  |---------|-----------|
22
- | 2.x | ✅ |
23
- | < 2.0 | ❌ |
22
+ | 3.x | ✅ |
23
+ | < 3.0 | ❌ |
@@ -1,4 +1,4 @@
1
- """Agentic commerce SDK — identity middleware + payment helpers + 402 builders + discovery + Stripe multichain.
1
+ """Agentic commerce SDK: identity middleware + payment helpers + 402 builders + discovery + Stripe multichain.
2
2
 
3
3
  Submodules:
4
4
  agentscore_commerce.identity - per-framework gate adapters
@@ -25,7 +25,6 @@ from agentscore_commerce.checkout import (
25
25
  MppxComposeOutcome,
26
26
  PricingResult,
27
27
  SettleOutcome,
28
- build_aip_trusted_issuers,
29
28
  format_pydantic_errors,
30
29
  get_identity_status,
31
30
  pricing_result,
@@ -60,7 +59,6 @@ from agentscore_commerce.identity import (
60
59
  A2A_DEFAULT_TRANSPORT,
61
60
  A2A_PROTOCOL_VERSION,
62
61
  AGENTSCORE_UCP_CAPABILITY,
63
- AIP_A2A_EXTENSION_URI,
64
62
  FIXABLE_DENIAL_REASONS,
65
63
  UCP_A2A_EXTENSION_URI,
66
64
  A2AAgentCard,
@@ -93,7 +91,6 @@ from agentscore_commerce.identity import (
93
91
  UCPSigningKey,
94
92
  UCPVerificationError,
95
93
  VerifyWalletSignerResult,
96
- aip_a2a_extension,
97
94
  build_a2a_agent_card,
98
95
  build_agent_memory_hint,
99
96
  build_contact_support_next_steps,
@@ -117,6 +114,7 @@ from agentscore_commerce.identity import (
117
114
  shipping_state_allowed,
118
115
  sign_ucp_profile,
119
116
  stripe_spt_payment_handler,
117
+ to_security_requirements,
120
118
  ucp_a2a_extension,
121
119
  validate_shipping_against_policy,
122
120
  verification_agent_instructions,
@@ -162,7 +160,7 @@ from agentscore_commerce.quote_cache import (
162
160
  try:
163
161
  __version__ = _pkg_version("agentscore-commerce")
164
162
  except PackageNotFoundError:
165
- # Editable install or pre-build state — fall back to a sentinel so consumers
163
+ # Editable install or pre-build state: fall back to a sentinel so consumers
166
164
  # don't crash on a missing dist-info dir. Real version always comes from
167
165
  # pyproject.toml at install time.
168
166
  __version__ = "0.0.0+local"
@@ -171,7 +169,6 @@ __all__ = [
171
169
  "A2A_DEFAULT_TRANSPORT",
172
170
  "A2A_PROTOCOL_VERSION",
173
171
  "AGENTSCORE_UCP_CAPABILITY",
174
- "AIP_A2A_EXTENSION_URI",
175
172
  "FIXABLE_DENIAL_REASONS",
176
173
  "UCP_A2A_EXTENSION_URI",
177
174
  "VERIFICATION_SESSION_HEADER",
@@ -242,10 +239,8 @@ __all__ = [
242
239
  "WorkOutcome",
243
240
  "X402BaseRailSpec",
244
241
  "__version__",
245
- "aip_a2a_extension",
246
242
  "build_a2a_agent_card",
247
243
  "build_agent_memory_hint",
248
- "build_aip_trusted_issuers",
249
244
  "build_contact_support_next_steps",
250
245
  "build_default_checkout_rails",
251
246
  "build_gate_from_policy",
@@ -290,6 +285,7 @@ __all__ = [
290
285
  "should_run_conditional_gate",
291
286
  "sign_ucp_profile",
292
287
  "stripe_spt_payment_handler",
288
+ "to_security_requirements",
293
289
  "ucp_a2a_extension",
294
290
  "validate_shipping_against_policy",
295
291
  "validation_envelope",
@@ -1,4 +1,4 @@
1
- """Internal header helpers — case-normalization for HTTP headers.
1
+ """Internal header helpers: case-normalization for HTTP headers.
2
2
 
3
3
  Replaces hand-rolled ``{k.lower(): v for k, v in headers.items()}`` loops in
4
4
  ``checkout``, ``signer`` and ``challenge.respond_402``.
@@ -19,11 +19,11 @@ def extract_mppx_receipt_header_from_raw(raw: Any) -> str | None:
19
19
 
20
20
  Covers three shapes hand-rolled hooks commonly return:
21
21
 
22
- * ``raw.receipt_header`` — pympp's current direct-attribute shape.
23
- * ``raw.to_payment_receipt()`` — pympp's older Receipt return-method shape
22
+ * ``raw.receipt_header``: pympp's current direct-attribute shape.
23
+ * ``raw.to_payment_receipt()``: pympp's older Receipt return-method shape
24
24
  (also reached when ``raw`` is a ``(credential, receipt)`` tuple OR a
25
25
  dict/object carrying ``.receipt``).
26
- * ``raw.with_receipt(response) -> Response`` — a shape that wraps an
26
+ * ``raw.with_receipt(response) -> Response``: a shape that wraps an
27
27
  outgoing Response and attaches the header.
28
28
 
29
29
  Returns ``None`` when none match or the underlying call raises.
@@ -4,7 +4,7 @@ Replaces the hand-rolled lazy-init pattern in ``quote_cache``,
4
4
  ``stripe_multichain.pi_cache``, and ``middleware._core`` so they don't drift
5
5
  on logging posture, TLS handling, or connect-error semantics.
6
6
 
7
- ``redis`` is an optional peer dep — callers pass ``redis_url`` (or rely on
7
+ ``redis`` is an optional peer dep: callers pass ``redis_url`` (or rely on
8
8
  ``REDIS_URL`` env); when unset or the lazy import fails, this returns ``None``
9
9
  and the caller falls back to its in-process dict.
10
10
 
@@ -80,7 +80,7 @@ def memoized_redis(*, url: str | None, label: str) -> Callable[[], Awaitable[Any
80
80
  First call constructs the client; later calls return the same client
81
81
  (or the same ``None``).
82
82
 
83
- Pairs with the per-caller ``redis_url`` opt — when ``url`` is ``None`` AND
83
+ Pairs with the per-caller ``redis_url`` opt: when ``url`` is ``None`` AND
84
84
  ``REDIS_URL`` is unset, the getter resolves to ``None`` once and remains so
85
85
  for the lifetime of the caller.
86
86
  """
@@ -28,7 +28,7 @@ def warn_missing_api_key_once(label: str) -> None:
28
28
  return
29
29
  _warned_no_api_key = True
30
30
  logging.getLogger(__name__).warning(
31
- f"[{label}] AGENTSCORE_API_KEY is not set — wallet OFAC SDN sanctions are NOT being enforced. "
31
+ f"[{label}] AGENTSCORE_API_KEY is not set: wallet OFAC SDN sanctions are NOT being enforced. "
32
32
  "Set the env var to enable strict-liability protection on settle."
33
33
  )
34
34
 
@@ -1,4 +1,4 @@
1
- """AgentScore SDK re-export — single import path for the underlying agentscore-py.
1
+ """AgentScore SDK re-export: single import path for the underlying agentscore-py.
2
2
 
3
3
  Vendors install only ``agentscore-commerce`` and reach everything from the underlying
4
4
  ``agentscore-py`` here. Don't add ``agentscore-py`` as a separate dep; the two can
@@ -58,7 +58,7 @@ _RAIL_CLIENTS: dict[str, list[str]] = {
58
58
  def compatible_clients_by_rails(rails: Iterable[str]) -> dict[str, list[str]] | None:
59
59
  """Smoke-verified client list for a set of rail keys.
60
60
 
61
- The single source of truth for "which CLIs we've verified end-to-end on each rail" —
61
+ The single source of truth for "which CLIs we've verified end-to-end on each rail":
62
62
  consumed both by the 402-body builder (``build_agent_instructions``) and by discovery
63
63
  surfaces (skill.md, llms.txt, etc.). Update here, every surface inherits.
64
64
  """
@@ -101,13 +101,13 @@ def build_agent_instructions(
101
101
  extra_warnings: list[str] | None = None,
102
102
  recommended: str | None = None,
103
103
  # Per-rail list of client names the merchant has verified work end-to-end.
104
- # Vendors set this from their own smoke matrix — defaults to None, in which case
104
+ # Vendors set this from their own smoke matrix: defaults to None, in which case
105
105
  # the field is not emitted (avoids vouching for clients the merchant has not tested).
106
106
  # Keys are rail identifiers (e.g. "x402_base", "tempo_mpp"); values are display labels.
107
107
  compatible_clients: dict[str, list[str]] | None = None,
108
108
  extra: dict[str, Any] | None = None,
109
109
  ) -> dict[str, Any]:
110
- """Build the agent_instructions block — combines how_to_pay with tools, warnings, compat note, timeout.
110
+ """Build the agent_instructions block: combines how_to_pay with tools, warnings, compat note, timeout.
111
111
 
112
112
  Defaults adapt to the rails declared in ``how_to_pay``: only tempo-relevant warnings/tools
113
113
  appear if ``how_to_pay["tempo"]`` is set, only x402-relevant ones if ``x402_base``/
@@ -10,7 +10,7 @@ Usage pattern:
10
10
  - Merchant tracks per-operator (or per-IP / per-fingerprint) "have I seen this agent
11
11
  before?" in their own DB
12
12
  - On first encounter, include the hint so the agent saves the pattern
13
- - On subsequent encounters, skip — the agent already has it (or never will)
13
+ - On subsequent encounters, skip: the agent already has it (or never will)
14
14
 
15
15
  The hint contents come from :func:`build_agent_memory_hint` (re-exported here for
16
16
  convenience). Keep it stateless: AgentScore's pattern doesn't depend on the merchant's
@@ -24,7 +24,6 @@ from agentscore_commerce.identity.types import AgentMemoryHint, build_agent_memo
24
24
 
25
25
  def first_encounter_agent_memory(
26
26
  first_encounter: bool,
27
- aip_trusted_issuers: list[str] | None = None,
28
27
  ) -> AgentMemoryHint | None:
29
28
  """Return the ``agent_memory`` hint when this is a first encounter, otherwise ``None``.
30
29
 
@@ -39,17 +38,13 @@ def first_encounter_agent_memory(
39
38
  ),
40
39
  )
41
40
 
42
- When the merchant accepts AIP, pass ``aip_trusted_issuers`` (AgentScore's canonical
43
- issuer plus any externals) so the hint advertises the ``agent_identity`` path. Omit for
44
- non-AIP merchants.
45
-
46
41
  Returning ``None`` means ``build_402_body`` cleanly skips the field instead of
47
42
  emitting ``agent_memory: null`` (which would imply "I tried but failed" rather than
48
43
  "didn't apply").
49
44
  """
50
45
  if not first_encounter:
51
46
  return None
52
- return build_agent_memory_hint(aip_trusted_issuers)
47
+ return build_agent_memory_hint()
53
48
 
54
49
 
55
50
  __all__ = ["AgentMemoryHint", "build_agent_memory_hint", "first_encounter_agent_memory"]
@@ -1,4 +1,4 @@
1
- """build_402_body — full enriched 402 response body builder."""
1
+ """build_402_body: full enriched 402 response body builder."""
2
2
 
3
3
  from dataclasses import asdict, dataclass, is_dataclass
4
4
  from typing import Any, Literal
@@ -1,4 +1,4 @@
1
- """how_to_pay block builder — per-rail setup/command/what_it_does for 402 agent_instructions."""
1
+ """how_to_pay block builder: per-rail setup/command/what_it_does for 402 agent_instructions."""
2
2
 
3
3
  import math
4
4
  from typing import Any
@@ -43,7 +43,7 @@ async def build_how_to_pay(
43
43
  retry_body_json: str,
44
44
  total_usd: float | str,
45
45
  rails: dict[str, TempoRailSpec | X402BaseRailSpec | SolanaMppRailSpec | StripeRailSpec],
46
- op_token_placeholder: str | None = "<your_opc_token>", # noqa: S107 — literal placeholder, not a secret
46
+ op_token_placeholder: str | None = "<your_opc_token>", # noqa: S107 # literal placeholder, not a secret
47
47
  max_spend: float | str | None = None,
48
48
  decimals: int = 2,
49
49
  ) -> dict[str, Any]:
@@ -65,7 +65,7 @@ async def build_how_to_pay(
65
65
 
66
66
  ``op_token_placeholder`` defaults to ``"<your_opc_token>"``. Pass ``None``
67
67
  (gateless merchants) to strip the ``-H 'X-Operator-Token: ...'`` snippet
68
- from every rail command — appropriate when the merchant doesn't run an
68
+ from every rail command: appropriate when the merchant doesn't run an
69
69
  identity gate. The always-on wallet OFAC SDN default does NOT need an
70
70
  operator token, so gateless merchants emit cleaner commands.
71
71
  """
@@ -1,8 +1,8 @@
1
1
  """Pricing block builder + canonical type.
2
2
 
3
3
  Composes cents-denominated price components into the dollar-string shape that 402
4
- challenge bodies advertise. Standardizes the pricing block so every merchant —
5
- current and future commerce-platform plugins (Commerce7, WooCommerce, Shopify) —
4
+ challenge bodies advertise. Standardizes the pricing block so every merchant:
5
+ current and future commerce-platform plugins (Commerce7, WooCommerce, Shopify):
6
6
  surfaces the same shape to agents.
7
7
 
8
8
  Shipping is included by default because most physical-goods merchants carry it; pass
@@ -1,14 +1,14 @@
1
- """``respond_402`` — single-call 402 emit for merchants who use both pympp + x402.
1
+ """``respond_402``: single-call 402 emit for merchants who use both pympp + x402.
2
2
 
3
3
  Pympp handles tempo + stripe MPP rails; x402 handles Base + Solana.
4
4
 
5
5
  The seam is fiddly enough to get wrong by hand:
6
6
 
7
7
  - pympp's compose returns a 402 response with WWW-Authenticate directives whose ids
8
- pympp's server-side validator REMEMBERS — they round-trip in client credentials.
8
+ pympp's server-side validator REMEMBERS: they round-trip in client credentials.
9
9
  Overwriting that header (e.g. with a freshly-built directive) breaks the round-trip.
10
10
  - x402 needs the binary-friendly ``PAYMENT-REQUIRED`` header (base64-encoded JSON of
11
- ``{x402Version, accepts, resource}``) — pympp doesn't emit it.
11
+ ``{x402Version, accepts, resource}``): pympp doesn't emit it.
12
12
  - Merchants want a richer JSON body (pricing, identity metadata, agent_instructions,
13
13
  agent_memory, retry_body, accepted_methods cross-reference) than the bare pympp body.
14
14
 
@@ -35,7 +35,7 @@ from agentscore_commerce.payment.wwwauthenticate import payment_required_header
35
35
 
36
36
  @dataclass
37
37
  class Respond402Result:
38
- """Framework-neutral 402 response shape — body + headers + status."""
38
+ """Framework-neutral 402 response shape: body + headers + status."""
39
39
 
40
40
  body: dict[str, object]
41
41
  headers: dict[str, str]
@@ -55,7 +55,7 @@ def respond_402(
55
55
 
56
56
  ``body`` is the already-built dict from :func:`build_402_body`. ``x402``, when
57
57
  set, carries the PAYMENT-REQUIRED header inputs (``x402_version``, ``accepts``,
58
- ``resource``); omit for merchants that don't accept x402 (Base / Solana) — pympp-only
58
+ ``resource``); omit for merchants that don't accept x402 (Base / Solana): pympp-only
59
59
  setups.
60
60
  """
61
61
  headers = {k.lower(): v for k, v in mppx_challenge_headers.items()}
@@ -3,7 +3,7 @@
3
3
  Pairs cleanly with the existing 402 / 403 builders. Every commerce merchant
4
4
  returning helpful ``bad_request`` / ``not_found`` / ``out_of_stock`` errors
5
5
  converges on the same shape: ``{error: {code, message}, ...optional_hints,
6
- next_steps?}``. This builder doesn't choose the HTTP status — vendors wrap the
6
+ next_steps?}``. This builder doesn't choose the HTTP status: vendors wrap the
7
7
  returned body in their framework's response (``JSONResponse(body, 400)`` in
8
8
  FastAPI, etc.). Status stays the merchant's call because the same shape works
9
9
  for 400/404/409/422.