ipor-fusion 4.0.0.dev30__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.
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/AGENTS.md +3 -1
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/PKG-INFO +1 -1
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/examples/composed_hypercore_flow_arbitrum_hyperevm.py +19 -10
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/examples/external_state_margin_leg_base.py +2 -2
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/pyproject.toml +1 -1
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/__init__.py +20 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/market_cmd.py +18 -26
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/context.py +3 -3
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/external_state_executor.py +29 -27
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/errors.py +3 -1
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/explorer.py +6 -5
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/external_state_events.py +6 -4
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/hypercore.py +39 -20
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/market_info.py +3 -3
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/mcp/server.py +4 -9
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/morpho_api.py +20 -13
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/hypercore.py +27 -17
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/hypercore_outcome.py +4 -3
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/lending_health.py +8 -4
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/substrates.py +2 -2
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/types.py +35 -2
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/vault_data.py +7 -4
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_cli_market_morpho_blue.py +3 -1
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_web3_context.py +1 -1
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/typed_client/consumer.py +3 -1
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/.claude-plugin/marketplace.json +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/.claude-plugin/plugin.json +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/.env.example +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/.gemini/settings.json +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/.git-blame-ignore-revs +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/.github/workflows/cd.yml +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/.github/workflows/ci.yml +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/.github/workflows/commit-lint.yml +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/.github/workflows/notify-slack.yml +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/.github/workflows/python-build.yml +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/.github/workflows/python-publish.yml +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/.github/workflows/release.yml +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/.github/workflows/report-slack.yml +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/.gitignore +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/.mcp.json +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/.pre-commit-config.yaml +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/.python-version +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/CHANGELOG.md +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/CLAUDE.md +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/CODEOWNERS +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/LICENSE +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/README.md +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/build.sh +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/examples/CONTRIBUTING.md +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/examples/README.md +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/examples/advanced_euler_v2_credit_market_base.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/examples/advanced_euler_v2_looping_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/examples/crosschain_ccip_usdc_arbitrum_hyperevm.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/examples/simple_aave_v3_supply_base.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/pytest.ini +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/scripts/commit-check.sh +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/scripts/crosschain_readiness.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/skills/ipor-deploy-vault/SKILL.md +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/about.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cache.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/chains.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/changelog_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/config_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/config_store.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/main.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/options.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/oracle_mapping_view.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/vault_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/vault_health.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/vault_info_view.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/vault_markets_view.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/cli/vault_rendering.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/config/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/config/roles.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/access.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/address.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/contract.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/erc20.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/fee_manager.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/fuse_action.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/fusion_factory.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/logs.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/multicall.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/oracle.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/plasma_vault.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/rewards_manager.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/simulation.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/ccip/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/ccip/chainlink.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/ccip/codec.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/ccip/contracts.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/ccip/events.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/ccip/indexer.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/ccip/lane.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/ccip/quote.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/ccip/transport.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/contracts.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/discovery.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/errors.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/lane.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/logs.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/messages.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/simulation.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/stargate/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/stargate/contracts.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/stargate/lane.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/stargate/layerzero.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/stargate/transport.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/crosschain/transport.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/dependency_graph.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/entry_cli.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/entry_mcp.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/field_docs.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/aave_v3.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/async_action.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/base.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/compound_v3.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/crosschain/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/crosschain/base.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/crosschain/ccip.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/crosschain/stargate.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/erc4626.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/euler_v2.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/events.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/external_state.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/fluid_instadapp.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/gearbox_v3.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/hypercore_events.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/merkl.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/morpho.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/ramses_v2.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/uniswap_v3.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/universal.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/guide/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/guide/architecture.md +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/guide/glossary.md +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/guide/invariants.md +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/guide/quickstart.md +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/market_ids.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/mcp/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/mcp/guide.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/mcp/models.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/py.typed +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/aave_v3.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/aave_v4.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/compound_v3.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/morpho.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/oracle_mapping.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/position_manager.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/ramses_v2.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/uniswap_v3.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/readers/unpriceable.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/validation.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/vault_info.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/UniswapV3UniversalRouter.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/_crosschain_lifecycle.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/_crosschain_recovery.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/_euler_v2.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/_foundry.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/_guide.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/_hypercore_model.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/_hypercore_shadow.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/_multicall.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/_simulate.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/_validation.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/addresses.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/conftest.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/constants.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/fixtures/hypercore_hip3_flow.json +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/fixtures/hypercore_market55.json +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/fixtures/vault_info_golden/clean.json +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/fixtures/vault_info_golden/clean.txt +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/fixtures/vault_info_golden/rich.json +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/fixtures/vault_info_golden/rich.txt +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_about.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_access_manager.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_cache.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_chains.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_cli_changelog.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_cli_commands.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_cli_config_store.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_cli_helpers.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_cli_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_cli_lending_health.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_cli_oracle_mapping.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_cli_pending_requests_scan.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_cli_role_accounts.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_cli_vault_info_golden.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_cli_vault_predates_getters.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_cli_vault_validate.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_contract_call.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_contract_encoder.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_ccip_events.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_ccip_indexer.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_ccip_quote.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_chainlink.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_contracts.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_errors.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_lane.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_layering.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_readiness.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_readiness_report.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_crosschain_transport.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_erc20.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_examples_composed_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_examples_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_examples_euler_looping_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_examples_vaults.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_explorer.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_external_state_events.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_external_state_executor.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_fee_manager.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_fuse_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_guide.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_hypercore_deployment.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_hypercore_events.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_hypercore_flow.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_hypercore_live.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_hypercore_outcome.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_hypercore_readers.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_hypercore_simulation.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_logs.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_mcp_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_mcp_models.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_mcp_server.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_mcp_vault_validate.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_multicall.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_oracle.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_oracle_mapping.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_plasma_vault.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_reader_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_readiness_selection.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_revert_decoding.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_rewards_manager.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_roles.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_sdk_layering.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_borrow_aave_v3_mainnet.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_claim_merkl_wrapper_base.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_claim_morpho_rewards.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_crosschain_canary.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_crosschain_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_crosschain_hyperevm.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_crosschain_lifecycle.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_euler_v2_batch_base.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_euler_v2_credit_market_base.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_euler_v2_swap_deploy_base.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_euler_v2_swap_reconfigure_base.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_euler_v2_swap_registry_base.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_examples_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_examples_base.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_examples_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_external_state_executor_base.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_fusion_factory_clone_base.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_looping_aave_v3_base.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_looping_morpho_blue_base.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_morpho_blue.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_pilot_v3.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_pilot_v4_uniswap.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_pilot_v5_ramses.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_pilot_v5_scheduled.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_plasma_vault_setters_base.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_readers_integration.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_release_funds.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_swap_on_base.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_simulate_vault_from_scratch_base.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_solidity_compiler.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_solidity_mirrors.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_substrates.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_types_and_events.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_unpriceable_tokens.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_validation.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_vault_dep_graph.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_vault_info_onchain_base.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_vault_info_onchain_base_no_withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_vault_simulator_blocks.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/tests/test_withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/uv.lock +0 -0
|
@@ -285,7 +285,9 @@ or examples.
|
|
|
285
285
|
`MarketId`, ...) name the unit, and nothing scales by decimals.
|
|
286
286
|
- Ids and addresses are nominal in every signature: `ChainId`, `MarketId` (each
|
|
287
287
|
`IporFusionMarkets` member is one), `RoleId | Roles`, `ChecksumAddress`;
|
|
288
|
-
`HexAddress` only for the lowercase addresses decoded from substrates
|
|
288
|
+
`HexAddress` only for the lowercase addresses decoded from substrates;
|
|
289
|
+
`MorphoBlueMarketId` is always `0x` + 64 lowercase hex, built by
|
|
290
|
+
`parse_morpho_market_id`. Raw input
|
|
289
291
|
is parsed once at the boundary (click param types, MCP tools, the user config).
|
|
290
292
|
`src/`, `examples/` and `tests/typed_client/` are checked with
|
|
291
293
|
`reportArgumentType` on, so a bare `int`/`str` passed for one fails pyright; the
|
|
@@ -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
|
|
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,
|
|
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(
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
598
|
+
token_index=USDC_TOKEN_INDEX,
|
|
590
599
|
amount_wei=to_evm,
|
|
591
600
|
),
|
|
592
601
|
override=None,
|
{ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/examples/external_state_margin_leg_base.py
RENAMED
|
@@ -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.
|
|
@@ -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,8 @@ from ipor_fusion.types import (
|
|
|
336
344
|
Tick,
|
|
337
345
|
TokenId,
|
|
338
346
|
TransferId,
|
|
347
|
+
TxHash,
|
|
348
|
+
parse_morpho_market_id,
|
|
339
349
|
)
|
|
340
350
|
from ipor_fusion.validation import (
|
|
341
351
|
Erc20Holding,
|
|
@@ -605,6 +615,16 @@ __all__ = [
|
|
|
605
615
|
"RoleId",
|
|
606
616
|
"ChainId",
|
|
607
617
|
"MorphoBlueMarketId",
|
|
618
|
+
"HyperCoreActionId",
|
|
619
|
+
"HyperCoreAsset",
|
|
620
|
+
"HyperCoreClientOrderId",
|
|
621
|
+
"HyperCoreOrderId",
|
|
622
|
+
"HyperCoreTokenIndex",
|
|
623
|
+
"MarginTableId",
|
|
624
|
+
"PayloadHash",
|
|
625
|
+
"ProposalHash",
|
|
626
|
+
"TxHash",
|
|
627
|
+
"parse_morpho_market_id",
|
|
608
628
|
"AssetId",
|
|
609
629
|
"CommandId",
|
|
610
630
|
"DeploymentRequestId",
|
|
@@ -42,7 +42,7 @@ from ipor_fusion.readers.morpho import (
|
|
|
42
42
|
MorphoReader,
|
|
43
43
|
morpho_blue_address,
|
|
44
44
|
)
|
|
45
|
-
from ipor_fusion.types import ChainId, MorphoBlueMarketId
|
|
45
|
+
from ipor_fusion.types import ChainId, MorphoBlueMarketId, parse_morpho_market_id
|
|
46
46
|
from ipor_fusion.vault_info import BLOCK_EXPLORER_URLS
|
|
47
47
|
|
|
48
48
|
|
|
@@ -54,12 +54,10 @@ class MarketIdType(click.ParamType):
|
|
|
54
54
|
def convert(self, value, param, ctx): # type: ignore[override]
|
|
55
55
|
if not isinstance(value, str):
|
|
56
56
|
self.fail(f"expected string, got {type(value).__name__}", param, ctx)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
)
|
|
62
|
-
return raw.lower()
|
|
57
|
+
try:
|
|
58
|
+
return parse_morpho_market_id(value)
|
|
59
|
+
except ValueError as exc:
|
|
60
|
+
self.fail(str(exc), param, ctx)
|
|
63
61
|
|
|
64
62
|
|
|
65
63
|
MARKET_ID = MarketIdType()
|
|
@@ -106,7 +104,7 @@ def market() -> None:
|
|
|
106
104
|
help="Emit machine-readable JSON instead of a table.",
|
|
107
105
|
)
|
|
108
106
|
def morpho_blue(
|
|
109
|
-
market_id:
|
|
107
|
+
market_id: MorphoBlueMarketId,
|
|
110
108
|
chain_id: ChainId,
|
|
111
109
|
block: int | None,
|
|
112
110
|
no_api: bool,
|
|
@@ -127,7 +125,7 @@ def morpho_blue(
|
|
|
127
125
|
if block is not None:
|
|
128
126
|
ctx.default_block = block
|
|
129
127
|
reader = MorphoReader(ctx, morpho_blue_address(chain_id))
|
|
130
|
-
mid =
|
|
128
|
+
mid = market_id
|
|
131
129
|
params, state = reader.require_market(mid)
|
|
132
130
|
rates = reader.rates_from(state, params)
|
|
133
131
|
|
|
@@ -171,7 +169,7 @@ def morpho_blue(
|
|
|
171
169
|
|
|
172
170
|
|
|
173
171
|
def _print_market(
|
|
174
|
-
market_id:
|
|
172
|
+
market_id: MorphoBlueMarketId,
|
|
175
173
|
chain_id: ChainId,
|
|
176
174
|
params: MorphoMarketParams,
|
|
177
175
|
state: MorphoMarket,
|
|
@@ -181,11 +179,11 @@ def _print_market(
|
|
|
181
179
|
chain_name = CHAIN_NAMES.get(chain_id, str(chain_id))
|
|
182
180
|
explorer = BLOCK_EXPLORER_URLS.get(chain_id, "")
|
|
183
181
|
liquidity = state.total_supply_assets - state.total_borrow_assets
|
|
184
|
-
click.secho(f"Morpho Blue market
|
|
182
|
+
click.secho(f"Morpho Blue market {market_id}", bold=True)
|
|
185
183
|
click.echo(f" Chain: {chain_name} (id {chain_id})")
|
|
186
184
|
if explorer:
|
|
187
185
|
click.echo(
|
|
188
|
-
f" App: https://app.morpho.org/{chain_name}/market/
|
|
186
|
+
f" App: https://app.morpho.org/{chain_name}/market/{market_id}"
|
|
189
187
|
)
|
|
190
188
|
click.echo(f" Loan token: {params.loan_token}")
|
|
191
189
|
click.echo(f" Collateral: {params.collateral_token}")
|
|
@@ -332,7 +330,7 @@ def _print_reallocate_hint(params: MorphoMarketParams) -> None:
|
|
|
332
330
|
@click.option(
|
|
333
331
|
"--market",
|
|
334
332
|
"market_filter",
|
|
335
|
-
type=
|
|
333
|
+
type=MARKET_ID,
|
|
336
334
|
default=None,
|
|
337
335
|
help="Filter caps/allocations to a single Morpho Blue market ID.",
|
|
338
336
|
)
|
|
@@ -346,7 +344,7 @@ def _print_reallocate_hint(params: MorphoMarketParams) -> None:
|
|
|
346
344
|
def meta_morpho(
|
|
347
345
|
vault_address: ChecksumAddress,
|
|
348
346
|
chain_id: ChainId,
|
|
349
|
-
market_filter:
|
|
347
|
+
market_filter: MorphoBlueMarketId | None,
|
|
350
348
|
json_output: bool,
|
|
351
349
|
) -> None:
|
|
352
350
|
"""Inspect a MetaMorpho V1 or Morpho Vault V2 by address.
|
|
@@ -361,22 +359,18 @@ def meta_morpho(
|
|
|
361
359
|
except MorphoApiError as exc:
|
|
362
360
|
raise click.UsageError(str(exc)) from exc
|
|
363
361
|
|
|
364
|
-
market_filter_norm = (
|
|
365
|
-
("0x" + market_filter.removeprefix("0x").lower()) if market_filter else None
|
|
366
|
-
)
|
|
367
|
-
|
|
368
362
|
if json_output:
|
|
369
363
|
click.echo(json_lib.dumps(build_meta_morpho_json(info, chain_id), indent=2))
|
|
370
364
|
return
|
|
371
365
|
|
|
372
366
|
if isinstance(info, VaultV2Info):
|
|
373
|
-
_print_vault_v2(info, chain_id,
|
|
367
|
+
_print_vault_v2(info, chain_id, market_filter)
|
|
374
368
|
else:
|
|
375
|
-
_print_vault_v1(info, chain_id,
|
|
369
|
+
_print_vault_v1(info, chain_id, market_filter)
|
|
376
370
|
|
|
377
371
|
|
|
378
372
|
def _print_vault_v2(
|
|
379
|
-
vault: VaultV2Info, chain_id: ChainId, market_filter:
|
|
373
|
+
vault: VaultV2Info, chain_id: ChainId, market_filter: MorphoBlueMarketId | None
|
|
380
374
|
) -> None:
|
|
381
375
|
chain_name = CHAIN_NAMES.get(chain_id, str(chain_id))
|
|
382
376
|
click.secho(f"Morpho Vault V2 — {vault.name} ({vault.symbol})", bold=True)
|
|
@@ -433,9 +427,7 @@ def _print_vault_v2(
|
|
|
433
427
|
market_caps = [c for c in vault.caps if c.cap_type == "MarketV1"]
|
|
434
428
|
other_caps = [c for c in vault.caps if c.cap_type != "MarketV1"]
|
|
435
429
|
if market_filter:
|
|
436
|
-
market_caps = [
|
|
437
|
-
c for c in market_caps if (c.market_id or "").lower() == market_filter
|
|
438
|
-
]
|
|
430
|
+
market_caps = [c for c in market_caps if c.market_id == market_filter]
|
|
439
431
|
|
|
440
432
|
click.secho(f"Morpho Blue market caps ({len(market_caps)}):", bold=True)
|
|
441
433
|
_print_market_caps(market_caps, vault.asset_symbol, vault.asset_decimals)
|
|
@@ -508,7 +500,7 @@ def _print_other_caps(
|
|
|
508
500
|
|
|
509
501
|
|
|
510
502
|
def _print_vault_v1(
|
|
511
|
-
vault: VaultV1Info, chain_id: ChainId, market_filter:
|
|
503
|
+
vault: VaultV1Info, chain_id: ChainId, market_filter: MorphoBlueMarketId | None
|
|
512
504
|
) -> None:
|
|
513
505
|
chain_name = CHAIN_NAMES.get(chain_id, str(chain_id))
|
|
514
506
|
public_allocator = PUBLIC_ALLOCATOR_ADDRESSES.get(chain_id)
|
|
@@ -552,7 +544,7 @@ def _print_vault_v1(
|
|
|
552
544
|
|
|
553
545
|
allocations = vault.allocations
|
|
554
546
|
if market_filter:
|
|
555
|
-
allocations = [a for a in allocations if a.market_id
|
|
547
|
+
allocations = [a for a in allocations if a.market_id == market_filter]
|
|
556
548
|
click.secho(f"Allocations ({len(allocations)}):", bold=True)
|
|
557
549
|
if not allocations:
|
|
558
550
|
click.echo(" (none)")
|
|
@@ -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.
|
|
232
|
+
tx_hash=TxHash(HexStr(tx_hash.to_0x_hex())),
|
|
233
233
|
revert_reason=reason,
|
|
234
234
|
)
|
|
235
235
|
return receipt
|
{ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/core/external_state_executor.py
RENAMED
|
@@ -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:
|
|
82
|
+
proposal_hash: ProposalHash
|
|
83
83
|
|
|
84
84
|
|
|
85
85
|
def _hash_of(
|
|
86
86
|
proposal: BalanceProposal, *, executor: ChecksumAddress, chain_id: ChainId
|
|
87
|
-
) ->
|
|
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:
|
|
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:
|
|
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
|
-
) ->
|
|
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
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
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:
|
|
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[
|
|
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[
|
|
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
|
-
|
|
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"
|
{ipor_fusion-4.0.0.dev30 → ipor_fusion-4.0.0.dev35}/src/ipor_fusion/fuses/external_state_events.py
RENAMED
|
@@ -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:
|
|
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) ->
|
|
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:
|