ipor-fusion 4.0.0.dev32__tar.gz → 4.0.0.dev35__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 (285) hide show
  1. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/PKG-INFO +1 -1
  2. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/examples/composed_hypercore_flow_arbitrum_hyperevm.py +19 -10
  3. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/examples/external_state_margin_leg_base.py +2 -2
  4. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/pyproject.toml +1 -1
  5. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/__init__.py +18 -0
  6. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/context.py +3 -3
  7. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/external_state_executor.py +29 -27
  8. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/errors.py +3 -1
  9. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/explorer.py +6 -5
  10. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/external_state_events.py +6 -4
  11. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/hypercore.py +39 -20
  12. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/hypercore.py +27 -17
  13. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/hypercore_outcome.py +4 -3
  14. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/substrates.py +2 -2
  15. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/types.py +19 -1
  16. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_web3_context.py +1 -1
  17. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/.claude-plugin/marketplace.json +0 -0
  18. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/.claude-plugin/plugin.json +0 -0
  19. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/.env.example +0 -0
  20. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/.gemini/settings.json +0 -0
  21. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/.git-blame-ignore-revs +0 -0
  22. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/.github/workflows/cd.yml +0 -0
  23. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/.github/workflows/ci.yml +0 -0
  24. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/.github/workflows/commit-lint.yml +0 -0
  25. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/.github/workflows/notify-slack.yml +0 -0
  26. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/.github/workflows/python-build.yml +0 -0
  27. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/.github/workflows/python-publish.yml +0 -0
  28. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/.github/workflows/release.yml +0 -0
  29. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/.github/workflows/report-slack.yml +0 -0
  30. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/.gitignore +0 -0
  31. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/.mcp.json +0 -0
  32. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/.pre-commit-config.yaml +0 -0
  33. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/.python-version +0 -0
  34. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/AGENTS.md +0 -0
  35. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/CHANGELOG.md +0 -0
  36. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/CLAUDE.md +0 -0
  37. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/CODEOWNERS +0 -0
  38. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/LICENSE +0 -0
  39. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/README.md +0 -0
  40. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/build.sh +0 -0
  41. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/examples/CONTRIBUTING.md +0 -0
  42. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/examples/README.md +0 -0
  43. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/examples/advanced_euler_v2_credit_market_base.py +0 -0
  44. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/examples/advanced_euler_v2_looping_arbitrum.py +0 -0
  45. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/examples/crosschain_ccip_usdc_arbitrum_hyperevm.py +0 -0
  46. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/examples/simple_aave_v3_supply_base.py +0 -0
  47. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/pytest.ini +0 -0
  48. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/scripts/commit-check.sh +0 -0
  49. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/scripts/crosschain_readiness.py +0 -0
  50. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/skills/ipor-deploy-vault/SKILL.md +0 -0
  51. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/about.py +0 -0
  52. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cache.py +0 -0
  53. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/chains.py +0 -0
  54. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/__init__.py +0 -0
  55. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/changelog_cmd.py +0 -0
  56. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/config_cmd.py +0 -0
  57. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/config_store.py +0 -0
  58. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/main.py +0 -0
  59. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/market_cmd.py +0 -0
  60. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/options.py +0 -0
  61. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/oracle_mapping_view.py +0 -0
  62. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/vault_cmd.py +0 -0
  63. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/vault_health.py +0 -0
  64. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/vault_info_view.py +0 -0
  65. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/vault_markets_view.py +0 -0
  66. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/vault_rendering.py +0 -0
  67. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/config/__init__.py +0 -0
  68. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/config/roles.py +0 -0
  69. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/__init__.py +0 -0
  70. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/access.py +0 -0
  71. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/address.py +0 -0
  72. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/contract.py +0 -0
  73. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/erc20.py +0 -0
  74. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/fee_manager.py +0 -0
  75. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/fuse_action.py +0 -0
  76. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/fusion_factory.py +0 -0
  77. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/logs.py +0 -0
  78. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/multicall.py +0 -0
  79. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/oracle.py +0 -0
  80. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/plasma_vault.py +0 -0
  81. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/rewards_manager.py +0 -0
  82. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/simulation.py +0 -0
  83. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/withdraw_manager.py +0 -0
  84. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/__init__.py +0 -0
  85. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/ccip/__init__.py +0 -0
  86. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/ccip/chainlink.py +0 -0
  87. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/ccip/codec.py +0 -0
  88. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/ccip/contracts.py +0 -0
  89. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/ccip/events.py +0 -0
  90. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/ccip/indexer.py +0 -0
  91. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/ccip/lane.py +0 -0
  92. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/ccip/quote.py +0 -0
  93. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/ccip/transport.py +0 -0
  94. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/contracts.py +0 -0
  95. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/discovery.py +0 -0
  96. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/errors.py +0 -0
  97. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/lane.py +0 -0
  98. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/logs.py +0 -0
  99. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/messages.py +0 -0
  100. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/simulation.py +0 -0
  101. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/stargate/__init__.py +0 -0
  102. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/stargate/contracts.py +0 -0
  103. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/stargate/lane.py +0 -0
  104. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/stargate/layerzero.py +0 -0
  105. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/stargate/transport.py +0 -0
  106. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/transport.py +0 -0
  107. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/dependency_graph.py +0 -0
  108. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/entry_cli.py +0 -0
  109. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/entry_mcp.py +0 -0
  110. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/field_docs.py +0 -0
  111. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/__init__.py +0 -0
  112. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/aave_v3.py +0 -0
  113. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/async_action.py +0 -0
  114. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/base.py +0 -0
  115. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/compound_v3.py +0 -0
  116. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/crosschain/__init__.py +0 -0
  117. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/crosschain/base.py +0 -0
  118. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/crosschain/ccip.py +0 -0
  119. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/crosschain/stargate.py +0 -0
  120. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/erc4626.py +0 -0
  121. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/euler_v2.py +0 -0
  122. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/events.py +0 -0
  123. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/external_state.py +0 -0
  124. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/fluid_instadapp.py +0 -0
  125. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/gearbox_v3.py +0 -0
  126. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/hypercore_events.py +0 -0
  127. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/merkl.py +0 -0
  128. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/morpho.py +0 -0
  129. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/ramses_v2.py +0 -0
  130. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/uniswap_v3.py +0 -0
  131. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/universal.py +0 -0
  132. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/guide/__init__.py +0 -0
  133. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/guide/architecture.md +0 -0
  134. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/guide/glossary.md +0 -0
  135. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/guide/invariants.md +0 -0
  136. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/guide/quickstart.md +0 -0
  137. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/market_ids.py +0 -0
  138. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/market_info.py +0 -0
  139. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/mcp/__init__.py +0 -0
  140. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/mcp/guide.py +0 -0
  141. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/mcp/models.py +0 -0
  142. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/mcp/server.py +0 -0
  143. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/morpho_api.py +0 -0
  144. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/py.typed +0 -0
  145. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/__init__.py +0 -0
  146. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/aave_v3.py +0 -0
  147. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/aave_v4.py +0 -0
  148. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/compound_v3.py +0 -0
  149. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/lending_health.py +0 -0
  150. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/morpho.py +0 -0
  151. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/oracle_mapping.py +0 -0
  152. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/position_manager.py +0 -0
  153. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/ramses_v2.py +0 -0
  154. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/uniswap_v3.py +0 -0
  155. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/unpriceable.py +0 -0
  156. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/validation.py +0 -0
  157. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/vault_data.py +0 -0
  158. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/vault_info.py +0 -0
  159. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/UniswapV3UniversalRouter.py +0 -0
  160. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/_crosschain.py +0 -0
  161. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/_crosschain_lifecycle.py +0 -0
  162. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/_crosschain_recovery.py +0 -0
  163. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/_euler_v2.py +0 -0
  164. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/_foundry.py +0 -0
  165. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/_guide.py +0 -0
  166. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/_hypercore_model.py +0 -0
  167. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/_hypercore_shadow.py +0 -0
  168. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/_multicall.py +0 -0
  169. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/_simulate.py +0 -0
  170. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/_validation.py +0 -0
  171. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/addresses.py +0 -0
  172. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/conftest.py +0 -0
  173. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/constants.py +0 -0
  174. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/fixtures/hypercore_hip3_flow.json +0 -0
  175. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/fixtures/hypercore_market55.json +0 -0
  176. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/fixtures/vault_info_golden/clean.json +0 -0
  177. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/fixtures/vault_info_golden/clean.txt +0 -0
  178. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/fixtures/vault_info_golden/rich.json +0 -0
  179. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/fixtures/vault_info_golden/rich.txt +0 -0
  180. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_about.py +0 -0
  181. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_access_manager.py +0 -0
  182. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_cache.py +0 -0
  183. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_chains.py +0 -0
  184. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_cli_changelog.py +0 -0
  185. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_cli_commands.py +0 -0
  186. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_cli_config_store.py +0 -0
  187. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_cli_helpers.py +0 -0
  188. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_cli_hypercore.py +0 -0
  189. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_cli_lending_health.py +0 -0
  190. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_cli_market_morpho_blue.py +0 -0
  191. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_cli_oracle_mapping.py +0 -0
  192. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_cli_pending_requests_scan.py +0 -0
  193. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_cli_role_accounts.py +0 -0
  194. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_cli_vault_info_golden.py +0 -0
  195. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_cli_vault_predates_getters.py +0 -0
  196. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_cli_vault_validate.py +0 -0
  197. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_contract_call.py +0 -0
  198. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_contract_encoder.py +0 -0
  199. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_ccip_events.py +0 -0
  200. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_ccip_indexer.py +0 -0
  201. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_ccip_quote.py +0 -0
  202. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_chainlink.py +0 -0
  203. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_contracts.py +0 -0
  204. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_encoding.py +0 -0
  205. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_errors.py +0 -0
  206. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_lane.py +0 -0
  207. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_layering.py +0 -0
  208. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_readiness.py +0 -0
  209. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_readiness_report.py +0 -0
  210. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_transport.py +0 -0
  211. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_erc20.py +0 -0
  212. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_examples_composed_hypercore.py +0 -0
  213. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_examples_crosschain.py +0 -0
  214. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_examples_euler_looping_arbitrum.py +0 -0
  215. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_examples_vaults.py +0 -0
  216. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_explorer.py +0 -0
  217. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_external_state_events.py +0 -0
  218. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_external_state_executor.py +0 -0
  219. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_fee_manager.py +0 -0
  220. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_fuse_encoding.py +0 -0
  221. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_guide.py +0 -0
  222. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_hypercore_deployment.py +0 -0
  223. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_hypercore_events.py +0 -0
  224. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_hypercore_flow.py +0 -0
  225. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_hypercore_live.py +0 -0
  226. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_hypercore_outcome.py +0 -0
  227. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_hypercore_readers.py +0 -0
  228. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_hypercore_simulation.py +0 -0
  229. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_logs.py +0 -0
  230. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_mcp_hypercore.py +0 -0
  231. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_mcp_models.py +0 -0
  232. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_mcp_server.py +0 -0
  233. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_mcp_vault_validate.py +0 -0
  234. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_multicall.py +0 -0
  235. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_oracle.py +0 -0
  236. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_oracle_mapping.py +0 -0
  237. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_plasma_vault.py +0 -0
  238. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_reader_encoding.py +0 -0
  239. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_readiness_selection.py +0 -0
  240. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_revert_decoding.py +0 -0
  241. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_rewards_manager.py +0 -0
  242. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_roles.py +0 -0
  243. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_sdk_layering.py +0 -0
  244. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_borrow_aave_v3_mainnet.py +0 -0
  245. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_claim_merkl_wrapper_base.py +0 -0
  246. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_claim_morpho_rewards.py +0 -0
  247. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_crosschain_canary.py +0 -0
  248. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_crosschain_hypercore.py +0 -0
  249. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_crosschain_hyperevm.py +0 -0
  250. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_crosschain_lifecycle.py +0 -0
  251. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_euler_v2_batch_base.py +0 -0
  252. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_euler_v2_credit_market_base.py +0 -0
  253. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_euler_v2_swap_deploy_base.py +0 -0
  254. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_euler_v2_swap_reconfigure_base.py +0 -0
  255. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_euler_v2_swap_registry_base.py +0 -0
  256. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_examples_arbitrum.py +0 -0
  257. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_examples_base.py +0 -0
  258. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_examples_crosschain.py +0 -0
  259. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_external_state_executor_base.py +0 -0
  260. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_fusion_factory_clone_base.py +0 -0
  261. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_looping_aave_v3_base.py +0 -0
  262. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_looping_morpho_blue_base.py +0 -0
  263. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_morpho_blue.py +0 -0
  264. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_pilot_v3.py +0 -0
  265. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_pilot_v4_uniswap.py +0 -0
  266. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_pilot_v5_ramses.py +0 -0
  267. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_pilot_v5_scheduled.py +0 -0
  268. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_plasma_vault_setters_base.py +0 -0
  269. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_readers_integration.py +0 -0
  270. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_release_funds.py +0 -0
  271. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_swap_on_base.py +0 -0
  272. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_vault_from_scratch_base.py +0 -0
  273. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_solidity_compiler.py +0 -0
  274. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_solidity_mirrors.py +0 -0
  275. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_substrates.py +0 -0
  276. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_types_and_events.py +0 -0
  277. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_unpriceable_tokens.py +0 -0
  278. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_validation.py +0 -0
  279. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_vault_dep_graph.py +0 -0
  280. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_vault_info_onchain_base.py +0 -0
  281. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_vault_info_onchain_base_no_withdraw_manager.py +0 -0
  282. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_vault_simulator_blocks.py +0 -0
  283. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/test_withdraw_manager.py +0 -0
  284. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/tests/typed_client/consumer.py +0 -0
  285. {ipor_fusion-4.0.0.dev32 → ipor_fusion-4.0.0.dev35}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: ipor-fusion
