iwa 0.0.17__tar.gz → 0.0.19__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 (217) hide show
  1. {iwa-0.0.17/src/iwa.egg-info → iwa-0.0.19}/PKG-INFO +1 -1
  2. {iwa-0.0.17 → iwa-0.0.19}/pyproject.toml +2 -2
  3. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/chain/interface.py +1 -65
  4. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/pricing.py +1 -4
  5. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/services/transaction.py +72 -70
  6. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/services/transfer/erc20.py +8 -0
  7. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/services/transfer/native.py +47 -13
  8. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/constants.py +41 -39
  9. iwa-0.0.19/src/iwa/plugins/olas/contracts/abis/mech_marketplace_v1.json +828 -0
  10. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/contracts/activity_checker.py +2 -51
  11. iwa-0.0.19/src/iwa/plugins/olas/contracts/mech_marketplace_v1.py +68 -0
  12. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/scripts/test_full_mech_flow.py +1 -1
  13. iwa-0.0.19/src/iwa/plugins/olas/service_manager/mech.py +622 -0
  14. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/tools/reset_tenderly.py +2 -2
  15. {iwa-0.0.17 → iwa-0.0.19/src/iwa.egg-info}/PKG-INFO +1 -1
  16. {iwa-0.0.17 → iwa-0.0.19}/src/iwa.egg-info/SOURCES.txt +2 -0
  17. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_chain.py +2 -97
  18. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_legacy_wallet.py +6 -6
  19. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_service_transaction.py +23 -8
  20. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_staking_router.py +14 -6
  21. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_transaction_service.py +20 -6
  22. iwa-0.0.17/src/iwa/plugins/olas/service_manager/mech.py +0 -404
  23. {iwa-0.0.17 → iwa-0.0.19}/LICENSE +0 -0
  24. {iwa-0.0.17 → iwa-0.0.19}/README.md +0 -0
  25. {iwa-0.0.17 → iwa-0.0.19}/setup.cfg +0 -0
  26. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/__init__.py +0 -0
  27. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/__main__.py +0 -0
  28. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/__init__.py +0 -0
  29. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/chain/__init__.py +0 -0
  30. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/chain/errors.py +0 -0
  31. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/chain/manager.py +0 -0
  32. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/chain/models.py +0 -0
  33. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/chain/rate_limiter.py +0 -0
  34. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/cli.py +0 -0
  35. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/constants.py +0 -0
  36. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/contracts/__init__.py +0 -0
  37. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/contracts/abis/erc20.json +0 -0
  38. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/contracts/abis/multisend.json +0 -0
  39. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/contracts/abis/multisend_call_only.json +0 -0
  40. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/contracts/contract.py +0 -0
  41. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/contracts/erc20.py +0 -0
  42. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/contracts/multisend.py +0 -0
  43. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/db.py +0 -0
  44. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/ipfs.py +0 -0
  45. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/keys.py +0 -0
  46. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/mnemonic.py +0 -0
  47. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/models.py +0 -0
  48. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/monitor.py +0 -0
  49. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/plugins.py +0 -0
  50. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/secrets.py +0 -0
  51. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/services/__init__.py +0 -0
  52. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/services/account.py +0 -0
  53. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/services/balance.py +0 -0
  54. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/services/plugin.py +0 -0
  55. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/services/safe.py +0 -0
  56. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/services/transfer/__init__.py +0 -0
  57. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/services/transfer/base.py +0 -0
  58. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/services/transfer/multisend.py +0 -0
  59. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/services/transfer/swap.py +0 -0
  60. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/tables.py +0 -0
  61. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/test.py +0 -0
  62. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/tests/test_wallet.py +0 -0
  63. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/types.py +0 -0
  64. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/ui.py +0 -0
  65. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/utils.py +0 -0
  66. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/core/wallet.py +0 -0
  67. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/__init__.py +0 -0
  68. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/gnosis/__init__.py +0 -0
  69. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/gnosis/cow/__init__.py +0 -0
  70. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/gnosis/cow/quotes.py +0 -0
  71. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/gnosis/cow/swap.py +0 -0
  72. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/gnosis/cow/types.py +0 -0
  73. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/gnosis/cow_utils.py +0 -0
  74. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/gnosis/plugin.py +0 -0
  75. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/gnosis/safe.py +0 -0
  76. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/gnosis/tests/test_cow.py +0 -0
  77. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/gnosis/tests/test_safe.py +0 -0
  78. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/__init__.py +0 -0
  79. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/contracts/abis/activity_checker.json +0 -0
  80. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/contracts/abis/mech.json +0 -0
  81. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/contracts/abis/mech_marketplace.json +0 -0
  82. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/contracts/abis/mech_new.json +0 -0
  83. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/contracts/abis/service_manager.json +0 -0
  84. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/contracts/abis/service_registry.json +0 -0
  85. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/contracts/abis/service_registry_token_utility.json +0 -0
  86. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/contracts/abis/staking.json +0 -0
  87. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/contracts/abis/staking_token.json +0 -0
  88. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/contracts/base.py +0 -0
  89. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/contracts/mech.py +0 -0
  90. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/contracts/mech_marketplace.py +0 -0
  91. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/contracts/service.py +0 -0
  92. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/contracts/staking.py +0 -0
  93. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/importer.py +0 -0
  94. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/mech_reference.py +0 -0
  95. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/models.py +0 -0
  96. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/plugin.py +0 -0
  97. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/scripts/test_simple_lifecycle.py +0 -0
  98. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/service_manager/__init__.py +0 -0
  99. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/service_manager/base.py +0 -0
  100. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/service_manager/drain.py +0 -0
  101. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/service_manager/lifecycle.py +0 -0
  102. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/service_manager/staking.py +0 -0
  103. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tests/conftest.py +0 -0
  104. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tests/test_importer.py +0 -0
  105. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tests/test_importer_error_handling.py +0 -0
  106. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tests/test_mech_contracts.py +0 -0
  107. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tests/test_olas_contracts.py +0 -0
  108. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tests/test_olas_integration.py +0 -0
  109. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tests/test_olas_models.py +0 -0
  110. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tests/test_olas_view.py +0 -0
  111. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tests/test_olas_view_actions.py +0 -0
  112. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tests/test_olas_view_modals.py +0 -0
  113. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tests/test_plugin.py +0 -0
  114. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tests/test_plugin_full.py +0 -0
  115. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tests/test_service_lifecycle.py +0 -0
  116. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tests/test_service_manager.py +0 -0
  117. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tests/test_service_manager_errors.py +0 -0
  118. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tests/test_service_manager_flows.py +0 -0
  119. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tests/test_service_manager_mech.py +0 -0
  120. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tests/test_service_manager_rewards.py +0 -0
  121. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tests/test_service_manager_validation.py +0 -0
  122. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tests/test_service_staking.py +0 -0
  123. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tests/test_staking_integration.py +0 -0
  124. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tests/test_staking_validation.py +0 -0
  125. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tui/__init__.py +0 -0
  126. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/plugins/olas/tui/olas_view.py +0 -0
  127. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/tools/__init__.py +0 -0
  128. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/tools/check_profile.py +0 -0
  129. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/tools/list_contracts.py +0 -0
  130. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/tools/release.py +0 -0
  131. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/tools/reset_env.py +0 -0
  132. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/tools/restore_backup.py +0 -0
  133. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/tools/wallet_check.py +0 -0
  134. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/tui/__init__.py +0 -0
  135. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/tui/app.py +0 -0
  136. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/tui/modals/__init__.py +0 -0
  137. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/tui/modals/base.py +0 -0
  138. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/tui/rpc.py +0 -0
  139. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/tui/screens/__init__.py +0 -0
  140. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/tui/screens/wallets.py +0 -0
  141. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/tui/tests/test_app.py +0 -0
  142. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/tui/tests/test_rpc.py +0 -0
  143. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/tui/tests/test_wallets_refactor.py +0 -0
  144. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/tui/tests/test_widgets.py +0 -0
  145. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/tui/widgets/__init__.py +0 -0
  146. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/tui/widgets/base.py +0 -0
  147. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/tui/workers.py +0 -0
  148. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/web/dependencies.py +0 -0
  149. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/web/models.py +0 -0
  150. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/web/routers/accounts.py +0 -0
  151. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/web/routers/olas/__init__.py +0 -0
  152. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/web/routers/olas/admin.py +0 -0
  153. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/web/routers/olas/funding.py +0 -0
  154. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/web/routers/olas/general.py +0 -0
  155. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/web/routers/olas/services.py +0 -0
  156. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/web/routers/olas/staking.py +0 -0
  157. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/web/routers/state.py +0 -0
  158. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/web/routers/swap.py +0 -0
  159. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/web/routers/transactions.py +0 -0
  160. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/web/server.py +0 -0
  161. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/web/static/app.js +0 -0
  162. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/web/static/index.html +0 -0
  163. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/web/static/style.css +0 -0
  164. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/web/tests/test_web_endpoints.py +0 -0
  165. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/web/tests/test_web_olas.py +0 -0
  166. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/web/tests/test_web_swap.py +0 -0
  167. {iwa-0.0.17 → iwa-0.0.19}/src/iwa/web/tests/test_web_swap_coverage.py +0 -0
  168. {iwa-0.0.17 → iwa-0.0.19}/src/iwa.egg-info/dependency_links.txt +0 -0
  169. {iwa-0.0.17 → iwa-0.0.19}/src/iwa.egg-info/entry_points.txt +0 -0
  170. {iwa-0.0.17 → iwa-0.0.19}/src/iwa.egg-info/requires.txt +0 -0
  171. {iwa-0.0.17 → iwa-0.0.19}/src/iwa.egg-info/top_level.txt +0 -0
  172. {iwa-0.0.17 → iwa-0.0.19}/src/tests/legacy_cow.py +0 -0
  173. {iwa-0.0.17 → iwa-0.0.19}/src/tests/legacy_safe.py +0 -0
  174. {iwa-0.0.17 → iwa-0.0.19}/src/tests/legacy_transaction_retry_logic.py +0 -0
  175. {iwa-0.0.17 → iwa-0.0.19}/src/tests/legacy_tui.py +0 -0
  176. {iwa-0.0.17 → iwa-0.0.19}/src/tests/legacy_wallets_screen.py +0 -0
  177. {iwa-0.0.17 → iwa-0.0.19}/src/tests/legacy_web.py +0 -0
  178. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_account_service.py +0 -0
  179. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_balance_service.py +0 -0
  180. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_chain_interface.py +0 -0
  181. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_chain_interface_coverage.py +0 -0
  182. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_cli.py +0 -0
  183. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_contract.py +0 -0
  184. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_db.py +0 -0
  185. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_drain_coverage.py +0 -0
  186. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_erc20.py +0 -0
  187. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_gnosis_plugin.py +0 -0
  188. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_keys.py +0 -0
  189. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_main.py +0 -0
  190. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_migration.py +0 -0
  191. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_mnemonic.py +0 -0
  192. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_modals.py +0 -0
  193. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_models.py +0 -0
  194. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_monitor.py +0 -0
  195. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_multisend.py +0 -0
  196. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_plugin_service.py +0 -0
  197. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_pricing.py +0 -0
  198. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_rate_limiter.py +0 -0
  199. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_reset_tenderly.py +0 -0
  200. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_rpc_rotation.py +0 -0
  201. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_rpc_view.py +0 -0
  202. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_safe_coverage.py +0 -0
  203. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_safe_service.py +0 -0
  204. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_service_manager_integration.py +0 -0
  205. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_service_manager_structure.py +0 -0
  206. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_staking_simple.py +0 -0
  207. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_tables.py +0 -0
  208. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_transfer_multisend.py +0 -0
  209. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_transfer_native.py +0 -0
  210. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_transfer_security.py +0 -0
  211. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_transfer_structure.py +0 -0
  212. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_transfer_swap_unit.py +0 -0
  213. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_ui_coverage.py +0 -0
  214. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_utils.py +0 -0
  215. {iwa-0.0.17 → iwa-0.0.19}/src/tests/test_workers.py +0 -0
  216. {iwa-0.0.17 → iwa-0.0.19}/src/tools/create_and_stake_service.py +0 -0
  217. {iwa-0.0.17 → iwa-0.0.19}/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.17
