agirails 2.3.1__tar.gz → 2.3.2__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 (267) hide show
  1. {agirails-2.3.1 → agirails-2.3.2}/.env.example +4 -4
  2. {agirails-2.3.1 → agirails-2.3.2}/CHANGELOG.md +3 -0
  3. {agirails-2.3.1 → agirails-2.3.2}/PKG-INFO +4 -4
  4. {agirails-2.3.1 → agirails-2.3.2}/README.md +3 -3
  5. {agirails-2.3.1 → agirails-2.3.2}/pyproject.toml +2 -2
  6. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/__init__.py +49 -0
  7. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/abis/actp_kernel.json +103 -6
  8. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/adapters/standard.py +21 -0
  9. agirails-2.3.2/src/agirails/api/__init__.py +5 -0
  10. agirails-2.3.2/src/agirails/api/agirails_app.py +236 -0
  11. agirails-2.3.2/src/agirails/api/discover.py +283 -0
  12. agirails-2.3.2/src/agirails/cli/commands/autopublish.py +190 -0
  13. agirails-2.3.2/src/agirails/cli/commands/claim.py +162 -0
  14. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/cli/commands/diff.py +6 -76
  15. agirails-2.3.2/src/agirails/cli/commands/find.py +276 -0
  16. agirails-2.3.2/src/agirails/cli/commands/health.py +262 -0
  17. agirails-2.3.2/src/agirails/cli/commands/negotiate.py +344 -0
  18. agirails-2.3.2/src/agirails/cli/commands/publish.py +600 -0
  19. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/cli/commands/pull.py +7 -67
  20. agirails-2.3.2/src/agirails/cli/commands/receipt.py +131 -0
  21. agirails-2.3.2/src/agirails/cli/commands/register.py +218 -0
  22. agirails-2.3.2/src/agirails/cli/commands/test.py +225 -0
  23. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/cli/main.py +22 -0
  24. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/cli/utils/output.py +12 -9
  25. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/config/agirailsmd.py +3 -0
  26. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/config/networks.py +70 -4
  27. agirails-2.3.2/src/agirails/config/on_chain_state.py +241 -0
  28. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/config/sync_operations.py +2 -15
  29. agirails-2.3.2/src/agirails/negotiation/__init__.py +148 -0
  30. agirails-2.3.2/src/agirails/negotiation/buyer_orchestrator.py +739 -0
  31. agirails-2.3.2/src/agirails/negotiation/decision_engine.py +196 -0
  32. agirails-2.3.2/src/agirails/negotiation/policy_engine.py +392 -0
  33. agirails-2.3.2/src/agirails/negotiation/session_store.py +231 -0
  34. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/protocol/agent_registry.py +3 -3
  35. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/protocol/base.py +60 -11
  36. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/protocol/eas.py +3 -3
  37. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/protocol/escrow.py +15 -4
  38. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/protocol/events.py +4 -4
  39. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/protocol/kernel.py +143 -32
  40. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/protocol/nonce.py +26 -17
  41. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/runtime/base.py +29 -3
  42. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/runtime/blockchain_runtime.py +60 -14
  43. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/runtime/mock_runtime.py +79 -3
  44. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/runtime/mock_state_manager.py +40 -11
  45. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/types/message.py +4 -22
  46. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/utils/circuit_breaker.py +9 -2
  47. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/utils/security.py +6 -1
  48. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/wallet/aa/dual_nonce_manager.py +9 -2
  49. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/wallet/aa/transaction_batcher.py +14 -6
  50. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/wallet/auto_wallet_provider.py +10 -5
  51. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/wallet/keystore.py +6 -5
  52. agirails-2.3.2/tests/integration/test_e2e_sepolia.py +169 -0
  53. {agirails-2.3.1 → agirails-2.3.2}/tests/test_adapters/test_standard.py +68 -0
  54. agirails-2.3.2/tests/test_api/test_agirails_app.py +158 -0
  55. agirails-2.3.2/tests/test_cli/test_autopublish.py +175 -0
  56. agirails-2.3.2/tests/test_cli/test_claim.py +67 -0
  57. agirails-2.3.2/tests/test_cli/test_e2e_publish_claim_discover.py +232 -0
  58. agirails-2.3.2/tests/test_cli/test_find.py +304 -0
  59. agirails-2.3.2/tests/test_cli/test_health.py +189 -0
  60. {agirails-2.3.1 → agirails-2.3.2}/tests/test_cli/test_publish.py +8 -8
  61. agirails-2.3.2/tests/test_cli/test_publish_parity.py +338 -0
  62. agirails-2.3.2/tests/test_cli/test_receipt.py +113 -0
  63. agirails-2.3.2/tests/test_cli/test_register.py +53 -0
  64. agirails-2.3.2/tests/test_cli/test_test.py +119 -0
  65. {agirails-2.3.1 → agirails-2.3.2}/tests/test_config/test_agirailsmd.py +4 -1
  66. agirails-2.3.2/tests/test_config/test_networks_aa.py +96 -0
  67. agirails-2.3.2/tests/test_config/test_on_chain_state.py +115 -0
  68. agirails-2.3.2/tests/test_negotiation/test_buyer_orchestrator.py +380 -0
  69. agirails-2.3.2/tests/test_negotiation/test_decision_engine.py +215 -0
  70. agirails-2.3.2/tests/test_negotiation/test_policy_engine.py +221 -0
  71. agirails-2.3.2/tests/test_negotiation/test_session_store.py +113 -0
  72. {agirails-2.3.1 → agirails-2.3.2}/tests/test_protocol/test_contract_base.py +2 -2
  73. agirails-2.3.2/tests/test_runtime/__init__.py +0 -0
  74. agirails-2.3.2/tests/test_runtime/test_accept_quote.py +211 -0
  75. {agirails-2.3.1 → agirails-2.3.2}/tests/test_runtime/test_concurrent_file_locking.py +5 -5
  76. {agirails-2.3.1 → agirails-2.3.2}/tests/test_runtime/test_mock_state_manager.py +4 -4
  77. agirails-2.3.2/tests/test_utils/__init__.py +0 -0
  78. agirails-2.3.1/src/agirails/abi/ACTPKernel.json +0 -1340
  79. agirails-2.3.1/src/agirails/abi/ERC20.json +0 -40
  80. agirails-2.3.1/src/agirails/abi/EscrowVault.json +0 -134
  81. agirails-2.3.1/src/agirails/cli/commands/publish.py +0 -187
  82. {agirails-2.3.1 → agirails-2.3.2}/.github/workflows/test.yml +0 -0
  83. {agirails-2.3.1 → agirails-2.3.2}/.gitignore +0 -0
  84. {agirails-2.3.1 → agirails-2.3.2}/LICENSE +0 -0
  85. {agirails-2.3.1 → agirails-2.3.2}/MIGRATION.md +0 -0
  86. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/abis/agent_registry.json +0 -0
  87. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/abis/eas.json +0 -0
  88. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/abis/escrow_vault.json +0 -0
  89. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/abis/usdc.json +0 -0
  90. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/adapters/__init__.py +0 -0
  91. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/adapters/adapter_registry.py +0 -0
  92. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/adapters/adapter_router.py +0 -0
  93. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/adapters/base.py +0 -0
  94. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/adapters/basic.py +0 -0
  95. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/adapters/i_adapter.py +0 -0
  96. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/adapters/types.py +0 -0
  97. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/adapters/x402_adapter.py +0 -0
  98. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/builders/__init__.py +0 -0
  99. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/builders/delivery_proof.py +0 -0
  100. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/builders/quote.py +0 -0
  101. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/cli/__init__.py +0 -0
  102. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/cli/commands/__init__.py +0 -0
  103. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/cli/commands/balance.py +0 -0
  104. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/cli/commands/batch.py +0 -0
  105. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/cli/commands/config.py +0 -0
  106. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/cli/commands/deploy_check.py +0 -0
  107. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/cli/commands/deploy_env.py +0 -0
  108. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/cli/commands/init.py +0 -0
  109. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/cli/commands/mint.py +0 -0
  110. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/cli/commands/pay.py +0 -0
  111. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/cli/commands/simulate.py +0 -0
  112. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/cli/commands/time.py +0 -0
  113. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/cli/commands/tx.py +0 -0
  114. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/cli/commands/watch.py +0 -0
  115. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/cli/utils/__init__.py +0 -0
  116. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/cli/utils/client.py +0 -0
  117. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/cli/utils/validation.py +0 -0
  118. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/client.py +0 -0
  119. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/config/__init__.py +0 -0
  120. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/config/abis/AgentRegistry.json +0 -0
  121. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/config/pending_publish.py +0 -0
  122. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/config/publish_pipeline.py +0 -0
  123. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/erc8004/__init__.py +0 -0
  124. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/erc8004/bridge.py +0 -0
  125. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/erc8004/reputation_reporter.py +0 -0
  126. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/errors/__init__.py +0 -0
  127. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/errors/agent.py +0 -0
  128. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/errors/base.py +0 -0
  129. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/errors/mock.py +0 -0
  130. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/errors/network.py +0 -0
  131. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/errors/storage.py +0 -0
  132. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/errors/transaction.py +0 -0
  133. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/errors/validation.py +0 -0
  134. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/level0/__init__.py +0 -0
  135. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/level0/directory.py +0 -0
  136. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/level0/provide.py +0 -0
  137. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/level0/provider.py +0 -0
  138. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/level0/request.py +0 -0
  139. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/level1/__init__.py +0 -0
  140. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/level1/agent.py +0 -0
  141. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/level1/config.py +0 -0
  142. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/level1/job.py +0 -0
  143. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/level1/pricing.py +0 -0
  144. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/protocol/__init__.py +0 -0
  145. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/protocol/did.py +0 -0
  146. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/protocol/messages.py +0 -0
  147. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/protocol/proofs.py +0 -0
  148. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/py.typed +0 -0
  149. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/runtime/__init__.py +0 -0
  150. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/runtime/types.py +0 -0
  151. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/storage/__init__.py +0 -0
  152. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/storage/archive_bundle_builder.py +0 -0
  153. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/storage/arweave_client.py +0 -0
  154. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/storage/filebase_client.py +0 -0
  155. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/storage/types.py +0 -0
  156. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/types/__init__.py +0 -0
  157. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/types/did.py +0 -0
  158. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/types/erc8004.py +0 -0
  159. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/types/transaction.py +0 -0
  160. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/types/x402.py +0 -0
  161. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/utils/__init__.py +0 -0
  162. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/utils/canonical_json.py +0 -0
  163. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/utils/helpers.py +0 -0
  164. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/utils/logger.py +0 -0
  165. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/utils/logging.py +0 -0
  166. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/utils/nonce_tracker.py +0 -0
  167. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/utils/received_nonce_tracker.py +0 -0
  168. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/utils/retry.py +0 -0
  169. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/utils/secure_nonce.py +0 -0
  170. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/utils/semaphore.py +0 -0
  171. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/utils/used_attestation_tracker.py +0 -0
  172. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/utils/validation.py +0 -0
  173. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/version.py +0 -0
  174. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/wallet/__init__.py +0 -0
  175. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/wallet/aa/__init__.py +0 -0
  176. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/wallet/aa/bundler_client.py +0 -0
  177. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/wallet/aa/constants.py +0 -0
  178. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/wallet/aa/paymaster_client.py +0 -0
  179. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/wallet/aa/user_op_builder.py +0 -0
  180. {agirails-2.3.1 → agirails-2.3.2}/src/agirails/wallet/eoa_wallet_provider.py +0 -0
  181. {agirails-2.3.1 → agirails-2.3.2}/tests/__init__.py +0 -0
  182. {agirails-2.3.1 → agirails-2.3.2}/tests/benchmarks/__init__.py +0 -0
  183. {agirails-2.3.1 → agirails-2.3.2}/tests/benchmarks/test_performance.py +0 -0
  184. {agirails-2.3.1 → agirails-2.3.2}/tests/conftest.py +0 -0
  185. {agirails-2.3.1 → agirails-2.3.2}/tests/fixtures/parity/canonical_json.json +0 -0
  186. {agirails-2.3.1 → agirails-2.3.2}/tests/fixtures/parity/delivery_proof.json +0 -0
  187. {agirails-2.3.1 → agirails-2.3.2}/tests/fixtures/parity/eip712.json +0 -0
  188. {agirails-2.3.1 → agirails-2.3.2}/tests/fixtures/parity/service_hash.json +0 -0
  189. {agirails-2.3.1 → agirails-2.3.2}/tests/integration/__init__.py +0 -0
  190. {agirails-2.3.1 → agirails-2.3.2}/tests/integration/test_blockchain_runtime.py +0 -0
  191. {agirails-2.3.1 → agirails-2.3.2}/tests/integration/test_eas.py +0 -0
  192. {agirails-2.3.1 → agirails-2.3.2}/tests/test_adapters/__init__.py +0 -0
  193. {agirails-2.3.1 → agirails-2.3.2}/tests/test_adapters/test_adapter_router.py +0 -0
  194. {agirails-2.3.1 → agirails-2.3.2}/tests/test_adapters/test_basic.py +0 -0
  195. {agirails-2.3.1 → agirails-2.3.2}/tests/test_adapters/test_x402_adapter.py +0 -0
  196. {agirails-2.3.1/tests/test_cli → agirails-2.3.2/tests/test_api}/__init__.py +0 -0
  197. {agirails-2.3.1 → agirails-2.3.2}/tests/test_builders/__init__.py +0 -0
  198. {agirails-2.3.1 → agirails-2.3.2}/tests/test_builders/test_delivery_proof.py +0 -0
  199. {agirails-2.3.1 → agirails-2.3.2}/tests/test_builders/test_quote.py +0 -0
  200. {agirails-2.3.1/tests/test_config → agirails-2.3.2/tests/test_cli}/__init__.py +0 -0
  201. {agirails-2.3.1 → agirails-2.3.2}/tests/test_cli/test_cli_original.py +0 -0
  202. {agirails-2.3.1 → agirails-2.3.2}/tests/test_cli_deploy/__init__.py +0 -0
  203. {agirails-2.3.1 → agirails-2.3.2}/tests/test_cli_deploy/test_deploy.py +0 -0
  204. {agirails-2.3.1 → agirails-2.3.2}/tests/test_client.py +0 -0
  205. {agirails-2.3.1/tests/test_runtime → agirails-2.3.2/tests/test_config}/__init__.py +0 -0
  206. {agirails-2.3.1 → agirails-2.3.2}/tests/test_config/test_pending_publish.py +0 -0
  207. {agirails-2.3.1 → agirails-2.3.2}/tests/test_erc8004/__init__.py +0 -0
  208. {agirails-2.3.1 → agirails-2.3.2}/tests/test_erc8004/test_bridge.py +0 -0
  209. {agirails-2.3.1 → agirails-2.3.2}/tests/test_erc8004/test_reputation_reporter.py +0 -0
  210. {agirails-2.3.1 → agirails-2.3.2}/tests/test_errors/__init__.py +0 -0
  211. {agirails-2.3.1 → agirails-2.3.2}/tests/test_errors/test_agent.py +0 -0
  212. {agirails-2.3.1 → agirails-2.3.2}/tests/test_errors/test_base.py +0 -0
  213. {agirails-2.3.1 → agirails-2.3.2}/tests/test_errors/test_network.py +0 -0
  214. {agirails-2.3.1 → agirails-2.3.2}/tests/test_errors/test_transaction.py +0 -0
  215. {agirails-2.3.1 → agirails-2.3.2}/tests/test_errors/test_transient_rpc.py +0 -0
  216. {agirails-2.3.1 → agirails-2.3.2}/tests/test_errors/test_validation.py +0 -0
  217. {agirails-2.3.1 → agirails-2.3.2}/tests/test_level0/__init__.py +0 -0
  218. {agirails-2.3.1 → agirails-2.3.2}/tests/test_level0/test_directory.py +0 -0
  219. {agirails-2.3.1 → agirails-2.3.2}/tests/test_level0/test_provider.py +0 -0
  220. {agirails-2.3.1 → agirails-2.3.2}/tests/test_level0/test_request.py +0 -0
  221. {agirails-2.3.1 → agirails-2.3.2}/tests/test_level1/__init__.py +0 -0
  222. {agirails-2.3.1 → agirails-2.3.2}/tests/test_level1/test_agent_lifecycle.py +0 -0
  223. {agirails-2.3.1 → agirails-2.3.2}/tests/test_level1/test_config.py +0 -0
  224. {agirails-2.3.1 → agirails-2.3.2}/tests/test_level1/test_pricing.py +0 -0
  225. {agirails-2.3.1/tests/test_utils → agirails-2.3.2/tests/test_negotiation}/__init__.py +0 -0
  226. {agirails-2.3.1 → agirails-2.3.2}/tests/test_packaging/__init__.py +0 -0
  227. {agirails-2.3.1 → agirails-2.3.2}/tests/test_packaging/test_smoke.py +0 -0
  228. {agirails-2.3.1 → agirails-2.3.2}/tests/test_parity.py +0 -0
  229. {agirails-2.3.1 → agirails-2.3.2}/tests/test_properties/__init__.py +0 -0
  230. {agirails-2.3.1 → agirails-2.3.2}/tests/test_properties/test_state_machine.py +0 -0
  231. {agirails-2.3.1 → agirails-2.3.2}/tests/test_protocol/__init__.py +0 -0
  232. {agirails-2.3.1 → agirails-2.3.2}/tests/test_protocol/test_did.py +0 -0
  233. {agirails-2.3.1 → agirails-2.3.2}/tests/test_protocol/test_eas_verification.py +0 -0
  234. {agirails-2.3.1 → agirails-2.3.2}/tests/test_protocol/test_networks.py +0 -0
  235. {agirails-2.3.1 → agirails-2.3.2}/tests/test_protocol/test_proofs.py +0 -0
  236. {agirails-2.3.1 → agirails-2.3.2}/tests/test_runtime/test_mock_runtime.py +0 -0
  237. {agirails-2.3.1 → agirails-2.3.2}/tests/test_security/__init__.py +0 -0
  238. {agirails-2.3.1 → agirails-2.3.2}/tests/test_security/test_security_audit.py +0 -0
  239. {agirails-2.3.1 → agirails-2.3.2}/tests/test_storage/__init__.py +0 -0
  240. {agirails-2.3.1 → agirails-2.3.2}/tests/test_storage/conftest.py +0 -0
  241. {agirails-2.3.1 → agirails-2.3.2}/tests/test_storage/test_archive_bundle_builder.py +0 -0
  242. {agirails-2.3.1 → agirails-2.3.2}/tests/test_storage/test_arweave_client.py +0 -0
  243. {agirails-2.3.1 → agirails-2.3.2}/tests/test_storage/test_filebase_client.py +0 -0
  244. {agirails-2.3.1 → agirails-2.3.2}/tests/test_storage/test_types.py +0 -0
  245. {agirails-2.3.1 → agirails-2.3.2}/tests/test_types/__init__.py +0 -0
  246. {agirails-2.3.1 → agirails-2.3.2}/tests/test_types/test_message.py +0 -0
  247. {agirails-2.3.1 → agirails-2.3.2}/tests/test_types/test_transaction.py +0 -0
  248. {agirails-2.3.1 → agirails-2.3.2}/tests/test_utils/test_attestation_replay.py +0 -0
  249. {agirails-2.3.1 → agirails-2.3.2}/tests/test_utils/test_circuit_breaker.py +0 -0
  250. {agirails-2.3.1 → agirails-2.3.2}/tests/test_utils/test_helpers.py +0 -0
  251. {agirails-2.3.1 → agirails-2.3.2}/tests/test_utils/test_helpers_extended.py +0 -0
  252. {agirails-2.3.1 → agirails-2.3.2}/tests/test_utils/test_nonce_tracker.py +0 -0
  253. {agirails-2.3.1 → agirails-2.3.2}/tests/test_utils/test_nonce_tracker_extended.py +0 -0
  254. {agirails-2.3.1 → agirails-2.3.2}/tests/test_utils/test_received_nonce_tracker_extended.py +0 -0
  255. {agirails-2.3.1 → agirails-2.3.2}/tests/test_utils/test_retry.py +0 -0
  256. {agirails-2.3.1 → agirails-2.3.2}/tests/test_utils/test_secure_nonce_concurrency.py +0 -0
  257. {agirails-2.3.1 → agirails-2.3.2}/tests/test_utils/test_security.py +0 -0
  258. {agirails-2.3.1 → agirails-2.3.2}/tests/test_utils/test_security_extended.py +0 -0
  259. {agirails-2.3.1 → agirails-2.3.2}/tests/test_utils/test_validation.py +0 -0
  260. {agirails-2.3.1 → agirails-2.3.2}/tests/test_utils/test_validation_extended.py +0 -0
  261. {agirails-2.3.1 → agirails-2.3.2}/tests/test_wallet/__init__.py +0 -0
  262. {agirails-2.3.1 → agirails-2.3.2}/tests/test_wallet/test_auto_wallet_provider.py +0 -0
  263. {agirails-2.3.1 → agirails-2.3.2}/tests/test_wallet/test_bundler_client.py +0 -0
  264. {agirails-2.3.1 → agirails-2.3.2}/tests/test_wallet/test_dual_nonce_manager.py +0 -0
  265. {agirails-2.3.1 → agirails-2.3.2}/tests/test_wallet/test_keystore.py +0 -0
  266. {agirails-2.3.1 → agirails-2.3.2}/tests/test_wallet/test_transaction_batcher.py +0 -0
  267. {agirails-2.3.1 → agirails-2.3.2}/tests/test_wallet/test_user_op_builder.py +0 -0