3
- Version: 4.0.0.dev32
3
+ Version: 4.0.0.dev35
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
@@ -100,12 +100,21 @@ from ipor_fusion.fuses import (
100
100
  from ipor_fusion.fuses.hypercore import (
101
101
  SPOT_DEX,
102
102
  USDC_SYSTEM_ADDRESS,
103
+ USDC_TOKEN_INDEX,
103
104
  TimeInForce,
104
105
  read_index_of,
105
106
  )
106
107
  from ipor_fusion.market_ids import IporFusionMarkets
107
108
  from ipor_fusion.readers.hypercore import HyperCoreReader
108
- from ipor_fusion.types import Amount, ChainId, MarketId, Period, Shares
109
+ from ipor_fusion.types import (
110
+ Amount,
111
+ ChainId,
112
+ HyperCoreAsset,
113
+ HyperCoreClientOrderId,
114
+ MarketId,
115
+ Period,
116
+ Shares,
117
+ )
109
118
 
110
119
  log = logging.getLogger("composed_hypercore_flow_arbitrum_hyperevm")
111
120
 
@@ -181,7 +190,7 @@ BRIDGE_LATENCY = Period(2 * 60)
181
190
  # ── The trade the live cycle ran ─────────────────────────────────────────────
182
191
  # xyz is HIP-3 perp dex 1; xyz:NVDA is action asset 100_000 + 1 * 10_000 + 2.
183
192
  XYZ_DEX = 1
184
- XYZ_NVDA_ASSET = 110_002
193
+ XYZ_NVDA_ASSET = HyperCoreAsset(110_002)
185
194
  # Core amounts are Core wei: 8 decimals for USDC; sizes carry 8 implied
186
195
  # decimals too (0.05 NVDA = 5_000_000), prices 8 implied decimals.
187
196
  CORE_WEI = 10**8
@@ -410,9 +419,9 @@ def core_leg_previews(web3_hype: Web3) -> list[Preview]:
410
419
  state = read_hypercore_vault_state(ctx, HYPERCORE_VAULT, HYPERCORE_BALANCE_FUSE)
411
420
  reader = HyperCoreReader(ctx)
412
421
  pending = bool(state.pending and state.pending.pending)
413
- spot = reader.spot_balance(HYPERCORE_VAULT, 0).call()
422
+ spot = reader.spot_balance(HYPERCORE_VAULT, USDC_TOKEN_INDEX).call()
414
423
  spot_available = _available_spot_wei(spot.total, spot.hold)
415
- usdc_info = reader.token_info(0).call()
424
+ usdc_info = reader.token_info(USDC_TOKEN_INDEX).call()
416
425
  evm_step = 10 ** max(int(usdc_info.wei_decimals) - 6, 0)
417
426
  xyz_equity_usd6 = int(
418
427
  reader.account_margin_summary(XYZ_DEX, HYPERCORE_VAULT).call().account_value
@@ -454,7 +463,7 @@ def core_leg_previews(web3_hype: Web3) -> list[Preview]:
454
463
  web3_hype,
455
464
  vault,
456
465
  "bridge_to_core",
457
- deposit_fuse.enter(token_index=0, amount=BRIDGE_AMOUNT_USDC),
466
+ deposit_fuse.enter(token_index=USDC_TOKEN_INDEX, amount=BRIDGE_AMOUNT_USDC),
458
467
  override=override,
459
468
  note="14 USDC EVM -> Core spot through the CoreDepositWallet; vault USDC balance overridden for the preview",
460
469
  )
@@ -472,7 +481,7 @@ def core_leg_previews(web3_hype: Web3) -> list[Preview]:
472
481
  destination=HYPERCORE_VAULT,
473
482
  source_dex=SPOT_DEX,
474
483
  destination_dex=XYZ_DEX,
475
- token_index=0,
484
+ token_index=USDC_TOKEN_INDEX,
476
485
  amount_wei=to_dex,
477
486
  ),
