iwa 0.0.15__tar.gz → 0.0.17__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 (215) hide show
  1. {iwa-0.0.15/src/iwa.egg-info → iwa-0.0.17}/PKG-INFO +1 -1
  2. {iwa-0.0.15 → iwa-0.0.17}/pyproject.toml +2 -2
  3. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/constants.py +13 -3
  4. iwa-0.0.17/src/iwa/plugins/olas/contracts/activity_checker.py +155 -0
  5. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/service_manager/mech.py +84 -2
  6. {iwa-0.0.15 → iwa-0.0.17/src/iwa.egg-info}/PKG-INFO +1 -1
  7. iwa-0.0.15/src/iwa/plugins/olas/contracts/activity_checker.py +0 -93
  8. {iwa-0.0.15 → iwa-0.0.17}/LICENSE +0 -0
  9. {iwa-0.0.15 → iwa-0.0.17}/README.md +0 -0
  10. {iwa-0.0.15 → iwa-0.0.17}/setup.cfg +0 -0
  11. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/__init__.py +0 -0
  12. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/__main__.py +0 -0
  13. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/__init__.py +0 -0
  14. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/chain/__init__.py +0 -0
  15. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/chain/errors.py +0 -0
  16. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/chain/interface.py +0 -0
  17. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/chain/manager.py +0 -0
  18. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/chain/models.py +0 -0
  19. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/chain/rate_limiter.py +0 -0
  20. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/cli.py +0 -0
  21. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/constants.py +0 -0
  22. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/contracts/__init__.py +0 -0
  23. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/contracts/abis/erc20.json +0 -0
  24. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/contracts/abis/multisend.json +0 -0
  25. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/contracts/abis/multisend_call_only.json +0 -0
  26. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/contracts/contract.py +0 -0
  27. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/contracts/erc20.py +0 -0
  28. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/contracts/multisend.py +0 -0
  29. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/db.py +0 -0
  30. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/ipfs.py +0 -0
  31. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/keys.py +0 -0
  32. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/mnemonic.py +0 -0
  33. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/models.py +0 -0
  34. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/monitor.py +0 -0
  35. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/plugins.py +0 -0
  36. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/pricing.py +0 -0
  37. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/secrets.py +0 -0
  38. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/services/__init__.py +0 -0
  39. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/services/account.py +0 -0
  40. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/services/balance.py +0 -0
  41. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/services/plugin.py +0 -0
  42. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/services/safe.py +0 -0
  43. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/services/transaction.py +0 -0
  44. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/services/transfer/__init__.py +0 -0
  45. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/services/transfer/base.py +0 -0
  46. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/services/transfer/erc20.py +0 -0
  47. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/services/transfer/multisend.py +0 -0
  48. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/services/transfer/native.py +0 -0
  49. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/services/transfer/swap.py +0 -0
  50. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/tables.py +0 -0
  51. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/test.py +0 -0
  52. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/tests/test_wallet.py +0 -0
  53. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/types.py +0 -0
  54. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/ui.py +0 -0
  55. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/utils.py +0 -0
  56. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/core/wallet.py +0 -0
  57. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/__init__.py +0 -0
  58. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/gnosis/__init__.py +0 -0
  59. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/gnosis/cow/__init__.py +0 -0
  60. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/gnosis/cow/quotes.py +0 -0
  61. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/gnosis/cow/swap.py +0 -0
  62. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/gnosis/cow/types.py +0 -0
  63. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/gnosis/cow_utils.py +0 -0
  64. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/gnosis/plugin.py +0 -0
  65. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/gnosis/safe.py +0 -0
  66. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/gnosis/tests/test_cow.py +0 -0
  67. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/gnosis/tests/test_safe.py +0 -0
  68. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/__init__.py +0 -0
  69. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/contracts/abis/activity_checker.json +0 -0
  70. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/contracts/abis/mech.json +0 -0
  71. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/contracts/abis/mech_marketplace.json +0 -0
  72. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/contracts/abis/mech_new.json +0 -0
  73. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/contracts/abis/service_manager.json +0 -0
  74. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/contracts/abis/service_registry.json +0 -0
  75. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/contracts/abis/service_registry_token_utility.json +0 -0
  76. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/contracts/abis/staking.json +0 -0
  77. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/contracts/abis/staking_token.json +0 -0
  78. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/contracts/base.py +0 -0
  79. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/contracts/mech.py +0 -0
  80. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/contracts/mech_marketplace.py +0 -0
  81. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/contracts/service.py +0 -0
  82. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/contracts/staking.py +0 -0
  83. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/importer.py +0 -0
  84. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/mech_reference.py +0 -0
  85. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/models.py +0 -0
  86. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/plugin.py +0 -0
  87. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/scripts/test_full_mech_flow.py +0 -0
  88. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/scripts/test_simple_lifecycle.py +0 -0
  89. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/service_manager/__init__.py +0 -0
  90. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/service_manager/base.py +0 -0
  91. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/service_manager/drain.py +0 -0
  92. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/service_manager/lifecycle.py +0 -0
  93. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/service_manager/staking.py +0 -0
  94. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tests/conftest.py +0 -0
  95. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tests/test_importer.py +0 -0
  96. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tests/test_importer_error_handling.py +0 -0
  97. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tests/test_mech_contracts.py +0 -0
  98. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tests/test_olas_contracts.py +0 -0
  99. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tests/test_olas_integration.py +0 -0
  100. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tests/test_olas_models.py +0 -0
  101. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tests/test_olas_view.py +0 -0
  102. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tests/test_olas_view_actions.py +0 -0
  103. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tests/test_olas_view_modals.py +0 -0
  104. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tests/test_plugin.py +0 -0
  105. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tests/test_plugin_full.py +0 -0
  106. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tests/test_service_lifecycle.py +0 -0
  107. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tests/test_service_manager.py +0 -0
  108. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tests/test_service_manager_errors.py +0 -0
  109. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tests/test_service_manager_flows.py +0 -0
  110. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tests/test_service_manager_mech.py +0 -0
  111. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tests/test_service_manager_rewards.py +0 -0
  112. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tests/test_service_manager_validation.py +0 -0
  113. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tests/test_service_staking.py +0 -0
  114. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tests/test_staking_integration.py +0 -0
  115. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tests/test_staking_validation.py +0 -0
  116. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tui/__init__.py +0 -0
  117. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/plugins/olas/tui/olas_view.py +0 -0
  118. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/tools/__init__.py +0 -0
  119. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/tools/check_profile.py +0 -0
  120. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/tools/list_contracts.py +0 -0
  121. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/tools/release.py +0 -0
  122. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/tools/reset_env.py +0 -0
  123. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/tools/reset_tenderly.py +0 -0
  124. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/tools/restore_backup.py +0 -0
  125. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/tools/wallet_check.py +0 -0
  126. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/tui/__init__.py +0 -0
  127. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/tui/app.py +0 -0
  128. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/tui/modals/__init__.py +0 -0
  129. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/tui/modals/base.py +0 -0
  130. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/tui/rpc.py +0 -0
  131. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/tui/screens/__init__.py +0 -0
  132. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/tui/screens/wallets.py +0 -0
  133. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/tui/tests/test_app.py +0 -0
  134. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/tui/tests/test_rpc.py +0 -0
  135. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/tui/tests/test_wallets_refactor.py +0 -0
  136. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/tui/tests/test_widgets.py +0 -0
  137. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/tui/widgets/__init__.py +0 -0
  138. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/tui/widgets/base.py +0 -0
  139. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/tui/workers.py +0 -0
  140. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/web/dependencies.py +0 -0
  141. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/web/models.py +0 -0
  142. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/web/routers/accounts.py +0 -0
  143. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/web/routers/olas/__init__.py +0 -0
  144. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/web/routers/olas/admin.py +0 -0
  145. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/web/routers/olas/funding.py +0 -0
  146. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/web/routers/olas/general.py +0 -0
  147. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/web/routers/olas/services.py +0 -0
  148. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/web/routers/olas/staking.py +0 -0
  149. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/web/routers/state.py +0 -0
  150. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/web/routers/swap.py +0 -0
  151. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/web/routers/transactions.py +0 -0
  152. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/web/server.py +0 -0
  153. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/web/static/app.js +0 -0
  154. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/web/static/index.html +0 -0
  155. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/web/static/style.css +0 -0
  156. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/web/tests/test_web_endpoints.py +0 -0
  157. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/web/tests/test_web_olas.py +0 -0
  158. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/web/tests/test_web_swap.py +0 -0
  159. {iwa-0.0.15 → iwa-0.0.17}/src/iwa/web/tests/test_web_swap_coverage.py +0 -0
  160. {iwa-0.0.15 → iwa-0.0.17}/src/iwa.egg-info/SOURCES.txt +0 -0
  161. {iwa-0.0.15 → iwa-0.0.17}/src/iwa.egg-info/dependency_links.txt +0 -0
  162. {iwa-0.0.15 → iwa-0.0.17}/src/iwa.egg-info/entry_points.txt +0 -0
  163. {iwa-0.0.15 → iwa-0.0.17}/src/iwa.egg-info/requires.txt +0 -0
  164. {iwa-0.0.15 → iwa-0.0.17}/src/iwa.egg-info/top_level.txt +0 -0
  165. {iwa-0.0.15 → iwa-0.0.17}/src/tests/legacy_cow.py +0 -0
  166. {iwa-0.0.15 → iwa-0.0.17}/src/tests/legacy_safe.py +0 -0
  167. {iwa-0.0.15 → iwa-0.0.17}/src/tests/legacy_transaction_retry_logic.py +0 -0
  168. {iwa-0.0.15 → iwa-0.0.17}/src/tests/legacy_tui.py +0 -0
  169. {iwa-0.0.15 → iwa-0.0.17}/src/tests/legacy_wallets_screen.py +0 -0
  170. {iwa-0.0.15 → iwa-0.0.17}/src/tests/legacy_web.py +0 -0
  171. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_account_service.py +0 -0
  172. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_balance_service.py +0 -0
  173. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_chain.py +0 -0
  174. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_chain_interface.py +0 -0
  175. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_chain_interface_coverage.py +0 -0
  176. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_cli.py +0 -0
  177. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_contract.py +0 -0
  178. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_db.py +0 -0
  179. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_drain_coverage.py +0 -0
  180. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_erc20.py +0 -0
  181. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_gnosis_plugin.py +0 -0
  182. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_keys.py +0 -0
  183. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_legacy_wallet.py +0 -0
  184. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_main.py +0 -0
  185. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_migration.py +0 -0
  186. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_mnemonic.py +0 -0
  187. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_modals.py +0 -0
  188. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_models.py +0 -0
  189. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_monitor.py +0 -0
  190. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_multisend.py +0 -0
  191. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_plugin_service.py +0 -0
  192. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_pricing.py +0 -0
  193. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_rate_limiter.py +0 -0
  194. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_reset_tenderly.py +0 -0
  195. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_rpc_rotation.py +0 -0
  196. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_rpc_view.py +0 -0
  197. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_safe_coverage.py +0 -0
  198. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_safe_service.py +0 -0
  199. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_service_manager_integration.py +0 -0
  200. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_service_manager_structure.py +0 -0
  201. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_service_transaction.py +0 -0
  202. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_staking_router.py +0 -0
  203. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_staking_simple.py +0 -0
  204. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_tables.py +0 -0
  205. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_transaction_service.py +0 -0
  206. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_transfer_multisend.py +0 -0
  207. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_transfer_native.py +0 -0
  208. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_transfer_security.py +0 -0
  209. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_transfer_structure.py +0 -0
  210. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_transfer_swap_unit.py +0 -0
  211. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_ui_coverage.py +0 -0
  212. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_utils.py +0 -0
  213. {iwa-0.0.15 → iwa-0.0.17}/src/tests/test_workers.py +0 -0
  214. {iwa-0.0.15 → iwa-0.0.17}/src/tools/create_and_stake_service.py +0 -0
  215. {iwa-0.0.15 → iwa-0.0.17}/src/tools/verify_drain.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iwa
