ipor-fusion 4.0.0.dev146__tar.gz → 4.0.0.dev149__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 (300) hide show
  1. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/MIGRATION_4.md +36 -4
  2. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/PKG-INFO +1 -1
  3. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/examples/composed_hypercore_flow_arbitrum_hyperevm.py +3 -2
  4. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/examples/crosschain_ccip_usdc_arbitrum_hyperevm.py +3 -3
  5. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/pyproject.toml +1 -1
  6. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/external_state_executor.py +9 -5
  7. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/fusion_factory.py +2 -2
  8. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/ccip/codec.py +4 -4
  9. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/ccip/contracts.py +21 -13
  10. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/ccip/transport.py +3 -3
  11. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/contracts.py +24 -14
  12. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/stargate/contracts.py +24 -13
  13. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/stargate/layerzero.py +9 -3
  14. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/stargate/transport.py +5 -5
  15. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/transport.py +3 -3
  16. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/external_state.py +3 -3
  17. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/morpho_api.py +66 -59
  18. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/aave_v4.py +3 -2
  19. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/hypercore.py +9 -7
  20. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/oracle_mapping.py +2 -1
  21. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/oracle_mapping_nodes.py +7 -6
  22. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/oracle_mapping_reader.py +12 -10
  23. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/.claude-plugin/marketplace.json +0 -0
  24. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/.claude-plugin/plugin.json +0 -0
  25. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/.env.example +0 -0
  26. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/.gemini/settings.json +0 -0
  27. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/.git-blame-ignore-revs +0 -0
  28. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/.github/workflows/cd.yml +0 -0
  29. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/.github/workflows/ci.yml +0 -0
  30. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/.github/workflows/commit-lint.yml +0 -0
  31. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/.github/workflows/notify-slack.yml +0 -0
  32. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/.github/workflows/python-build.yml +0 -0
  33. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/.github/workflows/python-publish.yml +0 -0
  34. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/.github/workflows/release.yml +0 -0
  35. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/.github/workflows/report-slack.yml +0 -0
  36. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/.gitignore +0 -0
  37. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/.mcp.json +0 -0
  38. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/.pre-commit-config.yaml +0 -0
  39. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/.python-version +0 -0
  40. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/AGENTS.md +0 -0
  41. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/CHANGELOG.md +0 -0
  42. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/CLAUDE.md +0 -0
  43. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/CODEOWNERS +0 -0
  44. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/LICENSE +0 -0
  45. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/README.md +0 -0
  46. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/build.sh +0 -0
  47. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/examples/CONTRIBUTING.md +0 -0
  48. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/examples/README.md +0 -0
  49. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/examples/advanced_euler_v2_credit_market_base.py +0 -0
  50. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/examples/advanced_euler_v2_looping_arbitrum.py +0 -0
  51. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/examples/external_state_margin_leg_base.py +0 -0
  52. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/examples/simple_aave_v3_supply_base.py +0 -0
  53. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/pytest.ini +0 -0
  54. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/scripts/commit-check.sh +0 -0
  55. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/scripts/crosschain_readiness.py +0 -0
  56. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/skills/ipor-deploy-vault/SKILL.md +0 -0
  57. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/__init__.py +0 -0
  58. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/about.py +0 -0
  59. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cache.py +0 -0
  60. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/chains.py +0 -0
  61. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/__init__.py +0 -0
  62. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/changelog_cmd.py +0 -0
  63. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/config_cmd.py +0 -0
  64. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/config_store.py +0 -0
  65. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/main.py +0 -0
  66. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/market_cmd.py +0 -0
  67. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/options.py +0 -0
  68. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/oracle_mapping_view.py +0 -0
  69. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/vault_cmd.py +0 -0
  70. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/vault_health.py +0 -0
  71. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/vault_info_view.py +0 -0
  72. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/vault_markets_view.py +0 -0
  73. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/cli/vault_rendering.py +0 -0
  74. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/config/__init__.py +0 -0
  75. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/config/roles.py +0 -0
  76. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/__init__.py +0 -0
  77. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/access.py +0 -0
  78. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/address.py +0 -0
  79. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/context.py +0 -0
  80. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/contract.py +0 -0
  81. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/erc20.py +0 -0
  82. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/fee_manager.py +0 -0
  83. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/fuse.py +0 -0
  84. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/fuse_action.py +0 -0
  85. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/logs.py +0 -0
  86. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/multicall.py +0 -0
  87. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/oracle.py +0 -0
  88. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/plasma_vault.py +0 -0
  89. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/rewards_manager.py +0 -0
  90. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/simulation.py +0 -0
  91. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/core/withdraw_manager.py +0 -0
  92. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/__init__.py +0 -0
  93. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/ccip/__init__.py +0 -0
  94. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/ccip/chainlink.py +0 -0
  95. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/ccip/events.py +0 -0
  96. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/ccip/indexer.py +0 -0
  97. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/ccip/lane.py +0 -0
  98. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/ccip/quote.py +0 -0
  99. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/discovery.py +0 -0
  100. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/errors.py +0 -0
  101. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/fuses/__init__.py +0 -0
  102. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/fuses/base.py +0 -0
  103. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/fuses/ccip.py +0 -0
  104. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/fuses/stargate.py +0 -0
  105. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/lane.py +0 -0
  106. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/logs.py +0 -0
  107. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/messages.py +0 -0
  108. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/simulation.py +0 -0
  109. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/stargate/__init__.py +0 -0
  110. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/crosschain/stargate/lane.py +0 -0
  111. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/dependency_graph.py +0 -0
  112. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/entry_cli.py +0 -0
  113. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/entry_mcp.py +0 -0
  114. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/errors.py +0 -0
  115. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/explorer.py +0 -0
  116. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/field_docs.py +0 -0
  117. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/__init__.py +0 -0
  118. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/aave_v3.py +0 -0
  119. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/async_action.py +0 -0
  120. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/base.py +0 -0
  121. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/compound_v3.py +0 -0
  122. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/erc4626.py +0 -0
  123. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/euler_v2.py +0 -0
  124. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/events.py +0 -0
  125. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/external_state_events.py +0 -0
  126. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/fluid_instadapp.py +0 -0
  127. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/gearbox_v3.py +0 -0
  128. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/hypercore.py +0 -0
  129. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/hypercore_events.py +0 -0
  130. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/merkl.py +0 -0
  131. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/morpho.py +0 -0
  132. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/ramses_v2.py +0 -0
  133. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/uniswap_v3.py +0 -0
  134. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/fuses/universal.py +0 -0
  135. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/guide/__init__.py +0 -0
  136. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/guide/architecture.md +0 -0
  137. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/guide/glossary.md +0 -0
  138. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/guide/invariants.md +0 -0
  139. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/guide/quickstart.md +0 -0
  140. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/market_ids.py +0 -0
  141. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/market_info.py +0 -0
  142. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/mcp/__init__.py +0 -0
  143. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/mcp/guide.py +0 -0
  144. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/mcp/models.py +0 -0
  145. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/mcp/server.py +0 -0
  146. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/py.typed +0 -0
  147. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/__init__.py +0 -0
  148. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/aave_v3.py +0 -0
  149. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/compound_v3.py +0 -0
  150. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/hypercore_outcome.py +0 -0
  151. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/lending_health.py +0 -0
  152. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/morpho.py +0 -0
  153. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/position_manager.py +0 -0
  154. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/ramses_v2.py +0 -0
  155. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/uniswap_v3.py +0 -0
  156. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/readers/unpriceable.py +0 -0
  157. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/substrates.py +0 -0
  158. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/types.py +0 -0
  159. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/validation.py +0 -0
  160. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/vault_data.py +0 -0
  161. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/vault_erc20.py +0 -0
  162. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/vault_info.py +0 -0
  163. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/vault_managers.py +0 -0
  164. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/vault_positions.py +0 -0
  165. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/src/ipor_fusion/vault_reads.py +0 -0
  166. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/UniswapV3UniversalRouter.py +0 -0
  167. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/_crosschain.py +0 -0
  168. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/_crosschain_lifecycle.py +0 -0
  169. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/_crosschain_recovery.py +0 -0
  170. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/_euler_v2.py +0 -0
  171. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/_foundry.py +0 -0
  172. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/_guide.py +0 -0
  173. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/_hypercore_model.py +0 -0
  174. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/_hypercore_shadow.py +0 -0
  175. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/_multicall.py +0 -0
  176. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/_simulate.py +0 -0
  177. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/_validation.py +0 -0
  178. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/addresses.py +0 -0
  179. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/conftest.py +0 -0
  180. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/constants.py +0 -0
  181. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/fixtures/hypercore_hip3_flow.json +0 -0
  182. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/fixtures/hypercore_market55.json +0 -0
  183. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/fixtures/vault_info_golden/clean.json +0 -0
  184. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/fixtures/vault_info_golden/clean.txt +0 -0
  185. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/fixtures/vault_info_golden/rich.json +0 -0
  186. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/fixtures/vault_info_golden/rich.txt +0 -0
  187. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_about.py +0 -0
  188. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_access_manager.py +0 -0
  189. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_cache.py +0 -0
  190. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_chains.py +0 -0
  191. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_cli_changelog.py +0 -0
  192. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_cli_commands.py +0 -0
  193. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_cli_config_store.py +0 -0
  194. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_cli_helpers.py +0 -0
  195. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_cli_hypercore.py +0 -0
  196. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_cli_lending_health.py +0 -0
  197. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_cli_market_morpho_blue.py +0 -0
  198. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_cli_oracle_mapping.py +0 -0
  199. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_cli_pending_requests_scan.py +0 -0
  200. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_cli_role_accounts.py +0 -0
  201. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_cli_vault_info_golden.py +0 -0
  202. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_cli_vault_predates_getters.py +0 -0
  203. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_cli_vault_validate.py +0 -0
  204. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_contract_call.py +0 -0
  205. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_contract_encoder.py +0 -0
  206. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_ccip_events.py +0 -0
  207. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_ccip_indexer.py +0 -0
  208. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_ccip_quote.py +0 -0
  209. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_chainlink.py +0 -0
  210. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_contracts.py +0 -0
  211. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_encoding.py +0 -0
  212. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_errors.py +0 -0
  213. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_lane.py +0 -0
  214. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_layering.py +0 -0
  215. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_readiness.py +0 -0
  216. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_readiness_report.py +0 -0
  217. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_crosschain_transport.py +0 -0
  218. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_docs_typing.py +0 -0
  219. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_erc20.py +0 -0
  220. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_error_hierarchy.py +0 -0
  221. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_examples_composed_hypercore.py +0 -0
  222. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_examples_crosschain.py +0 -0
  223. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_examples_euler_looping_arbitrum.py +0 -0
  224. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_examples_vaults.py +0 -0
  225. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_explorer.py +0 -0
  226. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_external_state_events.py +0 -0
  227. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_external_state_executor.py +0 -0
  228. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_fee_manager.py +0 -0
  229. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_fuse_encoding.py +0 -0
  230. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_fusion_instance.py +0 -0
  231. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_guide.py +0 -0
  232. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_hypercore_deployment.py +0 -0
  233. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_hypercore_events.py +0 -0
  234. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_hypercore_flow.py +0 -0
  235. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_hypercore_live.py +0 -0
  236. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_hypercore_outcome.py +0 -0
  237. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_hypercore_readers.py +0 -0
  238. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_hypercore_simulation.py +0 -0
  239. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_logs.py +0 -0
  240. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_mcp_hypercore.py +0 -0
  241. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_mcp_models.py +0 -0
  242. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_mcp_server.py +0 -0
  243. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_mcp_vault_validate.py +0 -0
  244. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_multicall.py +0 -0
  245. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_oracle.py +0 -0
  246. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_oracle_mapping.py +0 -0
  247. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_plasma_vault.py +0 -0
  248. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_public_api.py +0 -0
  249. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_public_type_reachability.py +0 -0
  250. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_reader_encoding.py +0 -0
  251. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_readiness_selection.py +0 -0
  252. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_revert_decoding.py +0 -0
  253. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_rewards_manager.py +0 -0
  254. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_roles.py +0 -0
  255. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_sdk_layering.py +0 -0
  256. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_borrow_aave_v3_mainnet.py +0 -0
  257. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_claim_merkl_wrapper_base.py +0 -0
  258. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_claim_morpho_rewards.py +0 -0
  259. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_crosschain_canary.py +0 -0
  260. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_crosschain_hypercore.py +0 -0
  261. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_crosschain_hyperevm.py +0 -0
  262. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_crosschain_lifecycle.py +0 -0
  263. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_euler_v2_batch_base.py +0 -0
  264. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_euler_v2_credit_market_base.py +0 -0
  265. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_euler_v2_swap_deploy_base.py +0 -0
  266. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_euler_v2_swap_reconfigure_base.py +0 -0
  267. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_euler_v2_swap_registry_base.py +0 -0
  268. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_examples_arbitrum.py +0 -0
  269. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_examples_base.py +0 -0
  270. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_examples_crosschain.py +0 -0
  271. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_external_state_executor_base.py +0 -0
  272. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_fusion_factory_clone_base.py +0 -0
  273. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_looping_aave_v3_base.py +0 -0
  274. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_looping_morpho_blue_base.py +0 -0
  275. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_morpho_blue.py +0 -0
  276. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_pilot_v3.py +0 -0
  277. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_pilot_v4_uniswap.py +0 -0
  278. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_pilot_v5_ramses.py +0 -0
  279. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_pilot_v5_scheduled.py +0 -0
  280. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_plasma_vault_setters_base.py +0 -0
  281. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_readers_integration.py +0 -0
  282. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_release_funds.py +0 -0
  283. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_swap_on_base.py +0 -0
  284. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_simulate_vault_from_scratch_base.py +0 -0
  285. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_solidity_compiler.py +0 -0
  286. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_solidity_mirrors.py +0 -0
  287. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_substrates.py +0 -0
  288. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_types_and_events.py +0 -0
  289. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_unpriceable_tokens.py +0 -0
  290. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_validation.py +0 -0
  291. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_vault_data_block.py +0 -0
  292. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_vault_dep_graph.py +0 -0
  293. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_vault_info_onchain_base.py +0 -0
  294. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_vault_info_onchain_base_no_withdraw_manager.py +0 -0
  295. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_vault_simulator_blocks.py +0 -0
  296. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_web3_context.py +0 -0
  297. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/test_withdraw_manager.py +0 -0
  298. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/typed_client/consumer.py +0 -0
  299. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/tests/typed_client/rejected.py +0 -0
  300. {ipor_fusion-4.0.0.dev146 → ipor_fusion-4.0.0.dev149}/uv.lock +0 -0
