ipor-fusion 4.0.0.dev162__tar.gz → 4.0.0.dev168__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 (332) hide show
  1. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/AGENTS.md +10 -0
  2. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/MIGRATION_4.md +42 -9
  3. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/PKG-INFO +1 -1
  4. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/examples/advanced_euler_v2_credit_market_base.py +1 -3
  5. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/examples/advanced_euler_v2_looping_arbitrum.py +1 -3
  6. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/examples/composed_hypercore_flow_arbitrum_hyperevm.py +1 -1
  7. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/examples/crosschain_ccip_usdc_arbitrum_hyperevm.py +1 -1
  8. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/examples/external_state_margin_leg_base.py +1 -3
  9. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/examples/simple_aave_v3_supply_base.py +1 -3
  10. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/pyproject.toml +1 -1
  11. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/__init__.py +54 -4
  12. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/core/simulation.py +52 -19
  13. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/fuses/__init__.py +34 -2
  14. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/fuses/external_state_events.py +106 -35
  15. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/fuses/hypercore_events.py +157 -36
  16. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/_event_args.py +14 -3
  17. ipor_fusion-4.0.0.dev168/tests/_golden.py +69 -0
  18. ipor_fusion-4.0.0.dev168/tests/_oracle_mapping_fake.py +200 -0
  19. ipor_fusion-4.0.0.dev168/tests/fixtures/market_golden/meta_morpho_v1.json +99 -0
  20. ipor_fusion-4.0.0.dev168/tests/fixtures/market_golden/meta_morpho_v1.mcp.json +111 -0
  21. ipor_fusion-4.0.0.dev168/tests/fixtures/market_golden/meta_morpho_v2.json +135 -0
  22. ipor_fusion-4.0.0.dev168/tests/fixtures/market_golden/meta_morpho_v2.mcp.json +140 -0
  23. ipor_fusion-4.0.0.dev168/tests/fixtures/market_golden/morpho_api/market.json +208 -0
  24. ipor_fusion-4.0.0.dev168/tests/fixtures/market_golden/morpho_api/vault_v1.json +168 -0
  25. ipor_fusion-4.0.0.dev168/tests/fixtures/market_golden/morpho_api/vault_v2.json +115 -0
  26. ipor_fusion-4.0.0.dev168/tests/fixtures/market_golden/morpho_api/vault_v2_not_found.json +12 -0
  27. ipor_fusion-4.0.0.dev168/tests/fixtures/market_golden/morpho_blue.json +107 -0
  28. ipor_fusion-4.0.0.dev168/tests/fixtures/market_golden/morpho_blue.mcp.json +108 -0
  29. ipor_fusion-4.0.0.dev168/tests/fixtures/market_golden/morpho_blue_api_error.json +28 -0
  30. ipor_fusion-4.0.0.dev168/tests/fixtures/market_golden/morpho_blue_api_error.mcp.json +31 -0
  31. ipor_fusion-4.0.0.dev168/tests/fixtures/market_golden/morpho_blue_no_api.json +27 -0
  32. ipor_fusion-4.0.0.dev168/tests/fixtures/market_golden/morpho_blue_no_api.mcp.json +31 -0
  33. ipor_fusion-4.0.0.dev168/tests/fixtures/oracle_mapping_golden/mapping.json +573 -0
  34. ipor_fusion-4.0.0.dev168/tests/fixtures/oracle_mapping_golden/mapping.mcp.json +573 -0
  35. ipor_fusion-4.0.0.dev168/tests/fixtures/vault_info_golden/clean.mcp.json +136 -0
  36. ipor_fusion-4.0.0.dev168/tests/fixtures/vault_info_golden/deployment_error.json +131 -0
  37. ipor_fusion-4.0.0.dev168/tests/fixtures/vault_info_golden/deployment_error.mcp.json +138 -0
  38. ipor_fusion-4.0.0.dev168/tests/fixtures/vault_info_golden/deployment_error.txt +54 -0
  39. ipor_fusion-4.0.0.dev168/tests/fixtures/vault_info_golden/full.json +688 -0
  40. ipor_fusion-4.0.0.dev168/tests/fixtures/vault_info_golden/full.mcp.json +709 -0
  41. ipor_fusion-4.0.0.dev168/tests/fixtures/vault_info_golden/full.txt +154 -0
  42. ipor_fusion-4.0.0.dev168/tests/fixtures/vault_info_golden/rich.mcp.json +406 -0
  43. ipor_fusion-4.0.0.dev168/tests/test_cli_market_golden.py +199 -0
  44. ipor_fusion-4.0.0.dev168/tests/test_cli_oracle_mapping_golden.py +275 -0
  45. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_cli_vault_info_golden.py +264 -16
  46. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_external_state_events.py +8 -6
  47. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_hypercore_events.py +21 -14
  48. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_oracle_mapping.py +25 -193
  49. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_public_api.py +44 -3
  50. ipor_fusion-4.0.0.dev168/tests/test_simulation_errors.py +229 -0
  51. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/typed_client/consumer.py +24 -6
  52. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/typed_client/rejected.py +4 -0
  53. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/.claude-plugin/marketplace.json +0 -0
  54. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/.claude-plugin/plugin.json +0 -0
  55. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/.env.example +0 -0
  56. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/.gemini/settings.json +0 -0
  57. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/.git-blame-ignore-revs +0 -0
  58. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/.github/workflows/cd.yml +0 -0
  59. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/.github/workflows/ci.yml +0 -0
  60. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/.github/workflows/commit-lint.yml +0 -0
  61. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/.github/workflows/notify-slack.yml +0 -0
  62. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/.github/workflows/python-build.yml +0 -0
  63. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/.github/workflows/python-publish.yml +0 -0
  64. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/.github/workflows/release.yml +0 -0
  65. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/.github/workflows/report-slack.yml +0 -0
  66. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/.gitignore +0 -0
  67. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/.mcp.json +0 -0
  68. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/.pre-commit-config.yaml +0 -0
  69. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/.python-version +0 -0
  70. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/CHANGELOG.md +0 -0
  71. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/CLAUDE.md +0 -0
  72. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/CODEOWNERS +0 -0
  73. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/LICENSE +0 -0
  74. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/README.md +0 -0
  75. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/build.sh +0 -0
  76. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/examples/CONTRIBUTING.md +0 -0
  77. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/examples/README.md +0 -0
  78. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/pytest.ini +0 -0
  79. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/scripts/commit-check.sh +0 -0
  80. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/scripts/crosschain_readiness.py +0 -0
  81. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/skills/ipor-deploy-vault/SKILL.md +0 -0
  82. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/about.py +0 -0
  83. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/cache.py +0 -0
  84. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/chains.py +0 -0
  85. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/cli/__init__.py +0 -0
  86. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/cli/changelog_cmd.py +0 -0
  87. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/cli/config_cmd.py +0 -0
  88. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/cli/config_store.py +0 -0
  89. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/cli/main.py +0 -0
  90. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/cli/market_cmd.py +0 -0
  91. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/cli/options.py +0 -0
  92. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/cli/oracle_mapping_view.py +0 -0
  93. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/cli/vault_cmd.py +0 -0
  94. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/cli/vault_health.py +0 -0
  95. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/cli/vault_info_view.py +0 -0
  96. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/cli/vault_markets_view.py +0 -0
  97. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/cli/vault_rendering.py +0 -0
  98. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/config/__init__.py +0 -0
  99. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/config/roles.py +0 -0
  100. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/core/__init__.py +0 -0
  101. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/core/access.py +0 -0
  102. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/core/address.py +0 -0
  103. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/core/context.py +0 -0
  104. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/core/contract.py +0 -0
  105. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/core/erc20.py +0 -0
  106. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/core/external_state_executor.py +0 -0
  107. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/core/fee_manager.py +0 -0
  108. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/core/fuse.py +0 -0
  109. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/core/fuse_action.py +0 -0
  110. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/core/fusion_factory.py +0 -0
  111. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/core/logs.py +0 -0
  112. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/core/multicall.py +0 -0
  113. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/core/oracle.py +0 -0
  114. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/core/plasma_vault.py +0 -0
  115. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/core/rewards_manager.py +0 -0
  116. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/core/withdraw_manager.py +0 -0
  117. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/__init__.py +0 -0
  118. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/ccip/__init__.py +0 -0
  119. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/ccip/chainlink.py +0 -0
  120. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/ccip/codec.py +0 -0
  121. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/ccip/contracts.py +0 -0
  122. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/ccip/events.py +0 -0
  123. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/ccip/indexer.py +0 -0
  124. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/ccip/lane.py +0 -0
  125. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/ccip/quote.py +0 -0
  126. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/ccip/transport.py +0 -0
  127. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/contracts.py +0 -0
  128. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/discovery.py +0 -0
  129. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/errors.py +0 -0
  130. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/fuses/__init__.py +0 -0
  131. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/fuses/base.py +0 -0
  132. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/fuses/ccip.py +0 -0
  133. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/fuses/stargate.py +0 -0
  134. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/lane.py +0 -0
  135. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/logs.py +0 -0
  136. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/messages.py +0 -0
  137. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/simulation.py +0 -0
  138. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/stargate/__init__.py +0 -0
  139. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/stargate/contracts.py +0 -0
  140. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/stargate/lane.py +0 -0
  141. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/stargate/layerzero.py +0 -0
  142. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/stargate/transport.py +0 -0
  143. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/crosschain/transport.py +0 -0
  144. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/dependency_graph.py +0 -0
  145. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/entry_cli.py +0 -0
  146. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/entry_mcp.py +0 -0
  147. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/errors.py +0 -0
  148. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/explorer.py +0 -0
  149. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/field_docs.py +0 -0
  150. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/fuses/aave_v3.py +0 -0
  151. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/fuses/async_action.py +0 -0
  152. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/fuses/base.py +0 -0
  153. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/fuses/compound_v3.py +0 -0
  154. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/fuses/erc4626.py +0 -0
  155. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/fuses/euler_v2.py +0 -0
  156. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/fuses/events.py +0 -0
  157. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/fuses/external_state.py +0 -0
  158. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/fuses/fluid_instadapp.py +0 -0
  159. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/fuses/gearbox_v3.py +0 -0
  160. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/fuses/hypercore.py +0 -0
  161. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/fuses/merkl.py +0 -0
  162. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/fuses/morpho.py +0 -0
  163. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/fuses/ramses_v2.py +0 -0
  164. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/fuses/uniswap_v3.py +0 -0
  165. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/fuses/universal.py +0 -0
  166. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/guide/__init__.py +0 -0
  167. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/guide/architecture.md +0 -0
  168. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/guide/glossary.md +0 -0
  169. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/guide/invariants.md +0 -0
  170. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/guide/quickstart.md +0 -0
  171. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/market_ids.py +0 -0
  172. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/market_info.py +0 -0
  173. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/mcp/__init__.py +0 -0
  174. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/mcp/guide.py +0 -0
  175. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/mcp/models.py +0 -0
  176. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/mcp/server.py +0 -0
  177. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/morpho_api.py +0 -0
  178. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/py.typed +0 -0
  179. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/readers/__init__.py +0 -0
  180. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/readers/aave_v3.py +0 -0
  181. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/readers/aave_v4.py +0 -0
  182. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/readers/compound_v3.py +0 -0
  183. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/readers/hypercore.py +0 -0
  184. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/readers/hypercore_outcome.py +0 -0
  185. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/readers/lending_health.py +0 -0
  186. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/readers/morpho.py +0 -0
  187. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/readers/oracle_mapping.py +0 -0
  188. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/readers/oracle_mapping_nodes.py +0 -0
  189. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/readers/oracle_mapping_reader.py +0 -0
  190. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/readers/position_manager.py +0 -0
  191. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/readers/ramses_v2.py +0 -0
  192. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/readers/uniswap_v3.py +0 -0
  193. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/readers/unpriceable.py +0 -0
  194. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/substrates.py +0 -0
  195. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/types.py +0 -0
  196. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/validation.py +0 -0
  197. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/vault_data.py +0 -0
  198. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/vault_erc20.py +0 -0
  199. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/vault_info.py +0 -0
  200. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/vault_managers.py +0 -0
  201. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/vault_positions.py +0 -0
  202. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/src/ipor_fusion/vault_reads.py +0 -0
  203. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/UniswapV3UniversalRouter.py +0 -0
  204. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/_crosschain.py +0 -0
  205. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/_crosschain_lifecycle.py +0 -0
  206. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/_crosschain_recovery.py +0 -0
  207. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/_euler_v2.py +0 -0
  208. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/_foundry.py +0 -0
  209. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/_guide.py +0 -0
  210. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/_hypercore_model.py +0 -0
  211. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/_hypercore_shadow.py +0 -0
  212. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/_multicall.py +0 -0
  213. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/_simulate.py +0 -0
  214. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/_validation.py +0 -0
  215. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/addresses.py +0 -0
  216. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/conftest.py +0 -0
  217. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/constants.py +0 -0
  218. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/fixtures/hypercore_hip3_flow.json +0 -0
  219. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/fixtures/hypercore_market55.json +0 -0
  220. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/fixtures/simulate_v1_request.json +0 -0
  221. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/fixtures/vault_info_golden/clean.json +0 -0
  222. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/fixtures/vault_info_golden/clean.txt +0 -0
  223. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/fixtures/vault_info_golden/rich.json +0 -0
  224. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/fixtures/vault_info_golden/rich.txt +0 -0
  225. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_about.py +0 -0
  226. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_access_manager.py +0 -0
  227. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_cache.py +0 -0
  228. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_chains.py +0 -0
  229. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_cli_changelog.py +0 -0
  230. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_cli_commands.py +0 -0
  231. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_cli_config_store.py +0 -0
  232. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_cli_helpers.py +0 -0
  233. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_cli_hypercore.py +0 -0
  234. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_cli_lending_health.py +0 -0
  235. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_cli_market_morpho_blue.py +0 -0
  236. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_cli_oracle_mapping.py +0 -0
  237. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_cli_pending_requests_scan.py +0 -0
  238. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_cli_role_accounts.py +0 -0
  239. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_cli_vault_predates_getters.py +0 -0
  240. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_cli_vault_validate.py +0 -0
  241. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_contract_call.py +0 -0
  242. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_contract_encoder.py +0 -0
  243. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_crosschain_ccip_events.py +0 -0
  244. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_crosschain_ccip_indexer.py +0 -0
  245. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_crosschain_ccip_quote.py +0 -0
  246. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_crosschain_chainlink.py +0 -0
  247. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_crosschain_contracts.py +0 -0
  248. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_crosschain_encoding.py +0 -0
  249. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_crosschain_errors.py +0 -0
  250. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_crosschain_lane.py +0 -0
  251. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_crosschain_layering.py +0 -0
  252. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_crosschain_readiness.py +0 -0
  253. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_crosschain_readiness_report.py +0 -0
  254. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_crosschain_transport.py +0 -0
  255. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_docs_typing.py +0 -0
  256. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_erc20.py +0 -0
  257. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_error_hierarchy.py +0 -0
  258. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_examples_composed_hypercore.py +0 -0
  259. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_examples_crosschain.py +0 -0
  260. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_examples_euler_looping_arbitrum.py +0 -0
  261. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_examples_vaults.py +0 -0
  262. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_explorer.py +0 -0
  263. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_external_state_executor.py +0 -0
  264. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_fee_manager.py +0 -0
  265. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_fuse_encoding.py +0 -0
  266. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_fusion_instance.py +0 -0
  267. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_guide.py +0 -0
  268. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_hypercore_deployment.py +0 -0
  269. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_hypercore_flow.py +0 -0
  270. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_hypercore_live.py +0 -0
  271. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_hypercore_outcome.py +0 -0
  272. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_hypercore_readers.py +0 -0
  273. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_hypercore_simulation.py +0 -0
  274. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_logs.py +0 -0
  275. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_mcp_hypercore.py +0 -0
  276. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_mcp_models.py +0 -0
  277. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_mcp_server.py +0 -0
  278. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_mcp_vault_validate.py +0 -0
  279. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_multicall.py +0 -0
  280. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_oracle.py +0 -0
  281. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_plasma_vault.py +0 -0
  282. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_public_type_reachability.py +0 -0
  283. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_reader_encoding.py +0 -0
  284. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_readiness_selection.py +0 -0
  285. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_revert_decoding.py +0 -0
  286. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_rewards_manager.py +0 -0
  287. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_roles.py +0 -0
  288. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_sdk_layering.py +0 -0
  289. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_borrow_aave_v3_mainnet.py +0 -0
  290. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_claim_merkl_wrapper_base.py +0 -0
  291. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_claim_morpho_rewards.py +0 -0
  292. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_crosschain_canary.py +0 -0
  293. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_crosschain_hypercore.py +0 -0
  294. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_crosschain_hyperevm.py +0 -0
  295. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_crosschain_lifecycle.py +0 -0
  296. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_euler_v2_batch_base.py +0 -0
  297. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_euler_v2_credit_market_base.py +0 -0
  298. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_euler_v2_swap_deploy_base.py +0 -0
  299. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_euler_v2_swap_reconfigure_base.py +0 -0
  300. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_euler_v2_swap_registry_base.py +0 -0
  301. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_examples_arbitrum.py +0 -0
  302. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_examples_base.py +0 -0
  303. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_examples_crosschain.py +0 -0
  304. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_external_state_executor_base.py +0 -0
  305. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_fusion_factory_clone_base.py +0 -0
  306. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_looping_aave_v3_base.py +0 -0
  307. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_looping_morpho_blue_base.py +0 -0
  308. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_morpho_blue.py +0 -0
  309. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_pilot_v3.py +0 -0
  310. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_pilot_v4_uniswap.py +0 -0
  311. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_pilot_v5_ramses.py +0 -0
  312. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_pilot_v5_scheduled.py +0 -0
  313. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_plasma_vault_setters_base.py +0 -0
  314. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_readers_integration.py +0 -0
  315. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_release_funds.py +0 -0
  316. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_swap_on_base.py +0 -0
  317. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulate_vault_from_scratch_base.py +0 -0
  318. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_simulation_observation.py +0 -0
  319. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_solidity_compiler.py +0 -0
  320. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_solidity_mirrors.py +0 -0
  321. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_substrates.py +0 -0
  322. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_types_and_events.py +0 -0
  323. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_unpriceable_tokens.py +0 -0
  324. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_validation.py +0 -0
  325. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_vault_data_block.py +0 -0
  326. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_vault_dep_graph.py +0 -0
  327. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_vault_info_onchain_base.py +0 -0
  328. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_vault_info_onchain_base_no_withdraw_manager.py +0 -0
  329. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_vault_simulator_blocks.py +0 -0
  330. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_web3_context.py +0 -0
  331. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/tests/test_withdraw_manager.py +0 -0
  332. {ipor_fusion-4.0.0.dev162 → ipor_fusion-4.0.0.dev168}/uv.lock +0 -0