3
- Version: 0.0.15
3
+ Version: 0.0.17
4
4
  Summary: A secure, modular, and plugin-based framework for crypto agents and ops
5
5
  Requires-Python: <4.0,>=3.12
6
6
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "iwa"
3
- version = "0.0.15"
3
+ version = "0.0.17"
4
4
  description = "A secure, modular, and plugin-based framework for crypto agents and ops"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12,<4.0"
@@ -71,7 +71,7 @@ where = ["src"]
71
71
 
72
72
  [tool.ruff]
73
73
  line-length = 100
74
- target-version = "0.0.15"
74
+ target-version = "0.0.17"
75
75
  fix = true
76
76
 
77
77
  [tool.ruff.lint]
@@ -51,11 +51,21 @@ OLAS_CONTRACTS: Dict[str, Dict[str, EthereumAddress]] = {
51
51
  "0xa45E64d13A30a51b91ae0eb182e88a40e9b18eD8"
52
52
  ),
53
53
  "OLAS_SERVICE_MANAGER": EthereumAddress("0x068a4f0946cF8c7f9C1B58a3b5243Ac8843bf473"),
54
- # Legacy mech - used by TRADER staking contracts for liveness
54
+ # Legacy mech - used by NON-MM TRADER staking contracts (e.g., "Expert X (Yk OLAS)")
55
+ # Activity checker calls agentMech.getRequestsCount(multisig) to count requests.
55
56
  "OLAS_MECH": EthereumAddress("0x77af31De935740567Cf4fF1986D04B2c964A786a"),