@@ -543,7 +543,8 @@ converted amounts `Amount`. A custom `VaultState` annotates the same.
543
543
  `erc20_direct_total`, `sum`, `on_chain_total_assets`, `delta`,
544
544
  `pending_withdrawals`, `implied_market_total`, `market_storage_divergence`) are
545
545
  `Amount`. `FusionInstance.asset_decimals` / `underlying_token_decimals` are
546
- `Decimals`. `VaultSimulator.current_time` is a `Timestamp`.
546
+ `Decimals`, and `CloneArgs.redemption_delay_seconds` is a `Period`.
547
+ `VaultSimulator.current_time` is a `Timestamp`.
547
548
 
548
549
  **Vault data and helpers.** `ensure_supported_chain` takes `ChainId`.
549
550
  `fetch_unpriceable_priced_tokens` takes the oracle and underlying as
@@ -577,6 +578,10 @@ Decimals`, and `PriceOracleMiddleware.base_currency_decimals()` returns
577
578
  `Call[Decimals]`. `get_logs_adaptive(chain_id=)` takes `ChainId | None` and
578
579
  `LogSource.get_logs` a `ChainId`; `quote_ccip_native_fee(block=)` and
579
580
  `OracleMappingReader.asset_source_events` take a `BlockIdentifier`.
581
+ `OracleMappingReader.token_decimals`, `feed_decimals` and `vault_decimals` return
582
+ `Decimals | None` and `vault_convert_to_assets` an `Amount | None`;
583
+ `AaveV4OracleReader.decimals()` returns `Call[Decimals]`; and `OraclePrice.decimals`, `OracleNode.decimals` and
584
+ `OracleAsset.decimals` are `Decimals` (`| None` on the nodes).
580
585
 
581
586
  **Address roles.** `PlasmaVault(address)`,
582
587
  `validate_vault`, `fetch_deployment_info`, the HyperCore, lending-health and
@@ -628,6 +633,12 @@ takes a `ChecksumAddress`, and `build_morpho_blue_market_json` takes
628
633
  records is `ChecksumAddress`; optional ones (`curator`, `guardian`, `fee_recipient`,
629
634
  `performance_fee_recipient`, `management_fee_recipient`, `inner_vault`,
630
635
  `VaultFlowCap.admin`, the `VaultV2Cap` market params) are `ChecksumAddress | None`.
636
+ Token amounts on those records are `Amount` (`VaultFlowCap.max_in` / `max_out`, the
637
+ `VaultAllocation`, `VaultV1Info`, `VaultV1MarketAllocation`, `VaultV2Info` and
638
+ `MorphoApiMarket` asset amounts and caps, `VaultV2Cap.absolute_cap` / `allocation`
639
+ / `room`, `VaultV2Adapter.assets`, `cap_room`), token decimals are `Decimals` and
640
+ `MorphoApiMarket.timestamp` is a `Timestamp`. `lltv`, `fee_wad`,
641
+ `relative_cap_wad` and `fee_wei` stay `int`.
631
642
 
632
643
  **Crosschain.** The executor, dispatcher and factory wrappers, the lanes and
633
644
  `StargateCrosschainCommandFuse.enter(request_id=)` take the crosschain ids above, and
@@ -644,7 +655,20 @@ on CCIP, `active_return` → `OperationId`, `asset_id`, `tracked_position_set_ha
644
655
  `STALENESS_MAX` / `BALANCE_STALENESS_MAX` on the executors) a `Period`, and so do