3
+ Version: 0.0.19
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.17"
3
+ version = "0.0.19"
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.17"
74
+ target-version = "0.0.19"
75
75
  fix = true
76
76
 
77
77
  [tool.ruff.lint]
@@ -2,9 +2,8 @@
2
2
 
3
3
  import threading
4
4
  import time
5
- from typing import Callable, Dict, Optional, Tuple, TypeVar, Union
5
+ from typing import Callable, Dict, Optional, TypeVar, Union
6
6
 
7
- from eth_account.datastructures import SignedTransaction
8
7
  from web3 import Web3
9
8
 
10
9
  from iwa.core.chain.errors import TenderlyQuotaExceededError, sanitize_rpc_url
@@ -449,69 +448,6 @@ class ChainInterface:
449
448
 
450
449
  return False
451
450
 
452
- def send_native_transfer(
453
- self,
454
- from_address: EthereumAddress,
455
- to_address: EthereumAddress,
456
- value_wei: int,
457
- sign_callback: Callable[[dict], SignedTransaction],
458
- ) -> Tuple[bool, Optional[str]]:
459
- """Send native currency transaction with retry logic."""
460
-
461
- def _do_transfer() -> Tuple[bool, Optional[str]]:
462
- tx = {
463
- "from": from_address,
464
- "to": to_address,
465
- "value": value_wei,
466
- "nonce": self.web3.eth.get_transaction_count(from_address),
467
- "chainId": self.chain.chain_id,
468
- }
469
-
470
- balance_wei = self.get_native_balance_wei(from_address)
471
- gas_price = self.web3.eth.gas_price
472
- gas_estimate = self.web3.eth.estimate_gas(tx)
473
- required_wei = value_wei + (gas_estimate * gas_price)
474
-
475
- if balance_wei < required_wei:
476
- logger.error(
477
- f"Insufficient balance. "
478
- f"Balance: {self.web3.from_wei(balance_wei, 'ether'):.4f} "
479
- f"{self.chain.native_currency}, "
480
- f"Required: {self.web3.from_wei(required_wei, 'ether'):.4f} "
481
- f"{self.chain.native_currency}"
482
- )
483
- return False, None
484
-
485
- tx["gas"] = gas_estimate
486
- tx["gasPrice"] = gas_price
487
-
488
- signed_tx = sign_callback(tx)
489
- txn_hash = self.web3.eth.send_raw_transaction(signed_tx.raw_transaction)
490
- receipt = self.web3.eth.wait_for_transaction_receipt(txn_hash)
491
-
492
- status = getattr(receipt, "status", None)
493
- if status is None and isinstance(receipt, dict):
494
- status = receipt.get("status")
495
-
496
- if receipt and status == 1:
497
- self.wait_for_no_pending_tx(from_address)
498
- logger.info(f"Transaction sent successfully. Tx Hash: {txn_hash.hex()}")
499
- # Check Tenderly block limit after each successful transaction
500
- self.check_block_limit()
501
- return True, receipt["transactionHash"].hex()
502
-
503
- logger.error("Transaction failed (status != 1)")
504
- return False, None
505
-
506
- try:
507
- return self.with_retry(
508
- _do_transfer,
509
- operation_name=f"native_transfer to {str(to_address)[:10]}...",
510
- )
511
- except Exception as e:
512
- logger.exception(f"Native transfer failed: {e}")
513
- return False, None
514
-
515
451
  def get_token_address(self, token_name: str) -> Optional[EthereumAddress]:
