ipor-fusion 4.0.0.dev156__tar.gz → 4.0.0.dev159__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.dev156 → ipor_fusion-4.0.0.dev159}/MIGRATION_4.md +19 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/PKG-INFO +1 -1
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/pyproject.toml +1 -1
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/__init__.py +82 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/cli/oracle_mapping_view.py +9 -5
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/core/external_state_executor.py +15 -7
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/fuses/__init__.py +36 -0
- ipor_fusion-4.0.0.dev159/src/ipor_fusion/fuses/events.py +45 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/fuses/external_state_events.py +93 -8
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/fuses/hypercore_events.py +185 -10
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/mcp/models.py +3 -1
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/readers/__init__.py +26 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/readers/oracle_mapping_nodes.py +158 -10
- ipor_fusion-4.0.0.dev159/tests/_event_args.py +29 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_cli_oracle_mapping.py +13 -5
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_external_state_events.py +23 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_external_state_executor.py +12 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_hypercore_events.py +20 -7
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_mcp_models.py +15 -3
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_oracle_mapping.py +59 -43
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_public_api.py +69 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/typed_client/consumer.py +28 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/typed_client/rejected.py +7 -0
- ipor_fusion-4.0.0.dev156/src/ipor_fusion/fuses/events.py +0 -25
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/.claude-plugin/marketplace.json +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/.claude-plugin/plugin.json +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/.env.example +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/.gemini/settings.json +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/.git-blame-ignore-revs +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/.github/workflows/cd.yml +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/.github/workflows/ci.yml +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/.github/workflows/commit-lint.yml +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/.github/workflows/notify-slack.yml +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/.github/workflows/python-build.yml +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/.github/workflows/python-publish.yml +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/.github/workflows/release.yml +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/.github/workflows/report-slack.yml +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/.gitignore +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/.mcp.json +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/.pre-commit-config.yaml +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/.python-version +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/AGENTS.md +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/CHANGELOG.md +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/CLAUDE.md +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/CODEOWNERS +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/LICENSE +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/README.md +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/build.sh +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/examples/CONTRIBUTING.md +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/examples/README.md +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/examples/advanced_euler_v2_credit_market_base.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/examples/advanced_euler_v2_looping_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/examples/composed_hypercore_flow_arbitrum_hyperevm.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/examples/crosschain_ccip_usdc_arbitrum_hyperevm.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/examples/external_state_margin_leg_base.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/examples/simple_aave_v3_supply_base.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/pytest.ini +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/scripts/commit-check.sh +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/scripts/crosschain_readiness.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/skills/ipor-deploy-vault/SKILL.md +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/about.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/cache.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/chains.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/cli/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/cli/changelog_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/cli/config_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/cli/config_store.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/cli/main.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/cli/market_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/cli/options.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/cli/vault_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/cli/vault_health.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/cli/vault_info_view.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/cli/vault_markets_view.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/cli/vault_rendering.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/config/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/config/roles.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/core/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/core/access.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/core/address.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/core/context.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/core/contract.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/core/erc20.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/core/fee_manager.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/core/fuse.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/core/fuse_action.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/core/fusion_factory.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/core/logs.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/core/multicall.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/core/oracle.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/core/plasma_vault.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/core/rewards_manager.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/core/simulation.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/core/withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/ccip/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/ccip/chainlink.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/ccip/codec.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/ccip/contracts.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/ccip/events.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/ccip/indexer.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/ccip/lane.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/ccip/quote.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/ccip/transport.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/contracts.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/discovery.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/errors.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/fuses/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/fuses/base.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/fuses/ccip.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/fuses/stargate.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/lane.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/logs.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/messages.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/simulation.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/stargate/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/stargate/contracts.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/stargate/lane.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/stargate/layerzero.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/stargate/transport.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/crosschain/transport.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/dependency_graph.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/entry_cli.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/entry_mcp.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/errors.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/explorer.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/field_docs.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/fuses/aave_v3.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/fuses/async_action.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/fuses/base.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/fuses/compound_v3.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/fuses/erc4626.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/fuses/euler_v2.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/fuses/external_state.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/fuses/fluid_instadapp.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/fuses/gearbox_v3.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/fuses/hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/fuses/merkl.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/fuses/morpho.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/fuses/ramses_v2.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/fuses/uniswap_v3.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/fuses/universal.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/guide/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/guide/architecture.md +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/guide/glossary.md +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/guide/invariants.md +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/guide/quickstart.md +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/market_ids.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/market_info.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/mcp/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/mcp/guide.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/mcp/server.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/morpho_api.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/py.typed +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/readers/aave_v3.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/readers/aave_v4.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/readers/compound_v3.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/readers/hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/readers/hypercore_outcome.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/readers/lending_health.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/readers/morpho.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/readers/oracle_mapping.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/readers/oracle_mapping_reader.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/readers/position_manager.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/readers/ramses_v2.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/readers/uniswap_v3.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/readers/unpriceable.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/substrates.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/types.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/validation.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/vault_data.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/vault_erc20.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/vault_info.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/vault_managers.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/vault_positions.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/vault_reads.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/UniswapV3UniversalRouter.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/_crosschain_lifecycle.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/_crosschain_recovery.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/_euler_v2.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/_foundry.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/_guide.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/_hypercore_model.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/_hypercore_shadow.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/_multicall.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/_simulate.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/_validation.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/addresses.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/conftest.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/constants.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/fixtures/hypercore_hip3_flow.json +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/fixtures/hypercore_market55.json +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/fixtures/vault_info_golden/clean.json +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/fixtures/vault_info_golden/clean.txt +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/fixtures/vault_info_golden/rich.json +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/fixtures/vault_info_golden/rich.txt +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_about.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_access_manager.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_cache.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_chains.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_cli_changelog.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_cli_commands.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_cli_config_store.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_cli_helpers.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_cli_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_cli_lending_health.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_cli_market_morpho_blue.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_cli_pending_requests_scan.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_cli_role_accounts.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_cli_vault_info_golden.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_cli_vault_predates_getters.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_cli_vault_validate.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_contract_call.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_contract_encoder.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_crosschain_ccip_events.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_crosschain_ccip_indexer.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_crosschain_ccip_quote.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_crosschain_chainlink.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_crosschain_contracts.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_crosschain_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_crosschain_errors.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_crosschain_lane.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_crosschain_layering.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_crosschain_readiness.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_crosschain_readiness_report.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_crosschain_transport.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_docs_typing.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_erc20.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_error_hierarchy.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_examples_composed_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_examples_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_examples_euler_looping_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_examples_vaults.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_explorer.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_fee_manager.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_fuse_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_fusion_instance.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_guide.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_hypercore_deployment.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_hypercore_flow.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_hypercore_live.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_hypercore_outcome.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_hypercore_readers.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_hypercore_simulation.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_logs.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_mcp_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_mcp_server.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_mcp_vault_validate.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_multicall.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_oracle.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_plasma_vault.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_public_type_reachability.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_reader_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_readiness_selection.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_revert_decoding.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_rewards_manager.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_roles.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_sdk_layering.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_borrow_aave_v3_mainnet.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_claim_merkl_wrapper_base.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_claim_morpho_rewards.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_crosschain_canary.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_crosschain_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_crosschain_hyperevm.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_crosschain_lifecycle.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_euler_v2_batch_base.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_euler_v2_credit_market_base.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_euler_v2_swap_deploy_base.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_euler_v2_swap_reconfigure_base.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_euler_v2_swap_registry_base.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_examples_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_examples_base.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_examples_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_external_state_executor_base.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_fusion_factory_clone_base.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_looping_aave_v3_base.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_looping_morpho_blue_base.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_morpho_blue.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_pilot_v3.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_pilot_v4_uniswap.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_pilot_v5_ramses.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_pilot_v5_scheduled.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_plasma_vault_setters_base.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_readers_integration.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_release_funds.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_swap_on_base.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulate_vault_from_scratch_base.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_simulation_observation.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_solidity_compiler.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_solidity_mirrors.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_substrates.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_types_and_events.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_unpriceable_tokens.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_validation.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_vault_data_block.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_vault_dep_graph.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_vault_info_onchain_base.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_vault_info_onchain_base_no_withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_vault_simulator_blocks.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_web3_context.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/tests/test_withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/uv.lock +0 -0
|
@@ -787,6 +787,7 @@ untyped code needs none of this section.
|
|
|
787
787
|
| `build_morpho_blue_market_json` | `MorphoBlueMarketJson` |
|
|
788
788
|
| `build_meta_morpho_json` | `MetaMorphoV1Json \| MetaMorphoV2Json`, told apart by `doc["version"]` |
|
|
789
789
|
| `RoleAccount.to_dict` | `RoleAccountJson` |
|
|
790
|
+
| `OracleMapping.to_dict` / `OracleNode.to_dict` | `OracleMappingJson` / `OracleNodeJson` |
|
|
790
791
|
|
|
791
792
|
Every nested block has its own TypedDict (`FeesJson`, `WithdrawManagerJson`,
|
|
792
793
|
`BalanceFuseJson`, `ReconciliationJson`, `HyperCoreJson`, `MorphoSupplyingVaultJson`,
|
|
@@ -813,6 +814,24 @@ that only some entries carry is `NotRequired` (a balance fuse's `pct_of_total` a
|
|
|
813
814
|
age) or `DeploymentErrorJson` (`{"error": ...}`) or `None`; `share_price` is
|
|
814
815
|
`SharePriceJson` (`asset`, and `usd` when the asset is priced); `dependency_graph`
|
|
815
816
|
is `DependencyGraphJson` (`edges`, `update_reach`, `update_groups`).
|
|
817
|
+
- `OracleNode.source_detail` is `SourceDetailJson`, one TypedDict per feed kind
|
|
818
|
+
(`ChainlinkDetailJson`, `DualXrefDetailJson`, `Erc4626DetailJson`,
|
|
819
|
+
`MorphoFeedDetailJson`, `MiddlewareFallbackDetailJson`; importable from
|
|
820
|
+
`ipor_fusion` and `ipor_fusion.readers`). Narrow by a key before reading a
|
|
821
|
+
kind-specific one: `if detail is not None and "aggregator" in detail:
|
|
822
|
+
detail["description"]`.
|
|
823
|
+
- Event `args` are typed per event kind: `ExternalStateEvent.args` is
|
|
824
|
+
`ExternalStateEventArgs` and `HyperCoreEvent.args` is `HyperCoreEventArgs`, a union
|
|
825
|
+
of one TypedDict per event (`ExternalStateUnpausedArgs`,
|
|
826
|
+
`HyperCoreDepositFuseEnterArgs`, ...; `EXTERNAL_STATE_EVENT_ARGS` /
|
|
827
|
+
`HYPERCORE_EVENT_ARGS` map an event name to its shape). Values carry nominal types
|
|
828
|
+
(`Amount`, `MarketId`, `FuseAddress`, `HyperCoreTokenIndex`, `PayloadHash`, web3's
|
|
829
|
+
`Timestamp`, ...). `event.args["signer"]` no longer type-checks on its own: narrow
|
|
830
|
+
with a key test (`if "signer" in event.args:`). `HyperCoreEvent.fuse` is a
|
|
831
|
+
`FuseAddress | None`.
|
|
832
|
+
- `RawLog` (the log shape `ExternalStateExecutor.parse_balance_proposed` /
|
|
833
|
+
`find_balance_proposed` accept) is `Mapping[str, object]`, not `Mapping[str, Any]`;
|
|
834
|
+
a web3 `LogReceipt` still fits it.
|
|
816
835
|
|
|
817
836
|
## Behavior changes
|
|
818
837
|
|
|
@@ -314,15 +314,44 @@ from ipor_fusion.fuses import (
|
|
|
314
314
|
system_address,
|
|
315
315
|
)
|
|
316
316
|
from ipor_fusion.fuses.external_state_events import (
|
|
317
|
+
EXTERNAL_STATE_EVENT_ARGS,
|
|
317
318
|
EXTERNAL_STATE_EVENT_SPECS,
|
|
318
319
|
EXTERNAL_STATE_EVENTS,
|
|
319
320
|
EXTERNAL_STATE_TOPICS,
|
|
321
|
+
ExternalStateAssetRescuedArgs,
|
|
322
|
+
ExternalStateBigChangeDetectedArgs,
|
|
323
|
+
ExternalStateCustodianTimestampUpdatedArgs,
|
|
320
324
|
ExternalStateEvent,
|
|
325
|
+
ExternalStateEventArgs,
|
|
321
326
|
ExternalStateEventSpec,
|
|
327
|
+
ExternalStateExecutorArgs,
|
|
328
|
+
ExternalStateOperationArgs,
|
|
329
|
+
ExternalStateTotalBalanceUpdatedArgs,
|
|
330
|
+
ExternalStateUnpausedArgs,
|
|
322
331
|
decode_external_state_event,
|
|
323
332
|
external_state_event_name,
|
|
324
333
|
external_state_events,
|
|
325
334
|
)
|
|
335
|
+
from ipor_fusion.fuses.hypercore_events import (
|
|
336
|
+
HYPERCORE_EVENT_ARGS,
|
|
337
|
+
HyperCoreActionEnqueuedArgs,
|
|
338
|
+
HyperCoreActionSettledArgs,
|
|
339
|
+
HyperCoreBuilderFeeFuseEnterArgs,
|
|
340
|
+
HyperCoreCancelByCloidArgs,
|
|
341
|
+
HyperCoreCancelByOidArgs,
|
|
342
|
+
HyperCoreDepositFuseEnterArgs,
|
|
343
|
+
HyperCoreEventArgs,
|
|
344
|
+
HyperCoreMarginFuseEnterArgs,
|
|
345
|
+
HyperCoreObserverSetChangedArgs,
|
|
346
|
+
HyperCoreObserverSetProposedArgs,
|
|
347
|
+
HyperCoreOrderFuseEnterArgs,
|
|
348
|
+
HyperCoreRecoveryExecutedArgs,
|
|
349
|
+
HyperCoreRecoveryProposedArgs,
|
|
350
|
+
HyperCoreReportedActionSettledArgs,
|
|
351
|
+
HyperCoreReportSubmittedArgs,
|
|
352
|
+
HyperCoreSendFuseSendAssetArgs,
|
|
353
|
+
HyperCoreSendFuseSpotSendArgs,
|
|
354
|
+
)
|
|
326
355
|
from ipor_fusion.market_ids import IporFusionMarkets
|
|
327
356
|
from ipor_fusion.market_info import (
|
|
328
357
|
MetaMorphoAdapterJson,
|
|
@@ -422,6 +451,20 @@ from ipor_fusion.readers import (
|
|
|
422
451
|
read_hypercore_transfer_snapshot,
|
|
423
452
|
read_hypercore_vault_state,
|
|
424
453
|
)
|
|
454
|
+
from ipor_fusion.readers.oracle_mapping_nodes import (
|
|
455
|
+
AggregatorDetailJson,
|
|
456
|
+
AggregatorFeedDetailJson,
|
|
457
|
+
ChainlinkDetailJson,
|
|
458
|
+
DualXrefDetailJson,
|
|
459
|
+
Erc4626DetailJson,
|
|
460
|
+
MiddlewareFallbackDetailJson,
|
|
461
|
+
MorphoFeedDetailJson,
|
|
462
|
+
OracleAssetJson,
|
|
463
|
+
OracleMappingJson,
|
|
464
|
+
OracleNodeJson,
|
|
465
|
+
OraclePriceJson,
|
|
466
|
+
SourceDetailJson,
|
|
467
|
+
)
|
|
425
468
|
from ipor_fusion.substrates import (
|
|
426
469
|
SubstrateInfo,
|
|
427
470
|
decode_substrate,
|
|
@@ -546,6 +589,15 @@ __all__ = [
|
|
|
546
589
|
"EXTERNAL_STATE_EVENTS",
|
|
547
590
|
"EXTERNAL_STATE_TOPICS",
|
|
548
591
|
"ExternalStateEvent",
|
|
592
|
+
"EXTERNAL_STATE_EVENT_ARGS",
|
|
593
|
+
"ExternalStateAssetRescuedArgs",
|
|
594
|
+
"ExternalStateBigChangeDetectedArgs",
|
|
595
|
+
"ExternalStateCustodianTimestampUpdatedArgs",
|
|
596
|
+
"ExternalStateEventArgs",
|
|
597
|
+
"ExternalStateExecutorArgs",
|
|
598
|
+
"ExternalStateOperationArgs",
|
|
599
|
+
"ExternalStateTotalBalanceUpdatedArgs",
|
|
600
|
+
"ExternalStateUnpausedArgs",
|
|
549
601
|
"ExternalStateEventDecodeError",
|
|
550
602
|
"ExternalStateEventSpec",
|
|
551
603
|
"decode_external_state_event",
|
|
@@ -554,6 +606,24 @@ __all__ = [
|
|
|
554
606
|
"HYPERCORE_EVENTS",
|
|
555
607
|
"HYPERCORE_EVENT_SPECS",
|
|
556
608
|
"HyperCoreEvent",
|
|
609
|
+
"HYPERCORE_EVENT_ARGS",
|
|
610
|
+
"HyperCoreActionEnqueuedArgs",
|
|
611
|
+
"HyperCoreActionSettledArgs",
|
|
612
|
+
"HyperCoreBuilderFeeFuseEnterArgs",
|
|
613
|
+
"HyperCoreCancelByCloidArgs",
|
|
614
|
+
"HyperCoreCancelByOidArgs",
|
|
615
|
+
"HyperCoreDepositFuseEnterArgs",
|
|
616
|
+
"HyperCoreEventArgs",
|
|
617
|
+
"HyperCoreMarginFuseEnterArgs",
|
|
618
|
+
"HyperCoreObserverSetChangedArgs",
|
|
619
|
+
"HyperCoreObserverSetProposedArgs",
|
|
620
|
+
"HyperCoreOrderFuseEnterArgs",
|
|
621
|
+
"HyperCoreRecoveryExecutedArgs",
|
|
622
|
+
"HyperCoreRecoveryProposedArgs",
|
|
623
|
+
"HyperCoreReportSubmittedArgs",
|
|
624
|
+
"HyperCoreReportedActionSettledArgs",
|
|
625
|
+
"HyperCoreSendFuseSendAssetArgs",
|
|
626
|
+
"HyperCoreSendFuseSpotSendArgs",
|
|
557
627
|
"HyperCoreEventSpec",
|
|
558
628
|
"decode_hypercore_event",
|
|
559
629
|
"find_hypercore_events",
|
|
@@ -945,6 +1015,18 @@ __all__ = [
|
|
|
945
1015
|
"OracleAsset",
|
|
946
1016
|
"OracleMapping",
|
|
947
1017
|
"OracleNode",
|
|
1018
|
+
"AggregatorDetailJson",
|
|
1019
|
+
"AggregatorFeedDetailJson",
|
|
1020
|
+
"ChainlinkDetailJson",
|
|
1021
|
+
"DualXrefDetailJson",
|
|
1022
|
+
"Erc4626DetailJson",
|
|
1023
|
+
"MiddlewareFallbackDetailJson",
|
|
1024
|
+
"MorphoFeedDetailJson",
|
|
1025
|
+
"OracleAssetJson",
|
|
1026
|
+
"OracleMappingJson",
|
|
1027
|
+
"OracleNodeJson",
|
|
1028
|
+
"OraclePriceJson",
|
|
1029
|
+
"SourceDetailJson",
|
|
948
1030
|
"OraclePrice",
|
|
949
1031
|
"build_oracle_mapping",
|
|
950
1032
|
"OracleMappingReader",
|
{ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/cli/oracle_mapping_view.py
RENAMED
|
@@ -24,21 +24,25 @@ def _format_wad_price(price: OraclePrice | None) -> str:
|
|
|
24
24
|
|
|
25
25
|
def _print_feed_line(node: OracleNode) -> None:
|
|
26
26
|
"""The feed's self-declared units — key for confirming what a value means."""
|
|
27
|
-
detail = node.source_detail
|
|
27
|
+
detail = node.source_detail
|
|
28
28
|
if node.source_type in (TYPE_CHAINLINK, TYPE_CHAINLINK_STYLE):
|
|
29
|
-
if detail
|
|
29
|
+
if detail is not None and "aggregator" in detail and detail["description"]:
|
|
30
30
|
click.echo(f" Feed: {detail['description']}")
|
|
31
31
|
else:
|
|
32
32
|
# only chainlink_style can land here — the confirmed tier
|
|
33
33
|
# requires a non-empty description
|
|
34
34
|
click.secho(" Feed: (no description)", fg="yellow")
|
|
35
|
-
elif
|
|
35
|
+
elif (
|
|
36
|
+
node.source_type == TYPE_DUAL_XREF
|
|
37
|
+
and detail is not None
|
|
38
|
+
and "asset_x" in detail
|
|
39
|
+
):
|
|
36
40
|
rendered = [
|
|
37
41
|
# quoted — the descriptions themselves contain " / "
|
|
38
42
|
f'"{d}"' if d else click.style("(no description)", fg="yellow")
|
|
39
43
|
for d in (
|
|
40
|
-
|
|
41
|
-
|
|
44
|
+
detail["asset_x_asset_y_feed"]["description"],
|
|
45
|
+
detail["asset_y_usd_feed"]["description"],
|
|
42
46
|
)
|
|
43
47
|
]
|
|
44
48
|
click.echo(f" Feed: {' × '.join(rendered)}")
|
|
@@ -18,7 +18,7 @@ from __future__ import annotations
|
|
|
18
18
|
|
|
19
19
|
from collections.abc import Iterable, Mapping
|
|
20
20
|
from dataclasses import dataclass, replace
|
|
21
|
-
from typing import
|
|
21
|
+
from typing import TypeAlias
|
|
22
22
|
|
|
23
23
|
from eth_abi import decode, encode
|
|
24
24
|
from eth_abi.exceptions import DecodingError
|
|
@@ -44,8 +44,9 @@ from ipor_fusion.types import (
|
|
|
44
44
|
# (HexBytes fields, checksummed address), and a raw JSON-RPC or
|
|
45
45
|
# `eth_simulateV1` row (0x-hex strings, lowercase address). Looser than
|
|
46
46
|
# `web3.types.LogReceipt`, which the rest of `core/` uses, because those rows
|
|
47
|
-
# carry neither its field types nor all of its required keys.
|
|
48
|
-
|
|
47
|
+
# carry neither its field types nor all of its required keys. Every field is
|
|
48
|
+
# read as `object` and narrowed; a `LogReceipt` is one of these mappings.
|
|
49
|
+
RawLog: TypeAlias = Mapping[str, object]
|
|
49
50
|
|
|
50
51
|
|
|
51
52
|
def _log_emitter(log: RawLog) -> ChecksumAddress | None:
|
|
@@ -55,7 +56,7 @@ def _log_emitter(log: RawLog) -> ChecksumAddress | None:
|
|
|
55
56
|
matched against an expected emitter, and a caller scanning foreign rows
|
|
56
57
|
should skip such a log rather than have the scan abort on it."""
|
|
57
58
|
emitter = log.get("address")
|
|
58
|
-
if emitter
|
|
59
|
+
if not isinstance(emitter, str | bytes):
|
|
59
60
|
return None
|
|
60
61
|
try:
|
|
61
62
|
return Web3.to_checksum_address(emitter)
|
|
@@ -590,11 +591,14 @@ class ExternalStateExecutor(ContractWrapper):
|
|
|
590
591
|
event -- the rule `_log_emitter` already applies to an unreadable
|
|
591
592
|
address, and it keeps a raise meaning "ours, but the payload is broken".
|
|
592
593
|
"""
|
|
593
|
-
topics = log.get("topics")
|
|
594
|
-
if not topics:
|
|
594
|
+
topics = log.get("topics")
|
|
595
|
+
if not isinstance(topics, list | tuple) or not topics:
|
|
596
|
+
return False
|
|
597
|
+
topic = topics[0]
|
|
598
|
+
if not isinstance(topic, str | bytes | bytearray):
|
|
595
599
|
return False
|
|
596
600
|
try:
|
|
597
|
-
return HexBytes(
|
|
601
|
+
return HexBytes(topic) == cls._BALANCE_PROPOSED_TOPIC
|
|
598
602
|
except (ValueError, TypeError):
|
|
599
603
|
return False
|
|
600
604
|
|
|
@@ -652,6 +656,10 @@ class ExternalStateExecutor(ContractWrapper):
|
|
|
652
656
|
data = log.get("data")
|
|
653
657
|
if data is None:
|
|
654
658
|
raise ExternalStateError("BalanceProposed log carries no data")
|
|
659
|
+
if not isinstance(data, str | bytes | bytearray):
|
|
660
|
+
raise ExternalStateError(
|
|
661
|
+
f"malformed BalanceProposed data: {type(data).__name__}"
|
|
662
|
+
)
|
|
655
663
|
try:
|
|
656
664
|
# Unpacked in the order `BalanceProposed` declares them; all six
|
|
657
665
|
# are unindexed, so topics carries topic0 alone.
|
|
@@ -50,10 +50,28 @@ from ipor_fusion.fuses.hypercore import (
|
|
|
50
50
|
system_address,
|
|
51
51
|
)
|
|
52
52
|
from ipor_fusion.fuses.hypercore_events import (
|
|
53
|
+
HYPERCORE_EVENT_ARGS,
|
|
53
54
|
HYPERCORE_EVENT_SPECS,
|
|
54
55
|
HYPERCORE_EVENTS,
|
|
56
|
+
HyperCoreActionEnqueuedArgs,
|
|
57
|
+
HyperCoreActionSettledArgs,
|
|
58
|
+
HyperCoreBuilderFeeFuseEnterArgs,
|
|
59
|
+
HyperCoreCancelByCloidArgs,
|
|
60
|
+
HyperCoreCancelByOidArgs,
|
|
61
|
+
HyperCoreDepositFuseEnterArgs,
|
|
55
62
|
HyperCoreEvent,
|
|
63
|
+
HyperCoreEventArgs,
|
|
56
64
|
HyperCoreEventSpec,
|
|
65
|
+
HyperCoreMarginFuseEnterArgs,
|
|
66
|
+
HyperCoreObserverSetChangedArgs,
|
|
67
|
+
HyperCoreObserverSetProposedArgs,
|
|
68
|
+
HyperCoreOrderFuseEnterArgs,
|
|
69
|
+
HyperCoreRecoveryExecutedArgs,
|
|
70
|
+
HyperCoreRecoveryProposedArgs,
|
|
71
|
+
HyperCoreReportedActionSettledArgs,
|
|
72
|
+
HyperCoreReportSubmittedArgs,
|
|
73
|
+
HyperCoreSendFuseSendAssetArgs,
|
|
74
|
+
HyperCoreSendFuseSpotSendArgs,
|
|
57
75
|
decode_hypercore_event,
|
|
58
76
|
find_hypercore_events,
|
|
59
77
|
hypercore_event_name,
|
|
@@ -94,6 +112,24 @@ __all__ = [
|
|
|
94
112
|
"HYPERCORE_EVENTS",
|
|
95
113
|
"HYPERCORE_EVENT_SPECS",
|
|
96
114
|
"HyperCoreEvent",
|
|
115
|
+
"HYPERCORE_EVENT_ARGS",
|
|
116
|
+
"HyperCoreActionEnqueuedArgs",
|
|
117
|
+
"HyperCoreActionSettledArgs",
|
|
118
|
+
"HyperCoreBuilderFeeFuseEnterArgs",
|
|
119
|
+
"HyperCoreCancelByCloidArgs",
|
|
120
|
+
"HyperCoreCancelByOidArgs",
|
|
121
|
+
"HyperCoreDepositFuseEnterArgs",
|
|
122
|
+
"HyperCoreEventArgs",
|
|
123
|
+
"HyperCoreMarginFuseEnterArgs",
|
|
124
|
+
"HyperCoreObserverSetChangedArgs",
|
|
125
|
+
"HyperCoreObserverSetProposedArgs",
|
|
126
|
+
"HyperCoreOrderFuseEnterArgs",
|
|
127
|
+
"HyperCoreRecoveryExecutedArgs",
|
|
128
|
+
"HyperCoreRecoveryProposedArgs",
|
|
129
|
+
"HyperCoreReportSubmittedArgs",
|
|
130
|
+
"HyperCoreReportedActionSettledArgs",
|
|
131
|
+
"HyperCoreSendFuseSendAssetArgs",
|
|
132
|
+
"HyperCoreSendFuseSpotSendArgs",
|
|
97
133
|
"HyperCoreEventSpec",
|
|
98
134
|
"decode_hypercore_event",
|
|
99
135
|
"find_hypercore_events",
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from eth_abi import decode
|
|
2
|
+
from eth_typing import ChecksumAddress
|
|
3
|
+
from web3 import Web3
|
|
4
|
+
from web3.types import TxReceipt
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def extract_events(
|
|
8
|
+
receipt: TxReceipt,
|
|
9
|
+
event_signature: str,
|
|
10
|
+
abi_types: list[str],
|
|
11
|
+
dataclass_type,
|
|
12
|
+
):
|
|
13
|
+
sig_hash = Web3.keccak(text=event_signature)
|
|
14
|
+
events = []
|
|
15
|
+
for log in receipt["logs"]:
|
|
16
|
+
if log["topics"][0] == sig_hash:
|
|
17
|
+
decoded = decode(abi_types, log["data"])
|
|
18
|
+
events.append(
|
|
19
|
+
dataclass_type(
|
|
20
|
+
*(
|
|
21
|
+
Web3.to_checksum_address(value) if abi == "address" else value
|
|
22
|
+
for abi, value in zip(abi_types, decoded, strict=True)
|
|
23
|
+
)
|
|
24
|
+
)
|
|
25
|
+
)
|
|
26
|
+
return events
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def abi_value(abi_type: str, value: object) -> int | bool | bytes | ChecksumAddress:
|
|
30
|
+
"""One ``eth_abi``-decoded event parameter as the Python type its ABI type
|
|
31
|
+
decodes to: an address checksummed, a ``uintN`` / ``intN`` an int, a
|
|
32
|
+
``bool`` a bool, a ``bytesN`` bytes. Anything else raises ``TypeError``."""
|
|
33
|
+
if abi_type == "address" and isinstance(value, str):
|
|
34
|
+
return Web3.to_checksum_address(value)
|
|
35
|
+
if abi_type == "bool" and isinstance(value, bool):
|
|
36
|
+
return value
|
|
37
|
+
if (
|
|
38
|
+
abi_type.startswith(("uint", "int"))
|
|
39
|
+
and isinstance(value, int)
|
|
40
|
+
and not isinstance(value, bool)
|
|
41
|
+
):
|
|
42
|
+
return value
|
|
43
|
+
if abi_type.startswith("bytes") and isinstance(value, bytes):
|
|
44
|
+
return value
|
|
45
|
+
raise TypeError(f"{abi_type} decoded as {type(value).__name__}")
|
{ipor_fusion-4.0.0.dev156 → ipor_fusion-4.0.0.dev159}/src/ipor_fusion/fuses/external_state_events.py
RENAMED
|
@@ -24,16 +24,17 @@ from __future__ import annotations
|
|
|
24
24
|
|
|
25
25
|
from collections.abc import Mapping
|
|
26
26
|
from dataclasses import dataclass
|
|
27
|
-
from typing import
|
|
27
|
+
from typing import TypeAlias, TypedDict, cast
|
|
28
28
|
|
|
29
29
|
from eth_abi import decode
|
|
30
30
|
from eth_abi.exceptions import DecodingError
|
|
31
31
|
from eth_typing import ChecksumAddress
|
|
32
32
|
from web3 import Web3
|
|
33
|
-
from web3.types import TxReceipt
|
|
33
|
+
from web3.types import Timestamp, TxReceipt
|
|
34
34
|
|
|
35
35
|
from ipor_fusion.errors import ExternalStateEventDecodeError
|
|
36
|
-
from ipor_fusion.
|
|
36
|
+
from ipor_fusion.fuses.events import abi_value
|
|
37
|
+
from ipor_fusion.types import Amount, FuseAddress, MarketId, TxHash, parse_tx_hash
|
|
37
38
|
|
|
38
39
|
|
|
39
40
|
@dataclass(frozen=True, slots=True)
|
|
@@ -114,6 +115,85 @@ EXTERNAL_STATE_EVENT_SPECS: tuple[ExternalStateEventSpec, ...] = (
|
|
|
114
115
|
),
|
|
115
116
|
)
|
|
116
117
|
|
|
118
|
+
|
|
119
|
+
class ExternalStateBigChangeDetectedArgs(TypedDict):
|
|
120
|
+
previousTotal: Amount
|
|
121
|
+
newTotal: Amount
|
|
122
|
+
thresholdBps: int
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class ExternalStateCustodianTimestampUpdatedArgs(TypedDict):
|
|
126
|
+
"""``ExternalStateBalanceFuseLastCustodianTimestampUpdated``."""
|
|
127
|
+
|
|
128
|
+
oldTimestamp: Timestamp
|
|
129
|
+
newTimestamp: Timestamp
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
class ExternalStateTotalBalanceUpdatedArgs(TypedDict):
|
|
133
|
+
"""``ExternalStateBalanceFuseLastTotalBalanceUpdated``."""
|
|
134
|
+
|
|
135
|
+
oldTotalBalance: Amount
|
|
136
|
+
newTotalBalance: Amount
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class ExternalStateUnpausedArgs(TypedDict):
|
|
140
|
+
signer: ChecksumAddress
|
|
141
|
+
confirmedTotalBalance: Amount
|
|
142
|
+
nonce: int
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class ExternalStateAssetRescuedArgs(TypedDict):
|
|
146
|
+
asset: ChecksumAddress
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class ExternalStateExecutorArgs(TypedDict):
|
|
150
|
+
"""``ExecutorCreated`` and ``ExternalStateExecutorDeployed``."""
|
|
151
|
+
|
|
152
|
+
executor: ChecksumAddress
|
|
153
|
+
marketId: MarketId
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
class ExternalStateOperationArgs(TypedDict):
|
|
157
|
+
"""``ExternalStateOperationFuseEnter`` and ``ExternalStateOperationFuseExit``;
|
|
158
|
+
``version`` is the operation fuse's address."""
|
|
159
|
+
|
|
160
|
+
version: FuseAddress
|
|
161
|
+
asset: ChecksumAddress
|
|
162
|
+
amount: Amount
|
|
163
|
+
balanceAccount: ChecksumAddress
|
|
164
|
+
valueInUnderlying: Amount
|
|
165
|
+
actionsCount: int
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
#: The parameters of one ExternalState event, by its Solidity names; tell the
|
|
169
|
+
#: shapes apart by ``ExternalStateEvent.name`` or a key (``"signer" in args``).
|
|
170
|
+
ExternalStateEventArgs: TypeAlias = (
|
|
171
|
+
ExternalStateBigChangeDetectedArgs
|
|
172
|
+
| ExternalStateCustodianTimestampUpdatedArgs
|
|
173
|
+
| ExternalStateTotalBalanceUpdatedArgs
|
|
174
|
+
| ExternalStateUnpausedArgs
|
|
175
|
+
| ExternalStateAssetRescuedArgs
|
|
176
|
+
| ExternalStateExecutorArgs
|
|
177
|
+
| ExternalStateOperationArgs
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
#: Event name -> the TypedDict its ``args`` is.
|
|
181
|
+
EXTERNAL_STATE_EVENT_ARGS: dict[str, type] = {
|
|
182
|
+
"ExternalStateBigChangeDetected": ExternalStateBigChangeDetectedArgs,
|
|
183
|
+
"ExternalStateBalanceFuseLastCustodianTimestampUpdated": (
|
|
184
|
+
ExternalStateCustodianTimestampUpdatedArgs
|
|
185
|
+
),
|
|
186
|
+
"ExternalStateBalanceFuseLastTotalBalanceUpdated": (
|
|
187
|
+
ExternalStateTotalBalanceUpdatedArgs
|
|
188
|
+
),
|
|
189
|
+
"ExternalStateUnpaused": ExternalStateUnpausedArgs,
|
|
190
|
+
"ExternalStateAssetRescued": ExternalStateAssetRescuedArgs,
|
|
191
|
+
"ExecutorCreated": ExternalStateExecutorArgs,
|
|
192
|
+
"ExternalStateOperationFuseEnter": ExternalStateOperationArgs,
|
|
193
|
+
"ExternalStateOperationFuseExit": ExternalStateOperationArgs,
|
|
194
|
+
"ExternalStateExecutorDeployed": ExternalStateExecutorArgs,
|
|
195
|
+
}
|
|
196
|
+
|
|
117
197
|
#: topic0 -> spec, for every ExternalState event the vault emits.
|
|
118
198
|
EXTERNAL_STATE_EVENTS: dict[bytes, ExternalStateEventSpec] = {
|
|
119
199
|
spec.topic: spec for spec in EXTERNAL_STATE_EVENT_SPECS
|
|
@@ -130,7 +210,7 @@ class ExternalStateEvent:
|
|
|
130
210
|
|
|
131
211
|
name: str
|
|
132
212
|
emitter: ChecksumAddress
|
|
133
|
-
args:
|
|
213
|
+
args: ExternalStateEventArgs
|
|
134
214
|
block_number: int | None = None
|
|
135
215
|
transaction_hash: TxHash | None = None
|
|
136
216
|
log_index: int | None = None
|
|
@@ -230,10 +310,15 @@ def decode_external_state_event( # proctor: ignore[primitives-untyped-dict]
|
|
|
230
310
|
values = decode([abi_type for abi_type, _ in spec.params], raw)
|
|
231
311
|
except DecodingError as exc:
|
|
232
312
|
raise ExternalStateEventDecodeError(f"{spec.name}: {exc}") from exc
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
313
|
+
# Each value is narrowed to its ABI type; the key set is the spec's, which
|
|
314
|
+
# EXTERNAL_STATE_EVENT_ARGS mirrors (pinned by the tests).
|
|
315
|
+
args = cast(
|
|
316
|
+
ExternalStateEventArgs,
|
|
317
|
+
{
|
|
318
|
+
name: abi_value(abi_type, value)
|
|
319
|
+
for (abi_type, name), value in zip(spec.params, values, strict=True)
|
|
320
|
+
},
|
|
321
|
+
)
|
|
237
322
|
address = log.get("address")
|
|
238
323
|
if not isinstance(address, str | bytes):
|
|
239
324
|
raise ExternalStateEventDecodeError(f"{spec.name}: emitter")
|