645
656
  the `LaneHubState` fields; `attestation(remote_timestamp=, expiry=)` and
646
657
  `BalanceObservation` take `Timestamp`, `needs_attestation(now=, margin=)` a
647
- `Timestamp` and a `Period`. Decoded event values
658
+ `Timestamp` and a `Period`. The other durations are `Period` too: the executors'
659
+ `min_update_interval()`, `transfer_staleness_max()` and `deployment_ttl()`, both
660
+ factories' `config_delay()`, and the time fields of `ExecutorInitParams` and
661
+ `SafetyConfig` (`rescue_delay`, the staleness fields, `min_update_interval`,
662
+ `deployment_ttl`); `in_flight_since()`, `last_approval_at()`, `oldest_pending_at()`
663
+ and `pending_deployment_created_at()` return a `Timestamp`. Decimals are
664
+ `Decimals`: `local_decimals()` / `shared_decimals()` on the executor and dispatcher,
665
+ `CcipChain.local_decimals`, `StargateChain.local_decimals` / `shared_decimals`, the
666
+ `shared_decimals` of `CcipCrosschainFactory.asset_config()`, `schedule_asset` and
667
+ `execute_asset`. Token amounts are `Amount` (`EVMTokenAmount.amount`,
668
+ `TokenTransferV1.amount`, `TaxiMessage.amount_sd`, `OutboundMessage.token_amount`,
669
+ `StargateChain.to_local_decimals`), and `pending_request_shares()` returns
670
+ `Shares`. Counters, sequences, epochs, versions, bps and gas limits stay `int`.
671
+ Decoded event values
648
672
  (`ccip_events` → `CcipEvent.values`) stay a generic mapping: convert a value