@@ -8,7 +8,7 @@
8
8
  # =============================================================================
9
9
 
10
10
  # Client wallet (requester) - Your private key for sending transactions
11
- # Generate a new wallet for testing: https://vanity-eth.tk/
11
+ # Generate a new wallet: use `actp init` or any Ethereum wallet generator
12
12
  CLIENT_PRIVATE_KEY=0x_your_client_private_key_here
13
13
 
14
14
  # Provider wallet - Private key for receiving payments (optional)
@@ -34,17 +34,17 @@ CHAIN_ID=84532
34
34
  MOCK_USDC_ADDRESS=0x444b4e1A65949AB2ac75979D5d0166Eb7A248Ccb
35
35
 
36
36
  # ACTP Kernel contract
37
- # ACTP_KERNEL_ADDRESS=0xD199070F8e9FB9a127F6Fe730Bc13300B4b3d962
37
+ # ACTP_KERNEL_ADDRESS=0x90a1Bcc218c148F63D036aB2f7B5329C9ee7868d
38
38
 
39
39
  # Escrow Vault contract
40
- # ESCROW_VAULT_ADDRESS=0x948b9Ea081C4Cec1E112Af2e539224c531d4d585
40
+ # ESCROW_VAULT_ADDRESS=0xA336967F4481EeE4A8Bb59e35423D273fbf9f5e7
41
41
 