478
487
  override=None,
@@ -511,7 +520,7 @@ def core_leg_previews(web3_hype: Web3) -> list[Preview]:
511
520
  limit_px=limit_buy,
512
521
  sz=ORDER_SIZE,
513
522
  tif=TimeInForce.IOC,
514
- cloid=1,
523
+ cloid=HyperCoreClientOrderId(1),
515
524
  ),
516
525
  override=None,
517
526
  note=f"buy 0.05 xyz:NVDA, limit {limit_buy} (mark +1 %), notional {notional_usd6} USD6 under the cap {max_notional_usd6}",
@@ -528,7 +537,7 @@ def core_leg_previews(web3_hype: Web3) -> list[Preview]:
528
537
  limit_px=limit_sell,
529
538
  sz=ORDER_SIZE,
530
539
  tif=TimeInForce.IOC,
531
- cloid=2,
540
+ cloid=HyperCoreClientOrderId(2),
532
541
  reduce_only=True,
533
542
  ),
534
543
  override=None,
@@ -551,7 +560,7 @@ def core_leg_previews(web3_hype: Web3) -> list[Preview]:
551
560
  destination=HYPERCORE_VAULT,
552
561
  source_dex=XYZ_DEX,
553
562
  destination_dex=SPOT_DEX,
554
- token_index=0,
563
+ token_index=USDC_TOKEN_INDEX,
555
564
  amount_wei=from_dex,