516
452
  """Get token address by name"""
517
453
  return self.chain.get_token_address(token_name)
@@ -19,7 +19,6 @@ class PriceService:
19
19
  """Service to fetch token prices from CoinGecko."""
20
20
 
21
21
  BASE_URL = "https://api.coingecko.com/api/v3"
22
- DEMO_URL = "https://demo-api.coingecko.com/api/v3"
23
22
 
24
23
  def __init__(self):
25
24
  """Initialize PriceService."""
@@ -60,9 +59,7 @@ class PriceService:
60
59
  max_retries = 2
61
60
  for attempt in range(max_retries + 1):
62
61
  try:
63
- # Use demo URL if API key is present, otherwise standard URL
64
- # NOTE: Demo URL is significantly more reliable for demo keys
65
- base_url = self.DEMO_URL if self.api_key else self.BASE_URL
62
+ base_url = self.BASE_URL
66
63
  url = f"{base_url}/simple/price"
67
64
  params = {"ids": token_id, "vs_currencies": vs_currency}
68
65
  headers = {}
@@ -1,6 +1,5 @@
1
1
  """Transaction service module."""
2
2
 
3
- import time
4
3
  from typing import TYPE_CHECKING, Dict, List, Optional, Tuple
5
4
 
6
5
  from loguru import logger