42
42
  # =============================================================================
43
43
  # EAS (Ethereum Attestation Service)
44
44
  # =============================================================================
45
45
 
46
46
  # Delivery proof schema UID on Base Sepolia
47
- EAS_DELIVERY_SCHEMA_UID=0x1525e033c59c1c34aa5ab5f38fc0524641835476bca08b2e5c5e076b9ba7ed84
47
+ EAS_DELIVERY_SCHEMA_UID=0x1b0ebdf0bd20c28ec9d5362571ce8715a55f46e81c3de2f9b0d8e1b95fb5ffce
48
48
 
49
49
  # =============================================================================
50
50
  # Local Development (Optional)
@@ -90,6 +90,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
90
90
 
91
91
  ## [Unreleased]
92
92
 
93
+ > Note: Changelog entries for v2.1.0 through v2.3.1 were not recorded.
94
+ > See git log for detailed changes.
95
+
93
96
  ### Planned for 2.1.0
94
97
  - `BlockchainRuntime` - Real blockchain integration
95
98
  - CLI tool implementation (`actp` command)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agirails
3
- Version: 2.3.1
3
+ Version: 2.3.2
4
4
  Summary: AGIRAILS Python SDK - Agent Commerce Transaction Protocol
5
5
  Project-URL: Homepage, https://agirails.io