556
565
  ),
557
566
  override=None,
@@ -586,7 +595,7 @@ def core_leg_previews(web3_hype: Web3) -> list[Preview]:
586
595
  destination=Web3.to_checksum_address(USDC_SYSTEM_ADDRESS),
587
596
  source_dex=SPOT_DEX,
588
597
  destination_dex=SPOT_DEX,
589
- token_index=0,
598
+ token_index=USDC_TOKEN_INDEX,
590
599
  amount_wei=to_evm,
591
600
  ),
592
601
  override=None,
@@ -95,7 +95,7 @@ from ipor_fusion.core import FusionFactory
95
95
  from ipor_fusion.core.fusion_factory import FusionInstance
96
96
  from ipor_fusion.fuses import ExternalStateOperationFuse
97
97
  from ipor_fusion.market_ids import IporFusionMarkets
98
- from ipor_fusion.types import Amount, ChainId, MarketId, Period, Shares
98
+ from ipor_fusion.types import Amount, ChainId, MarketId, Period, ProposalHash, Shares
99
99
 
100
100
  log = logging.getLogger("external_state_margin_leg_base")
101
101
 
@@ -288,7 +288,7 @@ RELEASE_OFFSET = REQUEST_OFFSET + RELEASE_DELAY
288
288
  DEMO_OFFSET = RELEASE_OFFSET + DEMO_DELAY
289
289
 
290
290
  # A hash that is deliberately not the pending proposal's, for the rejection demo.
291
- WRONG_PROPOSAL_HASH = b"\xde\xad" + b"\x00" * 30
291
+ WRONG_PROPOSAL_HASH = ProposalHash(b"\xde\xad" + b"\x00" * 30)
292
292
 
293
293
  # ── Derived from deployed signatures (NOT tunable) ───────────────────────────
294
294
  # Each of these is keccak over a signature the deployed contracts declare.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ipor-fusion"
3
- version = "4.0.0.dev32"
3
+ version = "4.0.0.dev35"
4
4
  description = "The IPOR Fusion SDK for Python"
5
5
  authors = [
6
6
  { name = "Adam Mydlarz", email = "amydlarz@gmail.com" },
@@ -318,16 +318,24 @@ from ipor_fusion.types import (
318
318
  Decimals,
319
319
  DeploymentRequestId,
320
320
  Fee,
321
+ HyperCoreActionId,
322
+ HyperCoreAsset,
323
+ HyperCoreClientOrderId,
324
+ HyperCoreOrderId,
325
+ HyperCoreTokenIndex,
321
326
  Liquidity,
322
327
  MappingStatus,
328
+ MarginTableId,
323
329
  MarketId,
324
330
  MessageId,
325
331
  MorphoBlueMarketId,
326
332
  NodeStatus,
327
333
  OperationId,
334
+ PayloadHash,
328
335
  Period,
329
336
  PositionSetHash,
330
337
  Price,
338
+ ProposalHash,
331
339
  ProposalId,
332
340
  ReturnRequestId,
333
341
  RoleId,
@@ -336,6 +344,7 @@ from ipor_fusion.types import (
336
344
  Tick,
337
345
  TokenId,
338
346
  TransferId,
347
+ TxHash,
339
348
  parse_morpho_market_id,
340
349
  )
341
350
  from ipor_fusion.validation import (
@@ -606,6 +615,15 @@ __all__ = [
606
615
  "RoleId",
607
616
  "ChainId",
608
617
  "MorphoBlueMarketId",
618
+ "HyperCoreActionId",
619
+ "HyperCoreAsset",
620
+ "HyperCoreClientOrderId",
621
+ "HyperCoreOrderId",
622
+ "HyperCoreTokenIndex",
623
+ "MarginTableId",
624
+ "PayloadHash",
625
+ "ProposalHash",
626
+ "TxHash",
609
627
  "parse_morpho_market_id",
610
628
  "AssetId",
611
629
  "CommandId",
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import logging
4
4
 
5
5
  from eth_account import Account
6
- from eth_typing import ChecksumAddress
6
+ from eth_typing import ChecksumAddress, HexStr
7
7
  from hexbytes import HexBytes
8
8
  from requests import ConnectionError as RequestsConnectionError
9
9
  from requests import HTTPError, Timeout
@@ -25,7 +25,7 @@ from ipor_fusion.core.logs import (
25
25
  get_logs_adaptive,
26
26
  )
27
27
  from ipor_fusion.errors import LogSourceUnavailable, TransactionError, get_revert_reason
28
- from ipor_fusion.types import ChainId
28
+ from ipor_fusion.types import ChainId, TxHash
29
29
 
30
30
  # web3 retries every allowlisted method on any HTTP error, a 400 included;
31
31
  # a too-wide eth_getLogs answered with HTTP 400/413 or a query timeout would be
@@ -229,7 +229,7 @@ class Web3Context:
229
229
  reason = get_revert_reason(self.web3, tx_hash, receipt)
230
230
  raise TransactionError(
231
231
  "Transaction failed",
232
- tx_hash=tx_hash.hex(),
232
+ tx_hash=TxHash(HexStr(tx_hash.to_0x_hex())),
233
233
  revert_reason=reason,
234
234
  )
235
235
  return receipt
@@ -32,7 +32,7 @@ from web3.types import BlockIdentifier, TxReceipt
32
32
  from ipor_fusion.core.context import Web3Context
33
33
  from ipor_fusion.core.contract import Call, ContractWrapper
34
34
  from ipor_fusion.market_ids import IporFusionMarkets
35
- from ipor_fusion.types import ZERO_ADDRESS, Amount, ChainId, MarketId
35
+ from ipor_fusion.types import ZERO_ADDRESS, Amount, ChainId, MarketId, ProposalHash
36
36
 
37
37
  if TYPE_CHECKING:
38
38
  from ipor_fusion.core.plasma_vault import PlasmaVault
@@ -79,12 +79,12 @@ class BalanceProposal:
79
79
  value: Amount
80
80
  nonce: int
81
81
  proposed_at: int
82
- proposal_hash: bytes
82
+ proposal_hash: ProposalHash
83
83
 
84
84
 
85
85
  def _hash_of(
86
86
  proposal: BalanceProposal, *, executor: ChecksumAddress, chain_id: ChainId
87
- ) -> bytes:
87
+ ) -> ProposalHash:
88
88
  """`proposal`'s canonical hash, as `confirmBalance` recomputes it.
89
89
 
90
90
  The sole mapping from a proposal's fields onto `proposal_hash` arguments,
@@ -132,7 +132,7 @@ class NavMark:
132
132
 
133
133
  proposed_at: int
134
134
  nonce: int
135
- proposal_hash: bytes
135
+ proposal_hash: ProposalHash
136
136
  propose_receipt: TxReceipt
137
137
  confirm_receipt: TxReceipt
138
138
  refresh_receipt: TxReceipt | None
@@ -463,7 +463,7 @@ class ExternalStateExecutor(ContractWrapper):
463
463
  value=Amount(value),
464
464
  nonce=nonce,
465
465
  proposed_at=proposed_at,
466
- proposal_hash=b"",
466
+ proposal_hash=ProposalHash(b""),
467
467
  )
468
468
  return replace(
469
469
  unstamped,
@@ -516,7 +516,7 @@ class ExternalStateExecutor(ContractWrapper):
516
516
  return self._write("proposeBalance(address,uint256)", balance_account, value)
517
517
 
518
518
  def confirm_balance(
519
- self, balance_account: ChecksumAddress, proposal_hash: bytes
519
+ self, balance_account: ChecksumAddress, proposal_hash: ProposalHash
520
520
  ) -> Call[None]:
521
521
  """CUSTODIAN-only: confirm the pending proposal for `balance_account`.
522
522
  Must be sent by a custodian other than the proposer, and `proposal_hash`
@@ -561,7 +561,7 @@ class ExternalStateExecutor(ContractWrapper):
561
561
  proposer: ChecksumAddress,
562
562
  proposed_at: int,
563
563
  nonce: int,
564
- ) -> bytes:
564
+ ) -> ProposalHash:
565
565
  """The confirm hash that `confirmBalance` verifies against:
566
566
  ``keccak(abi.encode(executor, chainId, balanceAccount, value, proposer,
567
567
  proposedAt, nonce))``.
@@ -571,26 +571,28 @@ class ExternalStateExecutor(ContractWrapper):
571
571
  event, never a fresh `nonce()` read -- see `nonce`. Pure -- no chain
572
572
  access -- so callers can pre-compute or verify a hash offline.
573
573
  """
574
- return keccak(
575
- encode(
576
- [
577
- "address",
578
- "uint256",
579
- "address",
580
- "uint256",
581
- "address",
582
- "uint64",
583
- "uint256",
584
- ],
585
- [
586
- Web3.to_checksum_address(executor),
587
- int(chain_id),
588
- Web3.to_checksum_address(balance_account),
589
- int(value),
590
- Web3.to_checksum_address(proposer),
591
- int(proposed_at),
592
- int(nonce),
593
- ],
574
+ return ProposalHash(
575
+ keccak(
576
+ encode(
577
+ [
578
+ "address",
579
+ "uint256",
580
+ "address",
581
+ "uint256",
582
+ "address",
583
+ "uint64",
584
+ "uint256",
585
+ ],
586
+ [
587
+ Web3.to_checksum_address(executor),
588
+ int(chain_id),
589
+ Web3.to_checksum_address(balance_account),
590
+ int(value),
591
+ Web3.to_checksum_address(proposer),
592
+ int(proposed_at),
593
+ int(nonce),
594
+ ],
595
+ )
594
596
  )
595
597
  )
596
598
 
@@ -11,6 +11,8 @@ from eth_utils import function_signature_to_4byte_selector
11
11
  from web3 import Web3
12
12
  from web3.types import TxReceipt
13
13
 
14
+ from ipor_fusion.types import TxHash
15
+
14
16
  log = logging.getLogger(__name__)
15
17
 
16
18
  PANIC_CODES: dict[int, str] = {
@@ -237,7 +239,7 @@ class TransactionError(IporFusionError):
237
239
  def __init__(
238
240
  self,
239
241
  message: str,
240
- tx_hash: str | None = None,
242
+ tx_hash: TxHash | None = None,
241
243
  revert_reason: str | None = None,
242
244
  ):
243
245
  self.tx_hash = tx_hash
@@ -10,10 +10,10 @@ import time
10
10
  from urllib.parse import urlencode
11
11
  from urllib.request import urlopen
12
12
 
13
- from eth_typing import HexAddress
13
+ from eth_typing import HexAddress, HexStr
14
14
 
15
15
  from ipor_fusion.cache import load_contract_cache, update_contract_cache
16
- from ipor_fusion.types import ChainId
16
+ from ipor_fusion.types import ChainId, TxHash
17
17
 
18
18
  ETHERSCAN_V2_URL = "https://api.etherscan.io/v2/api"
19
19
 
@@ -57,7 +57,7 @@ def get_contract_name(
57
57
 
58
58
  def get_deployment_tx(
59
59
  chain_id: ChainId, address: HexAddress, api_key: str | None = None
60
- ) -> tuple[str | None, str | None]:
60
+ ) -> tuple[TxHash | None, str | None]:
61
61
  """Return ``(tx_hash, error)`` for a contract deployment.
62
62
 
63
63
  ``error`` is a short machine-readable code when ``tx_hash`` is None and the
@@ -69,7 +69,7 @@ def get_deployment_tx(
69
69
 
70
70
  def _fetch_contract_creation_tx(
71
71
  chain_id: ChainId, address: HexAddress, api_key: str | None = None
72
- ) -> tuple[str | None, str | None]:
72
+ ) -> tuple[TxHash | None, str | None]:
73
73
  if chain_id not in SUPPORTED_CHAINS:
74
74
  return None, "chain-not-supported"
75
75
  if not api_key:
@@ -91,7 +91,8 @@ def _fetch_contract_creation_tx(
91
91
  with urlopen(url, timeout=10) as resp: # noqa: S310
92
92
  data = json.loads(resp.read().decode())
93
93
  if data.get("status") == "1" and data.get("result"):
94
- return data["result"][0].get("txHash"), None # type: ignore[no-any-return]
94
+ tx_hash = data["result"][0].get("txHash")
95
+ return (TxHash(HexStr(tx_hash)) if tx_hash else None), None
95
96
  result_text = str(data.get("result", "")).lower()
96
97
  if "free api access is not supported" in result_text:
97
98
  return None, "etherscan-paid-tier-required"
@@ -28,10 +28,12 @@ from typing import Any
28
28
 
29
29
  from eth_abi import decode
30
30
  from eth_abi.exceptions import DecodingError
31
- from eth_typing import ChecksumAddress
31
+ from eth_typing import ChecksumAddress, HexStr
32
32
  from web3 import Web3
33
33
  from web3.types import TxReceipt
34
34
 
35
+ from ipor_fusion.types import TxHash
36
+
35
37
 
36
38
  @dataclass(frozen=True, slots=True)
37
39
  class ExternalStateEventSpec:
@@ -134,7 +136,7 @@ class ExternalStateEvent:
134
136
  emitter: ChecksumAddress
135
137
  args: dict[str, Any]
136
138
  block_number: int | None = None
137
- transaction_hash: str | None = None
139
+ transaction_hash: TxHash | None = None
138
140
  log_index: int | None = None
139
141
 
140
142
 
@@ -191,10 +193,10 @@ def external_state_event_name(topic: bytes | str) -> str | None:
191
193
  return spec.name if spec else None
192
194
 
193
195
 
194
- def _hex(value: Any) -> str | None:
196
+ def _hex(value: Any) -> TxHash | None:
195
197
  if value is None:
196
198
  return None
197
- return "0x" + _as_bytes(value, "transactionHash").hex()
199
+ return TxHash(HexStr("0x" + _as_bytes(value, "transactionHash").hex()))
198
200
 
199
201
 
200
202
  def decode_external_state_event(log: Mapping[str, Any]) -> ExternalStateEvent | None:
@@ -56,14 +56,20 @@ from ipor_fusion.fuses.base import (
56
56
  _substrate_address_bytes,
57
57
  _validate_not_zero_address,
58
58
  )
59
- from ipor_fusion.types import Amount
59
+ from ipor_fusion.types import (
60
+ Amount,
61
+ HyperCoreAsset,
62
+ HyperCoreClientOrderId,
63
+ HyperCoreOrderId,
64
+ HyperCoreTokenIndex,
65
+ )
60
66
 
61
67
  #: ``HyperCoreLib.SPOT_DEX``: the spot account in ``sendAsset`` routes.
62
68
  SPOT_DEX = 0xFFFFFFFF
63
69
  #: ``HyperCoreLib.NATIVE_PERP_DEX``: Hyperliquid's own perp dex.
64
70
  NATIVE_PERP_DEX = 0
65
71
  #: Core token index of USDC.
66
- USDC_TOKEN_INDEX = 0
72
+ USDC_TOKEN_INDEX = HyperCoreTokenIndex(0)
67
73
  #: Core -> EVM route for token 0: a spot -> spot ``sendAsset`` to this address
68
74
  #: credits the sender's EVM balance. Never the target of an ERC-20 transfer.
69
75
  USDC_SYSTEM_ADDRESS: ChecksumAddress = to_checksum_address(
@@ -107,7 +113,7 @@ class HyperCoreConfigKey(IntEnum):
107
113
  SPOT_SEND_BRIDGE_ENABLED = 6
108
114
 
109
115
 
110
- def hip3_action_asset(dex: int, index_in_dex: int) -> int:
116
+ def hip3_action_asset(dex: int, index_in_dex: int) -> HyperCoreAsset:
111
117
  """The CoreWriter asset of market ``index_in_dex`` on perp dex ``dex``:
112
118
  the index itself on the native dex, ``100_000 + dex * 10_000 + index``
113
119
  on a HIP-3 dex. Rejects anything outside the two families the fuses
@@ -119,20 +125,20 @@ def hip3_action_asset(dex: int, index_in_dex: int) -> int:
119
125
  f"index_in_dex must be below {_HIP3_DEX_MULTIPLIER}, got {index_in_dex}"
120
126
  )
121
127
  if dex == NATIVE_PERP_DEX:
122
- return index_in_dex
128
+ return HyperCoreAsset(index_in_dex)
123
129
  asset = _HIP3_ASSET_OFFSET + dex * _HIP3_DEX_MULTIPLIER + index_in_dex
124
130
  if asset >= _OUTCOME_FIRST_ASSET:
125
131
  raise ValueError(f"dex {dex} is outside the HIP-3 asset range")
126
- return asset
132
+ return HyperCoreAsset(asset)
127
133
 
128
134
 
129
- def is_native_perp_asset(asset: int) -> bool:
135
+ def is_native_perp_asset(asset: HyperCoreAsset) -> bool:
130
136
  """``HyperCoreLib.isNativePerpAsset``: an action asset below 10 000."""
131
137
  _validate_uint(asset, 32, "asset")
132
138
  return asset < _NATIVE_PERP_ASSET_LIMIT
133
139
 
134
140
 
135
- def is_hip3_asset(asset: int) -> bool:
141
+ def is_hip3_asset(asset: HyperCoreAsset) -> bool:
136
142
  """``HyperCoreLib.isHip3Asset``: ``110_000 <= asset < 100_000_000``. Assets
137
143
  between the families (10 000 .. 109 999) and the outcome family above are
138
144
  neither, and the perp fuses reject them."""
@@ -147,7 +153,7 @@ def is_supported_perp_dex(dex: int) -> bool:
147
153
  return dex == NATIVE_PERP_DEX or dex in SUPPORTED_HIP3_DEXES
148
154
 
149
155
 
150
- def perp_dex_of(asset: int) -> int:
156
+ def perp_dex_of(asset: HyperCoreAsset) -> int:
151
157
  """``HyperCoreLib.perpDexOf``: 0 for a native asset, the dex index for a
152
158
  HIP-3 asset; raises for any other value, as the fuses revert."""
153
159
  if is_native_perp_asset(asset):
@@ -157,7 +163,7 @@ def perp_dex_of(asset: int) -> int:
157
163
  raise ValueError(f"asset {asset} is neither a native nor a HIP-3 perp asset")
158
164
 
159
165
 
160
- def read_index_of(asset: int) -> int:
166
+ def read_index_of(asset: HyperCoreAsset) -> int:
161
167
  """``HyperCoreLib.readIndexOf``: the index the read precompiles take --
162
168
  native assets unchanged, HIP-3 assets without the 100 000 offset; raises
163
169
  for any other value."""
@@ -179,7 +185,7 @@ def _validate_positive_uint(value: int, bits: int, name: str) -> None:
179
185
  _validate_uint(value, bits, name)
180
186
 
181
187
 
182
- def system_address(token_index: int) -> ChecksumAddress:
188
+ def system_address(token_index: HyperCoreTokenIndex) -> ChecksumAddress:
183
189
  """``HyperCoreLib.systemAddress``: the Core -> EVM route of Core token
184
190
  ``token_index`` (``0x2000…0000 + tokenIndex``; :data:`USDC_SYSTEM_ADDRESS`
185
191
  for token 0). A spot -> spot ``sendAsset`` or ``spotSend`` to it credits the
@@ -192,7 +198,7 @@ class HyperCoreDepositFuse(Fuse):
192
198
  """EVM -> Core deposit of a granted spot token (CoreWriter-free: the
193
199
  token's verified route, the CoreDepositWallet for Circle USDC)."""
194
200
 
195
- def enter(self, *, token_index: int, amount: Amount) -> FuseAction:
201
+ def enter(self, *, token_index: HyperCoreTokenIndex, amount: Amount) -> FuseAction:
196
202
  """Deposit up to ``amount`` (ERC-20 units) of Core token
197
203
  ``token_index``; the fuse caps it at the vault's balance. A fresh Core
198
204
  account pays an activation fee from its first deposit, so the Core
@@ -217,7 +223,11 @@ class HyperCoreSendFuse(Fuse):
217
223
  """``spotSend`` (action 6) and ``sendAsset`` (action 13)."""
218
224
 
219
225
  def spot_send(
220
- self, *, destination: ChecksumAddress, token_index: int, amount_wei: int
226
+ self,
227
+ *,
228
+ destination: ChecksumAddress,
229
+ token_index: HyperCoreTokenIndex,
230
+ amount_wei: int,
221
231
  ) -> FuseAction:
222
232
  """Send ``amount_wei`` of ``token_index`` from spot to a granted
223
233
  destination; a token system address additionally needs
@@ -236,7 +246,7 @@ class HyperCoreSendFuse(Fuse):
236
246
  destination: ChecksumAddress,
237
247
  source_dex: int,
238
248
  destination_dex: int,
239
- token_index: int,
249
+ token_index: HyperCoreTokenIndex,
240
250
  amount_wei: int,
241
251
  ) -> FuseAction:
242
252
  """Move ``amount_wei`` of ``token_index`` between ``source_dex`` and
@@ -264,12 +274,12 @@ class HyperCoreOrderFuse(Fuse):
264
274
  def enter(
265
275
  self,
266
276
  *,
267
- asset: int,
277
+ asset: HyperCoreAsset,
268
278
  is_buy: bool,
269
279
  limit_px: int,
270
280
  sz: int,
271
281
  tif: TimeInForce,
272
- cloid: int,
282
+ cloid: HyperCoreClientOrderId,
273
283
  reduce_only: bool = False,
274
284
  ) -> FuseAction:
275
285
  """Place ``sz`` (8 decimals) of ``asset`` at ``limit_px`` (8 decimals).
@@ -289,12 +299,16 @@ class HyperCoreOrderFuse(Fuse):
289
299
  class HyperCoreCancelFuse(Fuse):
290
300
  """Cancel by oid (action 10) or by cloid (action 11)."""
291
301
 
292
- def cancel_by_oid(self, *, asset: int, oid: int) -> FuseAction:
302
+ def cancel_by_oid(
303
+ self, *, asset: HyperCoreAsset, oid: HyperCoreOrderId
304
+ ) -> FuseAction:
293
305
  _validate_uint(asset, 32, "asset")
294
306
  _validate_positive_uint(oid, 64, "oid")
295
307
  return self._action_raw("enterCancelByOid((uint32,uint64))", [[asset, oid]])
296
308
 
297
- def cancel_by_cloid(self, *, asset: int, cloid: int) -> FuseAction:
309
+ def cancel_by_cloid(
310
+ self, *, asset: HyperCoreAsset, cloid: HyperCoreClientOrderId
311
+ ) -> FuseAction:
298
312
  _validate_uint(asset, 32, "asset")
299
313
  _validate_positive_uint(cloid, 128, "cloid")
300
314
  return self._action_raw(
@@ -342,7 +356,9 @@ class HyperCoreSubstrates:
342
356
  """
343
357
 
344
358
  @staticmethod
345
- def spot_token(token_index: int, evm_asset: ChecksumAddress) -> bytes:
359
+ def spot_token(
360
+ token_index: HyperCoreTokenIndex, evm_asset: ChecksumAddress
361
+ ) -> bytes:
346
362
  """Core token ``token_index`` priced through its EVM ERC-20 (for
347
363
  Circle USDC the wallet's ``token()``, not the CoreDepositWallet)."""
348
364
  _validate_uint(token_index, 64, "token_index")
@@ -350,7 +366,10 @@ class HyperCoreSubstrates:
350
366
 
351
367
  @staticmethod
352
368
  def perp_market(
353
- asset: int, max_notional_usd6: int, *, reduce_only_required: bool = False
369
+ asset: HyperCoreAsset,
370
+ max_notional_usd6: int,
371
+ *,
372
+ reduce_only_required: bool = False,
354
373
  ) -> bytes:
355
374
  """Action asset ``asset`` with a per-order notional cap in USD (6
356
375
  decimals); ``reduce_only_required`` admits only position-reducing orders."""
@@ -381,7 +400,7 @@ class HyperCoreSubstrates:
381
400
  return _word(5, (int(key) << 240) | value)
382
401
 
383
402
  @staticmethod
384
- def send_cap(token_index: int, max_wei: int) -> bytes:
403
+ def send_cap(token_index: HyperCoreTokenIndex, max_wei: int) -> bytes:
385
404
  """Per-transfer cap for ``token_index`` in Core wei."""
386
405
  _validate_uint(token_index, 64, "token_index")
387
406
  _validate_uint(max_wei, 128, "max_wei")