@@ -31,32 +30,37 @@ class TransferLogger:
31
30
  self.account_service = account_service
32
31
  self.chain_interface = chain_interface
33
32
 
34
- def log_transfers(self, receipt: Dict, tx: Dict) -> None:
33
+ def log_transfers(self, receipt: Dict) -> None:
35
34
  """Log all transfers (ERC20 and native) from a transaction receipt.
36
35
 
37
36
  Args:
38
37
  receipt: Transaction receipt containing logs.
39
- tx: Original transaction dict.
40
38
 
41
39
  """
42
- # Log native value transfer if present
43
- native_value = tx.get("value", 0)
44
- if native_value and int(native_value) > 0:
45
- self._log_native_transfer(tx, native_value)
40
+ # Get the original transaction to check for native value transfer
41
+ tx_hash = receipt.get("transactionHash") or getattr(receipt, "transactionHash", None)
42
+ if tx_hash:
43
+ try:
44
+ tx = self.chain_interface.web3.eth.get_transaction(tx_hash)
45
+ native_value = getattr(tx, "value", 0) or tx.get("value", 0) if isinstance(tx, dict) else getattr(tx, "value", 0)
46
+ if native_value and int(native_value) > 0:
47
+ from_addr = getattr(tx, "from", "") if hasattr(tx, "from") else tx.get("from", "")
48
+ # Handle AttributeDict's special 'from' attribute
49
+ if not from_addr and hasattr(tx, "__getitem__"):
50
+ from_addr = tx["from"]
51
+ to_addr = getattr(tx, "to", "") or (tx.get("to", "") if isinstance(tx, dict) else "")
52
+ self._log_native_transfer(from_addr, to_addr, native_value)
53
+ except Exception as e:
54
+ logger.debug(f"Could not get tx for native transfer logging: {e}")
46
55
 
47
56
  # Log ERC20 transfers from event logs
48
- logs = receipt.get("logs", [])
49
- if hasattr(receipt, "logs"):
50
- logs = receipt.logs
57
+ logs = receipt.get("logs", []) if isinstance(receipt, dict) else getattr(receipt, "logs", [])
51
58
 
52
59
  for log in logs:
53
60
  self._process_log(log)
54
61
 
55
- def _log_native_transfer(self, tx: Dict, value_wei: int) -> None:
62
+ def _log_native_transfer(self, from_addr: str, to_addr: str, value_wei: int) -> None:
56
63
  """Log a native currency transfer."""
57
- from_addr = tx.get("from", "")
58
- to_addr = tx.get("to", "")
59
-
60
64
  from_label = self._resolve_address_label(from_addr)
61
65
  to_label = self._resolve_address_label(to_addr)
62
66
 
@@ -213,53 +217,67 @@ class TransactionService:
213
217
  chain_name: str = "gnosis",
214
218
  tags: Optional[List[str]] = None,
215
219
  ) -> Tuple[bool, Dict]:
216
- """Sign and send a transaction with retry logic for gas."""
220
+ """Sign and send a transaction using unified retry mechanism.
221
+
222
+ Uses ChainInterface.with_retry() for consistent RPC rotation and retry logic.
223
+ Gas errors are handled by increasing gas and retrying within the same mechanism.
224
+ """
217
225
  chain_interface = ChainInterfaces().get(chain_name)
218
226
  tx = dict(transaction)
219
- max_retries = 10
220
227
 
221
228
  if not self._prepare_transaction(tx, signer_address_or_tag, chain_interface):
222
229
  return False, {}
223
230
 
224
- for attempt in range(1, max_retries + 1):
231
+ # Mutable state for retry attempts
232
+ state = {"gas_retries": 0, "max_gas_retries": 5}
233
+
234
+ def _do_sign_send_wait() -> Tuple[bool, Dict, bytes]:
235
+ """Inner operation wrapped by with_retry."""
225
236
  try:
226
237
  signed_txn = self.key_storage.sign_transaction(tx, signer_address_or_tag)