56
- # NEW Marketplace (v2) - no staking support yet
57
+ # NEW Marketplace (v2) - used by MM staking contracts (e.g., "Expert X MM (Yk OLAS)")
58
+ # Services staked in "Expert X MM" contracts MUST use marketplace requests.
59
+ # Legacy mech requests will NOT be counted by the activity checker.
57
60
  "OLAS_MECH_MARKETPLACE": EthereumAddress("0x735FAAb1c4Ec41128c367AFb5c3baC73509f70bB"),
58
- # OLD Marketplace (v1) - used by Pearl Beta Mech Marketplace staking
61
+ # Default priority mech for marketplace requests (from olas-operate-middleware)
62
+ # This is the mech that will process requests sent via the marketplace.
63
+ # Source: https://github.com/valory-xyz/olas-operate-middleware/blob/main/operate/ledger/profiles.py
64
+ # DEFAULT_PRIORITY_MECH["0x735FAAb1c..."] = ("0xC05e7412...", 2182)
65
+ "OLAS_MECH_MARKETPLACE_PRIORITY": EthereumAddress(
66
+ "0xC05e7412439bD7e91730a6880E18d5D5873F632C"
67
+ ),
68
+ # OLD Marketplace (v1) - legacy, kept for reference
59
69
  "OLAS_MECH_MARKETPLACE_OLD": EthereumAddress("0x4554fE75c1f5576c1d7F765B2A036c199Adae329"),