6
6
  Project-URL: Documentation, https://docs.agirails.io
@@ -63,12 +63,12 @@ Description-Content-Type: text/markdown
63
63
 
64
64
  The official Python SDK for the **Agent Commerce Transaction Protocol (ACTP)** — enabling AI agents to transact with each other through blockchain-based escrow on Base L2.
65
65
 
66
- **Full 1:1 parity with TypeScript SDK v2.5.0.**
66
+ **Full 1:1 parity with TypeScript SDK v2.5.0+.**
67
67
 
68
68
  ## Install
69
69
 
70
70
  ```bash
71
- pip install agirails==2.3.0
71
+ pip install agirails==2.3.1
72
72
  ```
73
73
 
74
74
  ## Features
@@ -185,7 +185,7 @@ actp time advance <duration>
185
185
 
186
186
  ## SDK Parity
187
187
 
188
- Full 1:1 parity with TypeScript SDK v2.5.0:
188
+ Full 1:1 parity with TypeScript SDK v2.5.0+:
189
189
 
190
190
  | Feature | Python | TypeScript |
191
191
  |---------|--------|------------|
@@ -7,12 +7,12 @@
7
7
 
8
8
  The official Python SDK for the **Agent Commerce Transaction Protocol (ACTP)** — enabling AI agents to transact with each other through blockchain-based escrow on Base L2.