@@ -32,9 +32,19 @@ uv run pytest -m "cli or mcp" --no-cov # fast offline sub
32
32
  uv run pytest --run-readiness -m readiness --no-cov -rA # opt-in live Ethereum-hub POC checks
33
33
  uv run python scripts/crosschain_readiness.py --output /tmp/crosschain-readiness.json # live Arbitrum/HyperEVM report
34
34
  uv run pytest tests/test_fuse_encoding.py -k aave --no-cov # single file / test
35
+ UPDATE_GOLDEN=1 uv run pytest -k golden --no-cov # rewrite pinned CLI/MCP output (tests/fixtures/*_golden/)
35
36
  uv lock --check # uv.lock in sync with pyproject.toml
36
37
  ```
37
38
 
39
+ **Golden output.** The exact text of `fusion vault info` (text and `--json`),
40
+ `fusion market morpho-blue|meta-morpho --json`, `fusion vault oracle-mapping
41
+ --json` and the matching MCP tools (`vault_info`, `market_morpho_blue`,
42
+ `market_meta_morpho`, `vault_oracle_mapping`, called through the server) is pinned
43
+ in `tests/fixtures/*_golden/` (`tests/_golden.py`, the `*_golden.py` tests), from
44
+ recorded inputs and no network. A change to any of them fails those tests;
45
+ regenerate with `UPDATE_GOLDEN=1` only when the change is intended and review the
46
+ fixture diff. Without it the tests only compare.
47
+
38
48
  Run format, check, pyright and pytest after every code change; that is exactly
39
49
  the sequence in `.github/workflows/python-build.yml`. When ruff `C901` trips,
40
50
  extract helpers, never suppress.
@@ -847,15 +847,31 @@ that only some entries carry is `NotRequired` (a balance fuse's `pct_of_total` a
847
847
  `ipor_fusion` and `ipor_fusion.readers`). Narrow by a key before reading a
848
848
  kind-specific one: `if detail is not None and "aggregator" in detail:
849
849
  detail["description"]`.
850
- - Event `args` are typed per event kind: `ExternalStateEvent.args` is
851
- `ExternalStateEventArgs` and `HyperCoreEvent.args` is `HyperCoreEventArgs`, a union
852
- of one TypedDict per event (`ExternalStateUnpausedArgs`,
853
- `HyperCoreDepositFuseEnterArgs`, ...; `EXTERNAL_STATE_EVENT_ARGS` /
854
- `HYPERCORE_EVENT_ARGS` map an event name to its shape). Values carry nominal types
855
- (`Amount`, `MarketId`, `FuseAddress`, `HyperCoreTokenIndex`, `PayloadHash`, web3's
856
- `Timestamp`, ...). `event.args["signer"]` no longer type-checks on its own: narrow
857
- with a key test (`if "signer" in event.args:`). `HyperCoreEvent.fuse` is a
858
- `FuseAddress | None`.
850
+ - Decoded events are discriminated unions. `ExternalStateEvent` and `HyperCoreEvent`
851
+ are type aliases over one frozen dataclass per event (`ExternalStateUnpausedEvent`,
852
+ `HyperCoreDepositFuseEnterEvent`, ...), each with `name: Literal["<event>"]` and
853
+ `args` typed as that event's TypedDict (`ExternalStateUnpausedArgs`, ...). Comparing
854
+ `name` narrows the event and its `args`, with no key test:
855
+
856
+ ```python
857
+ for event in external_state_events(receipt):
858
+ if event.name == "ExternalStateUnpaused":
859
+ event.args["signer"] # ChecksumAddress
860
+ match hc_event:
861
+ case HyperCoreDepositFuseEnterEvent(args=args):
862
+ args["evmAsset"]
863
+ ```
864
+
865
+ Without that comparison `event.args["signer"]` does not type-check.
866
+ `isinstance(x, ExternalStateEvent)` still works (the alias is a union); the events
867
+ are no longer built positionally (`ExternalStateEvent(...)` is not a class: build
868
+ the event's own class with keywords, its `name` is preset).
869
+ `EXTERNAL_STATE_EVENT_CLASSES` / `HYPERCORE_EVENT_CLASSES` map an event name to its
870
+ class; they replace `EXTERNAL_STATE_EVENT_ARGS` / `HYPERCORE_EVENT_ARGS`, which are
871
+ removed. An event's args TypedDict is its class's `args` annotation:
872
+ `typing.get_type_hints(EXTERNAL_STATE_EVENT_CLASSES[name])["args"]`. Values carry nominal types (`Amount`, `MarketId`, `FuseAddress`,
873
+ `HyperCoreTokenIndex`, `PayloadHash`, web3's `Timestamp`, ...), and
874
+ `HyperCoreEvent.fuse` is a `FuseAddress | None` on every event.
859
875
  - `RawLog` (the log shape `ExternalStateExecutor.parse_balance_proposed` /
860
876
  `find_balance_proposed` accept) is `Mapping[str, object]`, not `Mapping[str, Any]`;
861
877
  a web3 `LogReceipt` still fits it.
@@ -935,5 +951,22 @@ are listed with a link.
935
951
  decoder cannot read raises the decoder's error. 3.x left it out of
936
952
  `result.observations` (so `result.get(label)` raised `KeyError`) or reported an
937
953
  undecodable read as `None`, indistinguishable from a read that returns `None`.
954
+ - **Check `success`; `error` is always set on failure.** A failed
955
+ `SimulatedCallResult` always carries a non-empty `error`: the node's message joined
956
+ with the decoded revert (`"execution reverted: NotAllowed"`), the decoded revert
957
+ alone when the node sent no message, else `"reverted without a reason"` (with the
958
+ return data's hex when it is too short to decode). 3.x could report `success=False`
959
+ with `error=None`, and `error` was the node's message only. A successful call's
960
+ `error` is `None`, and constructing one with an `error` raises `ValueError`.
961
+ `revert_reason` is `None` exactly when the call succeeded. The messages of
962
+ `SimulationResult.raise_for_failure` and `SimulationObservation.value`'s
963
+ `SimulationError` are `failed: {error}`; drop any `call.error or "reverted"`
964
+ fallback and match on `revert_reason`, not on the text of `error`.
965
+ - **`SimulatedCallResult` and `SimulationResult` are frozen**, so the rule above
966
+ holds after construction too: assigning a field raises
967
+ `dataclasses.FrozenInstanceError`. Build a changed copy with
968
+ `dataclasses.replace(result, ...)` (a failed call's `error` is completed again).
969
+ Both stay unhashable (`__hash__` is `None`, as before). The freeze is shallow:
970
+ the `logs` / `calls` lists themselves can still be mutated.
938
971
  - Saved config entries are checksummed when loaded; the MCP `vault_add` tool rejects
939
972
  a value that is not an address.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: ipor-fusion
3
- Version: 4.0.0.dev162
3
+ Version: 4.0.0.dev168
4
4
  Summary: The IPOR Fusion SDK for Python
5
5
  Project-URL: homepage, https://ipor.io
6
6
  Project-URL: repository, https://github.com/IPOR-Labs/ipor-fusion.py
@@ -191,9 +191,7 @@ def _assert_all_success(result: SimulationResult) -> None:
191
191
  if result.all_success:
192
192
  return
193
193
  failed = [(c.label, c.error) for c in result.failed_calls]
194
- raise AssertionError(
195
- f"simulation calls failed: {failed} (reason={result.revert_reason})"
196
- )
194
+ raise AssertionError(f"simulation calls failed: {failed}")
197
195
 
198
196
 
199
197
  def _connected_web3() -> Web3:
@@ -153,9 +153,7 @@ def _assert_all_success(result: SimulationResult) -> None:
153
153
  if result.all_success:
154
154
  return
155
155
  failed = [(call.label, call.error) for call in result.failed_calls]
156
- raise AssertionError(
157
- f"simulation calls failed: {failed} (reason={result.revert_reason})"
158
- )
156
+ raise AssertionError(f"simulation calls failed: {failed}")
159
157
 
160
158
 
161
159
  def _connected_web3() -> Web3:
@@ -634,7 +634,7 @@ def core_leg_previews(web3_hype: Web3) -> list[Preview]:
634
634
  # ── Part B: the hub legs, simulated at pinned blocks ─────────────────────────
635
635
  def _assert_relay_success(results: dict[ChainId, SimulationResult]) -> None:
636
636
  failed = [
637
- f"{chain}:{call.label}:{call.revert_reason}"
637
+ f"{chain}:{call.label}:{call.error}"
638
638
  for chain, result in results.items()
639
639
  for call in result.calls
640
640
  if not call.success
@@ -179,7 +179,7 @@ def _assert_relay_success(results: dict[ChainId, SimulationResult]) -> None:
179
179
  """Raise with a readable summary if any simulated call on either chain
180
180
  reverted; each entry names the call and decodes its own revert."""
181
181
  failed = [
182
- (int(chain_id), call.label, call.revert_reason or call.error)
182
+ (int(chain_id), call.label, call.error)
183
183
  for chain_id, result in results.items()
184
184
  for call in result.calls
185
185
  if not call.success
@@ -332,9 +332,7 @@ def _assert_all_success(result: SimulationResult) -> None:
332
332
  if result.all_success:
333
333
  return
334
334
  failed = [(c.label, c.error) for c in result.failed_calls]
335
- raise AssertionError(
336
- f"simulation calls failed: {failed} (reason={result.revert_reason})"
337
- )
335
+ raise AssertionError(f"simulation calls failed: {failed}")
338
336
 
339
337
 
340
338
  def _assert_only_expected_failure(result: SimulationResult, label: str) -> bytes:
@@ -159,9 +159,7 @@ def _assert_all_success(result: SimulationResult) -> None:
159
159
  if result.all_success:
160
160
  return
161
161
  failed = [(c.label, c.error) for c in result.failed_calls]
162
- raise AssertionError(
163
- f"simulation calls failed: {failed} (reason={result.revert_reason})"
164
- )
162
+ raise AssertionError(f"simulation calls failed: {failed}")
165
163
 
166
164
 
167
165
  def _connected_web3() -> Web3:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ipor-fusion"
3
- version = "4.0.0.dev162"
3
+ version = "4.0.0.dev168"
4
4
  description = "The IPOR Fusion SDK for Python"
5
5
  authors = [
6
6
  { name = "Adam Mydlarz", email = "amydlarz@gmail.com" },
@@ -316,43 +316,68 @@ from ipor_fusion.fuses import (
316
316
  system_address,
317
317
  )
318
318
  from ipor_fusion.fuses.external_state_events import (
319
- EXTERNAL_STATE_EVENT_ARGS,
319
+ EXTERNAL_STATE_EVENT_CLASSES,
320
320
  EXTERNAL_STATE_EVENT_SPECS,
321
321
  EXTERNAL_STATE_EVENTS,
322
322
  EXTERNAL_STATE_TOPICS,
323
323
  ExternalStateAssetRescuedArgs,
324
+ ExternalStateAssetRescuedEvent,
325
+ ExternalStateBalanceFuseLastCustodianTimestampUpdatedEvent,
326
+ ExternalStateBalanceFuseLastTotalBalanceUpdatedEvent,
324
327
  ExternalStateBigChangeDetectedArgs,
328
+ ExternalStateBigChangeDetectedEvent,
325
329
  ExternalStateCustodianTimestampUpdatedArgs,
326
330
  ExternalStateEvent,
327
331
  ExternalStateEventArgs,
328
332
  ExternalStateEventSpec,
329
333
  ExternalStateExecutorArgs,
334
+ ExternalStateExecutorCreatedEvent,
335
+ ExternalStateExecutorDeployedEvent,
330
336
  ExternalStateOperationArgs,
337
+ ExternalStateOperationFuseEnterEvent,
338
+ ExternalStateOperationFuseExitEvent,
331
339
  ExternalStateTotalBalanceUpdatedArgs,
332
340
  ExternalStateUnpausedArgs,
341
+ ExternalStateUnpausedEvent,
333
342
  decode_external_state_event,
334
343
  external_state_event_name,
335
344
  external_state_events,
336
345
  )
337
346
  from ipor_fusion.fuses.hypercore_events import (
338
- HYPERCORE_EVENT_ARGS,
347
+ HYPERCORE_EVENT_CLASSES,
339
348
  HyperCoreActionEnqueuedArgs,
349
+ HyperCoreActionEnqueuedEvent,
340
350
  HyperCoreActionSettledArgs,
351
+ HyperCoreActionSettledEvent,
341
352
  HyperCoreBuilderFeeFuseEnterArgs,
353
+ HyperCoreBuilderFeeFuseEnterEvent,
342
354
  HyperCoreCancelByCloidArgs,
343
355
  HyperCoreCancelByOidArgs,
356
+ HyperCoreCancelFuseCancelByCloidEvent,
357
+ HyperCoreCancelFuseCancelByOidEvent,
344
358
  HyperCoreDepositFuseEnterArgs,
359
+ HyperCoreDepositFuseEnterEvent,
345
360
  HyperCoreEventArgs,
346
361
  HyperCoreMarginFuseEnterArgs,
362
+ HyperCoreMarginFuseEnterEvent,
347
363
  HyperCoreObserverSetChangedArgs,
364
+ HyperCoreObserverSetChangedEvent,
348
365
  HyperCoreObserverSetProposedArgs,
366
+ HyperCoreObserverSetProposedEvent,
349
367
  HyperCoreOrderFuseEnterArgs,
368
+ HyperCoreOrderFuseEnterEvent,
350
369
  HyperCoreRecoveryExecutedArgs,
370
+ HyperCoreRecoveryExecutedEvent,
351
371
  HyperCoreRecoveryProposedArgs,
372
+ HyperCoreRecoveryProposedEvent,
352
373
  HyperCoreReportedActionSettledArgs,
374
+ HyperCoreReportedActionSettledEvent,
353
375
  HyperCoreReportSubmittedArgs,
376
+ HyperCoreReportSubmittedEvent,
354
377
  HyperCoreSendFuseSendAssetArgs,
378
+ HyperCoreSendFuseSendAssetEvent,
355
379
  HyperCoreSendFuseSpotSendArgs,
380
+ HyperCoreSendFuseSpotSendEvent,
356
381
  )
357
382
  from ipor_fusion.market_ids import IporFusionMarkets
358
383
  from ipor_fusion.market_info import (
@@ -591,7 +616,16 @@ __all__ = [
591
616
  "EXTERNAL_STATE_EVENTS",
592
617
  "EXTERNAL_STATE_TOPICS",
593
618
  "ExternalStateEvent",
594
- "EXTERNAL_STATE_EVENT_ARGS",
619
+ "EXTERNAL_STATE_EVENT_CLASSES",
620
+ "ExternalStateBigChangeDetectedEvent",
621
+ "ExternalStateBalanceFuseLastCustodianTimestampUpdatedEvent",
622
+ "ExternalStateBalanceFuseLastTotalBalanceUpdatedEvent",
623
+ "ExternalStateUnpausedEvent",
624
+ "ExternalStateAssetRescuedEvent",
625
+ "ExternalStateExecutorCreatedEvent",
626
+ "ExternalStateOperationFuseEnterEvent",
627
+ "ExternalStateOperationFuseExitEvent",
628
+ "ExternalStateExecutorDeployedEvent",
595
629
  "ExternalStateAssetRescuedArgs",
596
630
  "ExternalStateBigChangeDetectedArgs",
597
631
  "ExternalStateCustodianTimestampUpdatedArgs",
@@ -608,7 +642,23 @@ __all__ = [
608
642
  "HYPERCORE_EVENTS",
609
643
  "HYPERCORE_EVENT_SPECS",
610
644
  "HyperCoreEvent",
611
- "HYPERCORE_EVENT_ARGS",
645
+ "HYPERCORE_EVENT_CLASSES",
646
+ "HyperCoreDepositFuseEnterEvent",
647
+ "HyperCoreMarginFuseEnterEvent",
648
+ "HyperCoreSendFuseSpotSendEvent",
649
+ "HyperCoreSendFuseSendAssetEvent",
650
+ "HyperCoreOrderFuseEnterEvent",
651
+ "HyperCoreCancelFuseCancelByOidEvent",
652
+ "HyperCoreCancelFuseCancelByCloidEvent",
653
+ "HyperCoreBuilderFeeFuseEnterEvent",
654
+ "HyperCoreActionEnqueuedEvent",
655
+ "HyperCoreActionSettledEvent",
656
+ "HyperCoreReportedActionSettledEvent",
657
+ "HyperCoreReportSubmittedEvent",
658
+ "HyperCoreObserverSetProposedEvent",
659
+ "HyperCoreObserverSetChangedEvent",
660
+ "HyperCoreRecoveryProposedEvent",
661
+ "HyperCoreRecoveryExecutedEvent",
612
662
  "HyperCoreActionEnqueuedArgs",
613
663
  "HyperCoreActionSettledArgs",
614
664
  "HyperCoreBuilderFeeFuseEnterArgs",
@@ -142,8 +142,17 @@ class _Block:
142
142
  override_provider: StateOverrideProvider | None = None
143
143
 
144
144
 
145
- @dataclass(slots=True)
145
+ @dataclass(frozen=True, slots=True)
146
146
  class SimulatedCallResult:
147
+ """One simulated call. ``error`` is set exactly when ``success`` is False:
148
+ check ``success``, then read ``error`` for a non-empty, human-readable
149
+ failure (the node's message with the decoded revert reason, or
150
+ ``"reverted without a reason"`` plus any undecodable return data).
151
+ Construction enforces it: a failed call's ``error`` is completed from its
152
+ return data, and a successful call given an ``error`` raises
153
+ ``ValueError``. The record is frozen, so the invariant holds afterwards;
154
+ build a changed copy with `dataclasses.replace`."""
155
+
147
156
  label: str | None
148
157
  success: bool
149
158
  return_data: HexBytes
@@ -151,19 +160,33 @@ class SimulatedCallResult:
151
160
  error: str | None
152
161
  logs: list[dict]
153
162
  predicted_address: ChecksumAddress | None = None
163
+ # Frozen would add a __hash__ that fails on the logs list; stay unhashable.
164
+ __hash__ = None # type: ignore[assignment]
165
+
166
+ def __post_init__(self) -> None:
167
+ if self.success:
168
+ if self.error is not None:
169
+ raise ValueError(
170
+ f"successful simulated call {self.label!r} carries an error"
171
+ )
172
+ else:
173
+ # The record is frozen; completing the error is part of building it.
174
+ object.__setattr__(
175
+ self, "error", _failure_message(self.error, self.return_data)
176
+ )
154
177
 
155
178
  @property
156
179
  def revert_reason(self) -> str | None:
157
180
  """This call's decoded revert (a registered custom error by name, an
158
- ``Error(string)`` text or ``Panic``), ``None`` when it succeeded or
159
- reverted without data. ``SimulationResult.revert_reason`` is the
181
+ ``Error(string)`` text or ``Panic``), else its ``error``; ``None``
182
+ exactly when it succeeded. ``SimulationResult.revert_reason`` is the
160
183
  chain's first failed call, which may be a different one."""
161
184
  if self.success:
162
185
  return None
163
186
  return _decode_revert(self.return_data, self.error)
164
187
 
165
188
 
166
- @dataclass(slots=True)
189
+ @dataclass(frozen=True, slots=True)
167
190
  class SimulationResult:
168
191
  success: bool
169
192
  all_success: bool
@@ -172,6 +195,7 @@ class SimulationResult:
172
195
  execute_logs: list[dict]
173
196
  calls: list[SimulatedCallResult] = field(default_factory=list)
174
197
  failed_calls: list[SimulatedCallResult] = field(default_factory=list)
198
+ __hash__ = None # type: ignore[assignment]
175
199
 
176
200
  def raise_for_failure(self) -> None:
177
201
  """Raise :class:`SimulationError` naming the first failed call (label,
@@ -179,15 +203,11 @@ class SimulationResult:
179
203
  if not self.failed_calls:
180
204
  return
181
205
  first = self.failed_calls[0]
182
- reason = _decode_revert(first.return_data, first.error)
183
206
  label = first.label or "<unlabelled>"
184
- detail = first.error or "reverted"
185
- if reason and reason != first.error:
186
- detail = f"{detail}: {reason}"
187
207
  raise SimulationError(
188
- f"simulated call {label!r} failed: {detail}",
208
+ f"simulated call {label!r} failed: {first.error}",
189
209
  label=first.label,
190
- revert_reason=reason,
210
+ revert_reason=first.revert_reason,
191
211
  )
192
212
 
193
213
 
@@ -223,12 +243,10 @@ class SimulationObservation(Generic[T_co]):
223
243
  result = self.result
224
244
  name = self._label or "<unlabelled>"
225
245
  if not result.success:
226
- reason = result.revert_reason
227
246
  raise SimulationError(
228
- f"observation {name!r} failed: {result.error or 'reverted'}"
229
- + (f": {reason}" if reason and reason != result.error else ""),
247
+ f"observation {name!r} failed: {result.error}",
230
248
  label=self._label,
231
- revert_reason=reason,
249
+ revert_reason=result.revert_reason,
232
250
  )
233
251
  if not result.return_data:
234
252
  raise EmptyCallResultError(
@@ -732,7 +750,7 @@ class VaultSimulator:
732
750
  status = int(raw.get("status", "0x1"), 16)
733
751
  success = status == 1
734
752
  gas_used = int(raw.get("gasUsed", "0x0"), 16)
735
- error, return_data = _normalize_call_error(raw.get("error"), return_data)
753
+ message, return_data = _normalize_call_error(raw.get("error"), return_data)
736
754
  logs = raw.get("logs", []) or []
737
755
 
738
756
  call_result = SimulatedCallResult(
@@ -740,7 +758,7 @@ class VaultSimulator:
740
758
  success=success,
741
759
  return_data=return_data,
742
760
  gas_used=gas_used,
743
- error=error,
761
+ error=None if success else message,
744
762
  logs=logs,
745
763
  predicted_address=(source.predicted_address if success else None),
746
764
  )
@@ -753,14 +771,13 @@ class VaultSimulator:
753
771
  execute_gas += gas_used
754
772
  execute_logs.extend(logs)
755
773
  if not success and revert_reason is None:
756
- revert_reason = _decode_revert(return_data, error)
774
+ revert_reason = call_result.revert_reason
757
775
 
758
776
  failed_calls = [c for c in parsed if not c.success]
759
777
  all_success = not failed_calls
760
778
  if revert_reason is None and failed_calls:
761
779
  # No execute call reverted but a setup/observation did — surface it.
762
- first_failed = failed_calls[0]
763
- revert_reason = _decode_revert(first_failed.return_data, first_failed.error)
780
+ revert_reason = failed_calls[0].revert_reason
764
781
 
765
782
  return SimulationResult(
766
783
  success=execute_success,
@@ -910,6 +927,22 @@ def _normalize_call_error(
910
927
  return (error_raw if isinstance(error_raw, str) else None), return_data
911
928
 
912
929
 
930
+ def _failure_message(message: str | None, return_data: HexBytes) -> str:
931
+ """A failed call's ``error``: the node's message joined with the decoded
932
+ revert unless the message already carries it, else whichever exists, else
933
+ ``"reverted without a reason"`` with any return data too short to decode."""
934
+ reason = _decode_revert(return_data, None)
935
+ if message and reason:
936
+ return message if reason in message else f"{message}: {reason}"
937
+ if message:
938
+ return message
939
+ if reason:
940
+ return reason
941
+ if return_data:
942
+ return f"reverted without a reason (return data 0x{bytes(return_data).hex()})"
943
+ return "reverted without a reason"
944
+
945
+
913
946
  def _decode_revert(return_data: HexBytes, error: str | None) -> str | None:
914
947
  if return_data and len(return_data) >= 4:
915
948
  selector = bytes(return_data[:4])
@@ -50,28 +50,44 @@ from ipor_fusion.fuses.hypercore import (
50
50
  system_address,
51
51
  )
52
52
  from ipor_fusion.fuses.hypercore_events import (
53
- HYPERCORE_EVENT_ARGS,
53
+ HYPERCORE_EVENT_CLASSES,
54
54
  HYPERCORE_EVENT_SPECS,
55
55
  HYPERCORE_EVENTS,
56
56
  HyperCoreActionEnqueuedArgs,
57
+ HyperCoreActionEnqueuedEvent,
57
58
  HyperCoreActionSettledArgs,
59
+ HyperCoreActionSettledEvent,
58
60
  HyperCoreBuilderFeeFuseEnterArgs,
61
+ HyperCoreBuilderFeeFuseEnterEvent,
59
62
  HyperCoreCancelByCloidArgs,
60
63
  HyperCoreCancelByOidArgs,
64
+ HyperCoreCancelFuseCancelByCloidEvent,
65
+ HyperCoreCancelFuseCancelByOidEvent,
61
66
  HyperCoreDepositFuseEnterArgs,
67
+ HyperCoreDepositFuseEnterEvent,
62
68
  HyperCoreEvent,
63
69
  HyperCoreEventArgs,
64
70
  HyperCoreEventSpec,
65
71
  HyperCoreMarginFuseEnterArgs,
72
+ HyperCoreMarginFuseEnterEvent,
66
73
  HyperCoreObserverSetChangedArgs,
74
+ HyperCoreObserverSetChangedEvent,
67
75
  HyperCoreObserverSetProposedArgs,
76
+ HyperCoreObserverSetProposedEvent,
68
77
  HyperCoreOrderFuseEnterArgs,
78
+ HyperCoreOrderFuseEnterEvent,
69
79
  HyperCoreRecoveryExecutedArgs,
80
+ HyperCoreRecoveryExecutedEvent,
70
81
  HyperCoreRecoveryProposedArgs,
82
+ HyperCoreRecoveryProposedEvent,
71
83
  HyperCoreReportedActionSettledArgs,
84
+ HyperCoreReportedActionSettledEvent,
72
85
  HyperCoreReportSubmittedArgs,
86
+ HyperCoreReportSubmittedEvent,
73
87
  HyperCoreSendFuseSendAssetArgs,
88
+ HyperCoreSendFuseSendAssetEvent,
74
89
  HyperCoreSendFuseSpotSendArgs,
90
+ HyperCoreSendFuseSpotSendEvent,
75
91
  decode_hypercore_event,
76
92
  find_hypercore_events,
77
93
  hypercore_event_name,
@@ -112,7 +128,23 @@ __all__ = [
112
128
  "HYPERCORE_EVENTS",
113
129
  "HYPERCORE_EVENT_SPECS",
114
130
  "HyperCoreEvent",
115
- "HYPERCORE_EVENT_ARGS",
131
+ "HYPERCORE_EVENT_CLASSES",
132
+ "HyperCoreDepositFuseEnterEvent",
133
+ "HyperCoreMarginFuseEnterEvent",
134
+ "HyperCoreSendFuseSpotSendEvent",
135
+ "HyperCoreSendFuseSendAssetEvent",
136
+ "HyperCoreOrderFuseEnterEvent",
137
+ "HyperCoreCancelFuseCancelByOidEvent",
138
+ "HyperCoreCancelFuseCancelByCloidEvent",
139
+ "HyperCoreBuilderFeeFuseEnterEvent",
140
+ "HyperCoreActionEnqueuedEvent",
141
+ "HyperCoreActionSettledEvent",
142
+ "HyperCoreReportedActionSettledEvent",
143
+ "HyperCoreReportSubmittedEvent",
144
+ "HyperCoreObserverSetProposedEvent",
145
+ "HyperCoreObserverSetChangedEvent",
146
+ "HyperCoreRecoveryProposedEvent",
147
+ "HyperCoreRecoveryExecutedEvent",
116
148
  "HyperCoreActionEnqueuedArgs",
117
149
  "HyperCoreActionSettledArgs",
118
150
  "HyperCoreBuilderFeeFuseEnterArgs",