ipor-fusion 4.0.0.dev28__tar.gz → 4.0.0.dev32__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.dev28 → ipor_fusion-4.0.0.dev32}/AGENTS.md +3 -1
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/PKG-INFO +1 -1
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/pyproject.toml +1 -1
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/__init__.py +22 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/cli/market_cmd.py +18 -26
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/ccip/chainlink.py +2 -2
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/ccip/codec.py +4 -3
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/ccip/contracts.py +25 -14
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/ccip/indexer.py +4 -3
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/contracts.py +12 -5
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/lane.py +6 -6
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/messages.py +7 -3
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/stargate/contracts.py +26 -13
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/stargate/layerzero.py +7 -7
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/stargate/transport.py +2 -2
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/transport.py +2 -2
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/fuses/crosschain/stargate.py +4 -3
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/market_info.py +3 -3
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/mcp/server.py +4 -9
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/morpho_api.py +20 -13
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/readers/lending_health.py +8 -4
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/types.py +31 -1
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/vault_data.py +7 -4
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_cli_market_morpho_blue.py +3 -1
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/typed_client/consumer.py +27 -2
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/.claude-plugin/marketplace.json +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/.claude-plugin/plugin.json +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/.env.example +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/.gemini/settings.json +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/.git-blame-ignore-revs +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/.github/workflows/cd.yml +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/.github/workflows/ci.yml +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/.github/workflows/commit-lint.yml +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/.github/workflows/notify-slack.yml +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/.github/workflows/python-build.yml +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/.github/workflows/python-publish.yml +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/.github/workflows/release.yml +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/.github/workflows/report-slack.yml +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/.gitignore +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/.mcp.json +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/.pre-commit-config.yaml +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/.python-version +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/CHANGELOG.md +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/CLAUDE.md +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/CODEOWNERS +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/LICENSE +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/README.md +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/build.sh +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/examples/CONTRIBUTING.md +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/examples/README.md +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/examples/advanced_euler_v2_credit_market_base.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/examples/advanced_euler_v2_looping_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/examples/composed_hypercore_flow_arbitrum_hyperevm.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/examples/crosschain_ccip_usdc_arbitrum_hyperevm.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/examples/external_state_margin_leg_base.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/examples/simple_aave_v3_supply_base.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/pytest.ini +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/scripts/commit-check.sh +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/scripts/crosschain_readiness.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/skills/ipor-deploy-vault/SKILL.md +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/about.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/cache.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/chains.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/cli/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/cli/changelog_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/cli/config_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/cli/config_store.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/cli/main.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/cli/options.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/cli/oracle_mapping_view.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/cli/vault_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/cli/vault_health.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/cli/vault_info_view.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/cli/vault_markets_view.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/cli/vault_rendering.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/config/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/config/roles.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/core/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/core/access.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/core/address.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/core/context.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/core/contract.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/core/erc20.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/core/external_state_executor.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/core/fee_manager.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/core/fuse_action.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/core/fusion_factory.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/core/logs.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/core/multicall.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/core/oracle.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/core/plasma_vault.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/core/rewards_manager.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/core/simulation.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/core/withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/ccip/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/ccip/events.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/ccip/lane.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/ccip/quote.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/ccip/transport.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/discovery.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/errors.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/logs.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/simulation.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/stargate/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/stargate/lane.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/dependency_graph.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/entry_cli.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/entry_mcp.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/errors.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/explorer.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/field_docs.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/fuses/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/fuses/aave_v3.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/fuses/async_action.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/fuses/base.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/fuses/compound_v3.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/fuses/crosschain/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/fuses/crosschain/base.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/fuses/crosschain/ccip.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/fuses/erc4626.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/fuses/euler_v2.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/fuses/events.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/fuses/external_state.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/fuses/external_state_events.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/fuses/fluid_instadapp.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/fuses/gearbox_v3.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/fuses/hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/fuses/hypercore_events.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/fuses/merkl.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/fuses/morpho.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/fuses/ramses_v2.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/fuses/uniswap_v3.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/fuses/universal.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/guide/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/guide/architecture.md +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/guide/glossary.md +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/guide/invariants.md +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/guide/quickstart.md +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/market_ids.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/mcp/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/mcp/guide.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/mcp/models.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/py.typed +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/readers/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/readers/aave_v3.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/readers/aave_v4.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/readers/compound_v3.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/readers/hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/readers/hypercore_outcome.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/readers/morpho.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/readers/oracle_mapping.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/readers/position_manager.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/readers/ramses_v2.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/readers/uniswap_v3.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/readers/unpriceable.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/substrates.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/validation.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/vault_info.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/UniswapV3UniversalRouter.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/_crosschain_lifecycle.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/_crosschain_recovery.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/_euler_v2.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/_foundry.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/_guide.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/_hypercore_model.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/_hypercore_shadow.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/_multicall.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/_simulate.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/_validation.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/addresses.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/conftest.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/constants.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/fixtures/hypercore_hip3_flow.json +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/fixtures/hypercore_market55.json +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/fixtures/vault_info_golden/clean.json +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/fixtures/vault_info_golden/clean.txt +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/fixtures/vault_info_golden/rich.json +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/fixtures/vault_info_golden/rich.txt +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_about.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_access_manager.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_cache.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_chains.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_cli_changelog.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_cli_commands.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_cli_config_store.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_cli_helpers.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_cli_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_cli_lending_health.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_cli_oracle_mapping.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_cli_pending_requests_scan.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_cli_role_accounts.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_cli_vault_info_golden.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_cli_vault_predates_getters.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_cli_vault_validate.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_contract_call.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_contract_encoder.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_crosschain_ccip_events.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_crosschain_ccip_indexer.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_crosschain_ccip_quote.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_crosschain_chainlink.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_crosschain_contracts.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_crosschain_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_crosschain_errors.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_crosschain_lane.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_crosschain_layering.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_crosschain_readiness.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_crosschain_readiness_report.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_crosschain_transport.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_erc20.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_examples_composed_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_examples_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_examples_euler_looping_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_examples_vaults.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_explorer.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_external_state_events.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_external_state_executor.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_fee_manager.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_fuse_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_guide.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_hypercore_deployment.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_hypercore_events.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_hypercore_flow.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_hypercore_live.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_hypercore_outcome.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_hypercore_readers.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_hypercore_simulation.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_logs.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_mcp_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_mcp_models.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_mcp_server.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_mcp_vault_validate.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_multicall.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_oracle.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_oracle_mapping.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_plasma_vault.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_reader_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_readiness_selection.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_revert_decoding.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_rewards_manager.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_roles.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_sdk_layering.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_borrow_aave_v3_mainnet.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_claim_merkl_wrapper_base.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_claim_morpho_rewards.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_crosschain_canary.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_crosschain_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_crosschain_hyperevm.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_crosschain_lifecycle.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_euler_v2_batch_base.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_euler_v2_credit_market_base.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_euler_v2_swap_deploy_base.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_euler_v2_swap_reconfigure_base.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_euler_v2_swap_registry_base.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_examples_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_examples_base.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_examples_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_external_state_executor_base.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_fusion_factory_clone_base.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_looping_aave_v3_base.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_looping_morpho_blue_base.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_morpho_blue.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_pilot_v3.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_pilot_v4_uniswap.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_pilot_v5_ramses.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_pilot_v5_scheduled.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_plasma_vault_setters_base.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_readers_integration.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_release_funds.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_swap_on_base.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_simulate_vault_from_scratch_base.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_solidity_compiler.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_solidity_mirrors.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_substrates.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_types_and_events.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_unpriceable_tokens.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_validation.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_vault_dep_graph.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_vault_info_onchain_base.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_vault_info_onchain_base_no_withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_vault_simulator_blocks.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_web3_context.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/tests/test_withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/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
|
|
@@ -311,21 +311,32 @@ from ipor_fusion.substrates import (
|
|
|
311
311
|
from ipor_fusion.types import (
|
|
312
312
|
MAX_UINT256,
|
|
313
313
|
Amount,
|
|
314
|
+
AssetId,
|
|
314
315
|
AssetSource,
|
|
315
316
|
ChainId,
|
|
317
|
+
CommandId,
|
|
316
318
|
Decimals,
|
|
319
|
+
DeploymentRequestId,
|
|
317
320
|
Fee,
|
|
318
321
|
Liquidity,
|
|
319
322
|
MappingStatus,
|
|
320
323
|
MarketId,
|
|
324
|
+
MessageId,
|
|
321
325
|
MorphoBlueMarketId,
|
|
322
326
|
NodeStatus,
|
|
327
|
+
OperationId,
|
|
323
328
|
Period,
|
|
329
|
+
PositionSetHash,
|
|
324
330
|
Price,
|
|
331
|
+
ProposalId,
|
|
332
|
+
ReturnRequestId,
|
|
325
333
|
RoleId,
|
|
326
334
|
Shares,
|
|
335
|
+
StargateAssetId,
|
|
327
336
|
Tick,
|
|
328
337
|
TokenId,
|
|
338
|
+
TransferId,
|
|
339
|
+
parse_morpho_market_id,
|
|
329
340
|
)
|
|
330
341
|
from ipor_fusion.validation import (
|
|
331
342
|
Erc20Holding,
|
|
@@ -595,6 +606,17 @@ __all__ = [
|
|
|
595
606
|
"RoleId",
|
|
596
607
|
"ChainId",
|
|
597
608
|
"MorphoBlueMarketId",
|
|
609
|
+
"parse_morpho_market_id",
|
|
610
|
+
"AssetId",
|
|
611
|
+
"CommandId",
|
|
612
|
+
"DeploymentRequestId",
|
|
613
|
+
"MessageId",
|
|
614
|
+
"OperationId",
|
|
615
|
+
"PositionSetHash",
|
|
616
|
+
"ProposalId",
|
|
617
|
+
"ReturnRequestId",
|
|
618
|
+
"StargateAssetId",
|
|
619
|
+
"TransferId",
|
|
598
620
|
"Price",
|
|
599
621
|
"Period",
|
|
600
622
|
"MAX_UINT256",
|
|
@@ -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)")
|
{ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/ccip/chainlink.py
RENAMED
|
@@ -16,7 +16,7 @@ from eth_typing import ChecksumAddress
|
|
|
16
16
|
from ipor_fusion.core.context import Web3Context
|
|
17
17
|
from ipor_fusion.core.contract import Call, ContractWrapper
|
|
18
18
|
from ipor_fusion.crosschain.contracts import _address
|
|
19
|
-
from ipor_fusion.types import ZERO_ADDRESS
|
|
19
|
+
from ipor_fusion.types import ZERO_ADDRESS, MessageId
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
class CcipRouter(ContractWrapper):
|
|
@@ -191,7 +191,7 @@ class CcipOffRamp(ContractWrapper):
|
|
|
191
191
|
def type_and_version(self) -> Call[str]:
|
|
192
192
|
return self._view("typeAndVersion()", output_types=["string"])
|
|
193
193
|
|
|
194
|
-
def execution_state(self, message_id:
|
|
194
|
+
def execution_state(self, message_id: MessageId) -> Call[MessageExecutionState]:
|
|
195
195
|
return self._view(
|
|
196
196
|
"getExecutionState(bytes32)",
|
|
197
197
|
message_id,
|
{ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/ccip/codec.py
RENAMED
|
@@ -21,6 +21,7 @@ from web3 import Web3
|
|
|
21
21
|
|
|
22
22
|
from ipor_fusion.core.contract import _encode_calldata
|
|
23
23
|
from ipor_fusion.crosschain.logs import log_bytes
|
|
24
|
+
from ipor_fusion.types import MessageId
|
|
24
25
|
|
|
25
26
|
#: topic0 of ``OnRamp 2.0.0``'s ``CCIPMessageSent``; ``destChainSelector``,
|
|
26
27
|
#: ``sender`` and ``messageId`` are indexed.
|
|
@@ -176,7 +177,7 @@ def evm_address(raw: bytes) -> ChecksumAddress:
|
|
|
176
177
|
class CcipMessageSent:
|
|
177
178
|
"""One ``CCIPMessageSent`` log: the Router-assigned id plus the decoded message."""
|
|
178
179
|
|
|
179
|
-
message_id:
|
|
180
|
+
message_id: MessageId
|
|
180
181
|
dest_chain_selector: int
|
|
181
182
|
sender: ChecksumAddress
|
|
182
183
|
message: MessageV1
|
|
@@ -193,7 +194,7 @@ class CcipMessageSent:
|
|
|
193
194
|
_EVENT_DATA_TYPES, log_bytes(log["data"])
|
|
194
195
|
)
|
|
195
196
|
return cls(
|
|
196
|
-
message_id=topics[3],
|
|
197
|
+
message_id=MessageId(bytes(topics[3])),
|
|
197
198
|
dest_chain_selector=int.from_bytes(topics[1], "big"),
|
|
198
199
|
sender=Web3.to_checksum_address(topics[2][12:]),
|
|
199
200
|
message=MessageV1.decode(bytes(encoded)),
|
|
@@ -215,7 +216,7 @@ class Any2EVMMessage:
|
|
|
215
216
|
``sender`` is the source address; it is ABI-encoded into the wire field,
|
|
216
217
|
which is how the receivers decode it."""
|
|
217
218
|
|
|
218
|
-
message_id:
|
|
219
|
+
message_id: MessageId
|
|
219
220
|
source_chain_selector: int
|
|
220
221
|
sender: ChecksumAddress
|
|
221
222
|
data: bytes
|
{ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/ccip/contracts.py
RENAMED
|
@@ -18,7 +18,16 @@ from ipor_fusion.crosschain.contracts import (
|
|
|
18
18
|
_address,
|
|
19
19
|
)
|
|
20
20
|
from ipor_fusion.crosschain.messages import CommandStatus, CrosschainTransportKind
|
|
21
|
-
from ipor_fusion.types import
|
|
21
|
+
from ipor_fusion.types import (
|
|
22
|
+
Amount,
|
|
23
|
+
AssetId,
|
|
24
|
+
ChainId,
|
|
25
|
+
CommandId,
|
|
26
|
+
MessageId,
|
|
27
|
+
OperationId,
|
|
28
|
+
PositionSetHash,
|
|
29
|
+
ProposalId,
|
|
30
|
+
)
|
|
22
31
|
|
|
23
32
|
|
|
24
33
|
@dataclass(frozen=True, slots=True)
|
|
@@ -30,7 +39,7 @@ class CcipObservation:
|
|
|
30
39
|
queued_token_amount: Amount
|
|
31
40
|
state_version: int
|
|
32
41
|
command_config_epoch: int
|
|
33
|
-
tracked_position_set_hash:
|
|
42
|
+
tracked_position_set_hash: PositionSetHash
|
|
34
43
|
|
|
35
44
|
|
|
36
45
|
@dataclass(frozen=True, slots=True)
|
|
@@ -161,13 +170,13 @@ class CcipCrosschainExecutor(CrosschainExecutor):
|
|
|
161
170
|
"activeReturn(uint256)", chain_id, output_types=["bytes32"], decoder=bytes
|
|
162
171
|
)
|
|
163
172
|
|
|
164
|
-
def active_command(self, chain_id: ChainId) -> Call[
|
|
173
|
+
def active_command(self, chain_id: ChainId) -> Call[CommandId]:
|
|
165
174
|
"""The active command id for the chain, or 32 zero bytes."""
|
|
166
175
|
return self._view(
|
|
167
176
|
"activeCommand(uint256)",
|
|
168
177
|
chain_id,
|
|
169
178
|
output_types=["bytes32"],
|
|
170
|
-
decoder=bytes,
|
|
179
|
+
decoder=lambda value: CommandId(bytes(value)),
|
|
171
180
|
)
|
|
172
181
|
|
|
173
182
|
def next_command_sequence(self, chain_id: ChainId) -> Call[int]:
|
|
@@ -203,7 +212,7 @@ class CcipCrosschainExecutor(CrosschainExecutor):
|
|
|
203
212
|
decoder=Amount,
|
|
204
213
|
)
|
|
205
214
|
|
|
206
|
-
def command_status(self, command_id:
|
|
215
|
+
def command_status(self, command_id: CommandId) -> Call[CommandStatus]:
|
|
207
216
|
return self._view(
|
|
208
217
|
"commandStatus(bytes32)",
|
|
209
218
|
command_id,
|
|
@@ -219,7 +228,7 @@ class CcipCrosschainExecutor(CrosschainExecutor):
|
|
|
219
228
|
"pendingTransferCount(uint256)", chain_id, output_types=["uint8"]
|
|
220
229
|
)
|
|
221
230
|
|
|
222
|
-
def processed_ccip_message(self, message_id:
|
|
231
|
+
def processed_ccip_message(self, message_id: MessageId) -> Call[bool]:
|
|
223
232
|
return self._view(
|
|
224
233
|
"processedCcipMessage(bytes32)", message_id, output_types=["bool"]
|
|
225
234
|
)
|
|
@@ -236,7 +245,7 @@ class CcipCrosschainExecutor(CrosschainExecutor):
|
|
|
236
245
|
output_types=["uint256"],
|
|
237
246
|
)
|
|
238
247
|
|
|
239
|
-
def reject_balance_and_block(self, proposal_id:
|
|
248
|
+
def reject_balance_and_block(self, proposal_id: ProposalId) -> Call[None]:
|
|
240
249
|
"""``BALANCE_APPROVER`` only: reject and fail the chain closed."""
|
|
241
250
|
return self._write("rejectBalanceAndBlock(uint256)", proposal_id)
|
|
242
251
|
|
|
@@ -292,12 +301,12 @@ class CcipCrosschainDispatcher(CrosschainDispatcher):
|
|
|
292
301
|
"queuedTokenAmount()", output_types=["uint256"], decoder=Amount
|
|
293
302
|
)
|
|
294
303
|
|
|
295
|
-
def processed_operation(self, operation_id:
|
|
304
|
+
def processed_operation(self, operation_id: OperationId) -> Call[bool]:
|
|
296
305
|
return self._view(
|
|
297
306
|
"processedOperation(bytes32)", operation_id, output_types=["bool"]
|
|
298
307
|
)
|
|
299
308
|
|
|
300
|
-
def processed_ccip_message(self, message_id:
|
|
309
|
+
def processed_ccip_message(self, message_id: MessageId) -> Call[bool]:
|
|
301
310
|
return self._view(
|
|
302
311
|
"processedCcipMessage(bytes32)", message_id, output_types=["bool"]
|
|
303
312
|
)
|
|
@@ -316,7 +325,7 @@ def _ccip_observation_decoder(values: tuple) -> CcipObservation:
|
|
|
316
325
|
queued_token_amount=Amount(queued),
|
|
317
326
|
state_version=int(version),
|
|
318
327
|
command_config_epoch=int(epoch),
|
|
319
|
-
tracked_position_set_hash=bytes(set_hash),
|
|
328
|
+
tracked_position_set_hash=PositionSetHash(bytes(set_hash)),
|
|
320
329
|
)
|
|
321
330
|
|
|
322
331
|
|
|
@@ -327,7 +336,7 @@ class CcipCrosschainFactory(CrosschainFactory):
|
|
|
327
336
|
def create_executor(
|
|
328
337
|
self,
|
|
329
338
|
user_salt: bytes,
|
|
330
|
-
asset_id:
|
|
339
|
+
asset_id: AssetId,
|
|
331
340
|
manager: ChecksumAddress,
|
|
332
341
|
safety: SafetyConfig,
|
|
333
342
|
) -> Call[ChecksumAddress]:
|
|
@@ -365,7 +374,9 @@ class CcipCrosschainFactory(CrosschainFactory):
|
|
|
365
374
|
decoder=ChainId,
|
|
366
375
|
)
|
|
367
376
|
|
|
368
|
-
def asset_config(
|
|
377
|
+
def asset_config(
|
|
378
|
+
self, asset_id: AssetId
|
|
379
|
+
) -> Call[tuple[ChecksumAddress, int, bool]]:
|
|
369
380
|
"""``(token, sharedDecimals, enabled)`` for an asset id."""
|
|
370
381
|
return self._view(
|
|
371
382
|
"assetConfig(bytes32)",
|
|
@@ -444,7 +455,7 @@ class CcipCrosschainFactory(CrosschainFactory):
|
|
|
444
455
|
)
|
|
445
456
|
|
|
446
457
|
def schedule_asset(
|
|
447
|
-
self, asset_id:
|
|
458
|
+
self, asset_id: AssetId, token: ChecksumAddress, shared_decimals: int
|
|
448
459
|
) -> Call[None]:
|
|
449
460
|
"""Owner-only; executable after ``config_delay`` with the same arguments."""
|
|
450
461
|
return self._write(
|
|
@@ -452,7 +463,7 @@ class CcipCrosschainFactory(CrosschainFactory):
|
|
|
452
463
|
)
|
|
453
464
|
|
|
454
465
|
def execute_asset(
|
|
455
|
-
self, asset_id:
|
|
466
|
+
self, asset_id: AssetId, token: ChecksumAddress, shared_decimals: int
|
|
456
467
|
) -> Call[None]:
|
|
457
468
|
return self._write(
|
|
458
469
|
"executeAsset(bytes32,address,uint8)", asset_id, token, shared_decimals
|
{ipor_fusion-4.0.0.dev28 → ipor_fusion-4.0.0.dev32}/src/ipor_fusion/crosschain/ccip/indexer.py
RENAMED
|
@@ -21,6 +21,7 @@ from web3 import Web3
|
|
|
21
21
|
|
|
22
22
|
from ipor_fusion.core.contract import Call
|
|
23
23
|
from ipor_fusion.crosschain.ccip.chainlink import CcipOffRamp
|
|
24
|
+
from ipor_fusion.types import MessageId
|
|
24
25
|
|
|
25
26
|
#: Chainlink Labs' public mainnet indexers, tried in order.
|
|
26
27
|
INDEXER_URLS: tuple[str, ...] = (
|
|
@@ -40,7 +41,7 @@ class VerifierResultUnavailable(LookupError):
|
|
|
40
41
|
class VerifierResult:
|
|
41
42
|
"""One message's committee result as the indexer serves it."""
|
|
42
43
|
|
|
43
|
-
message_id:
|
|
44
|
+
message_id: MessageId
|
|
44
45
|
#: The CCVs the message names, in the order ``execute`` expects.
|
|
45
46
|
ccv_addresses: tuple[ChecksumAddress, ...]
|
|
46
47
|
#: The verifier result for the committee CCV: version tag, signature
|
|
@@ -54,7 +55,7 @@ class VerifierResult:
|
|
|
54
55
|
|
|
55
56
|
|
|
56
57
|
def fetch_verifier_result(
|
|
57
|
-
message_id:
|
|
58
|
+
message_id: MessageId,
|
|
58
59
|
*,
|
|
59
60
|
indexers: Sequence[str] = INDEXER_URLS,
|
|
60
61
|
timeout: float = 15.0,
|
|
@@ -82,7 +83,7 @@ def fetch_verifier_result(
|
|
|
82
83
|
continue
|
|
83
84
|
result = results[0]["verifierResult"]
|
|
84
85
|
return VerifierResult(
|
|
85
|
-
message_id=bytes.fromhex(result["message_id"][2:]),
|
|
86
|
+
message_id=MessageId(bytes.fromhex(result["message_id"][2:])),
|
|
86
87
|
ccv_addresses=tuple(
|
|
87
88
|
Web3.to_checksum_address(a) for a in result["message_ccv_addresses"]
|
|
88
89
|
),
|
|
@@ -19,7 +19,14 @@ from web3 import Web3
|
|
|
19
19
|
|
|
20
20
|
from ipor_fusion.core.contract import Call, ContractWrapper
|
|
21
21
|
from ipor_fusion.crosschain.messages import CommandStatus
|
|
22
|
-
from ipor_fusion.types import
|
|
22
|
+
from ipor_fusion.types import (
|
|
23
|
+
Amount,
|
|
24
|
+
AssetId,
|
|
25
|
+
ChainId,
|
|
26
|
+
CommandId,
|
|
27
|
+
PositionSetHash,
|
|
28
|
+
ProposalId,
|
|
29
|
+
)
|
|
23
30
|
|
|
24
31
|
|
|
25
32
|
@dataclass(frozen=True, slots=True)
|
|
@@ -36,7 +43,7 @@ class BalanceObservation:
|
|
|
36
43
|
remote_block: int
|
|
37
44
|
remote_timestamp: int
|
|
38
45
|
expiry: int
|
|
39
|
-
tracked_position_set_hash:
|
|
46
|
+
tracked_position_set_hash: PositionSetHash
|
|
40
47
|
|
|
41
48
|
def as_tuple(self) -> tuple:
|
|
42
49
|
return (
|
|
@@ -150,7 +157,7 @@ class CrosschainExecutor(ContractWrapper):
|
|
|
150
157
|
"lastApprovedObservedAt(uint256)", chain_id, output_types=["uint64"]
|
|
151
158
|
)
|
|
152
159
|
|
|
153
|
-
def approve_balance(self, proposal_id:
|
|
160
|
+
def approve_balance(self, proposal_id: ProposalId) -> Call[None]:
|
|
154
161
|
"""``BALANCE_APPROVER`` only."""
|
|
155
162
|
return self._write("approveBalance(uint256)", proposal_id)
|
|
156
163
|
|
|
@@ -205,7 +212,7 @@ class CrosschainDispatcher(ContractWrapper):
|
|
|
205
212
|
"pendingRequestShares(address)", vault, output_types=["uint256"]
|
|
206
213
|
)
|
|
207
214
|
|
|
208
|
-
def command_status(self, command_id:
|
|
215
|
+
def command_status(self, command_id: CommandId) -> Call[CommandStatus]:
|
|
209
216
|
return self._view(
|
|
210
217
|
"commandStatus(bytes32)",
|
|
211
218
|
command_id,
|
|
@@ -253,7 +260,7 @@ class CrosschainFactory(ContractWrapper):
|
|
|
253
260
|
def is_allowed_creator(self, creator: ChecksumAddress) -> Call[bool]:
|
|
254
261
|
return self._view("isAllowedCreator(address)", creator, output_types=["bool"])
|
|
255
262
|
|
|
256
|
-
def asset_frozen(self, asset_id:
|
|
263
|
+
def asset_frozen(self, asset_id: AssetId) -> Call[bool]:
|
|
257
264
|
return self._view("assetFrozen(bytes32)", asset_id, output_types=["bool"])
|
|
258
265
|
|
|
259
266
|
def creation_codes_configured(self) -> Call[bool]:
|
|
@@ -40,7 +40,7 @@ from ipor_fusion.fuses.crosschain.base import (
|
|
|
40
40
|
CrosschainSupplyFuse,
|
|
41
41
|
SendParams,
|
|
42
42
|
)
|
|
43
|
-
from ipor_fusion.types import Amount, ChainId
|
|
43
|
+
from ipor_fusion.types import Amount, ChainId, PositionSetHash, ProposalId
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
@dataclass(frozen=True, slots=True)
|
|
@@ -54,7 +54,7 @@ class LaneObservation:
|
|
|
54
54
|
accounted_balance: Amount
|
|
55
55
|
state_version: int
|
|
56
56
|
command_config_epoch: int
|
|
57
|
-
tracked_position_set_hash:
|
|
57
|
+
tracked_position_set_hash: PositionSetHash
|
|
58
58
|
|
|
59
59
|
|
|
60
60
|
@dataclass(frozen=True, slots=True)
|
|
@@ -241,11 +241,11 @@ class CrosschainLane(ABC):
|
|
|
241
241
|
last = self.last_approved_observed_at().call()
|
|
242
242
|
return last == 0 or now - last > self.staleness_max().call() - margin
|
|
243
243
|
|
|
244
|
-
def approve_balance(self, proposal_id:
|
|
244
|
+
def approve_balance(self, proposal_id: ProposalId) -> Call[None]:
|
|
245
245
|
"""``BALANCE_APPROVER`` only."""
|
|
246
246
|
return self.executor.approve_balance(proposal_id)
|
|
247
247
|
|
|
248
|
-
def proposal_id_from_logs(self, logs: Iterable[Mapping]) ->
|
|
248
|
+
def proposal_id_from_logs(self, logs: Iterable[Mapping]) -> ProposalId:
|
|
249
249
|
"""The id of the proposal this lane's executor emitted in ``logs``
|
|
250
250
|
(a receipt's or a simulated call's), from its ``BalanceProposed``."""
|
|
251
251
|
for log in logs:
|
|
@@ -254,10 +254,10 @@ class CrosschainLane(ABC):
|
|
|
254
254
|
and log_address(log) == self.executor_address
|
|
255
255
|
):
|
|
256
256
|
(proposal_id,) = decode(["uint256"], log_bytes(log["data"])[:32])
|
|
257
|
-
return int(proposal_id)
|
|
257
|
+
return ProposalId(int(proposal_id))
|
|
258
258
|
raise ValueError("no BalanceProposed log from the executor")
|
|
259
259
|
|
|
260
|
-
def proposal_id_from_receipt(self, receipt: Mapping) ->
|
|
260
|
+
def proposal_id_from_receipt(self, receipt: Mapping) -> ProposalId:
|
|
261
261
|
return self.proposal_id_from_logs(receipt["logs"])
|
|
262
262
|
|
|
263
263
|
def _require_spoke(self, observation: BalanceObservation) -> None:
|
|
@@ -18,7 +18,7 @@ from eth_typing import ChecksumAddress
|
|
|
18
18
|
from web3 import Web3
|
|
19
19
|
|
|
20
20
|
from ipor_fusion.core.address import _validate_not_zero_address
|
|
21
|
-
from ipor_fusion.types import Amount, Shares
|
|
21
|
+
from ipor_fusion.types import Amount, CommandId, Shares
|
|
22
22
|
|
|
23
23
|
#: ``CrosschainConstants.CODEC_VERSION`` -- the Stargate/LayerZero envelope version.
|
|
24
24
|
CODEC_VERSION = 3
|
|
@@ -128,6 +128,10 @@ _ZERO_SHARES = Shares(0)
|
|
|
128
128
|
COMMAND_TUPLE_TYPE = "(bytes32,uint64,uint64,uint8,bytes)"
|
|
129
129
|
|
|
130
130
|
|
|
131
|
+
# The zero command id: no command, or one not yet assigned by the executor.
|
|
132
|
+
NO_COMMAND_ID = CommandId(bytes(32))
|
|
133
|
+
|
|
134
|
+
|
|
131
135
|
@dataclass(frozen=True, slots=True)
|
|
132
136
|
class Command:
|
|
133
137
|
"""``CrosschainMessages.Command``: one business command for a dispatcher.
|
|
@@ -143,7 +147,7 @@ class Command:
|
|
|
143
147
|
|
|
144
148
|
action: BusinessAction
|
|
145
149
|
action_data: bytes
|
|
146
|
-
command_id:
|
|
150
|
+
command_id: CommandId = NO_COMMAND_ID
|
|
147
151
|
sequence: int = 0
|
|
148
152
|
command_config_epoch: int = 0
|
|
149
153
|
|
|
@@ -167,7 +171,7 @@ class Command:
|
|
|
167
171
|
return cls(
|
|
168
172
|
action=BusinessAction(action),
|
|
169
173
|
action_data=bytes(action_data),
|
|
170
|
-
command_id=bytes(command_id),
|
|
174
|
+
command_id=CommandId(bytes(command_id)),
|
|
171
175
|
sequence=int(sequence),
|
|
172
176
|
command_config_epoch=int(config_epoch),
|
|
173
177
|
)
|