9
9
 
10
- **Full 1:1 parity with TypeScript SDK v2.5.0.**
10
+ **Full 1:1 parity with TypeScript SDK v2.5.0+.**
11
11
 
12
12
  ## Install
13
13
 
14
14
  ```bash
15
- pip install agirails==2.3.0
15
+ pip install agirails==2.3.1
16
16
  ```
17
17
 
18
18
  ## Features
@@ -129,7 +129,7 @@ actp time advance <duration>
129
129
 
130
130
  ## SDK Parity
131
131
 
132
- Full 1:1 parity with TypeScript SDK v2.5.0:
132
+ Full 1:1 parity with TypeScript SDK v2.5.0+:
133
133
 
134
134
  | Feature | Python | TypeScript |
135
135
  |---------|--------|------------|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "agirails"
7
- version = "2.3.1"
7
+ version = "2.3.2"
8
8
  description = "AGIRAILS Python SDK - Agent Commerce Transaction Protocol"
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -36,7 +36,7 @@ classifiers = [
36
36
  "Typing :: Typed",
37
37
  ]
38
38
  dependencies = [
39
- # Security Note (M-1): Pin upper bounds to prevent breaking changes
39
+ # Pin upper bounds to prevent breaking changes
40
40
  "web3>=7.0.0,<8.0.0",
41
41
  "eth-account>=0.13.0,<0.14.0",
42
42
  "eth-abi>=5.0.0,<6.0.0",
@@ -352,6 +352,32 @@ from agirails.storage import (
352
352
  CircuitBreakerConfig,
353
353
  )
354
354
 
355
+ # Negotiation Module (autonomous buyer-side negotiation)
356
+ from agirails.negotiation import (
357
+ DEFAULT_WEIGHTS,
358
+ PolicyEngine,
359
+ BuyerPolicy,
360
+ Constraints,
361
+ MaxUnitPrice,
362
+ MaxDailySpend,
363
+ Negotiation,
364
+ Selection,
365
+ QuoteOffer,
366
+ PolicyViolation,
367
+ PolicyResult,
368
+ DecisionEngine,
369
+ ScoringWeights,
370
+ CandidateStats,
371
+ ScoredCandidate,
372
+ ScoreBreakdown,
373
+ SessionStore,
374
+ SessionMapping,
375
+ BuyerOrchestrator,
376
+ NegotiationResult,
377
+ RoundResult,
378
+ OrchestratorConfig,
379
+ )
380
+
355
381
  __all__ = [
356
382
  # Version
357
383
  "__version__",
@@ -620,4 +646,27 @@ __all__ = [
620
646
  "DownloadResult",
621
647
  # Types - Circuit Breaker
622
648
  "CircuitBreakerConfig",
649
+ # Negotiation Module
650
+ "DEFAULT_WEIGHTS",
651
+ "PolicyEngine",
652
+ "BuyerPolicy",
653
+ "Constraints",
654
+ "MaxUnitPrice",
655
+ "MaxDailySpend",
656
+ "Negotiation",
657
+ "Selection",
658
+ "QuoteOffer",
659
+ "PolicyViolation",
660
+ "PolicyResult",
661
+ "DecisionEngine",
662
+ "ScoringWeights",
663
+ "CandidateStats",
664
+ "ScoredCandidate",
665
+ "ScoreBreakdown",
666
+ "SessionStore",
667
+ "SessionMapping",
668
+ "BuyerOrchestrator",
669
+ "NegotiationResult",
670
+ "RoundResult",
671
+ "OrchestratorConfig",
623
672
  ]
@@ -397,6 +397,16 @@
397
397
  "name": "serviceHash",
398
398
  "type": "bytes32",
399
399
  "internalType": "bytes32"
400
+ },
401
+ {
402
+ "name": "agentId",
403
+ "type": "uint256",
404
+ "internalType": "uint256"
405
+ },
406
+ {
407
+ "name": "requesterAgentId",
408
+ "type": "uint256",
409
+ "internalType": "uint256"
400
410
  }
401
411
  ],