227
- txn_hash = chain_interface.web3.eth.send_raw_transaction(signed_txn.raw_transaction)
228
-
229
- # Use chain_interface.with_retry for waiting for receipt to handle timeouts/RPC errors
230
- def wait_for_receipt(tx_h=txn_hash):
231
- return chain_interface.web3.eth.wait_for_transaction_receipt(tx_h)
232
-
233
- receipt = chain_interface.with_retry(
234
- wait_for_receipt, operation_name="wait_for_receipt"
238
+ txn_hash = chain_interface.web3.eth.send_raw_transaction(
239
+ signed_txn.raw_transaction
235
240
  )
241
+ receipt = chain_interface.web3.eth.wait_for_transaction_receipt(txn_hash)
236
242
 
237
- if receipt and getattr(receipt, "status", None) == 1:
238
- signer_account = self.account_service.resolve_account(signer_address_or_tag)
239
- chain_interface.wait_for_no_pending_tx(signer_account.address)
240
- logger.info(f"Transaction sent successfully. Tx Hash: {txn_hash.hex()}")
241
-
242
- self._log_successful_transaction(
243
- receipt, tx, signer_account, chain_name, txn_hash, tags, chain_interface
244
- )
245
- return True, receipt
243
+ status = getattr(receipt, "status", None)
244
+ if status is None and isinstance(receipt, dict):
245
+ status = receipt.get("status")
246
246
 
247
- # Transaction reverted
247
+ if receipt and status == 1:
248
+ return True, receipt, txn_hash
249
+ # Transaction mined but reverted - don't retry
248
250
  logger.error("Transaction failed (status 0).")
249
- return False, {}
251
+ raise ValueError("Transaction reverted")
250
252
 
251
253
  except web3_exceptions.Web3RPCError as e:
252
- if self._handle_gas_error(e, tx, attempt, max_retries):
253
- continue
254
- return False, {}
254
+ # Handle gas errors by increasing gas and re-raising
255
+ self._handle_gas_retry(e, tx, state)
256
+ raise # Re-raise to trigger with_retry's retry mechanism
255
257
 
256
- except Exception as e:
257
- # Attempt RPC rotation
258
- if self._handle_generic_error(e, chain_interface, attempt, max_retries):
259
- continue
258
+ try:
259
+ success, receipt, txn_hash = chain_interface.with_retry(
260
+ _do_sign_send_wait,
261
+ operation_name=f"sign_and_send to {tx.get('to', 'unknown')[:10]}...",
262
+ )
263
+ if success:
264
+ signer_account = self.account_service.resolve_account(signer_address_or_tag)
265
+ chain_interface.wait_for_no_pending_tx(signer_account.address)
266
+ logger.info(f"Transaction sent successfully. Tx Hash: {txn_hash.hex()}")
267
+ self._log_successful_transaction(
268
+ receipt, tx, signer_account, chain_name, txn_hash, tags, chain_interface
269
+ )
270
+ return True, receipt
271
+ return False, {}
272
+ except ValueError as e:
273
+ # Transaction reverted - already logged
274
+ if "reverted" in str(e).lower():
260
275
  return False, {}
261
-
262
- return False, {}
276
+ logger.exception(f"Transaction failed: {e}")
277
+ return False, {}
278
+ except Exception as e:
279
+ logger.exception(f"Transaction failed after retries: {e}")
280
+ return False, {}
263
281
 
264
282
  def _prepare_transaction(self, tx: dict, signer_tag: str, chain_interface) -> bool:
265
283
  """Ensure nonce and chainId are set."""
@@ -274,32 +292,16 @@ class TransactionService:
274
292
  tx["chainId"] = chain_interface.chain.chain_id
275
293
  return True
276
294
 
277
- def _handle_gas_error(self, e, tx, attempt, max_retries) -> bool:
278
- err_text = str(e)
279
- if self._is_gas_too_low_error(err_text) and attempt < max_retries:
280
- logger.warning(
281
- f"Gas too low error detected. Retrying with increased gas (Attempt {attempt}/{max_retries})..."
282
- )
295
+ def _handle_gas_retry(self, e: Exception, tx: dict, state: dict) -> None:
296
+ """Increase gas if error is gas-related and retries remaining."""
297
+ if self._is_gas_too_low_error(str(e)) and state["gas_retries"] < state["max_gas_retries"]:
283
298
  current_gas = int(tx.get("gas", 30_000))
284
299
  tx["gas"] = int(current_gas * 1.5)
285
- tx["gas"] = int(current_gas * 1.5)
286
- # Exponential backoff for gas errors
287
- time.sleep(min(2**attempt, 30))
288
- return True
289
- logger.exception(f"Error sending transaction: {e}")
290
- return False
291
-
292
- def _handle_generic_error(self, e, chain_interface, attempt, max_retries) -> bool:
293
- if attempt < max_retries:
294
- logger.warning(f"Error encountered: {e}. Attempting to rotate RPC...")
295
-
296
- if chain_interface.rotate_rpc():
297
- logger.info("Retrying with new RPC...")
298
- # Exponential backoff
299
- time.sleep(min(2**attempt, 30))
300
- return True
301
- logger.exception(f"Unexpected error sending transaction: {e}")
302
- return False
300
+ state["gas_retries"] += 1
301
+ logger.warning(
302
+ f"Gas too low, increasing to {tx['gas']} "
303
+ f"(attempt {state['gas_retries']}/{state['max_gas_retries']})"
304
+ )
303
305
 
304
306
  def _log_successful_transaction(
305
307
  self, receipt, tx, signer_account, chain_name, txn_hash, tags, chain_interface
@@ -323,7 +325,7 @@ class TransactionService:
323
325
 
324
326
  # Log transfer events (ERC20 and native value)
325
327
  transfer_logger = TransferLogger(self.account_service, chain_interface)
326
- transfer_logger.log_transfers(receipt, tx)
328
+ transfer_logger.log_transfers(receipt)
327
329
 
328
330
  except Exception as log_err:
329
331
  logger.warning(f"Failed to log transaction: {log_err}")
@@ -64,6 +64,14 @@ class ERC20TransferMixin:
64
64
  value_eur=v_eur,
65
65
  tags=["erc20-transfer", "safe-transaction"],
66
66
  )
67
+
68
+ # Log transfers extracted from receipt events
69
+ if receipt:
70
+ from iwa.core.services.transaction import TransferLogger
71
+
72
+ transfer_logger = TransferLogger(self.account_service, interface)
73
+ transfer_logger.log_transfers(receipt)
74
+
67
75
  return tx_hash
68
76
 
69
77
  def _send_erc20_via_eoa(
@@ -61,6 +61,15 @@ class NativeTransferMixin:
61
61
  value_eur=v_eur,
62
62
  tags=["native-transfer", "safe-transaction"],
63
63
  )
64
+
65
+ # Log transfers extracted from receipt events
66
+ if receipt:
67
+ from iwa.core.services.transaction import TransferLogger
68
+
69
+ interface = ChainInterfaces().get(chain_name)
70
+ transfer_logger = TransferLogger(self.account_service, interface)
71
+ transfer_logger.log_transfers(receipt)
72
+
64
73
  return tx_hash
65
74
 
66
75
  def _send_native_via_eoa(
@@ -74,20 +83,38 @@ class NativeTransferMixin:
74
83
  to_tag: Optional[str],
75
84
  token_symbol: str,
76
85
  ) -> Optional[str]:
77
- """Send native currency via EOA (externally owned account)."""
78
- success, tx_hash = chain_interface.send_native_transfer(
79
- from_address=from_account.address,
80
- to_address=to_address,
81
- value_wei=amount_wei,
82
- sign_callback=lambda tx: self.key_storage.sign_transaction(tx, from_account.address),
86
+ """Send native currency via EOA using unified TransactionService."""
87
+ # Build transaction dict
88
+ try:
89
+ gas_price = chain_interface.web3.eth.gas_price
90
+ gas_estimate = chain_interface.web3.eth.estimate_gas({
91
+ "from": from_account.address,
92
+ "to": to_address,
93
+ "value": amount_wei,
94
+ })
95
+ except Exception as e:
96
+ logger.error(f"Failed to estimate gas for native transfer: {e}")
97
+ return None
98
+
99
+ tx = {
100
+ "from": from_account.address,
101
+ "to": to_address,
102
+ "value": amount_wei,
103
+ "gas": gas_estimate,
104
+ "gasPrice": gas_price,
105
+ }
106
+
107
+ # Use unified TransactionService
108
+ success, receipt = self.transaction_service.sign_and_send(
109
+ tx, from_account.address, chain_name, tags=["native-transfer"]
83
110
  )
84
- if success and tx_hash:
85
- # Get receipt for gas calculation
86
- receipt = None
87
- try:
88
- receipt = chain_interface.web3.eth.get_transaction_receipt(tx_hash)
89
- except Exception as e:
90
- logger.warning(f"Could not get receipt for {tx_hash}: {e}")
111
+
112
+ if success and receipt:
113
+ tx_hash = receipt.get("transactionHash", b"")
114
+ if hasattr(tx_hash, "hex"):
115
+ tx_hash = tx_hash.hex()
116
+ elif isinstance(tx_hash, bytes):
117
+ tx_hash = tx_hash.hex()
91
118
 
92
119
  gas_cost, gas_value_eur = self._calculate_gas_info(receipt, chain_name)
93
120
  p_eur, v_eur = self._get_token_price_info(token_symbol, amount_wei, chain_name)
@@ -106,6 +133,13 @@ class NativeTransferMixin:
106
133
  value_eur=v_eur,
107
134
  tags=["native-transfer"],
108
135
  )
136
+
137
+ # Log transfers extracted from receipt events
138
+ from iwa.core.services.transaction import TransferLogger
139
+
140
+ transfer_logger = TransferLogger(self.account_service, chain_interface)
141
+ transfer_logger.log_transfers(receipt)
142
+
109
143
  return tx_hash
110
144
  return None
111
145
 
@@ -54,10 +54,10 @@ OLAS_CONTRACTS: Dict[str, Dict[str, EthereumAddress]] = {
54
54
  # Legacy mech - used by NON-MM TRADER staking contracts (e.g., "Expert X (Yk OLAS)")
55
55
  # Activity checker calls agentMech.getRequestsCount(multisig) to count requests.
56
56
  "OLAS_MECH": EthereumAddress("0x77af31De935740567Cf4fF1986D04B2c964A786a"),
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.
57
+ # Marketplace v2 - used by newer MM staking contracts (e.g., "Expert X MM v2 (Yk OLAS)")
58
+ # Services staked in MM v2 contracts MUST use marketplace requests.
59
59
  # Legacy mech requests will NOT be counted by the activity checker.
60
- "OLAS_MECH_MARKETPLACE": EthereumAddress("0x735FAAb1c4Ec41128c367AFb5c3baC73509f70bB"),
60
+ "OLAS_MECH_MARKETPLACE_V2": EthereumAddress("0x735FAAb1c4Ec41128c367AFb5c3baC73509f70bB"),
61
61
  # Default priority mech for marketplace requests (from olas-operate-middleware)
62
62
  # This is the mech that will process requests sent via the marketplace.
63
63
  # Source: https://github.com/valory-xyz/olas-operate-middleware/blob/main/operate/ledger/profiles.py
@@ -65,8 +65,9 @@ OLAS_CONTRACTS: Dict[str, Dict[str, EthereumAddress]] = {
65
65
  "OLAS_MECH_MARKETPLACE_PRIORITY": EthereumAddress(
66
66
  "0xC05e7412439bD7e91730a6880E18d5D5873F632C"
67
67
  ),
68
- # OLD Marketplace (v1) - legacy, kept for reference
69
- "OLAS_MECH_MARKETPLACE_OLD": EthereumAddress("0x4554fE75c1f5576c1d7F765B2A036c199Adae329"),
68
+ # Marketplace v1 (VERSION 1.0.0) - older MM contracts (e.g., "Expert 17 MM v1")
69
+ # Uses different request signature than v2. trader_ant uses this.
70
+ "OLAS_MECH_MARKETPLACE_V1": EthereumAddress("0x4554fE75c1f5576c1d7F765B2A036c199Adae329"),
70
71
  },
71
72
  "ethereum": {
72
73
  "OLAS_SERVICE_REGISTRY": EthereumAddress("0x48b6F34dDAf31f94086BFB45e69e0618DDe3677b"),
@@ -75,49 +76,50 @@ OLAS_CONTRACTS: Dict[str, Dict[str, EthereumAddress]] = {
75
76
  "base": {
76
77
  "OLAS_SERVICE_REGISTRY": EthereumAddress("0x3841C312061daB948332A78F042Ec61Ad09fc3D8"),
77
78
  "OLAS_SERVICE_MANAGER": EthereumAddress("0xF36183B106692DeD8b6e3B2B7347C9665f8a09B1"),
78
- "OLAS_MECH_MARKETPLACE": EthereumAddress("0x4554fE75c1f5576c1d7F765B2A036c199Adae329"),
79
+ "OLAS_MECH_MARKETPLACE_V1": EthereumAddress("0x4554fE75c1f5576c1d7F765B2A036c199Adae329"),
79
80
  },
80
81
  }
81
82
 
82
83
  # TRADER-compatible staking contracts categorized by chain
83
84
  # See https://govern.olas.network/contracts
84
- # NOTE: All TRADER staking contracts use the LEGACY MECH for activity tracking.
85
- # The activity checker calls agentMech.getRequestsCount(multisig), where agentMech
86
- # is hardcoded to the legacy mech (0x77af31De935740567Cf4fF1986D04B2c964A786a).
87
85
  #
88
- # This means:
89
- # - Legacy mech requests (use_marketplace=False) -> COUNT for liveness rewards
90
- # - Marketplace mech requests (use_marketplace=True) -> DO NOT COUNT
86
+ # Categories (verified on-chain via activity checker's mechMarketplace):
87
+ # - Legacy: No marketplace, uses legacy mech (0x77af31De...). agentMech.getRequestsCount()
88
+ # - MM v1: Old marketplace (0x4554fE75...). mechMarketplace.mapRequestCounts()
89
+ # - MM v2: New marketplace (0x735FAAb1...). mechMarketplace.mapRequestCounts()
91
90
  #
92
- # For staking rewards, services MUST use legacy mech requests.
91
+ # IMPORTANT: Services MUST use the correct mech request type for their staking contract!
93
92
  OLAS_TRADER_STAKING_CONTRACTS: Dict[str, Dict[str, EthereumAddress]] = {
94
93
  "gnosis": {
95
- "Hobbyist 1 (100 OLAS)": EthereumAddress("0x389B46C259631Acd6a69Bde8B6cEe218230bAE8C"),
96
- "Hobbyist 2 (500 OLAS)": EthereumAddress("0x238EB6993b90A978ec6AAD7530D6429c949C08DA"),
97
- "Expert (1k OLAS)": EthereumAddress("0x5344B7DD311e5d3DdDd46A4f71481Bd7b05AAA3e"),
98
- "Expert 2 (1k OLAS)": EthereumAddress("0xb964e44c126410df341ae04B13aB10A985fE3513"),
99
- "Expert 3 (2k OLAS)": EthereumAddress("0x80faD33Cadb5F53f9D29F02Db97D682E8B101618"),
100
- "Expert 4 (10k OLAS)": EthereumAddress("0xaD9d891134443B443D7F30013c7e14Fe27F2E029"),
101
- "Expert 5 (10k OLAS)": EthereumAddress("0xE56dF1E563De1B10715cB313D514af350D207212"),
102
- "Expert 6 (1k OLAS)": EthereumAddress("0x2546214aEE7eEa4bEE7689C81231017CA231Dc93"),
103
- "Expert 7 (10k OLAS)": EthereumAddress("0xD7A3C8b975f71030135f1a66E9e23164d54fF455"),
104
- "Expert 8 (2k OLAS)": EthereumAddress("0x356C108D49C5eebd21c84c04E9162de41933030c"),
105
- "Expert 9 (10k OLAS)": EthereumAddress("0x17dBAe44BC5618Cc254055B386A29576b4F87015"),
106
- "Expert 10 (10k OLAS)": EthereumAddress("0xB0ef657b8302bd2c74B6E6D9B2b4b39145b19c6f"),
107
- "Expert 11 (10k OLAS)": EthereumAddress("0x3112c1613eAC3dBAE3D4E38CeF023eb9E2C91CF7"),
108
- "Expert 12 (10k OLAS)": EthereumAddress("0xF4a75F476801B3fBB2e7093aCDcc3576593Cc1fc"),
109
- "Expert 15 (10k OLAS)": EthereumAddress("0x88eB38FF79fBa8C19943C0e5Acfa67D5876AdCC1"),
110
- "Expert 16 (10k OLAS)": EthereumAddress("0x6c65430515c70a3f5E62107CC301685B7D46f991"),
111
- "Expert 17 (10k OLAS)": EthereumAddress("0x1430107A785C3A36a0C1FC0ee09B9631e2E72aFf"),
112
- "Expert 18 (10k OLAS)": EthereumAddress("0x041e679d04Fc0D4f75Eb937Dea729Df09a58e454"),
113
- "Expert 3 MM (1k OLAS)": EthereumAddress("0x75eeca6207be98cac3fde8a20ecd7b01e50b3472"),
114
- "Expert 4 MM (2k OLAS)": EthereumAddress("0x9c7f6103e3a72e4d1805b9c683ea5b370ec1a99f"),
115
- "Expert 5 MM (10k OLAS)": EthereumAddress("0xcdC603e0Ee55Aae92519f9770f214b2Be4967f7d"),
116
- "Expert 6 MM (10k OLAS)": EthereumAddress("0x22d6cd3d587d8391c3aae83a783f26c67ab54a85"),
117
- "Expert 7 MM (10k OLAS)": EthereumAddress("0xaaecdf4d0cbd6ca0622892ac6044472f3912a5f3"),
118
- "Expert 8 MM (10k OLAS)": EthereumAddress("0x168aed532a0cd8868c22fc77937af78b363652b1"),
119
- "Expert 9 MM (10k OLAS)": EthereumAddress("0xdda9cd214f12e7c2d58e871404a0a3b1177065c8"),
120
- "Expert 10 MM (10k OLAS)": EthereumAddress("0x53a38655b4e659ef4c7f88a26fbf5c67932c7156"),
94
+ # === LEGACY (no marketplace) ===
95
+ "Hobbyist 1 Legacy (100 OLAS)": EthereumAddress("0x389B46C259631Acd6a69Bde8B6cEe218230bAE8C"),
96
+ "Hobbyist 2 Legacy (500 OLAS)": EthereumAddress("0x238EB6993b90A978ec6AAD7530D6429c949C08DA"),
97
+ "Expert Legacy (1k OLAS)": EthereumAddress("0x5344B7DD311e5d3DdDd46A4f71481Bd7b05AAA3e"),
98
+ "Expert 2 Legacy (1k OLAS)": EthereumAddress("0xb964e44c126410df341ae04B13aB10A985fE3513"),
99
+ "Expert 3 Legacy (2k OLAS)": EthereumAddress("0x80faD33Cadb5F53f9D29F02Db97D682E8B101618"),
100
+ "Expert 4 Legacy (10k OLAS)": EthereumAddress("0xaD9d891134443B443D7F30013c7e14Fe27F2E029"),
101
+ "Expert 5 Legacy (10k OLAS)": EthereumAddress("0xE56dF1E563De1B10715cB313D514af350D207212"),
102
+ "Expert 6 Legacy (1k OLAS)": EthereumAddress("0x2546214aEE7eEa4bEE7689C81231017CA231Dc93"),
103
+ "Expert 7 Legacy (10k OLAS)": EthereumAddress("0xD7A3C8b975f71030135f1a66E9e23164d54fF455"),
104
+ "Expert 8 Legacy (2k OLAS)": EthereumAddress("0x356C108D49C5eebd21c84c04E9162de41933030c"),
105
+ "Expert 9 Legacy (10k OLAS)": EthereumAddress("0x17dBAe44BC5618Cc254055B386A29576b4F87015"),
106
+ "Expert 10 Legacy (10k OLAS)": EthereumAddress("0xB0ef657b8302bd2c74B6E6D9B2b4b39145b19c6f"),
107
+ "Expert 11 Legacy (10k OLAS)": EthereumAddress("0x3112c1613eAC3dBAE3D4E38CeF023eb9E2C91CF7"),
108
+ "Expert 12 Legacy (10k OLAS)": EthereumAddress("0xF4a75F476801B3fBB2e7093aCDcc3576593Cc1fc"),
109
+ # === MM v1 (old marketplace 0x4554fE75...) ===
110
+ "Expert 15 MM v1 (10k OLAS)": EthereumAddress("0x88eB38FF79fBa8C19943C0e5Acfa67D5876AdCC1"),
111
+ "Expert 16 MM v1 (10k OLAS)": EthereumAddress("0x6c65430515c70a3f5E62107CC301685B7D46f991"),
112
+ "Expert 17 MM v1 (10k OLAS)": EthereumAddress("0x1430107A785C3A36a0C1FC0ee09B9631e2E72aFf"),
113
+ "Expert 18 MM v1 (10k OLAS)": EthereumAddress("0x041e679d04Fc0D4f75Eb937Dea729Df09a58e454"),
114
+ # === MM v2 (new marketplace 0x735FAAb1...) ===
115
+ "Expert 3 MM v2 (1k OLAS)": EthereumAddress("0x75eeca6207be98cac3fde8a20ecd7b01e50b3472"),
116
+ "Expert 4 MM v2 (2k OLAS)": EthereumAddress("0x9c7f6103e3a72e4d1805b9c683ea5b370ec1a99f"),
117
+ "Expert 5 MM v2 (10k OLAS)": EthereumAddress("0xcdC603e0Ee55Aae92519f9770f214b2Be4967f7d"),
118
+ "Expert 6 MM v2 (10k OLAS)": EthereumAddress("0x22d6cd3d587d8391c3aae83a783f26c67ab54a85"),
119
+ "Expert 7 MM v2 (10k OLAS)": EthereumAddress("0xaaecdf4d0cbd6ca0622892ac6044472f3912a5f3"),
120
+ "Expert 8 MM v2 (10k OLAS)": EthereumAddress("0x168aed532a0cd8868c22fc77937af78b363652b1"),
121
+ "Expert 9 MM v2 (10k OLAS)": EthereumAddress("0xdda9cd214f12e7c2d58e871404a0a3b1177065c8"),
122
+ "Expert 10 MM v2 (10k OLAS)": EthereumAddress("0x53a38655b4e659ef4c7f88a26fbf5c67932c7156"),
121
123
  },
122
124
  "ethereum": {},
123
125
  "base": {},