xytara 3.1.16 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (390) hide show
  1. package/README.md +120 -92
  2. package/RELEASE_NOTES.md +7 -3
  3. package/START_HERE.md +56 -224
  4. package/bin/xytara.js +21 -8
  5. package/client.js +79 -1
  6. package/lib/{delivery_receipt.js → delivery_receipt_verify.js} +14 -100
  7. package/package.json +25 -35
  8. package/scripts/verify_client.js +418 -0
  9. package/scripts/verify_release_candidate.js +146 -45
  10. package/.env.example +0 -173
  11. package/ADAPTER_START_HERE.md +0 -56
  12. package/BSV_TERANODE_PLATFORM_DISCONTINUITY_RUNBOOK.md +0 -126
  13. package/CARRIED_HANDOFF_DEMO.md +0 -60
  14. package/EXAMPLE_PATHS.md +0 -53
  15. package/FINAL_CONTRACT.md +0 -498
  16. package/PARTNER_READY_PATH.md +0 -71
  17. package/PUBLIC_DEMO_SCRIPT.md +0 -78
  18. package/REAL_PAYMENT_SETUP.md +0 -320
  19. package/SERVICE_CONTRACT.md +0 -419
  20. package/SUPABASE_RUNTIME_STATE_SETUP.md +0 -61
  21. package/TERMINOLOGY.md +0 -50
  22. package/WHY_XYTARA_XOONYA.md +0 -63
  23. package/XT1_EXECUTION_TRUTH_STANDARD.md +0 -78
  24. package/XYTARA_ADAPTER_PROTOCOL_TRUTH_MODEL.md +0 -75
  25. package/XYTARA_AUTONOMOUS_ENTRY_MODEL.md +0 -124
  26. package/XYTARA_DEFAULT_PATH_MODEL.md +0 -84
  27. package/XYTARA_EXECUTION_TRUTH_MODEL.md +0 -171
  28. package/XYTARA_PAYMENT_RAIL_TRUTH_MODEL.md +0 -68
  29. package/adapters/AUTHORING_GUIDE.md +0 -244
  30. package/adapters/ONBOARDING_POSTURE.md +0 -61
  31. package/adapters/THIRD_PARTY_SUBMISSION_PROCESS.md +0 -84
  32. package/adapters/adapter-manifest.schema.json +0 -283
  33. package/adapters/examples/example-execution-adapter.js +0 -61
  34. package/adapters/examples/example-execution-adapter.manifest.json +0 -81
  35. package/adapters/examples/example-settlement-adapter.js +0 -55
  36. package/adapters/examples/example-settlement-adapter.manifest.json +0 -78
  37. package/adapters/examples/example-third-party-acp-registration.submission-bundle.json +0 -124
  38. package/adapters/examples/example-third-party-erc8004-registration.submission-bundle.json +0 -121
  39. package/adapters/examples/example-third-party-identity-registration.certification-pack.json +0 -22
  40. package/adapters/examples/example-third-party-identity-registration.record.json +0 -26
  41. package/adapters/examples/example-third-party-identity-registration.submission-bundle.json +0 -126
  42. package/adapters/examples/example-third-party-langchain-registration.submission-bundle.json +0 -124
  43. package/adapters/examples/example-third-party-mpp-registration.submission-bundle.json +0 -120
  44. package/adapters/examples/example-third-party-registration.certification-pack.json +0 -22
  45. package/adapters/examples/example-third-party-registration.record.json +0 -28
  46. package/adapters/examples/example-third-party-registration.submission-bundle.json +0 -126
  47. package/adapters/examples/example-third-party-settlement-registration.certification-pack.json +0 -22
  48. package/adapters/examples/example-third-party-settlement-registration.record.json +0 -26
  49. package/adapters/examples/example-third-party-settlement-registration.submission-bundle.json +0 -127
  50. package/adapters/examples/langchain-reference-execution-adapter.js +0 -81
  51. package/adapters/examples/langchain-reference-execution-adapter.manifest.json +0 -79
  52. package/adapters/examples/langgraph-reference-execution-adapter.js +0 -81
  53. package/adapters/examples/langgraph-reference-execution-adapter.manifest.json +0 -79
  54. package/adapters/examples/minimal-third-party-execution-adapter.js +0 -61
  55. package/adapters/examples/minimal-third-party-execution-adapter.manifest.json +0 -79
  56. package/adapters/examples/minimal-third-party-execution-registration.record.json +0 -26
  57. package/adapters/examples/minimal-third-party-execution.certification-pack.json +0 -22
  58. package/adapters/examples/minimal-third-party-execution.submission-bundle.json +0 -126
  59. package/adapters/integration-certification-pack.schema.json +0 -82
  60. package/adapters/integration-registration-record.schema.json +0 -114
  61. package/adapters/integration-submission-bundle-set.schema.json +0 -39
  62. package/adapters/integration-submission-bundle.schema.json +0 -34
  63. package/adapters/interfaces.js +0 -56
  64. package/bin/xytara-release.js +0 -1429
  65. package/examples/_demo_env.js +0 -40
  66. package/examples/adapter_review_walkthrough.js +0 -54
  67. package/examples/export_carried_handoff.js +0 -81
  68. package/examples/funded_runtime_walkthrough.js +0 -71
  69. package/examples/partner_launch_walkthrough.js +0 -44
  70. package/examples/quickstart.js +0 -3256
  71. package/fixtures/catalog.js +0 -1156
  72. package/index.js +0 -395
  73. package/integrations/dispatch.js +0 -276
  74. package/integrations/registry-snapshot.schema.json +0 -36
  75. package/integrations/registry.js +0 -2261
  76. package/integrations/views.js +0 -28
  77. package/lib/a2a_lane_contract.js +0 -104
  78. package/lib/a2a_rpc.js +0 -287
  79. package/lib/a2c_lane_contract.js +0 -111
  80. package/lib/account_auth.js +0 -585
  81. package/lib/acp_lane_contract.js +0 -54
  82. package/lib/activity_audit_contract.js +0 -322
  83. package/lib/adapter_certification_contract.js +0 -130
  84. package/lib/adapter_depth_contract.js +0 -218
  85. package/lib/adapter_pack.js +0 -118
  86. package/lib/adapter_partner_pack.js +0 -89
  87. package/lib/adapter_promotion_pack.js +0 -89
  88. package/lib/adapter_protocol_truth_contract.js +0 -229
  89. package/lib/agent_identity.js +0 -162
  90. package/lib/announcement_pack.js +0 -61
  91. package/lib/artifact_distribution_lane_contract.js +0 -54
  92. package/lib/asyncapi_contract.js +0 -150
  93. package/lib/auth_interop_contract.js +0 -80
  94. package/lib/authority_binding_lifecycle_contract.js +0 -182
  95. package/lib/autonomous_entry_contract.js +0 -409
  96. package/lib/bolt_adapter.js +0 -187
  97. package/lib/bolt_lane_contract.js +0 -55
  98. package/lib/bolt_payment_front.js +0 -224
  99. package/lib/business_cockpit.js +0 -378
  100. package/lib/buyer_event_log.js +0 -230
  101. package/lib/buyer_safety_policy.js +0 -132
  102. package/lib/capability_execution_truth.js +0 -276
  103. package/lib/capability_registry.js +0 -633
  104. package/lib/catalog_contract.js +0 -966
  105. package/lib/catalog_family_model.js +0 -193
  106. package/lib/catalog_views.js +0 -55
  107. package/lib/cdp_jwt.js +0 -57
  108. package/lib/checkout_event_security.js +0 -142
  109. package/lib/checkout_processor_adapter.js +0 -217
  110. package/lib/cloudevents_contract.js +0 -80
  111. package/lib/command_flow.js +0 -911
  112. package/lib/commerce_artifacts.js +0 -591
  113. package/lib/commerce_authority.js +0 -449
  114. package/lib/commerce_bridge.js +0 -274
  115. package/lib/commerce_cases.js +0 -399
  116. package/lib/commerce_checkout.js +0 -509
  117. package/lib/commerce_coordination.js +0 -346
  118. package/lib/commerce_economics.js +0 -4017
  119. package/lib/commerce_identity.js +0 -578
  120. package/lib/commerce_quotes.js +0 -266
  121. package/lib/commerce_reports.js +0 -14461
  122. package/lib/commerce_runtime.js +0 -322
  123. package/lib/commerce_shell.js +0 -257
  124. package/lib/crypto_agility_matrix.js +0 -125
  125. package/lib/default_path_contract.js +0 -412
  126. package/lib/delivery_summary_contract.js +0 -95
  127. package/lib/ecosystem_entry.js +0 -64
  128. package/lib/erc8004_lane_contract.js +0 -65
  129. package/lib/event_system_lane_contract.js +0 -75
  130. package/lib/execution_dedupe.js +0 -86
  131. package/lib/execution_truth_contract.js +0 -234
  132. package/lib/external_credit_bridge.js +0 -142
  133. package/lib/external_execution_policy.js +0 -143
  134. package/lib/external_execution_runtime.js +0 -238
  135. package/lib/feature_control_lane_contract.js +0 -54
  136. package/lib/first_run_conversion_contract.js +0 -290
  137. package/lib/framework_lane_contract.js +0 -89
  138. package/lib/framework_provider_promotion.js +0 -235
  139. package/lib/full_catalog_contract.js +0 -525
  140. package/lib/go_live_operator_pack.js +0 -391
  141. package/lib/http_transport.js +0 -99
  142. package/lib/identity_auth.js +0 -175
  143. package/lib/identity_interop_contract.js +0 -82
  144. package/lib/integration_matrix_contract.js +0 -102
  145. package/lib/l402_adapter.js +0 -241
  146. package/lib/l402_lane_contract.js +0 -55
  147. package/lib/l402_payment_front.js +0 -265
  148. package/lib/launch_narrative.js +0 -53
  149. package/lib/lifecycle_continuity_contract.js +0 -115
  150. package/lib/machine_identity_registry_contract.js +0 -199
  151. package/lib/major_rails_lane_contract.js +0 -150
  152. package/lib/market_lane_contract.js +0 -467
  153. package/lib/market_lane_depth_contract.js +0 -182
  154. package/lib/market_lane_promotion_contract.js +0 -210
  155. package/lib/market_lane_trace_contract.js +0 -278
  156. package/lib/mcp_lane_contract.js +0 -137
  157. package/lib/mpp_adapter.js +0 -237
  158. package/lib/network_transport.js +0 -110
  159. package/lib/offline_verifiability_recovery_contract.js +0 -155
  160. package/lib/openapi_contract.js +0 -300
  161. package/lib/operational_receipt_contract.js +0 -165
  162. package/lib/operator_intelligence.js +0 -407
  163. package/lib/outreach_copy_pack.js +0 -51
  164. package/lib/outreach_message_pack.js +0 -71
  165. package/lib/outreach_proof.js +0 -71
  166. package/lib/outreach_target_pack.js +0 -60
  167. package/lib/partner_intelligence.js +0 -105
  168. package/lib/payment_config.js +0 -257
  169. package/lib/payment_front_registry.js +0 -53
  170. package/lib/payment_protocol_contract.js +0 -165
  171. package/lib/payment_rail_truth_contract.js +0 -324
  172. package/lib/payment_verification.js +0 -357
  173. package/lib/phase_10_closeout_pack.js +0 -45
  174. package/lib/phase_10_completion_pack.js +0 -76
  175. package/lib/phase_10_decision_record_pack.js +0 -54
  176. package/lib/phase_10_decision_resolution_pack.js +0 -53
  177. package/lib/phase_10_demand_signal_adapters_runtime_pack.js +0 -74
  178. package/lib/phase_10_ecosystem_backlog_triage_runtime_pack.js +0 -74
  179. package/lib/phase_10_freeze_baseline_pack.js +0 -67
  180. package/lib/phase_10_freeze_review_pack.js +0 -64
  181. package/lib/phase_10_gate_pack.js +0 -57
  182. package/lib/phase_10_long_tail_continuity_pack.js +0 -80
  183. package/lib/phase_10_long_tail_ecosystem_pack.js +0 -66
  184. package/lib/phase_10_niche_extension_registry_runtime_pack.js +0 -74
  185. package/lib/phase_1_claude_mcp_pack.js +0 -60
  186. package/lib/phase_1_claude_mcp_runtime_pack.js +0 -52
  187. package/lib/phase_1_ecosystem_pack.js +0 -67
  188. package/lib/phase_1_openai_codex_pack.js +0 -60
  189. package/lib/phase_1_openai_codex_runtime_pack.js +0 -52
  190. package/lib/phase_2_base_runtime_pack.js +0 -71
  191. package/lib/phase_2_base_usdc_runtime_pack.js +0 -72
  192. package/lib/phase_2_closeout_pack.js +0 -65
  193. package/lib/phase_2_completion_pack.js +0 -113
  194. package/lib/phase_2_decision_record_pack.js +0 -66
  195. package/lib/phase_2_decision_resolution_pack.js +0 -69
  196. package/lib/phase_2_eth_runtime_pack.js +0 -70
  197. package/lib/phase_2_evm_base_runtime_pack.js +0 -73
  198. package/lib/phase_2_evm_runtime_pack.js +0 -71
  199. package/lib/phase_2_flip_preview_pack.js +0 -60
  200. package/lib/phase_2_freeze_review_pack.js +0 -99
  201. package/lib/phase_2_gate_pack.js +0 -77
  202. package/lib/phase_2_payment_rails_pack.js +0 -71
  203. package/lib/phase_2_usdc_runtime_pack.js +0 -71
  204. package/lib/phase_3_brc_runtime_pack.js +0 -81
  205. package/lib/phase_3_bsv_teranode_runtime_pack.js +0 -83
  206. package/lib/phase_3_closeout_pack.js +0 -62
  207. package/lib/phase_3_completion_pack.js +0 -94
  208. package/lib/phase_3_decision_record_pack.js +0 -64
  209. package/lib/phase_3_decision_resolution_pack.js +0 -69
  210. package/lib/phase_3_freeze_baseline_pack.js +0 -67
  211. package/lib/phase_3_freeze_review_pack.js +0 -80
  212. package/lib/phase_3_gate_pack.js +0 -76
  213. package/lib/phase_3_metanet_runtime_pack.js +0 -81
  214. package/lib/phase_3_native_bsv_pack.js +0 -91
  215. package/lib/phase_3_native_continuity_pack.js +0 -82
  216. package/lib/phase_4_attestation_runtime_pack.js +0 -75
  217. package/lib/phase_4_closeout_pack.js +0 -45
  218. package/lib/phase_4_completion_pack.js +0 -94
  219. package/lib/phase_4_decision_record_pack.js +0 -54
  220. package/lib/phase_4_decision_resolution_pack.js +0 -45
  221. package/lib/phase_4_erc8004_runtime_pack.js +0 -76
  222. package/lib/phase_4_freeze_baseline_pack.js +0 -67
  223. package/lib/phase_4_freeze_review_pack.js +0 -68
  224. package/lib/phase_4_gate_pack.js +0 -58
  225. package/lib/phase_4_identity_registry_runtime_pack.js +0 -75
  226. package/lib/phase_4_identity_trust_pack.js +0 -73
  227. package/lib/phase_4_trust_continuity_pack.js +0 -86
  228. package/lib/phase_5_antelope_runtime_pack.js +0 -76
  229. package/lib/phase_5_closeout_pack.js +0 -44
  230. package/lib/phase_5_completion_pack.js +0 -82
  231. package/lib/phase_5_constellation_dag_runtime_pack.js +0 -76
  232. package/lib/phase_5_decision_record_pack.js +0 -54
  233. package/lib/phase_5_decision_resolution_pack.js +0 -45
  234. package/lib/phase_5_digibyte_dgb_runtime_pack.js +0 -76
  235. package/lib/phase_5_freeze_baseline_pack.js +0 -67
  236. package/lib/phase_5_freeze_review_pack.js +0 -68
  237. package/lib/phase_5_gate_pack.js +0 -58
  238. package/lib/phase_5_hedera_hbar_runtime_pack.js +0 -76
  239. package/lib/phase_5_kaspa_kas_runtime_pack.js +0 -76
  240. package/lib/phase_5_major_rails_continuity_pack.js +0 -86
  241. package/lib/phase_5_major_rails_pack.js +0 -110
  242. package/lib/phase_5_metal_runtime_pack.js +0 -76
  243. package/lib/phase_5_polkadot_dot_runtime_pack.js +0 -76
  244. package/lib/phase_5_proton_xpr_runtime_pack.js +0 -76
  245. package/lib/phase_5_solana_runtime_pack.js +0 -76
  246. package/lib/phase_6_autogen_runtime_pack.js +0 -72
  247. package/lib/phase_6_closeout_pack.js +0 -46
  248. package/lib/phase_6_completion_pack.js +0 -77
  249. package/lib/phase_6_decision_record_pack.js +0 -54
  250. package/lib/phase_6_decision_resolution_pack.js +0 -53
  251. package/lib/phase_6_framework_continuity_pack.js +0 -81
  252. package/lib/phase_6_framework_runtime_pack.js +0 -68
  253. package/lib/phase_6_freeze_baseline_pack.js +0 -68
  254. package/lib/phase_6_freeze_review_pack.js +0 -65
  255. package/lib/phase_6_gate_pack.js +0 -59
  256. package/lib/phase_6_langchain_runtime_pack.js +0 -72
  257. package/lib/phase_6_langgraph_runtime_pack.js +0 -72
  258. package/lib/phase_6_semantic_kernel_runtime_pack.js +0 -72
  259. package/lib/phase_7_closeout_pack.js +0 -45
  260. package/lib/phase_7_completion_pack.js +0 -85
  261. package/lib/phase_7_decision_record_pack.js +0 -53
  262. package/lib/phase_7_decision_resolution_pack.js +0 -53
  263. package/lib/phase_7_event_system_continuity_pack.js +0 -89
  264. package/lib/phase_7_event_system_pack.js +0 -76
  265. package/lib/phase_7_freeze_baseline_pack.js +0 -74
  266. package/lib/phase_7_freeze_review_pack.js +0 -65
  267. package/lib/phase_7_gate_pack.js +0 -58
  268. package/lib/phase_7_kafka_runtime_pack.js +0 -74
  269. package/lib/phase_7_mqtt_runtime_pack.js +0 -74
  270. package/lib/phase_7_nats_runtime_pack.js +0 -74
  271. package/lib/phase_7_webhook_event_bus_runtime_pack.js +0 -74
  272. package/lib/phase_8_closeout_pack.js +0 -46
  273. package/lib/phase_8_completion_pack.js +0 -82
  274. package/lib/phase_8_decision_record_pack.js +0 -54
  275. package/lib/phase_8_decision_resolution_pack.js +0 -53
  276. package/lib/phase_8_external_receipt_import_runtime_pack.js +0 -74
  277. package/lib/phase_8_external_result_import_runtime_pack.js +0 -74
  278. package/lib/phase_8_freeze_baseline_pack.js +0 -71
  279. package/lib/phase_8_freeze_review_pack.js +0 -64
  280. package/lib/phase_8_gate_pack.js +0 -58
  281. package/lib/phase_8_proof_bridge_continuity_pack.js +0 -86
  282. package/lib/phase_8_proof_bridges_pack.js +0 -72
  283. package/lib/phase_8_proof_bundle_normalization_runtime_pack.js +0 -74
  284. package/lib/phase_9_closeout_pack.js +0 -46
  285. package/lib/phase_9_completion_pack.js +0 -82
  286. package/lib/phase_9_custody_refs_runtime_pack.js +0 -74
  287. package/lib/phase_9_decision_record_pack.js +0 -54
  288. package/lib/phase_9_decision_resolution_pack.js +0 -53
  289. package/lib/phase_9_freeze_baseline_pack.js +0 -71
  290. package/lib/phase_9_freeze_review_pack.js +0 -64
  291. package/lib/phase_9_gate_pack.js +0 -58
  292. package/lib/phase_9_operator_accounting_bridges_runtime_pack.js +0 -74
  293. package/lib/phase_9_treasury_connectivity_pack.js +0 -72
  294. package/lib/phase_9_treasury_continuity_pack.js +0 -86
  295. package/lib/phase_9_treasury_destinations_runtime_pack.js +0 -74
  296. package/lib/phase_program_pack.js +0 -120
  297. package/lib/pricing_optimization_contract.js +0 -775
  298. package/lib/protocol_lane_contract.js +0 -117
  299. package/lib/provenance_lane_contract.js +0 -54
  300. package/lib/provider_lane_contract.js +0 -240
  301. package/lib/provider_network_contract.js +0 -149
  302. package/lib/provider_payout_execution.js +0 -155
  303. package/lib/provider_registry.js +0 -852
  304. package/lib/provider_runtime_journey_contract.js +0 -183
  305. package/lib/public_surface_policy_contract.js +0 -111
  306. package/lib/publish_plan.js +0 -51
  307. package/lib/rate_limiter.js +0 -81
  308. package/lib/record_queries.js +0 -48
  309. package/lib/release_candidate.js +0 -50
  310. package/lib/release_center.js +0 -1093
  311. package/lib/release_history.js +0 -205
  312. package/lib/release_manifest.js +0 -113
  313. package/lib/release_pack.js +0 -453
  314. package/lib/request_rate_limit.js +0 -144
  315. package/lib/resource_views.js +0 -31
  316. package/lib/revenue_launch_path_contract.js +0 -326
  317. package/lib/route_matchers.js +0 -34
  318. package/lib/route_params.js +0 -19
  319. package/lib/runtime_bridge.js +0 -124
  320. package/lib/runtime_operations_worker.js +0 -282
  321. package/lib/runtime_state_store.js +0 -495
  322. package/lib/settlement_bsv_live.js +0 -600
  323. package/lib/settlement_bsv_teranode.js +0 -117
  324. package/lib/settlement_lane_contract.js +0 -111
  325. package/lib/shared_signals_lane_contract.js +0 -54
  326. package/lib/signed_audit_provenance_contract.js +0 -83
  327. package/lib/soft_launch_pack.js +0 -78
  328. package/lib/stablecoin_lane_contract.js +0 -76
  329. package/lib/stripe_mpp_lane_contract.js +0 -96
  330. package/lib/stripe_mpp_payment_front.js +0 -258
  331. package/lib/telemetry_lane_contract.js +0 -54
  332. package/lib/treasury_destinations_contract.js +0 -764
  333. package/lib/treasury_egress_policy_contract.js +0 -91
  334. package/lib/treasury_lane_contract.js +0 -84
  335. package/lib/trust_portability_boundary_contract.js +0 -72
  336. package/lib/x402_facilitator.js +0 -198
  337. package/lib/x402_lane_contract.js +0 -136
  338. package/lib/x402_settlement_recovery.js +0 -175
  339. package/scripts/buyer_events_daily_report.js +0 -79
  340. package/scripts/registry_cli.js +0 -275
  341. package/scripts/state_backup_offsite.js +0 -196
  342. package/scripts/verify_a2a_rpc.js +0 -131
  343. package/scripts/verify_adapters.js +0 -554
  344. package/scripts/verify_agent_identity.js +0 -153
  345. package/scripts/verify_all.js +0 -4963
  346. package/scripts/verify_bolt_adapter.js +0 -128
  347. package/scripts/verify_buyer_event_log.js +0 -128
  348. package/scripts/verify_buyer_safety.js +0 -141
  349. package/scripts/verify_cdp_facilitator.js +0 -110
  350. package/scripts/verify_checkout_processor.js +0 -109
  351. package/scripts/verify_commerce_bridge.js +0 -177
  352. package/scripts/verify_control_plane_contracts.js +0 -34
  353. package/scripts/verify_control_plane_routes.js +0 -70
  354. package/scripts/verify_delivery_summary.js +0 -112
  355. package/scripts/verify_examples.js +0 -19
  356. package/scripts/verify_execution_dedupe.js +0 -189
  357. package/scripts/verify_execution_surfacing.js +0 -76
  358. package/scripts/verify_external_execution_retry.js +0 -140
  359. package/scripts/verify_final_activation.js +0 -191
  360. package/scripts/verify_first_run_conversions.js +0 -81
  361. package/scripts/verify_framework_provider_promotion.js +0 -152
  362. package/scripts/verify_full_catalog.js +0 -174
  363. package/scripts/verify_integrations.js +0 -620
  364. package/scripts/verify_l402_adapter.js +0 -86
  365. package/scripts/verify_lifecycle_continuity.js +0 -96
  366. package/scripts/verify_lifecycle_spend_binding.js +0 -88
  367. package/scripts/verify_market_lane_depth.js +0 -94
  368. package/scripts/verify_market_lane_promotion.js +0 -103
  369. package/scripts/verify_market_lane_traces.js +0 -98
  370. package/scripts/verify_market_lanes.js +0 -102
  371. package/scripts/verify_mpp_adapter.js +0 -128
  372. package/scripts/verify_operator_observability_boundary.js +0 -83
  373. package/scripts/verify_pricing_experiment_plan.js +0 -124
  374. package/scripts/verify_production_readiness.js +0 -268
  375. package/scripts/verify_provider_network.js +0 -819
  376. package/scripts/verify_provider_runtime_breadth.js +0 -109
  377. package/scripts/verify_provider_runtime_journeys.js +0 -111
  378. package/scripts/verify_rate_limiter.js +0 -52
  379. package/scripts/verify_refund_credit.js +0 -106
  380. package/scripts/verify_revenue_launch_paths.js +0 -105
  381. package/scripts/verify_runtime_durability.js +0 -52
  382. package/scripts/verify_runtime_state_guard.js +0 -117
  383. package/scripts/verify_service.js +0 -15421
  384. package/scripts/verify_settlement.js +0 -116
  385. package/scripts/verify_tooling.js +0 -1412
  386. package/scripts/verify_treasury_public_boundary.js +0 -97
  387. package/scripts/verify_verify_execute_settle.js +0 -209
  388. package/scripts/verify_x402_facilitator.js +0 -307
  389. package/scripts/verify_x402_settlement_recovery.js +0 -153
  390. package/server.js +0 -12245