402
412
  "outputs": [
@@ -553,6 +563,26 @@
553
563
  "name": "platformFeeBpsLocked",
554
564
  "type": "uint16",
555
565
  "internalType": "uint16"
566
+ },
567
+ {
568
+ "name": "agentId",
569
+ "type": "uint256",
570
+ "internalType": "uint256"
571
+ },
572
+ {
573
+ "name": "requesterAgentId",
574
+ "type": "uint256",
575
+ "internalType": "uint256"
576
+ },
577
+ {
578
+ "name": "disputeInitiator",
579
+ "type": "address",
580
+ "internalType": "address"
581
+ },
582
+ {
583
+ "name": "disputeBond",
584
+ "type": "uint256",
585
+ "internalType": "uint256"
556
586
  }
557
587
  ]
558
588
  }
@@ -1067,10 +1097,10 @@
1067
1097
  "internalType": "address"
1068
1098
  },
1069
1099
  {
1070
- "name": "disputeId",
1071
- "type": "bytes32",
1100
+ "name": "bondAmount",
1101
+ "type": "uint256",
1072
1102
  "indexed": false,
1073
- "internalType": "bytes32"
1103
+ "internalType": "uint256"
1074
1104
  },
1075
1105
  {
1076
1106
  "name": "timestamp",
@@ -1098,10 +1128,22 @@
1098
1128
  "internalType": "bytes32"
1099
1129
  },
1100
1130
  {
1101
- "name": "resolution",
1102
- "type": "uint8",
1131
+ "name": "initiator",
1132
+ "type": "address",
1133
+ "indexed": true,
1134
+ "internalType": "address"
1135
+ },
1136
+ {
1137
+ "name": "providerAtFault",
1138
+ "type": "bool",
1103
1139
  "indexed": false,
1104
- "internalType": "uint8"
1140
+ "internalType": "bool"
1141
+ },
1142
+ {
1143
+ "name": "bondAmount",
1144
+ "type": "uint256",
1145
+ "indexed": false,
1146
+ "internalType": "uint256"
1105
1147
  },
1106
1148
  {
1107
1149
  "name": "timestamp",
@@ -1594,6 +1636,12 @@
1594
1636
  "type": "uint256",
1595
1637
  "indexed": false,
1596
1638
  "internalType": "uint256"
1639
+ },
1640
+ {
1641
+ "name": "agentId",
1642
+ "type": "uint256",
1643
+ "indexed": false,
1644
+ "internalType": "uint256"
1597
1645
  }
1598
1646
  ],
1599
1647
  "anonymous": false
@@ -1603,6 +1651,55 @@
1603
1651
  "name": "ReentrancyGuardReentrantCall",
1604
1652
  "inputs": []
1605
1653
  },