649
673
  before passing it on.
650
674
 
@@ -667,7 +691,11 @@ fuse's `eid=` take it (`LayerZeroEid(30101)`). CCIP chain selectors are
667
691
  `read_hypercore_transfer_snapshot` and the helpers `system_address`,
668
692
  `precompile_index_of`, `perp_dex_of`, `is_native_perp_asset`, `is_hip3_asset` take the
669
693
  HyperCore ids; `HyperCorePerpAssetInfo`, `HyperCorePerpMarket`, `HyperCoreSpotLeg`,
670
- `HyperCorePendingState` and `HyperCoreTransferSnapshot` carry them.
694
+ `HyperCorePendingState` and `HyperCoreTransferSnapshot` carry them. Token decimals
695
+ (`HyperCoreTokenInfo.sz_decimals` / `wei_decimals` / `evm_extra_wei_decimals`,
696
+ `HyperCorePerpAssetInfo.sz_decimals`, `HyperCoreSpotLeg.wei_decimals`) are
697
+ `Decimals`, and `HyperCorePendingState.pending_until` / `current_timestamp` are
698
+ `Timestamp`; Core amounts, positions, WAD values and L1 block numbers stay `int`.
671
699
 
672
700
  **External state.** `ExternalStateExecutor.proposal_hash` returns and `confirm_balance`
673
701
  takes a `ProposalHash`; `BalanceProposal.proposal_hash` is a `ProposalHash`;
@@ -676,6 +704,9 @@ takes a `ProposalHash`; `BalanceProposal.proposal_hash` is a `ProposalHash`;
676
704
  `BalanceFuseSnapshot.last_custodian_update_timestamp`, `BalanceProposal.proposed_at`,
677
705
  `last_updated()` and `get_oldest_update_timestamp()` are web3's `Timestamp`, and
678
706
  `ExternalStateExecutor.proposal_hash(proposed_at=)` takes one.
707
+ `ExternalStateExecutor.staleness_max()` / `min_update_interval()` return a `Period`,
708
+ and `ExternalStateSubstrates.staleness_max` / `min_update_interval` take one
709
+ (`Period.DAY`).
679
710
 
680
711
  **Errors and explorer.** `TransactionError(tx_hash=)` takes a `TxHash | None`,
681
712
  `LogScanError(address=)` a `ChecksumAddress`; `get_revert_reason` takes a `TxHash`;
@@ -687,7 +718,8 @@ except as listed under [Behavior changes](#behavior-changes)): `chain_id` fields
687
718
  `ChainId`, `role_id` `RoleId`, `market_id` `MarketId` (except
688
719
  `LendingMarketHealth.market_id`, which stays `str | int`: a Morpho market id is a
689
720
  string). Calling an MCP tool function
690
- directly from Python takes `ChainId`.
721
+ directly from Python takes `ChainId`. Their amount, decimals and time fields stay
722
+ `int`: they are JSON output models, and the SDK values above fit them unchanged.
691
723
 
692
724
  ## Behavior changes
693
725
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: ipor-fusion
3
- Version: 4.0.0.dev146
3
+ Version: 4.0.0.dev149
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
@@ -110,6 +110,7 @@ from ipor_fusion.market_ids import IporFusionMarkets
110
110
  from ipor_fusion.types import (
111
111
  Amount,
112
112
  ChainId,
113
+ Decimals,
113
114
  HyperCoreAsset,
114
115
  HyperCoreClientOrderId,
115
116
  MarketId,
@@ -649,14 +650,14 @@ def _transport() -> CcipTransport:
649
650
  ARBITRUM_CCIP_SELECTOR,
650
651
  ARBITRUM_CCIP_ROUTER,
651
652
  ARBITRUM_USDC,
652
- 6,
653
+ Decimals(6),
653
654
  ),
654
655
  CcipChain(
655
656
  HYPEREVM_CHAIN_ID,
656
657
  HYPEREVM_CCIP_SELECTOR,
657
658
  HYPEREVM_CCIP_ROUTER,
658
659
  HYPEREVM_USDC,
659
- 6,
660
+ Decimals(6),
660
661
  ),
661
662
  )
662
663
  )
@@ -86,7 +86,7 @@ from ipor_fusion import (
86
86
  parse_plasma_vault_address,
87
87
  )
88
88
  from ipor_fusion.market_ids import IporFusionMarkets
89
- from ipor_fusion.types import Amount, ChainId, MarketId, Period, Shares
89
+ from ipor_fusion.types import Amount, ChainId, Decimals, MarketId, Period, Shares
90
90
 
91
91
  log = logging.getLogger("crosschain_ccip_usdc_arbitrum_hyperevm")
92
92
 
@@ -223,14 +223,14 @@ def transport() -> CcipTransport:
223
223
  ARBITRUM_CCIP_SELECTOR,
224
224
  ARBITRUM_CCIP_ROUTER,
225
225
  ARBITRUM_USDC,
226
- 6,
226
+ Decimals(6),
227
227
  ),
228
228
  CcipChain(
229
229
  HYPEREVM_CHAIN_ID,
230
230
  HYPEREVM_CCIP_SELECTOR,
231
231
  HYPEREVM_CCIP_ROUTER,
232
232
  HYPEREVM_USDC,
233
- 6,
233
+ Decimals(6),
234
234
  ),
235
235
  )
236
236
  )
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ipor-fusion"
3
- version = "4.0.0.dev146"
3
+ version = "4.0.0.dev149"
4
4
  description = "The IPOR Fusion SDK for Python"