60
70
  },
61
71
  "ethereum": {
@@ -0,0 +1,155 @@
1
+ """Activity checker contract interaction.
2
+
3
+ The MechActivityChecker contract tracks liveness for staked services by monitoring:
4
+ - Safe multisig transaction nonces
5
+ - Mech request counts
6
+
7
+ The liveness check (isRatioPass) verifies that the service is making enough mech
8
+ requests relative to the time elapsed since the last checkpoint.
9
+ """
10
+
11
+ from typing import Tuple
12
+
13
+ from web3 import Web3
14
+
15
+ from iwa.core.constants import DEFAULT_MECH_CONTRACT_ADDRESS
16
+ from iwa.core.types import EthereumAddress
17
+ from iwa.plugins.olas.contracts.base import OLAS_ABI_PATH, ContractInstance
18
+
19
+
20
+ class ActivityCheckerContract(ContractInstance):
21
+ """Class to interact with the MechActivityChecker contract.
22
+
23
+ This contract tracks mech request activity for staked services and determines
24
+ if they meet the liveness requirements for staking rewards.
25
+
26
+ The getMultisigNonces() function returns an array with two values:
27
+ - nonces[0]: Safe multisig nonce (total transaction count)
28
+ - nonces[1]: Mech requests count (from AgentMech.getRequestsCount)
29
+
30
+ The isRatioPass() function checks if:
31
+ 1. diffRequestsCounts <= diffNonces (requests can't exceed txs)
32
+ 2. ratio = (diffRequestsCounts * 1e18) / time >= livenessRatio
33
+ """
34
+
35
+ name = "activity_checker"
36
+ abi_path = OLAS_ABI_PATH / "activity_checker.json"
37
+
38
+ def __init__(self, address: EthereumAddress, chain_name: str = "gnosis"):
39
+ """Initialize ActivityCheckerContract.
40
+
41
+ Args:
42
+ address: The activity checker contract address.
43
+ chain_name: The chain name (default: gnosis).
44
+
45
+ """
46
+ super().__init__(address, chain_name=chain_name)
47
+
48
+ # Check for marketplace-aware checker
49
+ try:
50
+ mech_mp_function = getattr(self.contract.functions, "mechMarketplace", None)
51
+ self.mech_marketplace = mech_mp_function().call() if mech_mp_function else None
52
+ except Exception:
53
+ self.mech_marketplace = None
54
+
55
+ # Get the mech address this checker tracks (legacy or priority mech)
56
+ try:
57
+ agent_mech_function = getattr(self.contract.functions, "agentMech", None)
58
+ self.agent_mech = (
59
+ agent_mech_function().call() if agent_mech_function else DEFAULT_MECH_CONTRACT_ADDRESS
60
+ )
61
+ except Exception:
62
+ self.agent_mech = DEFAULT_MECH_CONTRACT_ADDRESS
63
+
64
+ # Get liveness ratio (requests per second * 1e18)
65
+ try:
66
+ self.liveness_ratio = self.contract.functions.livenessRatio().call()
67
+ except Exception:
68
+ self.liveness_ratio = 0
69
+
70
+ def get_multisig_nonces(self, multisig: EthereumAddress) -> Tuple[int, int]:
71
+ """Get the nonces for a multisig address.
72
+
73
+ This method reads directly from the source contracts to ensure fresh data
74
+ and compatibility with Legacy/MM contracts.
75
+
76
+ Args:
77
+ multisig: The multisig address to check.
78
+
79
+ Returns:
80
+ Tuple of (safe_nonce, mech_requests_count):
81
+ - safe_nonce: Total Safe transaction count
82
+ - mech_requests_count: Total mech requests made
83
+
84
+ """
85
+ # 1. Get Safe Nonce
86
+ safe_nonce = 0
87
+ try:
88
+ # Minimal ABI for Safe nonce
89
+ safe_abi = [{"name": "nonce", "type": "function", "inputs": [], "outputs": [{"type": "uint256"}]}]
90
+ safe_contract = self.chain_interface.web3._web3.eth.contract(
91
+ address=Web3.to_checksum_address(multisig), abi=safe_abi
92
+ )
93
+ safe_nonce = safe_contract.functions.nonce().call()
94
+ except Exception as e:
95
+ # Fallback or log error? If safe read fails, something is very wrong.
96
+ # But we don't want to crash the whole status check if possible.
97
+ # For now, let's log and keep 0 or re-raise if critical.
98
+ # safe_nonce is critical for liveness check (diffNonces).
99
+ from loguru import logger
100
+ logger.warning(f"Failed to read Safe nonce for {multisig}: {e}")
101
+
102
+ # 2. Get Mech Requests Count
103
+ mech_requests = 0
104
+
105
+ if self.mech_marketplace:
106
+ # Case A: Marketplace (MM)
107
+ try:
108
+ # Minimal ABI for Marketplace mapRequestCounts
109
+ mp_abi = [{"name": "mapRequestCounts", "type": "function", "inputs": [{"type": "address"}], "outputs": [{"type": "uint256"}]}]
110
+ mp_contract = self.chain_interface.web3._web3.eth.contract(
111
+ address=Web3.to_checksum_address(self.mech_marketplace), abi=mp_abi
112
+ )
113
+ mech_requests = mp_contract.functions.mapRequestCounts(multisig).call()
114
+ except Exception as e:
115
+ from loguru import logger
116
+ logger.warning(f"Failed to read Marketplace requests for {multisig}: {e}")
117
+ else:
118
+ # Case B: Legacy (AgentMech)
119
+ try:
120
+ # Minimal ABI for AgentMech getRequestsCount
121
+ mech_abi = [{"name": "getRequestsCount", "type": "function", "inputs": [{"type": "address"}], "outputs": [{"type": "uint256"}]}]
122
+ mech_contract = self.chain_interface.web3._web3.eth.contract(
123
+ address=Web3.to_checksum_address(self.agent_mech), abi=mech_abi
124
+ )
125
+ mech_requests = mech_contract.functions.getRequestsCount(multisig).call()
126
+ except Exception as e:
127
+ from loguru import logger
128
+ logger.warning(f"Failed to read AgentMech requests for {multisig}: {e}")
129
+
130
+ return (safe_nonce, mech_requests)
131
+
132
+ def is_ratio_pass(
133
+ self,
134
+ current_nonces: Tuple[int, int],
135
+ last_nonces: Tuple[int, int],
136
+ ts_diff: int,
137
+ ) -> bool:
138
+ """Check if the liveness ratio requirement is passed.
139
+
140
+ The formula checks:
141
+ 1. diffRequestsCounts <= diffNonces (mech requests can't exceed total txs)
142
+ 2. ratio = (diffRequestsCounts * 1e18) / ts_diff >= livenessRatio
143
+
144
+ Args:
145
+ current_nonces: Current (safe_nonce, mech_requests_count).
146
+ last_nonces: Nonces at last checkpoint (safe_nonce, mech_requests_count).
147
+ ts_diff: Time difference in seconds since last checkpoint.
148
+
149
+ Returns:
150
+ True if liveness requirements are met.
151
+
152
+ """
153
+ return self.contract.functions.isRatioPass(
154
+ list(current_nonces), list(last_nonces), ts_diff
155
+ ).call()
@@ -1,4 +1,29 @@
1
- """Mech manager mixin."""
1
+ """Mech manager mixin.
2
+
3
+ This module handles sending mech requests for OLAS services. There are TWO
4
+ distinct flows for mech requests, and the correct one MUST be used based on
5
+ the service's staking contract:
6
+
7
+ 1. **Legacy Mech Flow** (use_marketplace=False):
8
+ - Sends requests directly to the legacy mech contract (0x77af31De...)
9
+ - Used by NON-MM staking contracts (e.g., "Expert X (Yk OLAS)")
10
+ - Activity checker calls `agentMech.getRequestsCount(multisig)` to count
11
+
12
+ 2. **Marketplace Flow** (use_marketplace=True):
13
+ - Sends requests via MechMarketplace contract (0x735FAAb1c...)
14
+ - Used by MM staking contracts (e.g., "Expert X MM (Yk OLAS)")
15
+ - Activity checker calls `mechMarketplace.mapRequestCounts(multisig)` to count
16
+ - Requires a priority_mech that is registered on the marketplace
17
+ - Default priority_mech from olas-operate-middleware: 0xC05e7412...
18
+
19
+ **IMPORTANT**: If a service is staked in an MM contract but sends legacy mech
20
+ requests, those requests will NOT be counted by the activity checker, and the
21
+ service will not receive staking rewards.
22
+
23
+ The `get_marketplace_config()` method automatically detects which flow to use
24
+ by checking if the staking contract's activity checker has a `mechMarketplace`
25
+ field set to a non-zero address.
26
+ """
2
27
 
3
28
  from typing import Optional
4
29
 
@@ -17,12 +42,60 @@ from iwa.plugins.olas.contracts.mech_marketplace import MechMarketplaceContract
17
42
  class MechManagerMixin:
18
43
  """Mixin for Mech interactions."""
19
44
 
45
+ def get_marketplace_config(self) -> tuple:
46
+ """Check if current service requires marketplace mech requests.
47
+
48
+ Queries the staking contract's activityChecker to determine if it
49
+ tracks marketplace requests.
50
+
51
+ Returns:
52
+ Tuple of (use_marketplace, marketplace_address, priority_mech):
53
+ - use_marketplace: True if marketplace requests are required.
54
+ - marketplace_address: Address of the mech marketplace (if applicable).
55
+ - priority_mech: Address of the priority mech (if applicable).
56
+
57
+ """
58
+ from iwa.core.constants import ZERO_ADDRESS
59
+
60
+ if not self.service or not self.service.staking_contract_address:
61
+ return (False, None, None)
62
+
63
+ try:
64
+ # Get staking contract with its activity checker
65
+ from iwa.plugins.olas.contracts.staking import StakingContract
66
+
67
+ staking = StakingContract(
68
+ self.service.staking_contract_address, chain_name=self.chain_name
69
+ )
70
+
71
+ # StakingContract has activity_checker attribute set in __init__
72
+ checker = staking.activity_checker
73
+
74
+ if checker.mech_marketplace and checker.mech_marketplace != ZERO_ADDRESS:
75
+ # Use the default marketplace priority mech from constants
76
+ from iwa.plugins.olas.constants import OLAS_CONTRACTS
77
+
78
+ protocol_contracts = OLAS_CONTRACTS.get(self.chain_name, {})
79
+ priority_mech = protocol_contracts.get("OLAS_MECH_MARKETPLACE_PRIORITY")
80
+
81
+ logger.info(
82
+ f"[MECH] Service {self.service.service_id} requires marketplace requests "
83
+ f"(marketplace={checker.mech_marketplace}, priority_mech={priority_mech})"
84
+ )
85
+ return (True, checker.mech_marketplace, priority_mech)
86
+
87
+ return (False, None, None)
88
+
89
+ except Exception as e:
90
+ logger.debug(f"[MECH] Failed to detect marketplace config: {e}")
91
+ return (False, None, None)
92
+
20
93
  def send_mech_request(
21
94
  self,
22
95
  data: bytes,
23
96
  value: Optional[int] = None,
24
97
  mech_address: Optional[str] = None,
25
- use_marketplace: bool = False,
98
+ use_marketplace: Optional[bool] = None,
26
99
  use_new_abi: bool = False,
27
100
  priority_mech: Optional[str] = None,
28
101
  max_delivery_rate: Optional[int] = None,
@@ -37,6 +110,7 @@ class MechManagerMixin:
37
110
  value: Payment value in wei. For marketplace, should match mech's maxDeliveryRate.
38
111
  mech_address: Address of the Mech contract (for legacy/direct flow).
39
112
  use_marketplace: Whether to use the Mech Marketplace flow.
113
+ If None, auto-detects based on staking contract.
40
114
  use_new_abi: Whether to use new ABI for legacy flow.
41
115
  priority_mech: Priority mech address (required for marketplace).
42
116
  max_delivery_rate: Max delivery rate in wei (for marketplace). If None, uses value.
@@ -59,6 +133,14 @@ class MechManagerMixin:
59
133
  logger.error(f"Service {service_id} has no multisig address")
60
134
  return None
61
135
 
136
+ # Auto-detect marketplace requirement if not explicitly specified
137
+ if use_marketplace is None:
138
+ use_marketplace, detected_marketplace, detected_priority_mech = (
139
+ self.get_marketplace_config()
140
+ )
141
+ if use_marketplace:
142
+ priority_mech = priority_mech or detected_priority_mech
143
+
62
144
  if use_marketplace:
63
145
  return self._send_marketplace_mech_request(
64
146
  data=data,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iwa
3
- Version: 0.0.15
3
+ Version: 0.0.17
4
4
  Summary: A secure, modular, and plugin-based framework for crypto agents and ops
5
5
  Requires-Python: <4.0,>=3.12
6
6
  Description-Content-Type: text/markdown
@@ -1,93 +0,0 @@
1
- """Activity checker contract interaction.
2
-
3
- The MechActivityChecker contract tracks liveness for staked services by monitoring:
4
- - Safe multisig transaction nonces
5
- - Mech request counts
6
-
7
- The liveness check (isRatioPass) verifies that the service is making enough mech
8
- requests relative to the time elapsed since the last checkpoint.
9
- """
10
-
11
- from typing import Tuple
12
-
13
- from iwa.core.constants import DEFAULT_MECH_CONTRACT_ADDRESS
14
- from iwa.core.types import EthereumAddress
15
- from iwa.plugins.olas.contracts.base import OLAS_ABI_PATH, ContractInstance
16
-
17
-
18
- class ActivityCheckerContract(ContractInstance):
19
- """Class to interact with the MechActivityChecker contract.
20
-
21
- This contract tracks mech request activity for staked services and determines
22
- if they meet the liveness requirements for staking rewards.
23
-
24
- The getMultisigNonces() function returns an array with two values:
25
- - nonces[0]: Safe multisig nonce (total transaction count)
26
- - nonces[1]: Mech requests count (from AgentMech.getRequestsCount)
27
-
28
- The isRatioPass() function checks if:
29
- 1. diffRequestsCounts <= diffNonces (requests can't exceed txs)
30
- 2. ratio = (diffRequestsCounts * 1e18) / time >= livenessRatio
31
- """
32
-
33
- name = "activity_checker"
34
- abi_path = OLAS_ABI_PATH / "activity_checker.json"
35
-
36
- def __init__(self, address: EthereumAddress, chain_name: str = "gnosis"):
37
- """Initialize ActivityCheckerContract.
38
-
39
- Args:
40
- address: The activity checker contract address.
41
- chain_name: The chain name (default: gnosis).
42
-
43
- """
44
- super().__init__(address, chain_name=chain_name)
45
-
46
- # Get the mech address this checker tracks
47
- agent_mech_function = getattr(self.contract.functions, "agentMech", None)
48
- self.agent_mech = (
49
- agent_mech_function().call() if agent_mech_function else DEFAULT_MECH_CONTRACT_ADDRESS
50
- )
51
-
52
- # Get liveness ratio (requests per second * 1e18)
53
- self.liveness_ratio = self.contract.functions.livenessRatio().call()
54
-
55
- def get_multisig_nonces(self, multisig: EthereumAddress) -> Tuple[int, int]:
56
- """Get the nonces for a multisig address.
57
-
58
- Args:
59
- multisig: The multisig address to check.
60
-
61
- Returns:
62
- Tuple of (safe_nonce, mech_requests_count):
63
- - safe_nonce: Total Safe transaction count
64
- - mech_requests_count: Total mech requests made
65
-
66
- """
67
- nonces = self.contract.functions.getMultisigNonces(multisig).call()
68
- return (nonces[0], nonces[1])
69
-
70
- def is_ratio_pass(
71
- self,
72
- current_nonces: Tuple[int, int],
73
- last_nonces: Tuple[int, int],
74
- ts_diff: int,
75
- ) -> bool:
76
- """Check if the liveness ratio requirement is passed.
77
-
78
- The formula checks:
79
- 1. diffRequestsCounts <= diffNonces (mech requests can't exceed total txs)
80
- 2. ratio = (diffRequestsCounts * 1e18) / ts_diff >= livenessRatio
81
-
82
- Args:
83
- current_nonces: Current (safe_nonce, mech_requests_count).
84
- last_nonces: Nonces at last checkpoint (safe_nonce, mech_requests_count).
85
- ts_diff: Time difference in seconds since last checkpoint.
86
-
87
- Returns:
88
- True if liveness requirements are met.
89
-
90
- """
91
- return self.contract.functions.isRatioPass(
92
- list(current_nonces), list(last_nonces), ts_diff
93
- ).call()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes