ipor-fusion 4.0.0.dev122__tar.gz → 4.0.0.dev129__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.dev122 → ipor_fusion-4.0.0.dev129}/AGENTS.md +12 -6
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/MIGRATION_4.md +35 -18
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/PKG-INFO +14 -7
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/README.md +13 -6
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/examples/CONTRIBUTING.md +1 -5
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/examples/external_state_margin_leg_base.py +0 -7
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/pyproject.toml +1 -1
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/scripts/crosschain_readiness.py +1 -2
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/__init__.py +26 -3
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/core/__init__.py +4 -1
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/core/context.py +48 -20
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/core/external_state_executor.py +20 -160
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/__init__.py +2 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/errors.py +2 -3
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/readers/__init__.py +12 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_external_state_executor.py +6 -362
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_public_api.py +275 -37
- ipor_fusion-4.0.0.dev129/tests/test_public_type_reachability.py +228 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_web3_context.py +35 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/.claude-plugin/marketplace.json +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/.claude-plugin/plugin.json +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/.env.example +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/.gemini/settings.json +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/.git-blame-ignore-revs +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/.github/workflows/cd.yml +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/.github/workflows/ci.yml +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/.github/workflows/commit-lint.yml +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/.github/workflows/notify-slack.yml +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/.github/workflows/python-build.yml +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/.github/workflows/python-publish.yml +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/.github/workflows/release.yml +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/.github/workflows/report-slack.yml +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/.gitignore +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/.mcp.json +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/.pre-commit-config.yaml +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/.python-version +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/CHANGELOG.md +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/CLAUDE.md +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/CODEOWNERS +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/LICENSE +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/build.sh +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/examples/README.md +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/examples/advanced_euler_v2_credit_market_base.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/examples/advanced_euler_v2_looping_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/examples/composed_hypercore_flow_arbitrum_hyperevm.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/examples/crosschain_ccip_usdc_arbitrum_hyperevm.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/examples/simple_aave_v3_supply_base.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/pytest.ini +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/scripts/commit-check.sh +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/skills/ipor-deploy-vault/SKILL.md +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/about.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/cache.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/chains.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/cli/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/cli/changelog_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/cli/config_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/cli/config_store.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/cli/main.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/cli/market_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/cli/options.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/cli/oracle_mapping_view.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/cli/vault_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/cli/vault_health.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/cli/vault_info_view.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/cli/vault_markets_view.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/cli/vault_rendering.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/config/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/config/roles.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/core/access.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/core/address.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/core/contract.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/core/erc20.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/core/fee_manager.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/core/fuse.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/core/fuse_action.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/core/fusion_factory.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/core/logs.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/core/multicall.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/core/oracle.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/core/plasma_vault.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/core/rewards_manager.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/core/simulation.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/core/withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/ccip/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/ccip/chainlink.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/ccip/codec.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/ccip/contracts.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/ccip/events.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/ccip/indexer.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/ccip/lane.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/ccip/quote.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/ccip/transport.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/contracts.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/discovery.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/errors.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/fuses/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/fuses/base.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/fuses/ccip.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/fuses/stargate.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/lane.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/logs.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/messages.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/simulation.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/stargate/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/stargate/contracts.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/stargate/lane.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/stargate/layerzero.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/stargate/transport.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/crosschain/transport.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/dependency_graph.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/entry_cli.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/entry_mcp.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/explorer.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/field_docs.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/fuses/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/fuses/aave_v3.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/fuses/async_action.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/fuses/base.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/fuses/compound_v3.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/fuses/erc4626.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/fuses/euler_v2.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/fuses/events.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/fuses/external_state.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/fuses/external_state_events.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/fuses/fluid_instadapp.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/fuses/gearbox_v3.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/fuses/hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/fuses/hypercore_events.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/fuses/merkl.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/fuses/morpho.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/fuses/ramses_v2.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/fuses/uniswap_v3.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/fuses/universal.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/guide/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/guide/architecture.md +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/guide/glossary.md +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/guide/invariants.md +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/guide/quickstart.md +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/market_ids.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/market_info.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/mcp/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/mcp/guide.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/mcp/models.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/mcp/server.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/morpho_api.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/py.typed +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/readers/aave_v3.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/readers/aave_v4.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/readers/compound_v3.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/readers/hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/readers/hypercore_outcome.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/readers/lending_health.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/readers/morpho.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/readers/oracle_mapping.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/readers/oracle_mapping_nodes.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/readers/oracle_mapping_reader.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/readers/position_manager.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/readers/ramses_v2.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/readers/uniswap_v3.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/readers/unpriceable.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/substrates.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/types.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/validation.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/vault_data.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/vault_erc20.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/vault_info.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/vault_managers.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/vault_positions.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/src/ipor_fusion/vault_reads.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/UniswapV3UniversalRouter.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/_crosschain_lifecycle.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/_crosschain_recovery.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/_euler_v2.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/_foundry.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/_guide.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/_hypercore_model.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/_hypercore_shadow.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/_multicall.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/_simulate.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/_validation.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/addresses.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/conftest.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/constants.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/fixtures/hypercore_hip3_flow.json +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/fixtures/hypercore_market55.json +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/fixtures/vault_info_golden/clean.json +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/fixtures/vault_info_golden/clean.txt +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/fixtures/vault_info_golden/rich.json +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/fixtures/vault_info_golden/rich.txt +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_about.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_access_manager.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_cache.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_chains.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_cli_changelog.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_cli_commands.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_cli_config_store.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_cli_helpers.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_cli_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_cli_lending_health.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_cli_market_morpho_blue.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_cli_oracle_mapping.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_cli_pending_requests_scan.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_cli_role_accounts.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_cli_vault_info_golden.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_cli_vault_predates_getters.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_cli_vault_validate.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_contract_call.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_contract_encoder.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_crosschain_ccip_events.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_crosschain_ccip_indexer.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_crosschain_ccip_quote.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_crosschain_chainlink.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_crosschain_contracts.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_crosschain_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_crosschain_errors.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_crosschain_lane.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_crosschain_layering.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_crosschain_readiness.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_crosschain_readiness_report.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_crosschain_transport.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_erc20.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_error_hierarchy.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_examples_composed_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_examples_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_examples_euler_looping_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_examples_vaults.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_explorer.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_external_state_events.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_fee_manager.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_fuse_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_fusion_instance.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_guide.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_hypercore_deployment.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_hypercore_events.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_hypercore_flow.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_hypercore_live.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_hypercore_outcome.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_hypercore_readers.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_hypercore_simulation.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_logs.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_mcp_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_mcp_models.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_mcp_server.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_mcp_vault_validate.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_multicall.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_oracle.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_oracle_mapping.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_plasma_vault.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_reader_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_readiness_selection.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_revert_decoding.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_rewards_manager.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_roles.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_sdk_layering.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_borrow_aave_v3_mainnet.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_claim_merkl_wrapper_base.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_claim_morpho_rewards.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_crosschain_canary.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_crosschain_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_crosschain_hyperevm.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_crosschain_lifecycle.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_euler_v2_batch_base.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_euler_v2_credit_market_base.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_euler_v2_swap_deploy_base.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_euler_v2_swap_reconfigure_base.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_euler_v2_swap_registry_base.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_examples_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_examples_base.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_examples_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_external_state_executor_base.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_fusion_factory_clone_base.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_looping_aave_v3_base.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_looping_morpho_blue_base.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_morpho_blue.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_pilot_v3.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_pilot_v4_uniswap.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_pilot_v5_ramses.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_pilot_v5_scheduled.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_plasma_vault_setters_base.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_readers_integration.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_release_funds.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_swap_on_base.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_simulate_vault_from_scratch_base.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_solidity_compiler.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_solidity_mirrors.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_substrates.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_types_and_events.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_unpriceable_tokens.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_validation.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_vault_dep_graph.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_vault_info_onchain_base.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_vault_info_onchain_base_no_withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_vault_simulator_blocks.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/test_withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/typed_client/consumer.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/tests/typed_client/rejected.py +0 -0
- {ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/uv.lock +0 -0
|
@@ -161,11 +161,16 @@ the lifecycle matrix follows that.
|
|
|
161
161
|
public modules (`about`, `cache`, `chains`, `dependency_graph`, `errors`, `explorer`,
|
|
162
162
|
`field_docs`, `market_ids`, `market_info`, `morpho_api`, `substrates`, `types`,
|
|
163
163
|
`validation`, `vault_data`, `vault_info`) stay importable for the names they
|
|
164
|
-
define; `cli`, `mcp
|
|
165
|
-
|
|
164
|
+
define and the moved names README lists; `cli`, `mcp`, every other module and
|
|
165
|
+
every submodule of a public subpackage (`core.contract`, `fuses.base`, ...) are
|
|
166
|
+
internal. Examples, the guide, the skill and `scripts/` import from
|
|
167
|
+
`ipor_fusion`, a public subpackage or a public module, never an internal
|
|
166
168
|
path. Adding or removing a
|
|
167
|
-
name updates the
|
|
168
|
-
|
|
169
|
+
name updates the snapshots in `tests/test_public_api.py` (every `__all__`, and
|
|
170
|
+
the names each public module keeps by path); moving a name out of a public
|
|
171
|
+
module leaves a re-export there. A removal or rename is a breaking change.
|
|
172
|
+
A project type used in a public signature or field is exported too
|
|
173
|
+
(`tests/test_public_type_reachability.py`). The package is `py.typed`, so public APIs stay fully
|
|
169
174
|
annotated.
|
|
170
175
|
|
|
171
176
|
## Invariants that must change together
|
|
@@ -395,8 +400,9 @@ role-accounts, oracle-mapping). `vault info` runs independent fetch pipelines
|
|
|
395
400
|
(vault/asset, fees, WithdrawManager, markets, roles) concurrently on a
|
|
396
401
|
`ThreadPoolExecutor`, each a short chain of `Multicall3` batches; keep new
|
|
397
402
|
reads inside a batch rather than adding per-call round trips. A `from_url` context
|
|
398
|
-
bounds requests in flight (`max_concurrent_requests`, default 8
|
|
399
|
-
|
|
403
|
+
bounds requests in flight (`max_concurrent_requests`, default 8; an
|
|
404
|
+
`InFlightLimit` shares one bound across contexts) whatever the pool nesting, so a
|
|
405
|
+
new fan-out does not need its own limit. Contract names,
|
|
400
406
|
token symbols and decimals and deployment blocks are cached per chain in
|
|
401
407
|
`$XDG_CACHE_HOME/ipor-fusion/contract_cache.json` (`<chain>:<address>:<field>`
|
|
402
408
|
keys); tests redirect it with `monkeypatch.setenv("XDG_CACHE_HOME", ...)` or
|
|
@@ -56,7 +56,11 @@ a `bytes32` return (recall) request is `ReturnRequestId`.
|
|
|
56
56
|
names earlier reachable only by module path (`FusionFactory`, `FusionInstance`,
|
|
57
57
|
`fetch_market`, `resolve_token_symbol`, the crosschain codecs, ...). Import from
|
|
58
58
|
`ipor_fusion`: a module path outside the README's list (*Public API and stability*)
|
|
59
|
-
still works but is internal.
|
|
59
|
+
still works but is internal. Every project type a public signature or field uses is
|
|
60
|
+
exported too, among them `AaveV3PositionBreakdown`, `AaveV3ReserveTokens`,
|
|
61
|
+
`AccountRequest`, `StateOverrideProvider`, `TransferDirection` and the validation
|
|
62
|
+
vocabulary `Severity`, `Verdict` and `Check`. Also new: `InFlightLimit` (below) and
|
|
63
|
+
`log_bytes`, the hex-or-bytes log field helper the crosschain decoders use.
|
|
60
64
|
|
|
61
65
|
**Vault reads and validation.** The vault read is one pinned snapshot, and the
|
|
62
66
|
chain is always the context's:
|
|
@@ -110,8 +114,13 @@ now shown in share decimals labelled `shares` (``fusion vault info``) and its JS
|
|
|
110
114
|
`Web3Context.from_url(..., max_concurrent_requests=8)` bounds the RPC requests in
|
|
111
115
|
flight across every thread using the context (``None`` lifts the bound); the vault
|
|
112
116
|
reads fan out on nested thread pools, and the bound is what a rate-limited provider
|
|
113
|
-
sees.
|
|
114
|
-
|
|
117
|
+
sees. An `int` bounds one context. To bound several contexts on one provider (a
|
|
118
|
+
service that builds a context per request or per scan), create one
|
|
119
|
+
`InFlightLimit(n)` per provider and pass it as `max_concurrent_requests=`: every
|
|
120
|
+
context built with it shares the same `n` slots. A context built from your own
|
|
121
|
+
`Web3` object is not bounded unless you add the limit to it:
|
|
122
|
+
`limit.install(web3)` (innermost, as `from_url` does) or
|
|
123
|
+
`web3.middleware_onion.inject(limit.middleware, layer=0)`.
|
|
115
124
|
|
|
116
125
|
`ensure_supported_chain` takes `ChainId`. `fetch_unpriceable_priced_tokens` takes the oracle and
|
|
117
126
|
underlying as `ChecksumAddress`. `resolve_token_symbol`, `resolve_token_decimals`,
|
|
@@ -197,7 +206,13 @@ keyword arguments only. `ZERO_ADDRESS` is a `ChecksumAddress` (same value).
|
|
|
197
206
|
`HYPERCORE_PENDING_READERS` are keyed by `ChainId` (`HYPEREVM_CHAIN_ID` is one) and
|
|
198
207
|
`explorer.SUPPORTED_CHAINS` is a `frozenset[ChainId]`, so
|
|
199
208
|
`ensure_supported_chain(CHAIN_NAME_TO_ID["ethereum"])` type-checks;
|
|
200
|
-
`PUBLIC_ALLOCATOR_ADDRESSES` values are `ChecksumAddress`. `
|
|
209
|
+
`PUBLIC_ALLOCATOR_ADDRESSES` values are `ChecksumAddress`. Import `CHAIN_NAMES`,
|
|
210
|
+
`CHAIN_NAME_TO_ID`, `SUPPORTED_CHAIN_IDS`, `GET_LOGS_RANGE_HINTS`,
|
|
211
|
+
`PUBLIC_ALLOCATOR_ADDRESSES`, `HYPERCORE_PENDING_READERS`, `HYPEREVM_CHAIN_ID` and
|
|
212
|
+
`HYPERCORE_MARKET` from `ipor_fusion` (the HyperCore ones also from
|
|
213
|
+
`ipor_fusion.readers`). `BLOCK_EXPLORER_URLS`, `MORPHO_BLUE_ADDRESSES`,
|
|
214
|
+
`AAVE_V3_POOL` and `explorer.SUPPORTED_CHAINS` are internal: use
|
|
215
|
+
`morpho_blue_address(chain_id)` for Morpho Blue. `IporFusionMarkets.RWA`
|
|
201
216
|
is gone: market 50 is `IporFusionMarkets.EXTERNAL_STATE`. `MORPHO_BLUE_ADDRESS` is
|
|
202
217
|
gone: use `morpho_blue_address(chain_id)`.
|
|
203
218
|
|
|
@@ -240,8 +255,11 @@ before passing it on.
|
|
|
240
255
|
`HyperCorePendingState` and `HyperCoreTransferSnapshot` carry them.
|
|
241
256
|
|
|
242
257
|
**External state.** `ExternalStateExecutor.proposal_hash` returns and `confirm_balance`
|
|
243
|
-
takes a `ProposalHash`; `BalanceProposal.proposal_hash`
|
|
244
|
-
|
|
258
|
+
takes a `ProposalHash`; `BalanceProposal.proposal_hash` is a `ProposalHash`;
|
|
259
|
+
`ExternalStateEvent.transaction_hash` is a `TxHash`.
|
|
260
|
+
`ExternalStateExecutor.mark_nav` and `NavMark` are gone: send `propose_balance` and
|
|
261
|
+
`confirm_balance` from separate custodians, then
|
|
262
|
+
`PlasmaVault.update_markets_balances([IporFusionMarkets.EXTERNAL_STATE])`.
|
|
245
263
|
|
|
246
264
|
**Errors and explorer.** `TransactionError(tx_hash=)` takes a `TxHash`,
|
|
247
265
|
`LogScanError(address=)` a `ChecksumAddress`; `get_revert_reason` takes a `TxHash`;
|
|
@@ -253,8 +271,10 @@ except below): `chain_id` fields are `ChainId`, `role_id` `RoleId`, `market_id`
|
|
|
253
271
|
`MarketId`. Calling an MCP tool function directly from Python takes `ChainId`.
|
|
254
272
|
|
|
255
273
|
**Fuse base.** `Fuse`, `StakeFuse` and the shared validators and substrate packers
|
|
256
|
-
|
|
257
|
-
`ipor_fusion` re-
|
|
274
|
+
moved to `ipor_fusion.core.fuse`. Import `Fuse` and `StakeFuse` from `ipor_fusion`
|
|
275
|
+
or `ipor_fusion.fuses`. `ipor_fusion.fuses.base` still re-exports them in 4.0, but
|
|
276
|
+
it is a submodule of a public subpackage and therefore internal (see the README,
|
|
277
|
+
*Public API and stability*); so are the underscore validators and packers. Fuse equality and
|
|
258
278
|
hash now cover every attribute a fuse stores, not only its class and address (see
|
|
259
279
|
[Behavior changes](#behavior-changes)).
|
|
260
280
|
|
|
@@ -267,9 +287,7 @@ unchanged.
|
|
|
267
287
|
| 3.x import | 4.0 import |
|
|
268
288
|
|---|---|
|
|
269
289
|
| `ipor_fusion.fuses.crosschain` | `ipor_fusion.crosschain.fuses` (or `ipor_fusion.crosschain`) |
|
|
270
|
-
| `ipor_fusion.fuses.crosschain.base` | `ipor_fusion.crosschain.fuses
|
|
271
|
-
| `ipor_fusion.fuses.crosschain.ccip` | `ipor_fusion.crosschain.fuses.ccip` |
|
|
272
|
-
| `ipor_fusion.fuses.crosschain.stargate` | `ipor_fusion.crosschain.fuses.stargate` |
|
|
290
|
+
| `ipor_fusion.fuses.crosschain.base`, `.ccip`, `.stargate` | `ipor_fusion.crosschain.fuses` (its submodules `base`, `ccip` and `stargate` exist but are internal) |
|
|
273
291
|
| `from ipor_fusion.fuses import CcipCrosschainSupplyFuse` (and the other crosschain encoders, `SendParams`, `CrosschainSubstrate*`, `crosschain_market_id`) | `from ipor_fusion.crosschain import ...` or `from ipor_fusion import ...` |
|
|
274
292
|
|
|
275
293
|
`ipor_fusion.crosschain` now exports the whole crosschain surface: besides the
|
|
@@ -280,8 +298,9 @@ the transports and chains, `discover_deployment`, `open_lane(s)`, `LANES` and
|
|
|
280
298
|
and wrappers.
|
|
281
299
|
|
|
282
300
|
**Moved, still importable.** `FuseAction` lives in `ipor_fusion.core.fuse_action` and
|
|
283
|
-
`ZERO_ADDRESS` in `ipor_fusion.types`; both
|
|
284
|
-
`ipor_fusion.fuses
|
|
301
|
+
`ZERO_ADDRESS` in `ipor_fusion.types`; import both from `ipor_fusion` (`FuseAction`
|
|
302
|
+
also from `ipor_fusion.fuses`, `ZERO_ADDRESS` from the public module
|
|
303
|
+
`ipor_fusion.types`). The internal `ipor_fusion.fuses.base` still re-exports them. The CLI's internal
|
|
285
304
|
`ipor_fusion.cli.vault_cmd` was split into `options`, `vault_info_view`,
|
|
286
305
|
`vault_markets_view` and `oracle_mapping_view` (private names, not API).
|
|
287
306
|
|
|
@@ -333,7 +352,7 @@ placeholder wrapper.
|
|
|
333
352
|
and `VaultSimulator.observe` stamp the same hash for the same bytes, whatever
|
|
334
353
|
context executes them. Pass `ctx.chain_id` for the chain you read from.
|
|
335
354
|
`pending_proposals` now refuses an executor at the zero address when the Call is
|
|
336
|
-
built, not when it is decoded.
|
|
355
|
+
built, not when it is decoded.
|
|
337
356
|
|
|
338
357
|
| 3.x | 4.0 |
|
|
339
358
|
|---|---|
|
|
@@ -544,10 +563,8 @@ is the wrong one.
|
|
|
544
563
|
`parse_balance_proposed` / `find_balance_proposed` for one of the executor's own
|
|
545
564
|
`BalanceProposed` logs whose data is missing or malformed (including data that is
|
|
546
565
|
not hex at all, which raised `TypeError`) or whose hash is not the hash of its own
|
|
547
|
-
fields
|
|
548
|
-
|
|
549
|
-
executor, and `find_balance_proposed` over logs that hold no match, are still
|
|
550
|
-
`ValueError`.
|
|
566
|
+
fields. A log that is not the event or not from the executor, and
|
|
567
|
+
`find_balance_proposed` over logs that hold no match, are still `ValueError`.
|
|
551
568
|
- `ccip_token_lane` raises the new `UnsupportedContractVersionError` (still a
|
|
552
569
|
`ValueError`) for an OnRamp version whose layout is not verified.
|
|
553
570
|
- `quote_ccip_native_fee` raises `SimulationError` (label `"quote"`, with
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: ipor-fusion
|
|
3
|
-
Version: 4.0.0.
|
|
3
|
+
Version: 4.0.0.dev129
|
|
4
4
|
Summary: The IPOR Fusion SDK for Python
|
|
5
5
|
Project-URL: homepage, https://ipor.io
|
|
6
6
|
Project-URL: repository, https://github.com/IPOR-Labs/ipor-fusion.py
|
|
@@ -383,16 +383,23 @@ release; adding one does not.
|
|
|
383
383
|
- **Public modules** stay importable for the top-level names they define:
|
|
384
384
|
`about`, `cache`, `chains`, `dependency_graph`, `errors`, `explorer`, `field_docs`,
|
|
385
385
|
`market_ids`, `market_info`, `morpho_api`, `substrates`, `types`, `validation`,
|
|
386
|
-
`vault_data` and `vault_info` (all under `ipor_fusion.`).
|
|
386
|
+
`vault_data` and `vault_info` (all under `ipor_fusion.`). A name that moved out of
|
|
387
|
+
one of them keeps its old path there (`vault_data.FeeData`,
|
|
388
|
+
`vault_data.WithdrawManagerData`, `validation.Erc20Holding`,
|
|
389
|
+
`validation.Erc20Holdings`, `morpho_api.MorphoApiError`).
|
|
387
390
|
- **Internal:** `ipor_fusion.cli`, `ipor_fusion.mcp`, every other module (e.g.
|
|
388
|
-
`vault_reads
|
|
389
|
-
|
|
390
|
-
|
|
391
|
+
`vault_reads`) and every submodule of a public subpackage (e.g.
|
|
392
|
+
`ipor_fusion.core.contract`, `ipor_fusion.fuses.base`; import their names from
|
|
393
|
+
the subpackage or `ipor_fusion`), underscore names, and names in no `__all__`.
|
|
394
|
+
They change without notice; the CLI and the MCP server are stable as commands
|
|
395
|
+
and tools, not as Python modules.
|
|
391
396
|
- **Preview features** (`PREVIEW_FEATURES` in `ipor_fusion.about`: crosschain,
|
|
392
397
|
HyperCore) are exported like the rest but may change in a minor release.
|
|
393
398
|
|
|
394
|
-
`tests/test_public_api.py` snapshots every `__all__
|
|
395
|
-
is a deliberate, reviewed edit.
|
|
399
|
+
`tests/test_public_api.py` snapshots every `__all__` and the names each public
|
|
400
|
+
module keeps by path, so a change to the surface is a deliberate, reviewed edit.
|
|
401
|
+
`tests/test_public_type_reachability.py` fails when a public signature or field
|
|
402
|
+
uses a project type that no `__all__` exports.
|
|
396
403
|
|
|
397
404
|
## Architecture
|
|
398
405
|
|
|
@@ -335,16 +335,23 @@ release; adding one does not.
|
|
|
335
335
|
- **Public modules** stay importable for the top-level names they define:
|
|
336
336
|
`about`, `cache`, `chains`, `dependency_graph`, `errors`, `explorer`, `field_docs`,
|
|
337
337
|
`market_ids`, `market_info`, `morpho_api`, `substrates`, `types`, `validation`,
|
|
338
|
-
`vault_data` and `vault_info` (all under `ipor_fusion.`).
|
|
338
|
+
`vault_data` and `vault_info` (all under `ipor_fusion.`). A name that moved out of
|
|
339
|
+
one of them keeps its old path there (`vault_data.FeeData`,
|
|
340
|
+
`vault_data.WithdrawManagerData`, `validation.Erc20Holding`,
|
|
341
|
+
`validation.Erc20Holdings`, `morpho_api.MorphoApiError`).
|
|
339
342
|
- **Internal:** `ipor_fusion.cli`, `ipor_fusion.mcp`, every other module (e.g.
|
|
340
|
-
`vault_reads
|
|
341
|
-
|
|
342
|
-
|
|
343
|
+
`vault_reads`) and every submodule of a public subpackage (e.g.
|
|
344
|
+
`ipor_fusion.core.contract`, `ipor_fusion.fuses.base`; import their names from
|
|
345
|
+
the subpackage or `ipor_fusion`), underscore names, and names in no `__all__`.
|
|
346
|
+
They change without notice; the CLI and the MCP server are stable as commands
|
|
347
|
+
and tools, not as Python modules.
|
|
343
348
|
- **Preview features** (`PREVIEW_FEATURES` in `ipor_fusion.about`: crosschain,
|
|
344
349
|
HyperCore) are exported like the rest but may change in a minor release.
|
|
345
350
|
|
|
346
|
-
`tests/test_public_api.py` snapshots every `__all__
|
|
347
|
-
is a deliberate, reviewed edit.
|
|
351
|
+
`tests/test_public_api.py` snapshots every `__all__` and the names each public
|
|
352
|
+
module keeps by path, so a change to the surface is a deliberate, reviewed edit.
|
|
353
|
+
`tests/test_public_type_reachability.py` fails when a public signature or field
|
|
354
|
+
uses a project type that no `__all__` exports.
|
|
348
355
|
|
|
349
356
|
## Architecture
|
|
350
357
|
|
|
@@ -63,11 +63,7 @@ role-separation note is about. Label the collapse itself, not the calls: sending
|
|
|
63
63
|
as two separate calls *is* the production shape, and only "both keys in one process" is
|
|
64
64
|
simulation-only.
|
|
65
65
|
|
|
66
|
-
Cross-reference the SDK method a production caller would use instead, where one exists
|
|
67
|
-
where the SDK method is the one to reach for. `ExternalStateExecutor.mark_nav` is the counter-example:
|
|
68
|
-
it composes both custodian calls, its own docstring warns that this "does not preserve the
|
|
69
|
-
dual-custodian separation", and it is expected to be deprecated in favour of the two primitives. Do
|
|
70
|
-
not point readers at it.
|
|
66
|
+
Cross-reference the SDK method a production caller would use instead, where one exists.
|
|
71
67
|
|
|
72
68
|
## 3. One self-contained file
|
|
73
69
|
|
{ipor_fusion-4.0.0.dev122 → ipor_fusion-4.0.0.dev129}/examples/external_state_margin_leg_base.py
RENAMED
|
@@ -894,13 +894,6 @@ def run_simulation(web3: Web3) -> SimulationResult:
|
|
|
894
894
|
# driven from this one process. In a real deployment they live in separate
|
|
895
895
|
# systems -- if one process can send both, a single compromise moves the
|
|
896
896
|
# vault's NAV and the two-party design has bought nothing.
|
|
897
|
-
#
|
|
898
|
-
# ExternalStateExecutor.mark_nav runs the propose, the confirm and -- when
|
|
899
|
-
# handed a vault -- the refresh in one call. It cannot be used here for a
|
|
900
|
-
# mechanical reason: it .send(ctx)s each leg, and nothing is broadcast under
|
|
901
|
-
# eth_simulateV1. It is also not what a production deployment wants, for the
|
|
902
|
-
# reason above: one process holding both custodian keys is one key wearing
|
|
903
|
-
# two hats.
|
|
904
897
|
sim.next_block().with_block_time_shift(PROPOSE_OFFSET)
|
|
905
898
|
sim.add_call(
|
|
906
899
|
call=executor.propose_balance(VENUE_BALANCE_ACCOUNT, MARGIN_AMOUNT),
|
|
@@ -41,8 +41,7 @@ from eth_utils import function_signature_to_4byte_selector, keccak
|
|
|
41
41
|
from web3 import Web3
|
|
42
42
|
from web3.types import RPCEndpoint
|
|
43
43
|
|
|
44
|
-
from ipor_fusion import ERC20, Web3Context, ccip_token_lane
|
|
45
|
-
from ipor_fusion.core.contract import Call
|
|
44
|
+
from ipor_fusion import ERC20, Call, Web3Context, ccip_token_lane
|
|
46
45
|
from ipor_fusion.crosschain import CcipCrosschainFactory, CcipOffRamp, CcipRouter
|
|
47
46
|
from ipor_fusion.types import ChainId
|
|
48
47
|
|
|
@@ -31,7 +31,7 @@ from ipor_fusion.core.access import (
|
|
|
31
31
|
resolve_access_manager,
|
|
32
32
|
role_account_sort_key,
|
|
33
33
|
)
|
|
34
|
-
from ipor_fusion.core.context import Web3Context
|
|
34
|
+
from ipor_fusion.core.context import InFlightLimit, Web3Context
|
|
35
35
|
from ipor_fusion.core.contract import Call
|
|
36
36
|
from ipor_fusion.core.erc20 import ERC20
|
|
37
37
|
from ipor_fusion.core.external_state_executor import (
|
|
@@ -39,7 +39,6 @@ from ipor_fusion.core.external_state_executor import (
|
|
|
39
39
|
BalanceProposal,
|
|
40
40
|
ExternalStateExecutor,
|
|
41
41
|
ExternalStateVaultState,
|
|
42
|
-
NavMark,
|
|
43
42
|
RawLog,
|
|
44
43
|
read_external_state,
|
|
45
44
|
)
|
|
@@ -69,11 +68,13 @@ from ipor_fusion.core.rewards_manager import RewardsManager, VestingData
|
|
|
69
68
|
from ipor_fusion.core.simulation import (
|
|
70
69
|
SimulatedCallResult,
|
|
71
70
|
SimulationResult,
|
|
71
|
+
StateOverrideProvider,
|
|
72
72
|
VaultSimulator,
|
|
73
73
|
erc20_balance_slot,
|
|
74
74
|
is_simulate_v1_supported,
|
|
75
75
|
)
|
|
76
76
|
from ipor_fusion.core.withdraw_manager import (
|
|
77
|
+
AccountRequest,
|
|
77
78
|
PendingRequestsInfo,
|
|
78
79
|
WithdrawManager,
|
|
79
80
|
WithdrawRequestInfo,
|
|
@@ -183,6 +184,7 @@ from ipor_fusion.crosschain import (
|
|
|
183
184
|
encode_oft_compose_msg,
|
|
184
185
|
fetch_verifier_result,
|
|
185
186
|
find_ccip_events,
|
|
187
|
+
log_bytes,
|
|
186
188
|
lz_compose_calldata,
|
|
187
189
|
lz_receive_calldata,
|
|
188
190
|
manual_execution,
|
|
@@ -332,9 +334,14 @@ from ipor_fusion.morpho_api import (
|
|
|
332
334
|
fetch_vault,
|
|
333
335
|
)
|
|
334
336
|
from ipor_fusion.readers import (
|
|
337
|
+
HYPERCORE_MARKET,
|
|
338
|
+
HYPERCORE_PENDING_READERS,
|
|
339
|
+
HYPEREVM_CHAIN_ID,
|
|
335
340
|
AaveV3FuseReader,
|
|
336
341
|
AaveV3PoolAddressesProvider,
|
|
342
|
+
AaveV3PositionBreakdown,
|
|
337
343
|
AaveV3Reader,
|
|
344
|
+
AaveV3ReserveTokens,
|
|
338
345
|
AaveV3UserAccountData,
|
|
339
346
|
AaveV4OracleReader,
|
|
340
347
|
AaveV4SpokeReader,
|
|
@@ -375,6 +382,7 @@ from ipor_fusion.readers import (
|
|
|
375
382
|
PositionData,
|
|
376
383
|
RamsesV2Position,
|
|
377
384
|
RamsesV2Reader,
|
|
385
|
+
TransferDirection,
|
|
378
386
|
UniswapV3Position,
|
|
379
387
|
UniswapV3Reader,
|
|
380
388
|
VaultLendingHealth,
|
|
@@ -404,6 +412,7 @@ from ipor_fusion.types import (
|
|
|
404
412
|
AssetId,
|
|
405
413
|
AssetSource,
|
|
406
414
|
ChainId,
|
|
415
|
+
Check,
|
|
407
416
|
CommandId,
|
|
408
417
|
Decimals,
|
|
409
418
|
DeploymentRequestId,
|
|
@@ -432,12 +441,14 @@ from ipor_fusion.types import (
|
|
|
432
441
|
ProposalId,
|
|
433
442
|
ReturnRequestId,
|
|
434
443
|
RoleId,
|
|
444
|
+
Severity,
|
|
435
445
|
Shares,
|
|
436
446
|
StargateAssetId,
|
|
437
447
|
Tick,
|
|
438
448
|
TokenId,
|
|
439
449
|
TransferId,
|
|
440
450
|
TxHash,
|
|
451
|
+
Verdict,
|
|
441
452
|
parse_access_manager_address,
|
|
442
453
|
parse_fuse_address,
|
|
443
454
|
parse_hex_address,
|
|
@@ -497,6 +508,7 @@ __all__ = [
|
|
|
497
508
|
"read_changelog",
|
|
498
509
|
"repository_url",
|
|
499
510
|
"Web3Context",
|
|
511
|
+
"InFlightLimit",
|
|
500
512
|
"Call",
|
|
501
513
|
"get_logs_adaptive",
|
|
502
514
|
"find_creation_block",
|
|
@@ -504,6 +516,7 @@ __all__ = [
|
|
|
504
516
|
"Multicall3",
|
|
505
517
|
"MULTICALL3_ADDRESS",
|
|
506
518
|
"VaultSimulator",
|
|
519
|
+
"StateOverrideProvider",
|
|
507
520
|
"SimulationResult",
|
|
508
521
|
"SimulatedCallResult",
|
|
509
522
|
"is_simulate_v1_supported",
|
|
@@ -517,6 +530,7 @@ __all__ = [
|
|
|
517
530
|
"VestingData",
|
|
518
531
|
"ERC20",
|
|
519
532
|
"WithdrawManager",
|
|
533
|
+
"AccountRequest",
|
|
520
534
|
"FeeAccount",
|
|
521
535
|
"FeeManager",
|
|
522
536
|
"RecipientFee",
|
|
@@ -538,7 +552,6 @@ __all__ = [
|
|
|
538
552
|
"BalanceFuseSnapshot",
|
|
539
553
|
"ExternalStateVaultState",
|
|
540
554
|
"read_external_state",
|
|
541
|
-
"NavMark",
|
|
542
555
|
"CrosschainExecutor",
|
|
543
556
|
"StargateCrosschainExecutor",
|
|
544
557
|
"StargateCrosschainDispatcher",
|
|
@@ -563,6 +576,7 @@ __all__ = [
|
|
|
563
576
|
"CcipChain",
|
|
564
577
|
"CrosschainSimulator",
|
|
565
578
|
"CrosschainLane",
|
|
579
|
+
"log_bytes",
|
|
566
580
|
"StargateLane",
|
|
567
581
|
"CcipLane",
|
|
568
582
|
"LaneFuses",
|
|
@@ -820,12 +834,17 @@ __all__ = [
|
|
|
820
834
|
"morpho_blue_address",
|
|
821
835
|
"AaveV3FuseReader",
|
|
822
836
|
"AaveV3PoolAddressesProvider",
|
|
837
|
+
"AaveV3PositionBreakdown",
|
|
823
838
|
"AaveV3Reader",
|
|
839
|
+
"AaveV3ReserveTokens",
|
|
824
840
|
"AaveV3UserAccountData",
|
|
825
841
|
"AaveV4OracleReader",
|
|
826
842
|
"AaveV4SpokeReader",
|
|
827
843
|
"AaveV4UserAccountData",
|
|
828
844
|
"CompoundV3Reader",
|
|
845
|
+
"HYPERCORE_MARKET",
|
|
846
|
+
"HYPERCORE_PENDING_READERS",
|
|
847
|
+
"HYPEREVM_CHAIN_ID",
|
|
829
848
|
"HyperCoreAccountMarginSummary",
|
|
830
849
|
"HyperCoreActionClass",
|
|
831
850
|
"HyperCoreEvmExitCeiling",
|
|
@@ -843,6 +862,7 @@ __all__ = [
|
|
|
843
862
|
"HyperCoreTransferOutcome",
|
|
844
863
|
"HyperCoreTransferSnapshot",
|
|
845
864
|
"HyperCoreTransferStatus",
|
|
865
|
+
"TransferDirection",
|
|
846
866
|
"compare_hypercore_transfer",
|
|
847
867
|
"read_hypercore_evm_exit_ceiling",
|
|
848
868
|
"read_hypercore_transfer_outcome",
|
|
@@ -871,6 +891,9 @@ __all__ = [
|
|
|
871
891
|
"Erc20Holding",
|
|
872
892
|
"Erc20Holdings",
|
|
873
893
|
"Finding",
|
|
894
|
+
"Severity",
|
|
895
|
+
"Verdict",
|
|
896
|
+
"Check",
|
|
874
897
|
"Reconciliation",
|
|
875
898
|
"UnpriceableToken",
|
|
876
899
|
"VaultState",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from ipor_fusion.core.access import AccessManager, RoleAccount, RoleStatus
|
|
2
|
-
from ipor_fusion.core.context import Web3Context
|
|
2
|
+
from ipor_fusion.core.context import InFlightLimit, Web3Context
|
|
3
3
|
from ipor_fusion.core.erc20 import ERC20
|
|
4
4
|
from ipor_fusion.core.fee_manager import (
|
|
5
5
|
FeeAccount,
|
|
@@ -23,6 +23,7 @@ from ipor_fusion.core.plasma_vault import (
|
|
|
23
23
|
)
|
|
24
24
|
from ipor_fusion.core.rewards_manager import RewardsManager, VestingData
|
|
25
25
|
from ipor_fusion.core.withdraw_manager import (
|
|
26
|
+
AccountRequest,
|
|
26
27
|
PendingRequestsInfo,
|
|
27
28
|
WithdrawManager,
|
|
28
29
|
WithdrawRequestInfo,
|
|
@@ -30,6 +31,7 @@ from ipor_fusion.core.withdraw_manager import (
|
|
|
30
31
|
|
|
31
32
|
__all__ = [
|
|
32
33
|
"Web3Context",
|
|
34
|
+
"InFlightLimit",
|
|
33
35
|
"Multicall3",
|
|
34
36
|
"MULTICALL3_ADDRESS",
|
|
35
37
|
"PlasmaVault",
|
|
@@ -40,6 +42,7 @@ __all__ = [
|
|
|
40
42
|
"VestingData",
|
|
41
43
|
"ERC20",
|
|
42
44
|
"WithdrawManager",
|
|
45
|
+
"AccountRequest",
|
|
43
46
|
"WithdrawRequestInfo",
|
|
44
47
|
"PendingRequestsInfo",
|
|
45
48
|
"BalanceFuse",
|
|
@@ -170,11 +170,15 @@ class Web3Context:
|
|
|
170
170
|
log_scan_max_requests: int | None = DEFAULT_LOG_SCAN_MAX_REQUESTS,
|
|
171
171
|
log_source: LogSource | None = None,
|
|
172
172
|
cache: ContractCache | None = None,
|
|
173
|
-
max_concurrent_requests: int
|
|
173
|
+
max_concurrent_requests: int
|
|
174
|
+
| InFlightLimit
|
|
175
|
+
| None = DEFAULT_MAX_CONCURRENT_REQUESTS,
|
|
174
176
|
) -> Web3Context:
|
|
175
177
|
"""A context on an HTTP provider at ``url``. ``max_concurrent_requests``
|
|
176
|
-
bounds the RPC requests in flight across every thread using
|
|
177
|
-
|
|
178
|
+
bounds the RPC requests in flight: an ``int`` across every thread using
|
|
179
|
+
this context, an `InFlightLimit` across every context and `Web3` it is
|
|
180
|
+
installed on (share one per provider in a service that builds a context
|
|
181
|
+
per request); ``None`` leaves them unbounded."""
|
|
178
182
|
web3 = Web3(
|
|
179
183
|
Web3.HTTPProvider(
|
|
180
184
|
url,
|
|
@@ -192,15 +196,11 @@ class Web3Context:
|
|
|
192
196
|
# with a ValueError. The middleware moves it to proofOfAuthorityData
|
|
193
197
|
# and leaves every other block untouched.
|
|
194
198
|
web3.middleware_onion.inject(ExtraDataToPOAMiddleware, layer=0)
|
|
199
|
+
if isinstance(max_concurrent_requests, int):
|
|
200
|
+
max_concurrent_requests = InFlightLimit(max_concurrent_requests)
|
|
195
201
|
if max_concurrent_requests is not None:
|
|
196
|
-
#
|
|
197
|
-
|
|
198
|
-
# strategy reads a block) never waits on the slot it already holds.
|
|
199
|
-
web3.middleware_onion.inject(
|
|
200
|
-
_in_flight_limit(max_concurrent_requests),
|
|
201
|
-
name="in_flight_limit",
|
|
202
|
-
layer=0,
|
|
203
|
-
)
|
|
202
|
+
# Injected last, so innermost (see `InFlightLimit.install`).
|
|
203
|
+
max_concurrent_requests.install(web3)
|
|
204
204
|
chain_id = ChainId(web3.eth.chain_id)
|
|
205
205
|
|
|
206
206
|
return cls(
|
|
@@ -417,15 +417,43 @@ class Web3Context:
|
|
|
417
417
|
return value * percentage // 100
|
|
418
418
|
|
|
419
419
|
|
|
420
|
-
|
|
421
|
-
"""A
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
420
|
+
class InFlightLimit:
|
|
421
|
+
"""A bound on the RPC requests in flight, shareable across `Web3` objects.
|
|
422
|
+
|
|
423
|
+
Every `Web3` it is installed on (``install``, or
|
|
424
|
+
``Web3Context.from_url(max_concurrent_requests=limit)``) takes a slot from
|
|
425
|
+
the same semaphore for each provider call, so several contexts on one
|
|
426
|
+
provider, or a service that builds a context per request, stay within
|
|
427
|
+
``limit`` in total. A JSON-RPC batch is one HTTP request and takes one slot
|
|
428
|
+
whatever its item count; a failed request releases its slot.
|
|
429
|
+
"""
|
|
430
|
+
|
|
431
|
+
def __init__(self, limit: int):
|
|
432
|
+
if limit < 1:
|
|
433
|
+
raise ValueError(f"an in-flight limit must be at least 1, got {limit}")
|
|
434
|
+
self._limit = limit
|
|
435
|
+
self._middleware = _slot_middleware(threading.BoundedSemaphore(limit))
|
|
436
|
+
|
|
437
|
+
@property
|
|
438
|
+
def limit(self) -> int:
|
|
439
|
+
return self._limit
|
|
440
|
+
|
|
441
|
+
@property
|
|
442
|
+
def middleware(self) -> type[Web3Middleware]:
|
|
443
|
+
"""The middleware class to add to a `Web3` by hand; every instance
|
|
444
|
+
web3 builds from it shares this limit's slots."""
|
|
445
|
+
return self._middleware
|
|
446
|
+
|
|
447
|
+
def install(self, web3: Web3) -> None:
|
|
448
|
+
"""Add the limit to ``web3`` as its innermost middleware
|
|
449
|
+
(``in_flight_limit``). A slot then covers only the provider call, so a
|
|
450
|
+
middleware that issues its own request (the gas price strategy reads a
|
|
451
|
+
block) never waits on the slot it already holds."""
|
|
452
|
+
web3.middleware_onion.inject(self._middleware, name="in_flight_limit", layer=0)
|
|
453
|
+
|
|
427
454
|
|
|
428
|
-
|
|
455
|
+
def _slot_middleware(slots: threading.BoundedSemaphore) -> type[Web3Middleware]:
|
|
456
|
+
class InFlightLimitMiddleware(Web3Middleware):
|
|
429
457
|
def wrap_make_request(self, make_request: MakeRequestFn) -> MakeRequestFn:
|
|
430
458
|
def limited(method: RPCEndpoint, params: Any) -> RPCResponse:
|
|
431
459
|
with slots:
|
|
@@ -444,4 +472,4 @@ def _in_flight_limit(limit: int) -> type[Web3Middleware]:
|
|
|
444
472
|
|
|
445
473
|
return limited
|
|
446
474
|
|
|
447
|
-
return
|
|
475
|
+
return InFlightLimitMiddleware
|