5
5
  authors = [
6
6
  { name = "Adam Mydlarz", email = "amydlarz@gmail.com" },
@@ -35,6 +35,7 @@ from ipor_fusion.types import (
35
35
  ZERO_ADDRESS,
36
36
  Amount,
37
37
  ChainId,
38
+ Period,
38
39
  PlasmaVaultAddress,
39
40
  ProposalHash,
40
41
  )
@@ -371,10 +372,10 @@ class ExternalStateExecutor(ContractWrapper):
371
372
  "getOldestUpdateTimestamp()", output_types=["uint256"], decoder=Timestamp
372
373
  )
373
374
 
374
- def staleness_max(self) -> Call[int]:
375
+ def staleness_max(self) -> Call[Period]:
375
376
  """Seconds after which a custodian report counts as stale: the pre-hook
376
377
  blocks the vault's gated user operations past it."""
377
- return self._view("stalenessMax()", output_types=["uint256"])
378
+ return self._view("stalenessMax()", output_types=["uint256"], decoder=Period)
378
379
 
379
380
  def big_change_bps(self) -> Call[int]:
380
381
  """Basis points of total-balance change between two custodian updates
@@ -382,13 +383,16 @@ class ExternalStateExecutor(ContractWrapper):
382
383
  return self._view("bigChangeBps()", output_types=["uint256"])
383
384
 
384
385
  def dust_threshold(self) -> Call[int]:
385
- """Underlying units below which a leftover is dust, not a balance."""
386
+ """Dust threshold as a percent of one underlying token (100 = one whole
387
+ token); a leftover below it is dust, not a balance."""
386
388
  return self._view("dustThreshold()", output_types=["uint256"])
387
389
 
388
- def min_update_interval(self) -> Call[int]:
390
+ def min_update_interval(self) -> Call[Period]:
389
391
  """Seconds a balance account must wait between two custodian
390
392
  updates."""
391
- return self._view("minUpdateInterval()", output_types=["uint256"])
393
+ return self._view(
394
+ "minUpdateInterval()", output_types=["uint256"], decoder=Period
395
+ )
392
396
 
393
397
  def nonce(self) -> Call[int]:
394
398
  """Monotonic proposal nonce, incremented on every `proposeBalance`.
@@ -52,7 +52,7 @@ class CloneArgs:
52
52
  asset_name: str
53
53
  asset_symbol: str
54
54
  underlying_token: ChecksumAddress
55
- redemption_delay_seconds: int
55
+ redemption_delay_seconds: Period
56
56
  owner: ChecksumAddress
57
57
  dao_fee_package_index: int
58
58
 
@@ -391,7 +391,7 @@ class FusionFactory(ContractWrapper):
391
391
  asset_name=asset_name,
392
392
  asset_symbol=asset_symbol,
393
393
  underlying_token=Web3.to_checksum_address(underlying_token),
394
- redemption_delay_seconds=int(redemption_delay_seconds),
394
+ redemption_delay_seconds=Period(redemption_delay_seconds),
395
395
  owner=Web3.to_checksum_address(owner),
396
396
  dao_fee_package_index=int(dao_fee_package_index),
397
397
  )
@@ -21,7 +21,7 @@ from web3 import Web3
21
21
 
22
22
  from ipor_fusion.core.contract import _encode_calldata
23
23
  from ipor_fusion.crosschain.logs import log_bytes
24
- from ipor_fusion.types import CcipChainSelector, MessageId
24
+ from ipor_fusion.types import Amount, CcipChainSelector, MessageId
25
25
 
26
26
  #: topic0 of ``OnRamp 2.0.0``'s ``CCIPMessageSent``; ``destChainSelector``,
27
27
  #: ``sender`` and ``messageId`` are indexed.
@@ -72,7 +72,7 @@ class TokenTransferV1:
72
72
  """``MessageV1Codec.TokenTransferV1``. Address fields are raw bytes as
73
73
  encoded for the destination chain (20 bytes on EVM)."""
74
74
 
75
- amount: int
75
+ amount: Amount
76
76
  source_pool_address: bytes
77
77
  source_token_address: bytes
78
78
  dest_token_address: bytes
@@ -84,7 +84,7 @@ class TokenTransferV1:
84
84
  if reader.uint(1) != _MESSAGE_VERSION:
85
85
  raise ValueError("unsupported CCIP token transfer version")