@@ -1,911 +0,0 @@
1
- "use strict";
2
-
3
- const {
4
- createCommandResult,
5
- createQuote,
6
- hydrateQuoteStates
7
- } = require("./commerce_runtime");
8
- const { consumeAccountCredits, buildUsageMeterPreview, previewCreditSpend } = require("./commerce_economics");
9
- const { resolveSpendCredential, evaluateAuthorityBindingAction } = require("./account_auth");
10
- const { validateIntegrationSelection } = require("../integrations/dispatch");
11
- const { markPaymentAccepted, settleDeferredPayment, verifyPaymentAcceptance } = require("./payment_verification");
12
- const { executeExternalTarget, loadExecutionTargetRegistry, resolveExecutionTarget } = require("./external_execution_runtime");
13
- const {
14
- STATE_RESTORE_PENDING_RESPONSE,
15
- creditSpendPolicyMode,
16
- creditUnitPriceAtomic,
17
- isStateRestorePending,
18
- paidExecutionPolicyMode
19
- } = require("./buyer_safety_policy");
20
- const { externalExecutionBudgetMs } = require("./external_execution_policy");
21
- const { encodePaymentResponse } = require("./x402_facilitator");
22
- const {
23
- authorizationRefFromVerification,
24
- confirmAuthorizationUsed,
25
- rememberReplay,
26
- resolveReplay
27
- } = require("./x402_settlement_recovery");
28
- const { hashCanonical, issueDeliveryReceipt, loadDeliveryReceiptSigners } = require("./delivery_receipt");
29
-
30
- const DELIVERY_RECEIPT_ISSUER = "xytara-runtime";
31
- const DELIVERY_RECEIPT_RETENTION = 5000;
32
-
33
- // The payment leg of a delivery receipt: on-chain facts for x402, the spend record for credits,
34
- // and the verification mode for any other lane. Never the buyer's signature or secrets.
35
- function deliveryReceiptPayment(verification, quote) {
36
- const v = verification && typeof verification === "object" ? verification : {};
37
- const paymentPayload = v.payment_payload && typeof v.payment_payload === "object" ? v.payment_payload : {};
38
- if (v.verification_mode === "x402_facilitator") {
39
- const settlement = v.settlement && typeof v.settlement === "object" ? v.settlement : null;
40
- return {
41
- protocol: "x402",
42
- scheme: "exact",
43
- network: paymentPayload.x402_network || (settlement && settlement.network) || null,
44
- asset: paymentPayload.x402_asset || null,
45
- amount: paymentPayload.x402_amount !== undefined && paymentPayload.x402_amount !== null ? String(paymentPayload.x402_amount) : null,
46
- payer: paymentPayload.x402_payer || (settlement && settlement.payer) || null,
47
- pay_to: paymentPayload.x402_pay_to || null,
48
- settlement_tx: settlement ? (settlement.transaction || settlement.txid || null) : null,
49
- settled: Boolean(settlement && settlement.success !== false && (settlement.transaction || settlement.txid))
50
- };
51
- }
52
- if (v.verification_mode === "account_credits" || paymentPayload.credit_spend_id) {
53
- return {
54
- protocol: "account_credits",
55
- credit_spend_id: paymentPayload.credit_spend_id || null,
56
- quoted_amount_minor: quote && Number.isFinite(Number(quote.amount_minor)) ? Number(quote.amount_minor) : null,
57
- currency: (quote && quote.currency) || null
58
- };
59
- }
60
- return {
61
- protocol: v.verification_mode || "unspecified",
62
- quoted_amount_minor: quote && Number.isFinite(Number(quote.amount_minor)) ? Number(quote.amount_minor) : null,
63
- currency: (quote && quote.currency) || null
64
- };
65
- }
66
-
67
- // Issues the signed delivery receipt for a completed paid call, attaches it to the response, and
68
- // keeps it retrievable by id (bounded). Fail-safe: a receipt problem never breaks a completed call.
69
- function attachDeliveryReceipt(state, result, payload, quote, verification, externalExecutionOptions) {
70
- try {
71
- if (!result || !result.receipt) return;
72
- const execution = externalExecutionOptions && externalExecutionOptions.externalExecution
73
- ? externalExecutionOptions.externalExecution
74
- : null;
75
- const deliverables = result.command && Array.isArray(result.command.deliverables) ? result.command.deliverables : [];
76
- const outputs = deliverables.map((deliverable) => (deliverable && deliverable.output_payload !== undefined ? deliverable.output_payload : null));
77
- const body = payload && payload.body && typeof payload.body === "object" && !Array.isArray(payload.body) ? payload.body : {};
78
- const taskRef = (payload && payload.task_ref)
79
- || (Array.isArray(payload && payload.tasks) && payload.tasks[0] && payload.tasks[0].task_ref)
80
- || null;
81
- const { signers } = loadDeliveryReceiptSigners("XYTARA_DELIVERY_RECEIPT");
82
- const deliveryReceipt = issueDeliveryReceipt({
83
- receipt_id: `drcpt_${result.receipt.receipt_id.replace(/^rcpt_/, "")}`,
84
- issuer: DELIVERY_RECEIPT_ISSUER,
85
- call: {
86
- quote_id: quote && quote.quote_id ? quote.quote_id : null,
87
- transaction_id: result.transaction ? result.transaction.transaction_id : null,
88
- runtime_receipt_id: result.receipt.receipt_id,
89
- task_ref: taskRef,
90
- tool_name: typeof body.tool_name === "string" ? body.tool_name : null
91
- },
92
- payment: deliveryReceiptPayment(verification, quote),
93
- delivery: {
94
- status: "completed",
95
- provider_id: execution && execution.registered_provider_id ? execution.registered_provider_id : null,
96
- routing: execution
97
- ? (execution.registered_provider_id ? "open_provider_registry" : "operator_env_target")
98
- : "runtime_native",
99
- execution_target_id: execution && execution.target_id ? execution.target_id : null,
100
- request_sha256: hashCanonical(body),
101
- request_hash_input: "the request `body` object (e.g. { tool_name, arguments })",
102
- output_sha256: hashCanonical(outputs.length === 1 ? outputs[0] : outputs),
103
- output_hash_input: outputs.length === 1
104
- ? "command.deliverables[0].output_payload (null when the task returns no payload)"
105
- : "the array of command.deliverables[*].output_payload",
106
- completed_at: (result.receipt.timing && result.receipt.timing.completed_at_iso) || result.receipt.created_at_iso || null
107
- }
108
- }, signers);
109
- result.delivery_receipt = deliveryReceipt;
110
- if (!(state.deliveryReceipts instanceof Map)) state.deliveryReceipts = new Map();
111
- state.deliveryReceipts.set(deliveryReceipt.receipt_id, deliveryReceipt);
112
- while (state.deliveryReceipts.size > DELIVERY_RECEIPT_RETENTION) {
113
- state.deliveryReceipts.delete(state.deliveryReceipts.keys().next().value);
114
- }
115
- } catch (_) { /* non-fatal: never break a completed, possibly settled call */ }
116
- }
117
- const { resolveRegisteredTargets, hasActiveMatchingProvider, recordProviderHealth, recordProviderRouting, recordProviderSettlement } = require("./provider_registry");
118
- const { claimDeferredExecution, releaseDeferredExecution } = require("./execution_dedupe");
119
-
120
- function hasPaymentHeaders(headers, requiredHeaders) {
121
- return requiredHeaders.every((headerName) => headers[headerName]);
122
- }
123
-
124
- function parseBearerToken(headers) {
125
- const authorization = headers && typeof headers.authorization === "string"
126
- ? headers.authorization.trim()
127
- : "";
128
- const match = authorization.match(/^Bearer\s+(.+)$/i);
129
- return match ? match[1].trim() : null;
130
- }
131
-
132
- // Extract an agent-identity proof (for key-bound spend credentials) from request
133
- // headers: X-Agent-Signature (base64 ed25519 sig) + X-Agent-Timestamp (ms).
134
- function extractAgentProof(headers) {
135
- const h = headers || {};
136
- return {
137
- signature: typeof h["x-agent-signature"] === "string" ? h["x-agent-signature"] : null,
138
- timestamp: typeof h["x-agent-timestamp"] === "string" ? h["x-agent-timestamp"] : null
139
- };
140
- }
141
-
142
- function buildCreditCommitPayload(payload, quote, requiredUnits) {
143
- return {
144
- account_id: quote.account_id,
145
- agent_id: payload.agent_id || null,
146
- budget_id: payload.budget_id || null,
147
- pack_id: payload.pack_id || null,
148
- entitlement_id: payload.entitlement_id || null,
149
- quote_id: quote.quote_id,
150
- task_ref: payload.task_ref || null,
151
- workflow_ref: payload.workflow_ref || null,
152
- units: requiredUnits,
153
- reason: "credit_first_execution"
154
- };
155
- }
156
-
157
- function buildCreditRejectionResponse(creditDecision, quote) {
158
- const failureReason = creditDecision && creditDecision.credit_spend_preview
159
- ? creditDecision.credit_spend_preview.failure_reason
160
- : null;
161
- const reason = failureReason
162
- || (creditDecision && creditDecision.policy_guard && creditDecision.policy_guard.reason)
163
- || (creditDecision && creditDecision.entitlement_guard && creditDecision.entitlement_guard.reason)
164
- || (creditDecision && creditDecision.reason)
165
- || "credit_spend_not_allowed";
166
-
167
- if (reason === "insufficient_credits") {
168
- const preview = creditDecision && creditDecision.credit_spend_preview ? creditDecision.credit_spend_preview : {};
169
- return {
170
- status: 402,
171
- payload: {
172
- ok: false,
173
- reason: "insufficient_credits",
174
- insufficient_credits: {
175
- account_id: quote.account_id,
176
- required_units: preview.required_units,
177
- available_units: preview.available_units,
178
- recommended_next_surfaces: {
179
- credits_topup: "/x402/credits/topup",
180
- direct_payment: "/v1/payment-quotes"
181
- }
182
- },
183
- quote
184
- }
185
- };
186
- }
187
-
188
- return {
189
- status: 403,
190
- payload: {
191
- ok: false,
192
- reason,
193
- account_id: quote.account_id,
194
- policy_guard: creditDecision && creditDecision.policy_guard ? creditDecision.policy_guard : null,
195
- entitlement_guard: creditDecision && creditDecision.entitlement_guard ? creditDecision.entitlement_guard : null,
196
- quote
197
- }
198
- };
199
- }
200
-
201
- // What a provider is allowed to see of the buyer's payment context: the verification outcome and
202
- // scalar payment facts only. NEVER the signed x402 authorization / deferred-settlement material
203
- // (that would hand a third-party provider the buyer's signature before settlement), and never
204
- // signature-, secret- or raw-looking keys or nested objects from any lane's payload.
205
- const SENSITIVE_CONTEXT_KEY = /signature|secret|private|authorization|raw|base64|header|token/i;
206
- function sanitizeAuthorizationContextForProvider(context) {
207
- if (!context || typeof context !== "object") return null;
208
- const payload = context.payment_payload && typeof context.payment_payload === "object" ? context.payment_payload : null;
209
- const safePayload = payload
210
- ? Object.fromEntries(Object.entries(payload).filter(([key, value]) => !SENSITIVE_CONTEXT_KEY.test(key) && (value === null || typeof value !== "object")))
211
- : null;
212
- return {
213
- ok: context.ok === true,
214
- verification_mode: context.verification_mode || null,
215
- wallet_id: context.wallet_id || null,
216
- age_seconds: Number.isFinite(Number(context.age_seconds)) ? Number(context.age_seconds) : null,
217
- payment_payload: safePayload
218
- };
219
- }
220
-
221
- // The execution deadline: the configured budget, but never so late that the buyer's signed x402
222
- // authorization expires before we can settle it (keep 20 s for the settle call).
223
- function executionDeadlineMs(authorizationContext) {
224
- const budgetDeadline = Date.now() + externalExecutionBudgetMs();
225
- const deferred = authorizationContext && authorizationContext.deferred_settlement;
226
- const signed = deferred && deferred.authorization && deferred.authorization.paymentPayload
227
- && deferred.authorization.paymentPayload.payload && deferred.authorization.paymentPayload.payload.authorization;
228
- const validBeforeSeconds = signed ? Number(signed.validBefore) : NaN;
229
- if (!Number.isFinite(validBeforeSeconds) || validBeforeSeconds <= 0) return budgetDeadline;
230
- return Math.min(budgetDeadline, validBeforeSeconds * 1000 - 20000);
231
- }
232
-
233
- async function buildExternalExecutionOptions(state, payload, quote, authorizationContext) {
234
- // One wall-clock budget for the whole call (every retry of every candidate), inside the x402
235
- // authorization window — see external_execution_policy.js.
236
- const executionOptions = { deadline_ms: executionDeadlineMs(authorizationContext) };
237
- const forwardedContext = sanitizeAuthorizationContextForProvider(authorizationContext);
238
- // Operator-pinned env target resolves first and is used as-is (an explicit single target,
239
- // no failover). Empty env + empty registry -> {} (unchanged behavior).
240
- const envTarget = resolveExecutionTarget(payload, quote);
241
- if (envTarget) {
242
- const execution = await executeExternalTarget(envTarget, payload, quote, forwardedContext, executionOptions);
243
- if (!execution || !execution.ok) {
244
- return { error: execution || { ok: false, status: 502, reason: "external_execution_failed" } };
245
- }
246
- return { externalExecution: execution };
247
- }
248
-
249
- // Open-network path: try health-ranked registered providers (healthy first, then half-open)
250
- // in order, FAILING OVER to the next when one is down — so a single unhealthy/throttled
251
- // provider doesn't fail the buyer when another serves the same capability. Each attempt
252
- // updates the provider's health; accounting is wrapped so it can never break execution.
253
- const candidates = resolveRegisteredTargets(state, payload, quote);
254
- if (candidates.length < 1) {
255
- // No HEALTHY candidate. If providers DO serve this capability but are all in cooldown,
256
- // fail closed (503) so the buyer is NOT charged for undelivered work — rather than falling
257
- // through to the synthetic no-op. If nothing serves it, keep the legacy local path ({}).
258
- if (hasActiveMatchingProvider(state, payload, quote)) {
259
- return { error: { ok: false, status: 503, reason: "no_healthy_provider" } };
260
- }
261
- // Defense in depth behind assessPaidExecutability: on a hosted deploy a call with no real
262
- // execution target must never reach settlement with a synthetic result.
263
- if (paidExecutionPolicyMode() === "strict") {
264
- return { error: { ok: false, status: 501, reason: "capability_not_executable" } };
265
- }
266
- return {};
267
- }
268
- let lastError = null;
269
- for (const target of candidates) {
270
- if (Date.now() >= executionOptions.deadline_ms) {
271
- // Budget spent on earlier candidates: stop here rather than start a call that cannot settle.
272
- lastError = lastError || { ok: false, status: 504, reason: "external_execution_budget_exhausted" };
273
- break;
274
- }
275
- const execution = await executeExternalTarget(target, payload, quote, forwardedContext, executionOptions);
276
- try { recordProviderRouting(state, target.registered_provider_id); } catch (_) { /* non-fatal */ }
277
- if (execution && execution.ok) {
278
- try { recordProviderHealth(state, target.registered_provider_id, { ok: true }); } catch (_) { /* non-fatal */ }
279
- execution.registered_provider_id = target.registered_provider_id;
280
- return { externalExecution: execution };
281
- }
282
- try { recordProviderHealth(state, target.registered_provider_id, { ok: false }); } catch (_) { /* non-fatal */ }
283
- lastError = execution || { ok: false, status: 502, reason: "external_execution_failed" };
284
- // Fail over to the NEXT provider ONLY when this one provably did NOT process the request
285
- // (rejected / unreachable). Never on an ambiguous failure (timeout, reset, 5xx) — that
286
- // could make a side-effectful provider execute twice. Health still marks the failure.
287
- if (!(execution && execution.failover_safe)) break;
288
- }
289
- return { error: lastError };
290
- }
291
-
292
- // Assets the x402 lane can settle in, with their on-chain decimals (needed to turn settled base
293
- // units into the ledger's cents). Anything else cannot be reconciled and must not accrue on the quote.
294
- const X402_ASSET_DECIMALS = new Map([
295
- ["0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", 6], // USDC, Base mainnet (eip155:8453)
296
- ["0x036cbd53842c5426634e7929541ec2318f3dcf7e", 6] // USDC, Base Sepolia (eip155:84532)
297
- ]);
298
-
299
- // The amount a provider's revenue share is computed from. The quote is what we ASKED for; on the
300
- // x402 lane the facilitator settles exactly the advertised `accepts` amount, which may differ from
301
- // the catalog quote — so accrue on min(quote, settled) and never on money that was not collected.
302
- // Other lanes bind the paid amount to the quote at verification time (local_signed) or charge the
303
- // quote directly (credits / hosted checkout), so the quote is the settled amount there.
304
- function reconcileProviderSettlementAmount(quote, verification) {
305
- const quoted = quote && Number.isFinite(Number(quote.amount_minor)) ? Math.max(0, Math.round(Number(quote.amount_minor))) : 0;
306
- const mode = verification && typeof verification.verification_mode === "string" ? verification.verification_mode : null;
307
- // Credit spends accrue on what the consumed units were actually bought for (units x unit
308
- // price; USDC 6 decimals -> cents), never on the catalog quote.
309
- const creditPayload = (verification && verification.payment_payload) || {};
310
- const creditUnits = Number(creditPayload.credit_units);
311
- const unitPriceAtomic = Number(creditPayload.credit_unit_price_atomic);
312
- if (Number.isFinite(creditUnits) && creditUnits > 0 && Number.isFinite(unitPriceAtomic) && unitPriceAtomic > 0) {
313
- const settledCents = Math.floor((creditUnits * unitPriceAtomic) / 10000);
314
- return { amount_minor: Math.min(quoted, settledCents), quoted_minor: quoted, settled_minor: settledCents, settlement_basis: "credits_unit_value_min_quote", reconciled: true };
315
- }
316
- if (mode !== "x402_facilitator") {
317
- return { amount_minor: quoted, quoted_minor: quoted, settled_minor: null, settlement_basis: mode ? `${mode}_quote` : "quote", reconciled: true };
318
- }
319
- const paymentPayload = (verification && verification.payment_payload) || {};
320
- const decimals = X402_ASSET_DECIMALS.get(String(paymentPayload.x402_asset || "").toLowerCase());
321
- const baseUnits = /^\d{1,30}$/.test(String(paymentPayload.x402_amount)) ? Number(paymentPayload.x402_amount) : NaN;
322
- const centsCurrency = /^USD(_CENTS)?$/i.test(String((quote && quote.currency) || "USD_CENTS"));
323
- if (decimals === undefined || !Number.isFinite(baseUnits) || !centsCurrency) {
324
- return { amount_minor: 0, quoted_minor: quoted, settled_minor: null, settlement_basis: "x402_unreconciled_asset", reconciled: false };
325
- }
326
- const settledCents = Math.floor(baseUnits / Math.pow(10, decimals - 2));
327
- return { amount_minor: Math.min(quoted, settledCents), quoted_minor: quoted, settled_minor: settledCents, settlement_basis: "x402_settled_min_quote", reconciled: true };
328
- }
329
-
330
- // Records the provider revenue-share split for a settled call routed to a registered
331
- // provider. Fail-safe: metering must NEVER break or reverse a settled/charged response.
332
- function attributeProviderSettlement(state, externalExecutionOptions, payload, quote, extra, verification) {
333
- const execution = externalExecutionOptions && externalExecutionOptions.externalExecution;
334
- const providerId = execution && execution.registered_provider_id;
335
- if (!providerId) return;
336
- try {
337
- const taskRef = (payload && payload.task_ref)
338
- || (Array.isArray(payload && payload.tasks) && payload.tasks[0] && payload.tasks[0].task_ref)
339
- || null;
340
- const reconciled = reconcileProviderSettlementAmount(quote, verification);
341
- recordProviderSettlement(state, {
342
- provider_id: providerId,
343
- amount_minor: reconciled.amount_minor,
344
- quoted_minor: reconciled.quoted_minor,
345
- settled_minor: reconciled.settled_minor,
346
- settlement_basis: reconciled.settlement_basis,
347
- reconciled: reconciled.reconciled,
348
- currency: quote && quote.currency ? quote.currency : null,
349
- transaction_id: (extra && extra.transaction_id) || (quote && quote.quote_id) || null,
350
- settlement_ref: (extra && extra.settlement_ref) || null,
351
- task_ref: taskRef
352
- });
353
- } catch (_) { /* non-fatal: a settled call is never undone by an accounting error */ }
354
- }
355
-
356
- // When a buyer is quoted for a routed task, wake the provider(s) that will serve it: the buyer
357
- // spends a few seconds signing the payment, which is usually enough for a sleeping free-tier host
358
- // to come up. Fire-and-forget, at most once a minute per provider, never blocks the response.
359
- const providerWarmedAt = new Map();
360
- function warmProvidersForCall(state, payload, quote) {
361
- try {
362
- const now = Date.now();
363
- for (const target of resolveRegisteredTargets(state, payload, quote).slice(0, 3)) {
364
- const last = providerWarmedAt.get(target.registered_provider_id) || 0;
365
- if (now - last < 60000) continue;
366
- providerWarmedAt.set(target.registered_provider_id, now);
367
- const origin = new URL(target.endpoint_url).origin;
368
- fetch(`${origin}/health`, { method: "GET", signal: AbortSignal.timeout(3000), redirect: "error" }).catch(() => {});
369
- }
370
- } catch (_) { /* best effort */ }
371
- }
372
-
373
- // Task refs that resolve to a real execution target right now: operator-pinned env targets plus
374
- // active open-network providers. This is the set a hosted deploy will accept payment for.
375
- function listExecutableTaskRefs(state) {
376
- const refs = new Set();
377
- try {
378
- for (const target of loadExecutionTargetRegistry()) {
379
- if (target && target.enabled && target.task_ref) refs.add(target.task_ref);
380
- }
381
- } catch (_) { /* a malformed env registry simply contributes nothing */ }
382
- const registry = state && state.providerRegistry;
383
- if (registry && typeof registry.values === "function") {
384
- for (const provider of registry.values()) {
385
- if (provider && provider.status === "active" && Array.isArray(provider.task_refs)) {
386
- provider.task_refs.forEach((ref) => refs.add(ref));
387
- }
388
- }
389
- }
390
- return Array.from(refs).sort();
391
- }
392
-
393
- // Refuse BEFORE quoting/charging any task that nothing can actually execute (strict policy), so
394
- // a buyer never pays for a synthetic "completed" result. Permissive (local) keeps legacy behavior.
395
- function assessPaidExecutability(state, payload) {
396
- if (paidExecutionPolicyMode() !== "strict") return { ok: true };
397
- const body = payload && typeof payload === "object" ? payload : {};
398
- const taskRefs = Array.isArray(body.tasks) && body.tasks.length > 0
399
- ? body.tasks.map((task) => String((task && task.task_ref) || "").trim())
400
- : [String(body.task_ref || "").trim()];
401
- const executable = listExecutableTaskRefs(state);
402
- if (taskRefs.some((ref) => !ref)) {
403
- return {
404
- ok: false,
405
- status: 400,
406
- payload: { ok: false, reason: "task_ref_required", detail: "Name the task to run in task_ref.", executable_task_refs: executable }
407
- };
408
- }
409
- const probeQuote = { integration_ids: Array.isArray(body.integration_ids) ? body.integration_ids : [] };
410
- const runnable = (ref) => {
411
- const single = { ...body, task_ref: ref, tasks: undefined };
412
- return Boolean(resolveExecutionTarget(single, probeQuote)) || hasActiveMatchingProvider(state, single, probeQuote);
413
- };
414
- const missing = taskRefs.filter((ref) => !runnable(ref));
415
- if (missing.length > 0) {
416
- return {
417
- ok: false,
418
- status: 501,
419
- payload: {
420
- ok: false,
421
- reason: "capability_not_executable",
422
- detail: "Nothing can execute " + missing.join(", ") + " right now, so no payment is requested. Choose one of executable_task_refs, or call the MCP tools directly at https://xytara-mcp-executor.onrender.com/mcp.",
423
- task_refs: missing,
424
- executable_task_refs: executable
425
- }
426
- };
427
- }
428
- return { ok: true };
429
- }
430
-
431
- async function executeCommandRequest(state, payload, headers, options) {
432
- const opts = options || {};
433
- const requiredHeaders = Array.isArray(opts.requiredHeaders) && opts.requiredHeaders.length > 0
434
- ? opts.requiredHeaders
435
- : ["x-wallet-id", "x-payment", "x-payment-signature"];
436
- const challengePayload = typeof opts.challengePayload === "function"
437
- ? opts.challengePayload
438
- : (quote) => ({ ok: false, quote });
439
-
440
- hydrateQuoteStates(state);
441
- const validation = validateIntegrationSelection(payload);
442
- if (!validation.ok) {
443
- return {
444
- status: 400,
445
- payload: {
446
- ok: false,
447
- reason: validation.reason,
448
- errors: validation.errors,
449
- selection: validation.selection
450
- }
451
- };
452
- }
453
- const executability = assessPaidExecutability(state, payload);
454
- if (!executability.ok) {
455
- return { status: executability.status, payload: executability.payload };
456
- }
457
- const prefersCredits = payload && payload.payment_preference === "credits_first";
458
- if (prefersCredits && isStateRestorePending()) {
459
- return { status: 503, payload: { ...STATE_RESTORE_PENDING_RESPONSE }, headers: { "Retry-After": "30" } };
460
- }
461
- if (!hasPaymentHeaders(headers || {}, requiredHeaders)) {
462
- const bearerToken = parseBearerToken(headers);
463
- const delegatedSpendRequested = typeof bearerToken === "string" && bearerToken.startsWith("xytara_spend_");
464
- const delegatedSpend = delegatedSpendRequested
465
- ? resolveSpendCredential(state, bearerToken, extractAgentProof(headers), {
466
- account_id: payload && payload.account_id,
467
- task_ref: payload && payload.task_ref,
468
- units: payload && payload.quoted_units,
469
- // Strict binding is scoped to this execute path (where a binding is supplied); the
470
- // lifecycle paths pass no binding and are intentionally unaffected.
471
- require: String(process.env.XYTARA_REQUIRE_SPEND_PROOF_BINDING || "").trim() === "1"
472
- })
473
- : { ok: false, reason: "spend_credential_not_requested" };
474
- if (delegatedSpendRequested && !delegatedSpend.ok) {
475
- return {
476
- status: 403,
477
- payload: {
478
- ok: false,
479
- reason: delegatedSpend.reason
480
- }
481
- };
482
- }
483
- if (delegatedSpend.ok) {
484
- // Pin the command to the credential's own account — a delegated spend token must
485
- // never be aimed at another account by supplying a different account_id.
486
- if (payload && typeof payload.account_id === "string" && payload.account_id && payload.account_id !== delegatedSpend.credential.account_id) {
487
- return { status: 403, payload: { ok: false, reason: "delegated_account_mismatch" } };
488
- }
489
- payload = {
490
- ...payload,
491
- account_id: delegatedSpend.credential.account_id,
492
- agent_id: payload && payload.agent_id ? payload.agent_id : delegatedSpend.credential.agent_id,
493
- budget_id: payload && payload.budget_id ? payload.budget_id : delegatedSpend.credential.budget_id,
494
- pack_id: delegatedSpend.credential.pack_id || (payload && payload.pack_id) || null,
495
- entitlement_id: delegatedSpend.credential.entitlement_id || (payload && payload.entitlement_id) || null
496
- };
497
- }
498
- if (prefersCredits && !delegatedSpend.ok && creditSpendPolicyMode() === "strict") {
499
- return {
500
- status: 401,
501
- payload: {
502
- ok: false,
503
- reason: "credit_spend_credential_required",
504
- detail: "Spending credits needs the account's spend credential: send it as `Authorization: Bearer xytara_spend_...`. A self-serve top-up (POST /x402/credits/topup) returns one for the paying address; or pay per call with x402 instead (omit payment_preference).",
505
- credits_topup: "/x402/credits/topup"
506
- }
507
- };
508
- }
509
- const quote = createQuote(state, payload);
510
- if (prefersCredits) {
511
- const creditPayload = {
512
- ...payload,
513
- account_id: quote.account_id,
514
- quoted_units: Number.isFinite(Number(payload.quoted_units)) ? Number(payload.quoted_units) : undefined
515
- };
516
- const meteringPreview = buildUsageMeterPreview(state, creditPayload);
517
- const requiredUnits = meteringPreview.usage_units;
518
- if (delegatedSpend.ok && delegatedSpend.binding) {
519
- const authorityDecision = evaluateAuthorityBindingAction(delegatedSpend.binding, "delegated_credit_spend", requiredUnits);
520
- if (!authorityDecision.ok) {
521
- return {
522
- status: 403,
523
- payload: {
524
- ok: false,
525
- reason: authorityDecision.reason,
526
- binding_id: authorityDecision.binding_id || null,
527
- required_scope: authorityDecision.required_scope || null,
528
- authority_scope: authorityDecision.authority_scope || [],
529
- required_consequence_family: authorityDecision.required_consequence_family || null,
530
- allowed_consequence_families: authorityDecision.allowed_consequence_families || [],
531
- max_units: authorityDecision.max_units || null,
532
- attempted_units: authorityDecision.attempted_units || requiredUnits
533
- }
534
- };
535
- }
536
- }
537
-
538
- const creditDecision = previewCreditSpend(state, creditPayload);
539
- if (!creditDecision.ok || !creditDecision.credit_spend_preview || creditDecision.credit_spend_preview.executable_now !== true) {
540
- return buildCreditRejectionResponse(creditDecision, quote);
541
- }
542
-
543
- const preCommitAuthorizationContext = delegatedSpend.ok
544
- ? delegatedSpend.authorization_context
545
- : {
546
- ok: true,
547
- verification_mode: "account_credits",
548
- wallet_id: quote.account_id,
549
- age_seconds: 0,
550
- payment_payload: {
551
- credit_spend_status: "precommit"
552
- }
553
- };
554
- const externalExecutionOptions = await buildExternalExecutionOptions(state, payload, quote, preCommitAuthorizationContext);
555
- if (externalExecutionOptions.error) {
556
- return {
557
- status: externalExecutionOptions.error.status || 502,
558
- payload: {
559
- ok: false,
560
- reason: externalExecutionOptions.error.reason || "external_execution_failed",
561
- details: externalExecutionOptions.error.details || null,
562
- credit_spend_status: "not_committed",
563
- credit_spend_preview: creditDecision.credit_spend_preview,
564
- quote
565
- }
566
- };
567
- }
568
-
569
- const creditSpend = consumeAccountCredits(state, buildCreditCommitPayload(payload, quote, requiredUnits));
570
- if (creditSpend.ok) {
571
- const paymentVerification = {
572
- ...(delegatedSpend.ok
573
- ? delegatedSpend.authorization_context
574
- : {
575
- ok: true,
576
- verification_mode: "account_credits",
577
- wallet_id: quote.account_id,
578
- age_seconds: 0,
579
- payment_payload: {}
580
- }),
581
- payment_payload: {
582
- ...((delegatedSpend.ok && delegatedSpend.authorization_context && delegatedSpend.authorization_context.payment_payload) || {}),
583
- credit_spend_id: creditSpend.credit_spend.credit_spend_id,
584
- credit_units: requiredUnits,
585
- credit_unit_price_atomic: creditUnitPriceAtomic()
586
- }
587
- };
588
- attributeProviderSettlement(state, externalExecutionOptions, payload, quote, {
589
- transaction_id: creditSpend.credit_spend.credit_spend_id
590
- }, paymentVerification);
591
- const creditResult = createCommandResult(state, {
592
- ...payload,
593
- payment_preference: "credits_first"
594
- }, quote, {
595
- paymentVerification,
596
- creditSpend: creditSpend.credit_spend,
597
- skipPaymentLedger: true,
598
- externalExecution: externalExecutionOptions.externalExecution || null
599
- });
600
- attachDeliveryReceipt(state, creditResult, payload, quote, paymentVerification, externalExecutionOptions);
601
- return {
602
- status: 200,
603
- payload: creditResult
604
- };
605
- }
606
- if (creditSpend.reason !== "insufficient_credits") {
607
- return {
608
- status: 403,
609
- payload: {
610
- ok: false,
611
- reason: creditSpend.reason,
612
- account_id: quote.account_id,
613
- provider_execution_completed_but_credit_commit_failed: Boolean(externalExecutionOptions.externalExecution),
614
- policy_guard: {
615
- agent_id: creditSpend.agent_id || null,
616
- budget_id: creditSpend.budget_id || null,
617
- task_domain: creditSpend.task_domain || null,
618
- policy_ref: creditSpend.policy_ref || null,
619
- max_reserve_units: creditSpend.max_reserve_units || null,
620
- allowed_job_domains: creditSpend.allowed_job_domains || null,
621
- budget_status: creditSpend.budget_status || null,
622
- agent_status: creditSpend.agent_status || null
623
- },
624
- quote
625
- }
626
- };
627
- }
628
- return {
629
- status: 402,
630
- payload: {
631
- ok: false,
632
- reason: "insufficient_credits",
633
- provider_execution_completed_but_credit_commit_failed: Boolean(externalExecutionOptions.externalExecution),
634
- insufficient_credits: {
635
- account_id: quote.account_id,
636
- required_units: creditSpend.required_units,
637
- available_units: creditSpend.available_units,
638
- recommended_next_surfaces: {
639
- credits_topup: "/x402/credits/topup",
640
- direct_payment: "/v1/payment-quotes"
641
- }
642
- },
643
- quote
644
- }
645
- };
646
- }
647
- warmProvidersForCall(state, payload, quote);
648
- return {
649
- status: 402,
650
- payload: await challengePayload(quote)
651
- };
652
- }
653
-
654
- const quote = payload.quote_id && state.quotes.get(payload.quote_id)
655
- ? state.quotes.get(payload.quote_id)
656
- : createQuote(state, payload);
657
-
658
- if (quote && quote.status === "expired") {
659
- return {
660
- status: 409,
661
- payload: {
662
- ok: false,
663
- reason: "quote_expired",
664
- quote
665
- }
666
- };
667
- }
668
-
669
- if (quote && (quote.status === "executed" || quote.status === "accepted")) {
670
- return {
671
- status: 409,
672
- payload: {
673
- ok: false,
674
- reason: "quote_already_used",
675
- quote
676
- }
677
- };
678
- }
679
-
680
- // A resent x402 payment we already settled (or were still confirming) gets its stored result
681
- // instead of a re-execution or a confusing "nonce already used" failure.
682
- const requestDigest = hashCanonical({
683
- task_ref: (payload && payload.task_ref) || null,
684
- tasks: (payload && payload.tasks) || null,
685
- body: (payload && payload.body) || null
686
- });
687
- if (requiredHeaders.includes("payment-signature")) {
688
- const replay = await resolveReplay(state, headers || {}, { request_digest: requestDigest });
689
- if (replay) return replay;
690
- }
691
-
692
- // Verify-execute-settle: for the x402 facilitator path, settlement is DEFERRED
693
- // until execution succeeds, so a failed call never settles/charges. Other paths
694
- // (native/credits, and the external rails L402/BOLT/MPP whose funds already moved
695
- // before the proof) have nothing to defer and are unaffected.
696
- const paymentVerification = await verifyPaymentAcceptance(state, headers || {}, requiredHeaders, quote, {
697
- payment_protocol: opts.paymentProtocol || (payload && payload.payment_protocol) || null,
698
- authorization_scheme: opts.authorizationScheme || null,
699
- resource_url: opts.resourceUrl || null,
700
- deferSettlement: true
701
- });
702
- if (!paymentVerification.ok) {
703
- return {
704
- status: paymentVerification.status || 403,
705
- payload: {
706
- ok: false,
707
- reason: paymentVerification.reason,
708
- ...(paymentVerification.detail ? { detail: paymentVerification.detail } : {}),
709
- quote
710
- }
711
- };
712
- }
713
-
714
- markPaymentAccepted(state, paymentVerification);
715
- const settlementDeferred = Boolean(paymentVerification.deferred_settlement);
716
-
717
- // Reserve an execution slot so the same signed x402 authorization cannot execute
718
- // twice concurrently (the deferred settle no longer fronts the on-chain nonce as an
719
- // implicit pre-execution guard). No-op for non-deferred lanes; fails open if the
720
- // store is unavailable. The slot is released in the finally below, whatever happens.
721
- const executionClaim = claimDeferredExecution(state, paymentVerification);
722
- if (!executionClaim.ok) {
723
- return {
724
- status: executionClaim.status || 409,
725
- payload: {
726
- ok: false,
727
- reason: executionClaim.reason || "payment_authorization_in_progress",
728
- ...(executionClaim.detail ? { detail: executionClaim.detail } : {}),
729
- payment_settled: false,
730
- quote
731
- }
732
- };
733
- }
734
-
735
- try {
736
- const externalExecutionOptions = await buildExternalExecutionOptions(state, payload, quote, paymentVerification);
737
- if (externalExecutionOptions.error) {
738
- // Execution failed. Report the money state by what actually happened, not by lane:
739
- // - deferred x402: we never settled, so the caller is NOT charged.
740
- // - a concrete receipt is in hand (an x402 settlement already captured): the caller
741
- // WAS charged, so surface the receipt and a refund path.
742
- // - everything else (native/local_signed, presence, and the access-token rails
743
- // whose proof we only validated): no receipt was produced on this request, so we
744
- // do not claim a charge — a bare retry hint, never a false refund pointer.
745
- const hasReceipt = Boolean(paymentVerification.settlement || paymentVerification.payment_response_base64);
746
- const failureStatus = externalExecutionOptions.error.status || 502;
747
- // A provider outage/timeout is not the buyer's input: say so, and say when to retry.
748
- const providerUnavailable = failureStatus === 502 || failureStatus === 503 || failureStatus === 504;
749
- const retryHint = providerUnavailable ? "the provider did not respond in time — retry in a few seconds" : "retry with corrected input";
750
- return {
751
- status: failureStatus,
752
- ...(providerUnavailable ? { headers: { "Retry-After": "5" } } : {}),
753
- payload: {
754
- ok: false,
755
- reason: externalExecutionOptions.error.reason || "external_execution_failed",
756
- details: externalExecutionOptions.error.details || null,
757
- payment_settled: hasReceipt,
758
- ...(paymentVerification.settlement ? { settlement: paymentVerification.settlement } : {}),
759
- remediation: settlementDeferred
760
- ? `execution failed before settlement; you were not charged — ${retryHint}`
761
- : hasReceipt
762
- ? `payment was accepted but execution failed; ${retryHint}, or request a refund with your payment proof`
763
- : `execution failed; ${retryHint}`,
764
- quote
765
- },
766
- ...(hasReceipt && paymentVerification.payment_response_base64
767
- ? { paymentResponse: paymentVerification.payment_response_base64 }
768
- : {})
769
- };
770
- }
771
-
772
- // Execution succeeded — settle the deferred payment now (no-op for non-deferred).
773
- const finalizePaid = (settleResult) => {
774
- // settleDeferredPayment is a no-op for non-deferred paths (returns {ok:true} with no
775
- // settlement) — in that case keep the verification untouched; only when a deferred
776
- // x402 settlement actually ran do we fold its receipt in and drop the deferred marker.
777
- const settlementOccurred = Boolean(settleResult.settlement || settleResult.payment_response_base64);
778
- const settledVerification = settlementOccurred
779
- ? { ...paymentVerification, settlement: settleResult.settlement, payment_response_base64: settleResult.payment_response_base64, deferred_settlement: undefined }
780
- : paymentVerification;
781
-
782
- attributeProviderSettlement(state, externalExecutionOptions, payload, quote, {
783
- settlement_ref: (settledVerification.settlement && (settledVerification.settlement.transaction || settledVerification.settlement.txid)) || null
784
- }, settledVerification);
785
- const paidResult = createCommandResult(state, payload, quote, {
786
- paymentVerification: settledVerification,
787
- externalExecution: externalExecutionOptions.externalExecution || null
788
- });
789
- attachDeliveryReceipt(state, paidResult, payload, quote, settledVerification, externalExecutionOptions);
790
- return {
791
- status: 200,
792
- payload: paidResult,
793
- ...(settledVerification.payment_response_base64
794
- ? { paymentResponse: settledVerification.payment_response_base64 }
795
- : {})
796
- };
797
- };
798
-
799
- let settleResult = await settleDeferredPayment(paymentVerification);
800
- const authorizationRef = settlementDeferred ? authorizationRefFromVerification(paymentVerification) : null;
801
- if (!settleResult.ok && authorizationRef && settleResult.reason === "facilitator_unreachable") {
802
- // The facilitator timed out / dropped: it may still have broadcast the transfer. Ask the chain.
803
- const used = await confirmAuthorizationUsed(authorizationRef);
804
- if (used === true) {
805
- const settlement = { success: true, transaction: null, network: authorizationRef.network, payer: authorizationRef.authorizer, recovered_from: "authorization_state" };
806
- settleResult = { ok: true, settlement, payment_response_base64: encodePaymentResponse(settlement) };
807
- } else {
808
- // Not confirmed (yet). Keep the finished result under this payment so resending the SAME
809
- // signature delivers it once the transfer shows up on-chain — never ask for a new payment.
810
- rememberReplay(state, authorizationRef, {
811
- status: "unconfirmed",
812
- request_digest: requestDigest,
813
- finalize: async (settlement) => finalizePaid({ ok: true, settlement, payment_response_base64: encodePaymentResponse(settlement) })
814
- });
815
- return {
816
- status: 502,
817
- payload: {
818
- ok: false,
819
- reason: used === false ? "settlement_not_confirmed" : "settlement_outcome_unknown",
820
- detail: "The payment processor did not answer in time. Your work is done and held for 15 minutes: if this payment shows up on-chain, resend the SAME payment signature to receive the result; if it never settles you are not charged. Do not sign a new payment for this request.",
821
- payment_settled: used === false ? false : null,
822
- money_moved: used !== false,
823
- quote
824
- }
825
- };
826
- }
827
- }
828
- if (!settleResult.ok) {
829
- return {
830
- status: settleResult.status || 402,
831
- payload: {
832
- ok: false,
833
- reason: settleResult.reason || "settlement_failed",
834
- ...(settleResult.detail ? { detail: settleResult.detail } : {}),
835
- payment_settled: false,
836
- remediation: "the work executed but the payment was declined at settlement; you were not charged — retry with a valid payment",
837
- quote
838
- }
839
- };
840
- }
841
- const paidResponse = finalizePaid(settleResult);
842
- if (authorizationRef) rememberReplay(state, authorizationRef, { status: "settled", request_digest: requestDigest, response: paidResponse });
843
- return paidResponse;
844
- } finally {
845
- releaseDeferredExecution(state, executionClaim.key);
846
- }
847
- }
848
-
849
- async function executeAuthorizedCommandRequest(state, payload, authorizationContext) {
850
- const validation = validateIntegrationSelection(payload);
851
- if (!validation.ok) {
852
- return {
853
- status: 400,
854
- payload: {
855
- ok: false,
856
- reason: validation.reason,
857
- errors: validation.errors,
858
- selection: validation.selection
859
- }
860
- };
861
- }
862
-
863
- hydrateQuoteStates(state);
864
-
865
- const quote = createQuote(state, payload);
866
- const paymentVerification = {
867
- ok: true,
868
- verification_mode: authorizationContext && authorizationContext.verification_mode
869
- ? authorizationContext.verification_mode
870
- : "hosted_checkout",
871
- wallet_id: authorizationContext && authorizationContext.wallet_id
872
- ? authorizationContext.wallet_id
873
- : "hosted_checkout",
874
- age_seconds: 0,
875
- payment_payload: authorizationContext && authorizationContext.payment_payload
876
- ? authorizationContext.payment_payload
877
- : null
878
- };
879
- const externalExecutionOptions = await buildExternalExecutionOptions(state, payload, quote, paymentVerification);
880
- if (externalExecutionOptions.error) {
881
- return {
882
- status: externalExecutionOptions.error.status || 502,
883
- payload: {
884
- ok: false,
885
- reason: externalExecutionOptions.error.reason || "external_execution_failed",
886
- details: externalExecutionOptions.error.details || null
887
- }
888
- };
889
- }
890
-
891
- attributeProviderSettlement(state, externalExecutionOptions, payload, quote, undefined, paymentVerification);
892
- const authorizedResult = createCommandResult(state, payload, quote, {
893
- paymentVerification,
894
- externalExecution: externalExecutionOptions.externalExecution || null
895
- });
896
- attachDeliveryReceipt(state, authorizedResult, payload, quote, paymentVerification, externalExecutionOptions);
897
- return {
898
- status: 200,
899
- payload: authorizedResult
900
- };
901
- }
902
-
903
- module.exports = {
904
- executeAuthorizedCommandRequest,
905
- executeCommandRequest,
906
- listExecutableTaskRefs,
907
- assessPaidExecutability,
908
- buildExternalExecutionOptions,
909
- reconcileProviderSettlementAmount,
910
- sanitizeAuthorizationContextForProvider
911
- };