ipor-fusion 4.0.0.dev63__tar.gz → 4.0.0.dev66__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.dev63 → ipor_fusion-4.0.0.dev66}/MIGRATION_4.md +12 -4
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/PKG-INFO +1 -1
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/pyproject.toml +1 -1
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/cli/vault_info_view.py +2 -2
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/external_state_events.py +6 -1
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/mcp/server.py +2 -2
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/substrates.py +21 -16
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/types.py +16 -9
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_cli_vault_info_golden.py +2 -2
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_external_state_events.py +7 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_types_and_events.py +16 -5
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/typed_client/consumer.py +1 -1
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/.claude-plugin/marketplace.json +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/.claude-plugin/plugin.json +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/.env.example +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/.gemini/settings.json +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/.git-blame-ignore-revs +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/.github/workflows/cd.yml +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/.github/workflows/ci.yml +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/.github/workflows/commit-lint.yml +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/.github/workflows/notify-slack.yml +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/.github/workflows/python-build.yml +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/.github/workflows/python-publish.yml +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/.github/workflows/release.yml +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/.github/workflows/report-slack.yml +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/.gitignore +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/.mcp.json +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/.pre-commit-config.yaml +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/.python-version +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/AGENTS.md +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/CHANGELOG.md +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/CLAUDE.md +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/CODEOWNERS +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/LICENSE +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/README.md +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/build.sh +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/examples/CONTRIBUTING.md +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/examples/README.md +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/examples/advanced_euler_v2_credit_market_base.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/examples/advanced_euler_v2_looping_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/examples/composed_hypercore_flow_arbitrum_hyperevm.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/examples/crosschain_ccip_usdc_arbitrum_hyperevm.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/examples/external_state_margin_leg_base.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/examples/simple_aave_v3_supply_base.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/pytest.ini +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/scripts/commit-check.sh +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/scripts/crosschain_readiness.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/skills/ipor-deploy-vault/SKILL.md +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/about.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/cache.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/chains.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/cli/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/cli/changelog_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/cli/config_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/cli/config_store.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/cli/main.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/cli/market_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/cli/options.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/cli/oracle_mapping_view.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/cli/vault_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/cli/vault_health.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/cli/vault_markets_view.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/cli/vault_rendering.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/config/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/config/roles.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/core/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/core/access.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/core/address.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/core/context.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/core/contract.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/core/erc20.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/core/external_state_executor.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/core/fee_manager.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/core/fuse_action.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/core/fusion_factory.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/core/logs.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/core/multicall.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/core/oracle.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/core/plasma_vault.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/core/rewards_manager.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/core/simulation.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/core/withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/ccip/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/ccip/chainlink.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/ccip/codec.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/ccip/contracts.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/ccip/events.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/ccip/indexer.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/ccip/lane.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/ccip/quote.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/ccip/transport.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/contracts.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/discovery.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/errors.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/lane.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/logs.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/messages.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/simulation.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/stargate/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/stargate/contracts.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/stargate/lane.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/stargate/layerzero.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/stargate/transport.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/transport.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/dependency_graph.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/entry_cli.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/entry_mcp.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/errors.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/explorer.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/field_docs.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/aave_v3.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/async_action.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/base.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/compound_v3.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/crosschain/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/crosschain/base.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/crosschain/ccip.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/crosschain/stargate.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/erc4626.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/euler_v2.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/events.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/external_state.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/fluid_instadapp.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/gearbox_v3.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/hypercore_events.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/merkl.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/morpho.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/ramses_v2.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/uniswap_v3.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/universal.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/guide/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/guide/architecture.md +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/guide/glossary.md +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/guide/invariants.md +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/guide/quickstart.md +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/market_ids.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/market_info.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/mcp/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/mcp/guide.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/mcp/models.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/morpho_api.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/py.typed +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/readers/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/readers/aave_v3.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/readers/aave_v4.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/readers/compound_v3.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/readers/hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/readers/hypercore_outcome.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/readers/lending_health.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/readers/morpho.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/readers/oracle_mapping.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/readers/oracle_mapping_nodes.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/readers/oracle_mapping_reader.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/readers/position_manager.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/readers/ramses_v2.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/readers/uniswap_v3.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/readers/unpriceable.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/validation.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/vault_data.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/vault_info.py +1 -1
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/vault_managers.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/vault_positions.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/vault_reads.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/UniswapV3UniversalRouter.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/_crosschain_lifecycle.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/_crosschain_recovery.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/_euler_v2.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/_foundry.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/_guide.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/_hypercore_model.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/_hypercore_shadow.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/_multicall.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/_simulate.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/_validation.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/addresses.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/conftest.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/constants.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/fixtures/hypercore_hip3_flow.json +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/fixtures/hypercore_market55.json +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/fixtures/vault_info_golden/clean.json +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/fixtures/vault_info_golden/clean.txt +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/fixtures/vault_info_golden/rich.json +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/fixtures/vault_info_golden/rich.txt +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_about.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_access_manager.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_cache.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_chains.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_cli_changelog.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_cli_commands.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_cli_config_store.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_cli_helpers.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_cli_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_cli_lending_health.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_cli_market_morpho_blue.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_cli_oracle_mapping.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_cli_pending_requests_scan.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_cli_role_accounts.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_cli_vault_predates_getters.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_cli_vault_validate.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_contract_call.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_contract_encoder.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_crosschain_ccip_events.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_crosschain_ccip_indexer.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_crosschain_ccip_quote.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_crosschain_chainlink.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_crosschain_contracts.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_crosschain_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_crosschain_errors.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_crosschain_lane.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_crosschain_layering.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_crosschain_readiness.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_crosschain_readiness_report.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_crosschain_transport.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_erc20.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_examples_composed_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_examples_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_examples_euler_looping_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_examples_vaults.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_explorer.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_external_state_executor.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_fee_manager.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_fuse_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_guide.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_hypercore_deployment.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_hypercore_events.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_hypercore_flow.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_hypercore_live.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_hypercore_outcome.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_hypercore_readers.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_hypercore_simulation.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_logs.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_mcp_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_mcp_models.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_mcp_server.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_mcp_vault_validate.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_multicall.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_oracle.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_oracle_mapping.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_plasma_vault.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_reader_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_readiness_selection.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_revert_decoding.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_rewards_manager.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_roles.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_sdk_layering.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_borrow_aave_v3_mainnet.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_claim_merkl_wrapper_base.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_claim_morpho_rewards.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_crosschain_canary.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_crosschain_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_crosschain_hyperevm.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_crosschain_lifecycle.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_euler_v2_batch_base.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_euler_v2_credit_market_base.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_euler_v2_swap_deploy_base.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_euler_v2_swap_reconfigure_base.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_euler_v2_swap_registry_base.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_examples_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_examples_base.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_examples_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_external_state_executor_base.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_fusion_factory_clone_base.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_looping_aave_v3_base.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_looping_morpho_blue_base.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_morpho_blue.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_pilot_v3.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_pilot_v4_uniswap.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_pilot_v5_ramses.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_pilot_v5_scheduled.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_plasma_vault_setters_base.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_readers_integration.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_release_funds.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_swap_on_base.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_simulate_vault_from_scratch_base.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_solidity_compiler.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_solidity_mirrors.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_substrates.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_unpriceable_tokens.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_validation.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_vault_dep_graph.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_vault_info_onchain_base.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_vault_info_onchain_base_no_withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_vault_simulator_blocks.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_web3_context.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/tests/test_withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/uv.lock +0 -0
|
@@ -29,15 +29,22 @@ widths or address spelling.
|
|
|
29
29
|
| `RoleId` | a `Roles` member (accepted as is), or `RoleId(n)`; `Roles.resolve(name)` returns one |
|
|
30
30
|
| `Decimals`, `Period`, `Amount`, ... | `Decimals(8)`, `Period(0)`, `Amount(n)` (unchanged) |
|
|
31
31
|
| `ChecksumAddress` | `Web3.to_checksum_address(value)` |
|
|
32
|
-
| `HexAddress` | any `ChecksumAddress`, or `parse_hex_address(value)` (20 bytes or hex in any
|
|
32
|
+
| `HexAddress` | any `ChecksumAddress`, or `parse_hex_address(value)` (20 bytes or `0x`/`0X`-prefixed hex in any case → lowercase `0x` form) |
|
|
33
33
|
| `MorphoBlueMarketId` | `parse_morpho_market_id(value)`: 32 bytes or hex in any spelling, always `0x` + 64 lowercase digits |
|
|
34
|
-
| `TxHash` | `parse_tx_hash(value)` (32 bytes or hex in any
|
|
34
|
+
| `TxHash` | `parse_tx_hash(value)` (32 bytes or `0x`/`0X`-prefixed hex in any case) |
|
|
35
35
|
| `PlasmaVaultAddress`, `FuseAddress`, `AccessManagerAddress` | from the SDK (`PlasmaVault.address`, `get_fuses()`, `get_access_manager_address()`, `FusionInstance`, discovery), or `parse_plasma_vault_address` / `parse_fuse_address` / `parse_access_manager_address(value)` for a raw address; they label the role and check nothing on chain |
|
|
36
36
|
| crosschain ids | `CommandId(b)`, `MessageId(b)`, `AssetId(b)`, `OperationId(b)`, `TransferId(b)`, `ReturnRequestId(b)`, `PositionSetHash(b)` (bytes32); `ProposalId(n)`, `DeploymentRequestId(n)`, `StargateAssetId(n)` (int) |
|
|
37
37
|
| HyperCore ids | `HyperCoreTokenIndex(n)` (or `USDC_TOKEN_INDEX`), `HyperCoreAsset(n)` (or `hip3_action_asset(dex, index)`), `HyperCoreOrderId(n)`, `HyperCoreClientOrderId(n)`, `MarginTableId(n)`, `HyperCoreActionId(n)`, `PayloadHash(b)` |
|
|
38
38
|
| external state | `ProposalHash(b)` |
|
|
39
39
|
| `BlockIdentifier` | a block number, `"latest"` / `"pending"` / ..., or a block hash |
|
|
40
40
|
|
|
41
|
+
The address and hash parsers (`parse_hex_address`, `parse_tx_hash`,
|
|
42
|
+
`parse_plasma_vault_address`, `parse_fuse_address`, `parse_access_manager_address`)
|
|
43
|
+
validate strictly: a string needs exactly one `0x`/`0X` prefix and the exact number of
|
|
44
|
+
hex digits, with no surrounding whitespace; anything else raises `ValueError`. Strip
|
|
45
|
+
user input yourself before parsing it. `parse_morpho_market_id` still accepts hex
|
|
46
|
+
without `0x`.
|
|
47
|
+
|
|
41
48
|
`MessageId` covers both a CCIP `messageId` and a LayerZero `guid`. `AssetId` is the
|
|
42
49
|
crosschain executor's `bytes32` asset id; a Stargate pool's `uint16` asset id is
|
|
43
50
|
`StargateAssetId`. `DeploymentRequestId` is a factory's `uint256` dispatcher request;
|
|
@@ -49,8 +56,9 @@ a `bytes32` return (recall) request is `ReturnRequestId`.
|
|
|
49
56
|
`build_vault_info_json`, `ensure_supported_chain` and `fetch_vault_lending_health`
|
|
50
57
|
take `ChainId`. The vault is a `PlasmaVaultAddress` (see *Address roles*) in
|
|
51
58
|
`validate_vault` and `fetch_deployment_info`; `build_vault_info_json(ctx, plasma_vault,
|
|
52
|
-
data, chain_id, chain_label)` takes no address
|
|
53
|
-
`plasma_vault.address
|
|
59
|
+
data, *, chain_id, chain_label)` takes no address, takes the chain by keyword, and
|
|
60
|
+
labels the document with `plasma_vault.address` (a test that mocks `PlasmaVault`
|
|
61
|
+
sets `.address`). `fetch_unpriceable_priced_tokens` takes the oracle and
|
|
54
62
|
underlying as `ChecksumAddress`. `resolve_token_symbol`, `resolve_token_decimals`,
|
|
55
63
|
`get_contract_name` and `get_deployment_tx` take `HexAddress` (a checksum address
|
|
56
64
|
fits), and the `resolve_name` / `resolve_symbol` callbacks receive one (a callback
|
|
@@ -98,8 +98,8 @@ def _print_vault_info(
|
|
|
98
98
|
ctx,
|
|
99
99
|
plasma_vault,
|
|
100
100
|
data,
|
|
101
|
-
chain_id,
|
|
102
|
-
chain_label,
|
|
101
|
+
chain_id=chain_id,
|
|
102
|
+
chain_label=chain_label,
|
|
103
103
|
resolve_name=partial(get_contract_name, chain_id, api_key=api_key),
|
|
104
104
|
)
|
|
105
105
|
click.echo(json.dumps(result, indent=2))
|
{ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/fuses/external_state_events.py
RENAMED
|
@@ -196,7 +196,12 @@ def external_state_event_name(topic: bytes | str) -> str | None:
|
|
|
196
196
|
def _hex(value: Any) -> TxHash | None:
|
|
197
197
|
if value is None:
|
|
198
198
|
return None
|
|
199
|
-
|
|
199
|
+
raw = _as_bytes(value, "transactionHash")
|
|
200
|
+
if len(raw) != 32:
|
|
201
|
+
raise ExternalStateEventDecodeError(
|
|
202
|
+
f"transactionHash: {len(raw)} bytes, expected 32"
|
|
203
|
+
)
|
|
204
|
+
return parse_tx_hash(raw)
|
|
200
205
|
|
|
201
206
|
|
|
202
207
|
def decode_external_state_event(log: Mapping[str, Any]) -> ExternalStateEvent | None:
|
|
@@ -216,8 +216,8 @@ def vault_info(
|
|
|
216
216
|
ctx,
|
|
217
217
|
plasma_vault,
|
|
218
218
|
data,
|
|
219
|
-
chain_id,
|
|
220
|
-
chain_label,
|
|
219
|
+
chain_id=chain_id,
|
|
220
|
+
chain_label=chain_label,
|
|
221
221
|
resolve_name=partial(get_contract_name, chain_id, api_key=api_key),
|
|
222
222
|
)
|
|
223
223
|
return VaultInfoResponse.model_validate(result)
|
|
@@ -47,10 +47,15 @@ class SubstrateInfo:
|
|
|
47
47
|
# Slippage variant: [2 type chars][62 value chars]
|
|
48
48
|
|
|
49
49
|
|
|
50
|
+
def _address(hex_digits: str) -> HexAddress:
|
|
51
|
+
"""The address in 40 hex digits sliced out of a substrate word."""
|
|
52
|
+
return parse_hex_address("0x" + hex_digits)
|
|
53
|
+
|
|
54
|
+
|
|
50
55
|
def _decode_type_lshift160(hex_str: str, types: dict[int, str]) -> SubstrateInfo:
|
|
51
56
|
"""Decode type<<160 | address (Ebisu, Midas, Balancer, Velodrome)."""
|
|
52
57
|
type_byte = int(hex_str[22:24], 16)
|
|
53
|
-
addr =
|
|
58
|
+
addr = _address(hex_str[24:])
|
|
54
59
|
label = types.get(type_byte, f"type={type_byte}")
|
|
55
60
|
return SubstrateInfo(address=addr, type_label=label)
|
|
56
61
|
|
|
@@ -63,13 +68,13 @@ def _decode_type_lshift248(hex_str: str, types: dict[int, str]) -> SubstrateInfo
|
|
|
63
68
|
return SubstrateInfo(
|
|
64
69
|
raw_hex=f"0x{hex_str}", type_label=label, extra={"slippage": str(value)}
|
|
65
70
|
)
|
|
66
|
-
addr =
|
|
71
|
+
addr = _address(hex_str[24:])
|
|
67
72
|
return SubstrateInfo(address=addr, type_label=label)
|
|
68
73
|
|
|
69
74
|
|
|
70
75
|
def _decode_plain_address(hex_str: str) -> SubstrateInfo:
|
|
71
76
|
"""Decode zero-padded address: 12 zero bytes + 20 address bytes."""
|
|
72
|
-
return SubstrateInfo(address=
|
|
77
|
+
return SubstrateInfo(address=_address(hex_str[24:]))
|
|
73
78
|
|
|
74
79
|
|
|
75
80
|
def _decode_morpho(hex_str: str) -> SubstrateInfo:
|
|
@@ -84,14 +89,14 @@ def _decode_uniswap_v4(hex_str: str) -> SubstrateInfo:
|
|
|
84
89
|
substrate-as-asset (12 zero bytes + address)."""
|
|
85
90
|
if hex_str[:24] == "0" * 24:
|
|
86
91
|
return SubstrateInfo(
|
|
87
|
-
address=
|
|
92
|
+
address=_address(hex_str[24:]), type_label="uniswap_v4_token"
|
|
88
93
|
)
|
|
89
94
|
return SubstrateInfo(raw_hex=f"0x{hex_str}", type_label="uniswap_v4_pool_id")
|
|
90
95
|
|
|
91
96
|
|
|
92
97
|
def _decode_enso(hex_str: str) -> SubstrateInfo:
|
|
93
98
|
"""Decode address<<96 | selector<<64 (Enso)."""
|
|
94
|
-
addr =
|
|
99
|
+
addr = _address(hex_str[0:40])
|
|
95
100
|
selector = f"0x{hex_str[40:48]}"
|
|
96
101
|
return SubstrateInfo(
|
|
97
102
|
address=addr, type_label="ENSO_TARGET", extra={"selector": selector}
|
|
@@ -100,7 +105,7 @@ def _decode_enso(hex_str: str) -> SubstrateInfo:
|
|
|
100
105
|
|
|
101
106
|
def _decode_dolomite(hex_str: str) -> SubstrateInfo:
|
|
102
107
|
"""Decode asset<<96 | subAccountId<<88 | canBorrow<<80 (Dolomite)."""
|
|
103
|
-
addr =
|
|
108
|
+
addr = _address(hex_str[0:40])
|
|
104
109
|
sub_account_id = int(hex_str[40:42], 16)
|
|
105
110
|
can_borrow = (int(hex_str[42:44], 16) & 0x01) == 1
|
|
106
111
|
return SubstrateInfo(
|
|
@@ -127,7 +132,7 @@ def _decode_aave_v4(hex_str: str) -> SubstrateInfo:
|
|
|
127
132
|
return SubstrateInfo(raw_hex=f"0x{hex_str}", type_label=label)
|
|
128
133
|
flags = int(hex_str[50:52], 16)
|
|
129
134
|
return SubstrateInfo(
|
|
130
|
-
address=
|
|
135
|
+
address=_address(hex_str[2:42]),
|
|
131
136
|
type_label="AAVE_V4_RESERVE",
|
|
132
137
|
extra={
|
|
133
138
|
"reserve_id": str(int(hex_str[42:50], 16)),
|
|
@@ -145,7 +150,7 @@ def _decode_euler_v2(hex_str: str) -> SubstrateInfo:
|
|
|
145
150
|
plain-address path silently produces a malformed address (last 20 bytes are
|
|
146
151
|
flag bytes + zero padding).
|
|
147
152
|
"""
|
|
148
|
-
addr =
|
|
153
|
+
addr = _address(hex_str[0:40])
|
|
149
154
|
is_collateral = (int(hex_str[40:42], 16) & 0x01) == 1
|
|
150
155
|
can_borrow = (int(hex_str[42:44], 16) & 0x01) == 1
|
|
151
156
|
sub_account = f"0x{hex_str[44:46]}"
|
|
@@ -174,13 +179,13 @@ def _decode_async_action(hex_str: str) -> SubstrateInfo:
|
|
|
174
179
|
type_byte = int(hex_str[0:2], 16)
|
|
175
180
|
if type_byte == 0:
|
|
176
181
|
return SubstrateInfo(
|
|
177
|
-
address=
|
|
182
|
+
address=_address(hex_str[2:42]),
|
|
178
183
|
type_label="ALLOWED_AMOUNT_TO_OUTSIDE",
|
|
179
184
|
extra={"amount": str(int(hex_str[42:64], 16))},
|
|
180
185
|
)
|
|
181
186
|
if type_byte == 1:
|
|
182
187
|
return SubstrateInfo(
|
|
183
|
-
address=
|
|
188
|
+
address=_address(hex_str[16:56]),
|
|
184
189
|
type_label="ALLOWED_TARGETS",
|
|
185
190
|
extra={"selector": f"0x{hex_str[56:64]}"},
|
|
186
191
|
)
|
|
@@ -225,10 +230,10 @@ def _decode_external_state(hex_str: str) -> SubstrateInfo:
|
|
|
225
230
|
if type_byte == 0:
|
|
226
231
|
return SubstrateInfo(raw_hex=f"0x{hex_str}", type_label="UNDEFINED")
|
|
227
232
|
if label := _EXTERNAL_STATE_ADDRESS_TYPES.get(type_byte):
|
|
228
|
-
return SubstrateInfo(address=
|
|
233
|
+
return SubstrateInfo(address=_address(hex_str[24:]), type_label=label)
|
|
229
234
|
if type_byte == 2:
|
|
230
235
|
return SubstrateInfo(
|
|
231
|
-
address=
|
|
236
|
+
address=_address(hex_str[24:]),
|
|
232
237
|
type_label="TARGET",
|
|
233
238
|
extra={"selector": f"0x{hex_str[16:24]}"},
|
|
234
239
|
)
|
|
@@ -266,7 +271,7 @@ def _decode_crosschain(hex_str: str) -> SubstrateInfo:
|
|
|
266
271
|
is_error=True,
|
|
267
272
|
extra={"chain_id": str(chain_id)},
|
|
268
273
|
)
|
|
269
|
-
info = SubstrateInfo(address=
|
|
274
|
+
info = SubstrateInfo(address=_address(hex_str[24:]), type_label=label)
|
|
270
275
|
if type_byte == 2:
|
|
271
276
|
info.extra = {"chain_id": str(chain_id)}
|
|
272
277
|
return info
|
|
@@ -326,7 +331,7 @@ def _decode_hypercore(hex_str: str) -> SubstrateInfo:
|
|
|
326
331
|
return _hypercore_invalid(hex_str, label)
|
|
327
332
|
if type_byte == 1:
|
|
328
333
|
return SubstrateInfo(
|
|
329
|
-
address=
|
|
334
|
+
address=_address(hex_str[24:]),
|
|
330
335
|
type_label=label,
|
|
331
336
|
extra={"token_index": str(int(hex_str[8:24], 16))},
|
|
332
337
|
)
|
|
@@ -347,10 +352,10 @@ def _decode_hypercore(hex_str: str) -> SubstrateInfo:
|
|
|
347
352
|
extra["read_index"] = str(read_index_of(asset))
|
|
348
353
|
return SubstrateInfo(raw_hex=f"0x{hex_str}", type_label=label, extra=extra)
|
|
349
354
|
if type_byte == 3:
|
|
350
|
-
return SubstrateInfo(address=
|
|
355
|
+
return SubstrateInfo(address=_address(hex_str[24:]), type_label=label)
|
|
351
356
|
if type_byte == 4:
|
|
352
357
|
return SubstrateInfo(
|
|
353
|
-
address=
|
|
358
|
+
address=_address(hex_str[24:]),
|
|
354
359
|
type_label=label,
|
|
355
360
|
extra={"max_fee_rate_decibps": str(int(hex_str[8:24], 16))},
|
|
356
361
|
)
|
|
@@ -145,22 +145,28 @@ def _hex_digits(value: str | bytes, size: int, what: str) -> str:
|
|
|
145
145
|
if len(value) != size:
|
|
146
146
|
raise ValueError(f"invalid {what} (expected {size} bytes): {value!r}")
|
|
147
147
|
return value.hex()
|
|
148
|
-
digits = value.
|
|
149
|
-
if
|
|
150
|
-
|
|
148
|
+
digits = value[2:].lower()
|
|
149
|
+
if (
|
|
150
|
+
value[:2] not in ("0x", "0X")
|
|
151
|
+
or len(digits) != 2 * size
|
|
152
|
+
or any(c not in "0123456789abcdef" for c in digits)
|
|
153
|
+
):
|
|
154
|
+
raise ValueError(f"invalid {what} (expected 0x and {size}-byte hex): {value!r}")
|
|
151
155
|
return digits
|
|
152
156
|
|
|
153
157
|
|
|
154
158
|
def parse_hex_address(value: str | bytes) -> HexAddress:
|
|
155
|
-
"""An address as ``0x`` and 40 lowercase hex digits, from 20 raw bytes or
|
|
156
|
-
in any
|
|
159
|
+
"""An address as ``0x`` and 40 lowercase hex digits, from 20 raw bytes or
|
|
160
|
+
``0x``-prefixed hex in any case; raises ``ValueError`` on anything else,
|
|
161
|
+
surrounding whitespace included. For a checksummed
|
|
157
162
|
address use ``Web3.to_checksum_address``."""
|
|
158
163
|
return HexAddress(HexStr("0x" + _hex_digits(value, 20, "address")))
|
|
159
164
|
|
|
160
165
|
|
|
161
166
|
def parse_tx_hash(value: str | bytes) -> TxHash:
|
|
162
167
|
"""A transaction hash as ``0x`` and 64 lowercase hex digits, from 32 raw bytes
|
|
163
|
-
or hex in any
|
|
168
|
+
or ``0x``-prefixed hex in any case; raises ``ValueError`` on anything else,
|
|
169
|
+
surrounding whitespace included."""
|
|
164
170
|
return TxHash(HexStr("0x" + _hex_digits(value, 32, "transaction hash")))
|
|
165
171
|
|
|
166
172
|
|
|
@@ -169,9 +175,10 @@ def _checksum(value: str | bytes) -> ChecksumAddress:
|
|
|
169
175
|
|
|
170
176
|
|
|
171
177
|
def parse_plasma_vault_address(value: str | bytes) -> PlasmaVaultAddress:
|
|
172
|
-
"""A Plasma Vault's address, checksummed from 20 raw bytes or
|
|
173
|
-
|
|
174
|
-
checks nothing on
|
|
178
|
+
"""A Plasma Vault's address, checksummed from 20 raw bytes or ``0x``/``0X``
|
|
179
|
+
and 40 hex digits in any case; raises ``ValueError`` on anything else,
|
|
180
|
+
surrounding whitespace included. It labels the role and checks nothing on
|
|
181
|
+
chain."""
|
|
175
182
|
return PlasmaVaultAddress(_checksum(value))
|
|
176
183
|
|
|
177
184
|
|
|
@@ -378,8 +378,8 @@ def test_public_builder_renders_the_cli_json(scenario: str) -> None:
|
|
|
378
378
|
ctx,
|
|
379
379
|
PlasmaVault(ctx, VAULT), # type: ignore[arg-type]
|
|
380
380
|
data,
|
|
381
|
-
1,
|
|
382
|
-
"ethereum",
|
|
381
|
+
chain_id=1,
|
|
382
|
+
chain_label="ethereum",
|
|
383
383
|
resolve_name=lambda address: _NAMES_BY_ADDRESS.get(address.lower(), ""),
|
|
384
384
|
)
|
|
385
385
|
expected = (FIXTURES / f"{scenario}.json").read_text(encoding="utf-8")
|
|
@@ -96,6 +96,13 @@ def test_hex_text_data_and_topics_from_an_indexer_decode_too():
|
|
|
96
96
|
assert event.transaction_hash == "0x" + "fb" * 32
|
|
97
97
|
|
|
98
98
|
|
|
99
|
+
def test_a_short_transaction_hash_is_a_decode_error():
|
|
100
|
+
log = _log("ExternalStateAssetRescued", (SIGNER,))
|
|
101
|
+
log["transactionHash"] = bytes(31)
|
|
102
|
+
with pytest.raises(ExternalStateEventDecodeError, match="transactionHash"):
|
|
103
|
+
decode_external_state_event(log)
|
|
104
|
+
|
|
105
|
+
|
|
99
106
|
def test_an_unknown_topic_is_none_and_a_malformed_listed_one_raises():
|
|
100
107
|
assert (
|
|
101
108
|
decode_external_state_event(
|
|
@@ -64,23 +64,34 @@ class TestExtractEvents:
|
|
|
64
64
|
|
|
65
65
|
|
|
66
66
|
class TestParsers:
|
|
67
|
-
def
|
|
67
|
+
def test_hex_address_is_lowercase_0x_from_either_prefix_case(self):
|
|
68
68
|
from ipor_fusion import parse_hex_address
|
|
69
69
|
|
|
70
70
|
checksum = "0xAbCdEf0123456789aBcDeF0123456789AbCdEf01"
|
|
71
71
|
lower = checksum.lower()
|
|
72
72
|
assert parse_hex_address(checksum) == lower
|
|
73
|
-
assert parse_hex_address(lower[2:]) == lower
|
|
73
|
+
assert parse_hex_address("0X" + lower[2:]) == lower
|
|
74
74
|
assert parse_hex_address(bytes.fromhex(lower[2:])) == lower
|
|
75
75
|
|
|
76
|
-
def
|
|
76
|
+
def test_tx_hash_is_lowercase_0x_from_either_prefix_case(self):
|
|
77
77
|
from ipor_fusion import parse_tx_hash
|
|
78
78
|
|
|
79
79
|
digest = "AB" * 32
|
|
80
|
-
assert parse_tx_hash(digest) == "0x" + digest.lower()
|
|
80
|
+
assert parse_tx_hash("0x" + digest) == "0x" + digest.lower()
|
|
81
81
|
assert parse_tx_hash(bytes.fromhex(digest)) == "0x" + digest.lower()
|
|
82
82
|
|
|
83
|
-
@pytest.mark.parametrize(
|
|
83
|
+
@pytest.mark.parametrize(
|
|
84
|
+
"value",
|
|
85
|
+
[
|
|
86
|
+
"0x1234",
|
|
87
|
+
"0x" + "zz" * 20,
|
|
88
|
+
b"\x00" * 19,
|
|
89
|
+
"ab" * 20,
|
|
90
|
+
" 0x" + "ab" * 20,
|
|
91
|
+
"0x" + "ab" * 20 + "\n",
|
|
92
|
+
"0x0X" + "ab" * 19,
|
|
93
|
+
],
|
|
94
|
+
)
|
|
84
95
|
def test_hex_address_rejects_anything_else(self, value):
|
|
85
96
|
from ipor_fusion import parse_hex_address
|
|
86
97
|
|
|
@@ -78,7 +78,7 @@ def vault_reads(ctx: Web3Context, vault: PlasmaVault) -> None:
|
|
|
78
78
|
ensure_supported_chain(ETHEREUM)
|
|
79
79
|
data = fetch_vault_data(ctx, vault, chain_id=ETHEREUM)
|
|
80
80
|
fetch_deployment_info(ctx, ETHEREUM, VAULT, None)
|
|
81
|
-
build_vault_info_json(ctx, vault, data, ETHEREUM, "ethereum")
|
|
81
|
+
build_vault_info_json(ctx, vault, data, chain_id=ETHEREUM, chain_label="ethereum")
|
|
82
82
|
validate_vault(ctx, VAULT)
|
|
83
83
|
resolve_token_symbol(ctx, VAULT)
|
|
84
84
|
fetch_unpriceable_priced_tokens(ctx, VAULT, VAULT, [], {}, None)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/examples/advanced_euler_v2_credit_market_base.py
RENAMED
|
File without changes
|
{ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/examples/advanced_euler_v2_looping_arbitrum.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/examples/external_state_margin_leg_base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/cli/oracle_mapping_view.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/cli/vault_markets_view.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/core/external_state_executor.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/core/withdraw_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/ccip/__init__.py
RENAMED
|
File without changes
|
{ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/ccip/chainlink.py
RENAMED
|
File without changes
|
{ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/ccip/codec.py
RENAMED
|
File without changes
|
{ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/ccip/contracts.py
RENAMED
|
File without changes
|
{ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/ccip/events.py
RENAMED
|
File without changes
|
{ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/ccip/indexer.py
RENAMED
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/ccip/quote.py
RENAMED
|
File without changes
|
{ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/ccip/transport.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/simulation.py
RENAMED
|
File without changes
|
{ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/stargate/__init__.py
RENAMED
|
File without changes
|
{ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/stargate/contracts.py
RENAMED
|
File without changes
|
{ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/stargate/lane.py
RENAMED
|
File without changes
|
{ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/stargate/layerzero.py
RENAMED
|
File without changes
|
{ipor_fusion-4.0.0.dev63 → ipor_fusion-4.0.0.dev66}/src/ipor_fusion/crosschain/stargate/transport.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|