86
86
  return cls(
87
- amount=reader.uint(32),
87
+ amount=Amount(reader.uint(32)),
88
88
  source_pool_address=reader.prefixed(1),
89
89
  source_token_address=reader.prefixed(1),
90
90
  dest_token_address=reader.prefixed(1),
@@ -207,7 +207,7 @@ class EVMTokenAmount:
207
207
  """``CcipClient.EVMTokenAmount``."""
208
208
 
209
209
  token: ChecksumAddress
210
- amount: int
210
+ amount: Amount
211
211
 
212
212
 
213
213
  @dataclass(frozen=True, slots=True)
@@ -8,6 +8,7 @@ from dataclasses import dataclass
8
8
  from eth_abi import encode
9
9
  from eth_typing import ChecksumAddress
10
10
  from eth_utils import keccak
11
+ from web3.types import Timestamp
11
12
 
12
13
  from ipor_fusion.core.contract import Call
13
14
  from ipor_fusion.crosschain.contracts import (
@@ -24,6 +25,7 @@ from ipor_fusion.types import (
24
25
  CcipChainSelector,
25
26
  ChainId,
26
27
  CommandId,
28
+ Decimals,
27
29
  MessageId,
28
30
  OperationId,
29
31
  Period,
@@ -93,11 +95,11 @@ class SafetyConfig:
93
95
  rescue_guardian: ChecksumAddress
94
96
  balance_proposer: ChecksumAddress
95
97
  balance_approver: ChecksumAddress
96
- rescue_delay: int
97
- balance_staleness_max: int
98
+ rescue_delay: Period
99
+ balance_staleness_max: Period
98
100
  big_change_bps: int
99
- min_update_interval: int
100
- transfer_staleness_max: int
101
+ min_update_interval: Period
102
+ transfer_staleness_max: Period
101
103
 
102
104
  def as_tuple(self) -> tuple:
103
105
  return (
@@ -231,8 +233,13 @@ class CcipCrosschainExecutor(CrosschainExecutor):
231
233
  decoder=CommandStatus,
232
234
  )
233
235
 
234
- def oldest_pending_at(self, chain_id: ChainId) -> Call[int]:
235
- return self._view("oldestPendingAt(uint256)", chain_id, output_types=["uint64"])
236
+ def oldest_pending_at(self, chain_id: ChainId) -> Call[Timestamp]:
237
+ return self._view(
238
+ "oldestPendingAt(uint256)",
239
+ chain_id,
240
+ output_types=["uint64"],
241
+ decoder=Timestamp,
242
+ )
236
243
 
237
244
  def pending_transfer_count(self, chain_id: ChainId) -> Call[int]:
238
245
  return self._view(
@@ -390,13 +397,13 @@ class CcipCrosschainFactory(CrosschainFactory):
390
397
 
391
398
  def asset_config(
392
399
  self, asset_id: AssetId
393
- ) -> Call[tuple[ChecksumAddress, int, bool]]:
400
+ ) -> Call[tuple[ChecksumAddress, Decimals, bool]]:
394
401
  """``(token, sharedDecimals, enabled)`` for an asset id."""
395
402
  return self._view(
396
403
  "assetConfig(bytes32)",
397
404
  asset_id,
398
405
  output_types=["address", "uint8", "bool"],
399
- decoder=lambda v: (_address(v[0]), int(v[1]), bool(v[2])),
406
+ decoder=lambda v: (_address(v[0]), Decimals(v[1]), bool(v[2])),
400
407
  )
401
408
 
402
409
  def is_dispatcher(self, dispatcher: ChecksumAddress) -> Call[bool]:
@@ -415,22 +422,23 @@ class CcipCrosschainFactory(CrosschainFactory):
415
422
 
416
423
  def pending_deployment_created_at(
417
424
  self, executor: ChecksumAddress, dst_chain_id: ChainId
418
- ) -> Call[int]:
425
+ ) -> Call[Timestamp]:
419
426
  return self._view(
420
427
  "pendingDeploymentCreatedAt(address,uint256)",
421
428
  executor,
422
429
  dst_chain_id,
423
430
  output_types=["uint64"],
431
+ decoder=Timestamp,
424
432
  )
425
433
 
426
434
  def owner(self) -> Call[ChecksumAddress]:
427
435
  return self._view("OWNER()", output_types=["address"], decoder=_address)
428
436
 
429
- def config_delay(self) -> Call[int]:
437
+ def config_delay(self) -> Call[Period]:
430
438
  """Timelock of every scheduled asset, factory route and dispatcher
431
439
  deployment gas limit: 24 hours in source, 300 seconds on the test
432
440
  builds."""
433
- return self._view("CONFIG_DELAY()", output_types=["uint256"])
441
+ return self._view("CONFIG_DELAY()", output_types=["uint256"], decoder=Period)
434
442
 
435
443
  def executor_creation_code_hash(self) -> Call[bytes]:
436
444
  """keccak of the executor creation code the factory stores. It tells
@@ -469,7 +477,7 @@ class CcipCrosschainFactory(CrosschainFactory):
469
477
  )
470
478
 
471
479
  def schedule_asset(
472
- self, asset_id: AssetId, token: ChecksumAddress, shared_decimals: int
480
+ self, asset_id: AssetId, token: ChecksumAddress, shared_decimals: Decimals
473
481
  ) -> Call[None]:
474
482
  """Owner-only; executable after ``config_delay`` with the same arguments."""
475
483
  return self._write(
@@ -477,7 +485,7 @@ class CcipCrosschainFactory(CrosschainFactory):
477
485
  )
478
486
 
479
487
  def execute_asset(
480
- self, asset_id: AssetId, token: ChecksumAddress, shared_decimals: int
488
+ self, asset_id: AssetId, token: ChecksumAddress, shared_decimals: Decimals
481
489
  ) -> Call[None]:
482
490
  return self._write(
483
491
  "executeAsset(bytes32,address,uint8)", asset_id, token, shared_decimals
@@ -29,7 +29,7 @@ from ipor_fusion.crosschain.transport import (
29
29
  OutboundMessage,
30
30
  transfer_call,
31
31
  )
32
- from ipor_fusion.types import CcipChainSelector, ChainId
32
+ from ipor_fusion.types import Amount, CcipChainSelector, ChainId, Decimals
33
33
 
34
34
 
35
35
  @dataclass(frozen=True, slots=True)
@@ -45,7 +45,7 @@ class CcipChain:
45
45
  chain_selector: CcipChainSelector
46
46
  router: ChecksumAddress
47
47
  token: ChecksumAddress
48
- local_decimals: int
48
+ local_decimals: Decimals
49
49
  token_source: ChecksumAddress | None = None
50
50
 
51
51
  def __post_init__(self) -> None:
@@ -119,7 +119,7 @@ class CcipTransport(CrosschainTransport):
119
119
  raise ValueError(
120
120
  f"CCIP message to unconfigured selector {message.dest_chain_selector}"
121
121
  )
122
- token_amount = 0
122
+ token_amount = Amount(0)
123
123
  if message.token_transfer:
124
124
  # The codec admits at most one transfer (MAX_NUMBER_OF_TOKENS = 1).
125
125
  transfer = message.token_transfer[0]
@@ -25,9 +25,12 @@ from ipor_fusion.types import (
25
25
  AssetId,
26
26
  ChainId,
27
27
  CommandId,
28
+ Decimals,
29
+ Period,
28
30
  PlasmaVaultAddress,
29
31
  PositionSetHash,
30
32
  ProposalId,
33
+ Shares,
31
34
  )
32
35
 
33
36
 
@@ -107,17 +110,21 @@ class CrosschainExecutor(ContractWrapper):
107
110
  def big_change_bps(self) -> Call[int]:
108
111
  return self._view("BIG_CHANGE_BPS()", output_types=["uint256"])
109
112
 
110
- def min_update_interval(self) -> Call[int]:
111
- return self._view("MIN_UPDATE_INTERVAL()", output_types=["uint256"])
113
+ def min_update_interval(self) -> Call[Period]:
114
+ return self._view(
115
+ "MIN_UPDATE_INTERVAL()", output_types=["uint256"], decoder=Period
116
+ )
112
117
 
113
- def transfer_staleness_max(self) -> Call[int]:
114
- return self._view("TRANSFER_STALENESS_MAX()", output_types=["uint256"])
118
+ def transfer_staleness_max(self) -> Call[Period]:
119
+ return self._view(
120
+ "TRANSFER_STALENESS_MAX()", output_types=["uint256"], decoder=Period
121
+ )
115
122
 
116
- def local_decimals(self) -> Call[int]:
117
- return self._view("LOCAL_DECIMALS()", output_types=["uint8"])
123
+ def local_decimals(self) -> Call[Decimals]:
124
+ return self._view("LOCAL_DECIMALS()", output_types=["uint8"], decoder=Decimals)
118
125
 
119
- def shared_decimals(self) -> Call[int]:
120
- return self._view("SHARED_DECIMALS()", output_types=["uint8"])
126
+ def shared_decimals(self) -> Call[Decimals]:
127
+ return self._view("SHARED_DECIMALS()", output_types=["uint8"], decoder=Decimals)
121
128
 
122
129
  def get_balance(self) -> Call[Amount]:
123
130
  """Fail-closed aggregate NAV in local asset decimals: idle plus every
@@ -197,11 +204,11 @@ class CrosschainDispatcher(ContractWrapper):
197
204
  "EXECUTOR_CHAIN_ID()", output_types=["uint256"], decoder=ChainId
198
205
  )
199
206
 
200
- def local_decimals(self) -> Call[int]:
201
- return self._view("LOCAL_DECIMALS()", output_types=["uint8"])
207
+ def local_decimals(self) -> Call[Decimals]:
208
+ return self._view("LOCAL_DECIMALS()", output_types=["uint8"], decoder=Decimals)
202
209
 
203
- def shared_decimals(self) -> Call[int]:
204
- return self._view("SHARED_DECIMALS()", output_types=["uint8"])
210
+ def shared_decimals(self) -> Call[Decimals]:
211
+ return self._view("SHARED_DECIMALS()", output_types=["uint8"], decoder=Decimals)
205
212
 
206
213
  def state_version(self) -> Call[int]:
207
214
  return self._view("stateVersion()", output_types=["uint64"])
@@ -221,9 +228,12 @@ class CrosschainDispatcher(ContractWrapper):
221
228
  def is_tracked_vault(self, vault: ChecksumAddress) -> Call[bool]:
222
229
  return self._view("isTrackedVault(address)", vault, output_types=["bool"])
223
230
 
224
- def pending_request_shares(self, vault: PlasmaVaultAddress) -> Call[int]:
231
+ def pending_request_shares(self, vault: PlasmaVaultAddress) -> Call[Shares]:
225
232
  return self._view(
226
- "pendingRequestShares(address)", vault, output_types=["uint256"]
233
+ "pendingRequestShares(address)",
234
+ vault,
235
+ output_types=["uint256"],
236
+ decoder=Shares,
227
237
  )
228
238
 
229
239
  def command_status(self, command_id: CommandId) -> Call[CommandStatus]:
@@ -6,6 +6,7 @@ from __future__ import annotations
6
6
  from dataclasses import dataclass
7
7
 
8
8
  from eth_typing import ChecksumAddress
9
+ from web3.types import Timestamp
9
10
 
10
11
  from ipor_fusion.core.contract import Call, ContractWrapper
11
12
  from ipor_fusion.crosschain.contracts import (
@@ -69,14 +70,14 @@ class ExecutorInitParams:
69
70
  manager: PlasmaVaultAddress
70
71
  admin: ChecksumAddress
71
72
  rescue_guardian: ChecksumAddress
72
- rescue_delay: int
73
+ rescue_delay: Period
73
74
  balance_proposer: ChecksumAddress
74
75
  balance_approver: ChecksumAddress
75
- staleness_max: int
76
+ staleness_max: Period
76
77
  big_change_bps: int
77
- min_update_interval: int
78
- deployment_ttl: int
79
- transfer_staleness_max: int
78
+ min_update_interval: Period
79
+ deployment_ttl: Period
80
+ transfer_staleness_max: Period
80
81
 
81
82
  def as_tuple(self) -> tuple:
82
83
  return (
@@ -115,8 +116,8 @@ class StargateCrosschainExecutor(CrosschainExecutor):
115
116
  def staleness_max(self) -> Call[Period]:
116
117
  return self._view("STALENESS_MAX()", output_types=["uint256"], decoder=Period)
117
118
 
118
- def deployment_ttl(self) -> Call[int]:
119
- return self._view("DEPLOYMENT_TTL()", output_types=["uint256"])
119
+ def deployment_ttl(self) -> Call[Period]:
120
+ return self._view("DEPLOYMENT_TTL()", output_types=["uint256"], decoder=Period)
120
121
 
121
122
  def registered_chain_count(self) -> Call[int]:
122
123
  return self._view("registeredChainCount()", output_types=["uint256"])
@@ -147,8 +148,13 @@ class StargateCrosschainExecutor(CrosschainExecutor):
147
148
  "pendingArrivalReserve()", output_types=["uint256"], decoder=Amount
148
149
  )
149
150
 
150
- def in_flight_since(self, chain_id: ChainId) -> Call[int]:
151
- return self._view("inFlightSince(uint256)", chain_id, output_types=["uint64"])
151
+ def in_flight_since(self, chain_id: ChainId) -> Call[Timestamp]:
152
+ return self._view(
153
+ "inFlightSince(uint256)",
154
+ chain_id,
155
+ output_types=["uint64"],
156
+ decoder=Timestamp,
157
+ )
152
158
 
153
159
  def acknowledged_remote_state_version(self, chain_id: ChainId) -> Call[int]:
154
160
  return self._view(
@@ -207,8 +213,13 @@ class StargateCrosschainExecutor(CrosschainExecutor):
207
213
  decoder=ProposalId,
208
214
  )
209
215
 
210
- def last_approval_at(self, chain_id: ChainId) -> Call[int]:
211
- return self._view("lastApprovalAt(uint256)", chain_id, output_types=["uint64"])
216
+ def last_approval_at(self, chain_id: ChainId) -> Call[Timestamp]:
217
+ return self._view(
218
+ "lastApprovalAt(uint256)",
219
+ chain_id,
220
+ output_types=["uint64"],
221
+ decoder=Timestamp,
222
+ )
212
223
 
213
224
  def deployment_status(
214
225
  self, request_id: DeploymentRequestId
@@ -365,8 +376,8 @@ class StargateCrosschainFactory(CrosschainFactory):
365
376
  def max_native_fee(self, chain_id: ChainId) -> Call[int]:
366
377
  return self._view("maxNativeFee(uint256)", chain_id, output_types=["uint256"])
367
378
 
368
- def config_delay(self) -> Call[int]:
369
- return self._view("CONFIG_DELAY()", output_types=["uint256"])
379
+ def config_delay(self) -> Call[Period]:
380
+ return self._view("CONFIG_DELAY()", output_types=["uint256"], decoder=Period)
370
381
 
371
382
  def request_count(self) -> Call[int]:
372
383
  return self._view("requestCount()", output_types=["uint256"])
@@ -30,7 +30,13 @@ from web3 import Web3
30
30
  from ipor_fusion.core.address import _validate_not_zero_address
31
31
  from ipor_fusion.core.contract import _encode_calldata
32
32
  from ipor_fusion.crosschain.logs import log_bytes
33
- from ipor_fusion.types import ZERO_ADDRESS, LayerZeroEid, MessageId, StargateAssetId
33
+ from ipor_fusion.types import (
34
+ ZERO_ADDRESS,
35
+ Amount,
36
+ LayerZeroEid,
37
+ MessageId,
38
+ StargateAssetId,
39
+ )
34
40
 
35
41
  _TYPE_3 = b"\x00\x03"
36
42
  _EXECUTOR_WORKER_ID = 1
@@ -187,7 +193,7 @@ class TaxiMessage:
187
193
 
188
194
  asset_id: StargateAssetId
189
195
  receiver: ChecksumAddress
190
- amount_sd: int
196
+ amount_sd: Amount
191
197
  compose_msg: bytes
192
198
 
193
199
  @classmethod
@@ -197,7 +203,7 @@ class TaxiMessage:
197
203
  return cls(
198
204
  asset_id=StargateAssetId(int.from_bytes(message[1:3], "big")),
199
205
  receiver=bytes32_to_address(message[3:35]),
200
- amount_sd=int.from_bytes(message[35:43], "big"),
206
+ amount_sd=Amount(int.from_bytes(message[35:43], "big")),
201
207
  compose_msg=message[43:],
202
208
  )
203
209
 
@@ -28,7 +28,7 @@ from ipor_fusion.crosschain.transport import (
28
28
  OutboundMessage,
29
29
  transfer_call,
30
30
  )
31
- from ipor_fusion.types import ChainId, LayerZeroEid, StargateAssetId
31
+ from ipor_fusion.types import Amount, ChainId, Decimals, LayerZeroEid, StargateAssetId
32
32
 
33
33
 
34
34
  @dataclass(frozen=True, slots=True)
@@ -50,8 +50,8 @@ class StargateChain:
50
50
  stargate_pool: ChecksumAddress
51
51
  token: ChecksumAddress
52
52
  asset_id: StargateAssetId
53
- local_decimals: int
54
- shared_decimals: int
53
+ local_decimals: Decimals
54
+ shared_decimals: Decimals
55
55
  token_source: ChecksumAddress | None = None
56
56
 
57
57
  def __post_init__(self) -> None:
@@ -75,8 +75,8 @@ class StargateChain:
75
75
  def credit_source(self) -> ChecksumAddress:
76
76
  return self.token_source or self.stargate_pool
77
77
 
78
- def to_local_decimals(self, amount_sd: int) -> int:
79
- return amount_sd * 10 ** (self.local_decimals - self.shared_decimals)
78
+ def to_local_decimals(self, amount_sd: Amount) -> Amount:
79
+ return Amount(amount_sd * 10 ** (self.local_decimals - self.shared_decimals))
80
80
 
81
81
 
82
82
  class StargateTransport(CrosschainTransport):
@@ -29,7 +29,7 @@ from web3 import Web3
29
29
  from ipor_fusion.core.contract import _encode_calldata
30
30
  from ipor_fusion.crosschain.contracts import CrosschainDispatcher, CrosschainExecutor
31
31
  from ipor_fusion.crosschain.messages import CrosschainTransportKind
32
- from ipor_fusion.types import ChainId, MessageId
32
+ from ipor_fusion.types import Amount, ChainId, MessageId
33
33
 
34
34
 
35
35
  @dataclass(frozen=True, slots=True)
@@ -49,7 +49,7 @@ class OutboundMessage:
49
49
  sender: ChecksumAddress
50
50
  receiver: ChecksumAddress
51
51
  payload: bytes
52
- token_amount: int = 0
52
+ token_amount: Amount = Amount(0)
53
53
  raw: Any = None
54
54
 
55
55
 
@@ -106,7 +106,7 @@ SYNTHETIC_TOKEN_SOURCE: ChecksumAddress = Web3.to_checksum_address(
106
106
 
107
107
 
108
108
  def transfer_call(
109
- token: ChecksumAddress, source: ChecksumAddress, to: ChecksumAddress, amount: int
109
+ token: ChecksumAddress, source: ChecksumAddress, to: ChecksumAddress, amount: Amount
110
110
  ) -> DeliveryCall:
111
111
  return DeliveryCall(
112
112
  to=token,
@@ -30,7 +30,7 @@ from ipor_fusion.fuses.base import (
30
30
  _validate_not_zero_address,
31
31
  _validate_selector,
32
32
  )
33
- from ipor_fusion.types import Amount
33
+ from ipor_fusion.types import Amount, Period
34
34
 
35
35
  #: One external call run from the executor context: (target, calldata).
36
36
  ExternalStateAction = tuple[ChecksumAddress, bytes]
@@ -203,7 +203,7 @@ class ExternalStateSubstrates:
203
203
  raise ValueError(f"{name} must not be zero")
204
204
 
205
205
  @classmethod
206
- def staleness_max(cls, seconds: int) -> bytes:
206
+ def staleness_max(cls, seconds: Period) -> bytes:
207
207
  """Maximum age of the confirmed balance, in seconds, before user
208
208
  operations are blocked. Must be non-zero -- the executor treats a zero
209
209
  as a missing grant and refuses to sync its substrate cache."""
@@ -225,7 +225,7 @@ class ExternalStateSubstrates:
225
225
  return _encode_uint248_substrate(cls._DUST_THRESHOLD, percent, "dust threshold")
226
226
 
227
227
  @classmethod
228
- def min_update_interval(cls, seconds: int) -> bytes:
228
+ def min_update_interval(cls, seconds: Period) -> bytes:
229
229
  """Minimum delay, in seconds, between two confirmed balance updates."""
230
230
  return _encode_uint248_substrate(
231
231
  cls._MIN_UPDATE_INTERVAL, seconds, "min update interval"