1654
+ {
1655
+ "type": "function",
1656
+ "name": "acceptQuote",
1657
+ "inputs": [
1658
+ {
1659
+ "name": "transactionId",
1660
+ "type": "bytes32",
1661
+ "internalType": "bytes32"
1662
+ },
1663
+ {
1664
+ "name": "newAmount",
1665
+ "type": "uint256",
1666
+ "internalType": "uint256"
1667
+ }
1668
+ ],
1669
+ "outputs": [],
1670
+ "stateMutability": "nonpayable"
1671
+ },
1672
+ {
1673
+ "type": "event",
1674
+ "name": "QuoteAccepted",
1675
+ "inputs": [
1676
+ {
1677
+ "name": "transactionId",
1678
+ "type": "bytes32",
1679
+ "indexed": true,
1680
+ "internalType": "bytes32"
1681
+ },
1682
+ {
1683
+ "name": "oldAmount",
1684
+ "type": "uint256",
1685
+ "indexed": false,
1686
+ "internalType": "uint256"
1687
+ },
1688
+ {
1689
+ "name": "newAmount",
1690
+ "type": "uint256",
1691
+ "indexed": false,
1692
+ "internalType": "uint256"
1693
+ },
1694
+ {
1695
+ "name": "timestamp",
1696
+ "type": "uint256",
1697
+ "indexed": false,
1698
+ "internalType": "uint256"
1699
+ }
1700
+ ],
1701
+ "anonymous": false
1702
+ },
1606
1703
  {
1607
1704
  "type": "error",
1608
1705
  "name": "SafeERC20FailedOperation",
@@ -229,6 +229,27 @@ class StandardAdapter(BaseAdapter):
229
229
 
230
230
  return tx_id
231
231
 
232
+ async def accept_quote(
233
+ self,
234
+ tx_id: str,
235
+ new_amount: Union[str, int, float],
236
+ ) -> None:
237
+ """
238
+ Accept a provider's quote, updating the transaction amount.
239
+
240
+ Does NOT change state (stays QUOTED). After accept_quote, call link_escrow.
241
+
242
+ Args:
243
+ tx_id: Transaction ID
244
+ new_amount: New amount in user-friendly format ("100", 100.50, "100 USDC")
245
+
246
+ Raises:
247
+ TransactionNotFoundError: If transaction doesn't exist.
248
+ InvalidStateTransitionError: If not in QUOTED state.
249
+ """
250
+ amount_wei = self.parse_amount(new_amount)
251
+ await self._runtime.accept_quote(tx_id=tx_id, new_amount=amount_wei)
252
+
232
253
  async def link_escrow(self, tx_id: str, amount: Optional[Union[str, int, float]] = None) -> str:
233
254
  """
234
255
  Link escrow to transaction (locks funds).
@@ -0,0 +1,5 @@
1
+ """AGIRAILS API clients."""
2
+
3
+ from agirails.api.discover import discover_agents, DiscoverParams, DiscoverResult, DiscoverAgent
4
+
5
+ __all__ = ["discover_agents", "DiscoverParams", "DiscoverResult", "DiscoverAgent"]
@@ -0,0 +1,236 @@
1
+ """agirails.app API Client — Profile sync, slug check, claim.
2
+
3
+ Four functions matching TS src/api/agirailsApp.ts:
4
+ - check_slug: Pre-chain slug availability
5
+ - upsert_agent: Post-publish profile sync (dual auth)
6
+ - get_claim_challenge: Redis challenge generation
7
+ - claim_agent: Ownership verification
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import json as _json
13
+ import os
14
+ from dataclasses import dataclass
15
+ from typing import Any, Dict, Optional
16
+
17
+ try:
18
+ import httpx
19
+
20
+ _HAS_HTTPX = True
21
+ except ImportError:
22
+ _HAS_HTTPX = False
23
+
24
+ try:
25
+ import aiohttp
26
+
27
+ _HAS_AIOHTTP = True
28
+ except ImportError:
29
+ _HAS_AIOHTTP = False
30
+
31
+
32
+ # ============================================================================
33
+ # Constants
34
+ # ============================================================================
35
+
36
+ AGIRAILS_APP_BASE_URL = os.environ.get("AGIRAILS_APP_URL", "https://agirails.app")
37
+
38
+
39
+ # ============================================================================
40
+ # Types
41
+ # ============================================================================
42
+
43
+
44
+ class AgirailsAppError(Exception):
45
+ """Error from agirails.app API."""
46
+
47
+ def __init__(self, message: str, status_code: int = 0):
48
+ super().__init__(message)
49
+ self.status_code = status_code
50
+
51
+
52
+ @dataclass
53
+ class UpsertAgentParams:
54
+ """Parameters for upsert_agent (1:1 with TS UpsertAgentParams)."""
55
+
56
+ slug: str
57
+ agent_id: str # agentId in TS
58
+ wallet: str
59
+ config_cid: str # configCid in TS
60
+ config_hash: str # configHash in TS
61
+ signature: str # EIP-191 wallet signature
62
+ message: str # the signed message
63
+ timestamp: int # Unix seconds — part of signed message, server rejects >5min
64
+ network: str = "" # Network name (e.g. "base-sepolia") — bound in signed message
65
+
66
+ def to_camel_case_dict(self) -> Dict[str, Any]:
67
+ """Serialize to camelCase keys matching TS API contract."""
68
+ return {
69
+ "slug": self.slug,
70
+ "agentId": self.agent_id,
71
+ "wallet": self.wallet,
72
+ "configCid": self.config_cid,
73
+ "configHash": self.config_hash,
74
+ "signature": self.signature,
75
+ "message": self.message,
76
+ "timestamp": self.timestamp,
77
+ **({"network": self.network} if self.network else {}),
78
+ }
79
+
80
+
81
+ @dataclass
82
+ class ClaimAgentParams:
83
+ """Parameters for claim_agent."""
84
+
85
+ agent_id: str
86
+ wallet: str
87
+ challenge: str
88
+ signature: str
89
+
90
+
91
+ # ============================================================================
92
+ # HTTP Helpers (same fallback pattern as discover.py)
93
+ # ============================================================================
94
+
95
+
96
+ async def _get(url: str, timeout: float = 15.0) -> Dict[str, Any]:
97
+ """HTTP GET with httpx → aiohttp → urllib fallback."""
98
+ if _HAS_HTTPX:
99
+ async with httpx.AsyncClient() as client:
100
+ resp = await client.get(url, headers={"Accept": "application/json"}, timeout=timeout)
101
+ if resp.status_code >= 400:
102
+ raise AgirailsAppError(f"GET {url} failed: {resp.status_code}", resp.status_code)
103
+ return resp.json()
104
+
105
+ if _HAS_AIOHTTP:
106
+ async with aiohttp.ClientSession() as session:
107
+ async with session.get(url, headers={"Accept": "application/json"}, timeout=aiohttp.ClientTimeout(total=timeout)) as resp:
108
+ if resp.status >= 400:
109
+ raise AgirailsAppError(f"GET {url} failed: {resp.status}", resp.status)
110
+ return await resp.json()
111
+
112
+ from urllib.request import Request, urlopen
113
+
114
+ req = Request(url, headers={"Accept": "application/json"})
115
+ with urlopen(req, timeout=int(timeout)) as resp:
116
+ if resp.status >= 400:
117
+ raise AgirailsAppError(f"GET {url} failed: {resp.status}", resp.status)
118
+ return _json.loads(resp.read().decode("utf-8"))
119
+
120
+
121
+ async def _post(url: str, body: Dict[str, Any], timeout: float = 15.0) -> Dict[str, Any]:
122
+ """HTTP POST with httpx → aiohttp → urllib fallback."""
123
+ if _HAS_HTTPX:
124
+ async with httpx.AsyncClient() as client:
125
+ resp = await client.post(
126
+ url,
127
+ json=body,
128
+ headers={"Content-Type": "application/json", "Accept": "application/json"},
129
+ timeout=timeout,
130
+ )
131
+ if resp.status_code >= 400:
132
+ raise AgirailsAppError(f"POST {url} failed: {resp.status_code}", resp.status_code)
133
+ return resp.json()
134
+
135
+ if _HAS_AIOHTTP:
136
+ async with aiohttp.ClientSession() as session:
137
+ async with session.post(
138
+ url,
139
+ json=body,
140
+ headers={"Content-Type": "application/json", "Accept": "application/json"},
141
+ timeout=aiohttp.ClientTimeout(total=timeout),
142
+ ) as resp:
143
+ if resp.status >= 400:
144
+ raise AgirailsAppError(f"POST {url} failed: {resp.status}", resp.status)
145
+ return await resp.json()
146
+
147
+ from urllib.request import Request, urlopen
148
+
149
+ data = _json.dumps(body).encode("utf-8")
150
+ req = Request(
151
+ url,
152
+ data=data,
153
+ headers={"Content-Type": "application/json", "Accept": "application/json"},
154
+ method="POST",
155
+ )
156
+ with urlopen(req, timeout=int(timeout)) as resp:
157
+ if resp.status >= 400:
158
+ raise AgirailsAppError(f"POST {url} failed: {resp.status}", resp.status)
159
+ return _json.loads(resp.read().decode("utf-8"))
160
+
161
+
162
+ # ============================================================================
163
+ # API Functions
164
+ # ============================================================================
165
+
166
+
167
+ async def check_slug(slug: str) -> Dict[str, Any]:
168
+ """Check slug availability on agirails.app.
169
+
170
+ Args:
171
+ slug: Agent slug to check (3-64 chars).
172
+
173
+ Returns:
174
+ Dict with 'available' (bool), 'slug' (str), optionally 'suggestions' (list).
175
+ """
176
+ from urllib.parse import quote
177
+
178
+ url = f"{AGIRAILS_APP_BASE_URL}/api/v1/agents/check-slug?slug={quote(slug)}"
179
+ return await _get(url)
180
+
181
+
182
+ async def upsert_agent(params: UpsertAgentParams) -> Dict[str, Any]:
183
+ """Create or update agent profile on agirails.app.
184
+
185
+ Dual auth: session (Supabase JWT) + wallet-sig (SDK publish via EIP-712).
186
+
187
+ Args:
188
+ params: Agent data with EIP-712 signature.
189
+
190
+ Returns:
191
+ API response dict.
192
+ """
193
+ url = f"{AGIRAILS_APP_BASE_URL}/api/v1/agents"
194
+ return await _post(url, params.to_camel_case_dict())
195
+
196
+
197
+ async def get_claim_challenge(wallet: str) -> Dict[str, Any]:
198
+ """Get a Redis-backed challenge for agent claiming.
199
+
200
+ Args:
201
+ wallet: Wallet address.
202
+
203
+ Returns:
204
+ Dict with 'challenge' (str).
205
+ """
206
+ url = f"{AGIRAILS_APP_BASE_URL}/api/v1/agents/claim/challenge"
207
+ return await _post(url, {"wallet": wallet})
208
+
209
+
210
+ async def claim_agent(params: ClaimAgentParams) -> Dict[str, Any]:
211
+ """Claim agent ownership via on-chain ownerOf verification.
212
+
213
+ Args:
214
+ params: Claim parameters with challenge signature.
215
+
216
+ Returns:
217
+ API response dict.
218
+ """
219
+ url = f"{AGIRAILS_APP_BASE_URL}/api/v1/agents/claim"
220
+ return await _post(url, {
221
+ "agentId": params.agent_id,
222
+ "wallet": params.wallet,
223
+ "challenge": params.challenge,
224
+ "signature": params.signature,
225
+ })
226
+
227
+
228
+ __all__ = [
229
+ "AgirailsAppError",
230
+ "UpsertAgentParams",
231
+ "ClaimAgentParams",
232
+ "check_slug",
233
+ "upsert_agent",
234
+ "get_claim_challenge",
235
+ "claim_agent",
236
+ ]