ipor-fusion 4.0.0.dev120__tar.gz → 4.0.0.dev126__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.dev120 → ipor_fusion-4.0.0.dev126}/AGENTS.md +16 -9
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/MIGRATION_4.md +33 -16
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/PKG-INFO +14 -7
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/README.md +13 -6
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/pyproject.toml +1 -1
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/scripts/crosschain_readiness.py +1 -2
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/__init__.py +26 -1
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/core/__init__.py +4 -1
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/core/context.py +48 -20
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/__init__.py +2 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/readers/__init__.py +12 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/validation.py +4 -3
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/vault_data.py +4 -2
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_public_api.py +275 -36
- ipor_fusion-4.0.0.dev126/tests/test_public_type_reachability.py +228 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_validation.py +50 -23
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_web3_context.py +35 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/.claude-plugin/marketplace.json +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/.claude-plugin/plugin.json +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/.env.example +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/.gemini/settings.json +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/.git-blame-ignore-revs +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/.github/workflows/cd.yml +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/.github/workflows/ci.yml +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/.github/workflows/commit-lint.yml +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/.github/workflows/notify-slack.yml +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/.github/workflows/python-build.yml +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/.github/workflows/python-publish.yml +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/.github/workflows/release.yml +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/.github/workflows/report-slack.yml +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/.gitignore +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/.mcp.json +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/.pre-commit-config.yaml +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/.python-version +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/CHANGELOG.md +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/CLAUDE.md +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/CODEOWNERS +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/LICENSE +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/build.sh +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/examples/CONTRIBUTING.md +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/examples/README.md +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/examples/advanced_euler_v2_credit_market_base.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/examples/advanced_euler_v2_looping_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/examples/composed_hypercore_flow_arbitrum_hyperevm.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/examples/crosschain_ccip_usdc_arbitrum_hyperevm.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/examples/external_state_margin_leg_base.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/examples/simple_aave_v3_supply_base.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/pytest.ini +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/scripts/commit-check.sh +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/skills/ipor-deploy-vault/SKILL.md +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/about.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/cache.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/chains.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/cli/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/cli/changelog_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/cli/config_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/cli/config_store.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/cli/main.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/cli/market_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/cli/options.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/cli/oracle_mapping_view.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/cli/vault_cmd.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/cli/vault_health.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/cli/vault_info_view.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/cli/vault_markets_view.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/cli/vault_rendering.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/config/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/config/roles.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/core/access.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/core/address.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/core/contract.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/core/erc20.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/core/external_state_executor.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/core/fee_manager.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/core/fuse.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/core/fuse_action.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/core/fusion_factory.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/core/logs.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/core/multicall.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/core/oracle.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/core/plasma_vault.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/core/rewards_manager.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/core/simulation.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/core/withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/ccip/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/ccip/chainlink.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/ccip/codec.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/ccip/contracts.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/ccip/events.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/ccip/indexer.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/ccip/lane.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/ccip/quote.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/ccip/transport.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/contracts.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/discovery.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/errors.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/fuses/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/fuses/base.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/fuses/ccip.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/fuses/stargate.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/lane.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/logs.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/messages.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/simulation.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/stargate/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/stargate/contracts.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/stargate/lane.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/stargate/layerzero.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/stargate/transport.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/transport.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/dependency_graph.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/entry_cli.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/entry_mcp.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/errors.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/explorer.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/field_docs.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/fuses/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/fuses/aave_v3.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/fuses/async_action.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/fuses/base.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/fuses/compound_v3.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/fuses/erc4626.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/fuses/euler_v2.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/fuses/events.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/fuses/external_state.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/fuses/external_state_events.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/fuses/fluid_instadapp.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/fuses/gearbox_v3.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/fuses/hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/fuses/hypercore_events.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/fuses/merkl.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/fuses/morpho.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/fuses/ramses_v2.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/fuses/uniswap_v3.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/fuses/universal.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/guide/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/guide/architecture.md +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/guide/glossary.md +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/guide/invariants.md +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/guide/quickstart.md +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/market_ids.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/market_info.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/mcp/__init__.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/mcp/guide.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/mcp/models.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/mcp/server.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/morpho_api.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/py.typed +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/readers/aave_v3.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/readers/aave_v4.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/readers/compound_v3.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/readers/hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/readers/hypercore_outcome.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/readers/lending_health.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/readers/morpho.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/readers/oracle_mapping.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/readers/oracle_mapping_nodes.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/readers/oracle_mapping_reader.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/readers/position_manager.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/readers/ramses_v2.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/readers/uniswap_v3.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/readers/unpriceable.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/substrates.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/types.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/vault_erc20.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/vault_info.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/vault_managers.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/vault_positions.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/vault_reads.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/UniswapV3UniversalRouter.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/_crosschain_lifecycle.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/_crosschain_recovery.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/_euler_v2.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/_foundry.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/_guide.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/_hypercore_model.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/_hypercore_shadow.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/_multicall.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/_simulate.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/_validation.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/addresses.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/conftest.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/constants.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/fixtures/hypercore_hip3_flow.json +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/fixtures/hypercore_market55.json +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/fixtures/vault_info_golden/clean.json +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/fixtures/vault_info_golden/clean.txt +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/fixtures/vault_info_golden/rich.json +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/fixtures/vault_info_golden/rich.txt +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_about.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_access_manager.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_cache.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_chains.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_cli_changelog.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_cli_commands.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_cli_config_store.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_cli_helpers.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_cli_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_cli_lending_health.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_cli_market_morpho_blue.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_cli_oracle_mapping.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_cli_pending_requests_scan.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_cli_role_accounts.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_cli_vault_info_golden.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_cli_vault_predates_getters.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_cli_vault_validate.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_contract_call.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_contract_encoder.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_crosschain_ccip_events.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_crosschain_ccip_indexer.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_crosschain_ccip_quote.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_crosschain_chainlink.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_crosschain_contracts.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_crosschain_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_crosschain_errors.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_crosschain_lane.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_crosschain_layering.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_crosschain_readiness.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_crosschain_readiness_report.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_crosschain_transport.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_erc20.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_error_hierarchy.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_examples_composed_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_examples_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_examples_euler_looping_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_examples_vaults.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_explorer.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_external_state_events.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_external_state_executor.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_fee_manager.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_fuse_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_fusion_instance.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_guide.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_hypercore_deployment.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_hypercore_events.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_hypercore_flow.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_hypercore_live.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_hypercore_outcome.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_hypercore_readers.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_hypercore_simulation.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_logs.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_mcp_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_mcp_models.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_mcp_server.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_mcp_vault_validate.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_multicall.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_oracle.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_oracle_mapping.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_plasma_vault.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_reader_encoding.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_readiness_selection.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_revert_decoding.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_rewards_manager.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_roles.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_sdk_layering.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_borrow_aave_v3_mainnet.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_claim_merkl_wrapper_base.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_claim_morpho_rewards.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_crosschain_canary.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_crosschain_hypercore.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_crosschain_hyperevm.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_crosschain_lifecycle.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_euler_v2_batch_base.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_euler_v2_credit_market_base.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_euler_v2_swap_deploy_base.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_euler_v2_swap_reconfigure_base.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_euler_v2_swap_registry_base.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_examples_arbitrum.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_examples_base.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_examples_crosschain.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_external_state_executor_base.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_fusion_factory_clone_base.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_looping_aave_v3_base.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_looping_morpho_blue_base.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_morpho_blue.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_pilot_v3.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_pilot_v4_uniswap.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_pilot_v5_ramses.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_pilot_v5_scheduled.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_plasma_vault_setters_base.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_readers_integration.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_release_funds.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_swap_on_base.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_simulate_vault_from_scratch_base.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_solidity_compiler.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_solidity_mirrors.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_substrates.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_types_and_events.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_unpriceable_tokens.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_vault_dep_graph.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_vault_info_onchain_base.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_vault_info_onchain_base_no_withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_vault_simulator_blocks.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/test_withdraw_manager.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/typed_client/consumer.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/tests/typed_client/rejected.py +0 -0
- {ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/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
|
|
@@ -429,9 +435,10 @@ are not validated.
|
|
|
429
435
|
everything validation and the ``vault info`` document need, so neither reads the
|
|
430
436
|
chain. The chain is `ctx.chain_id`; ``lending=False`` skips lending health, the
|
|
431
437
|
position breakdowns, their prices and the unpriceable check; ``metadata=False``
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
438
|
+
(`validate_vault`'s default) skips the display metadata (`token_symbols`,
|
|
439
|
+
`token_decimals`, the ERC20 holdings' symbols) but not the asset's symbol and
|
|
440
|
+
decimals or the decimals valuation needs; ``metadata=True`` reads it in one cached
|
|
441
|
+
Multicall3 batch that also names the ERC20 holdings. Add a new chain-state input to the snapshot, never a
|
|
435
442
|
read inside a renderer or validator.
|
|
436
443
|
- PlasmaVault serves governance/view functions via `fallback()` delegatecall to
|
|
437
444
|
PlasmaVaultBase, so Etherscan's ABI for the vault address omits callable
|
|
@@ -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:
|
|
@@ -65,14 +69,15 @@ chain is always the context's:
|
|
|
65
69
|
the vault address (not a `PlasmaVault`) and no `chain_id`. It resolves one block
|
|
66
70
|
(``block``, else a numeric `ctx.default_block`, else the latest) and runs every
|
|
67
71
|
read, log scans included, on `ctx.at_block(block)`; `ctx` is not modified. The old
|
|
68
|
-
``chain_id=0`` switch is ``lending=False``; ``metadata=False``
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
+
``chain_id=0`` switch is ``lending=False``; ``metadata=False`` skips the
|
|
73
|
+
display metadata: `token_symbols` and `token_decimals` stay empty and the ERC20
|
|
74
|
+
holdings' symbols are `"?"`. The underlying asset's symbol and decimals and the
|
|
75
|
+
decimals the valuation needs are still read. With ``metadata=True`` the holdings
|
|
76
|
+
are named by the same cached, batched read as `token_symbols`. `VaultData` gains `vault`, `chain_id`, `market_balances`, `erc20`,
|
|
72
77
|
`token_symbols` and `token_decimals`; `WithdrawManagerData` gains
|
|
73
78
|
`shares_to_release_assets` and `pending_request_assets`.
|
|
74
79
|
- `validate_vault(ctx, vault, *, block=None, metadata=False)` fetches (by default
|
|
75
|
-
without
|
|
80
|
+
without display metadata) and validates; it no longer takes ``resolve_symbol``.
|
|
76
81
|
``metadata=True`` names the ERC20 holdings in the result and its findings. `validate_vault_state(state)` is
|
|
77
82
|
pure: a custom `VaultState` also provides `vault`, `chain_id`, `market_balances`,
|
|
78
83
|
`erc20` and the queue's `shares_to_release_assets`. `read_erc20_holdings` is gone:
|
|
@@ -109,8 +114,13 @@ now shown in share decimals labelled `shares` (``fusion vault info``) and its JS
|
|
|
109
114
|
`Web3Context.from_url(..., max_concurrent_requests=8)` bounds the RPC requests in
|
|
110
115
|
flight across every thread using the context (``None`` lifts the bound); the vault
|
|
111
116
|
reads fan out on nested thread pools, and the bound is what a rate-limited provider
|
|
112
|
-
sees.
|
|
113
|
-
|
|
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)`.
|
|
114
124
|
|
|
115
125
|
`ensure_supported_chain` takes `ChainId`. `fetch_unpriceable_priced_tokens` takes the oracle and
|
|
116
126
|
underlying as `ChecksumAddress`. `resolve_token_symbol`, `resolve_token_decimals`,
|
|
@@ -196,7 +206,13 @@ keyword arguments only. `ZERO_ADDRESS` is a `ChecksumAddress` (same value).
|
|
|
196
206
|
`HYPERCORE_PENDING_READERS` are keyed by `ChainId` (`HYPEREVM_CHAIN_ID` is one) and
|
|
197
207
|
`explorer.SUPPORTED_CHAINS` is a `frozenset[ChainId]`, so
|
|
198
208
|
`ensure_supported_chain(CHAIN_NAME_TO_ID["ethereum"])` type-checks;
|
|
199
|
-
`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`
|
|
200
216
|
is gone: market 50 is `IporFusionMarkets.EXTERNAL_STATE`. `MORPHO_BLUE_ADDRESS` is
|
|
201
217
|
gone: use `morpho_blue_address(chain_id)`.
|
|
202
218
|
|
|
@@ -252,8 +268,10 @@ except below): `chain_id` fields are `ChainId`, `role_id` `RoleId`, `market_id`
|
|
|
252
268
|
`MarketId`. Calling an MCP tool function directly from Python takes `ChainId`.
|
|
253
269
|
|
|
254
270
|
**Fuse base.** `Fuse`, `StakeFuse` and the shared validators and substrate packers
|
|
255
|
-
|
|
256
|
-
`ipor_fusion` re-
|
|
271
|
+
moved to `ipor_fusion.core.fuse`. Import `Fuse` and `StakeFuse` from `ipor_fusion`
|
|
272
|
+
or `ipor_fusion.fuses`. `ipor_fusion.fuses.base` still re-exports them in 4.0, but
|
|
273
|
+
it is a submodule of a public subpackage and therefore internal (see the README,
|
|
274
|
+
*Public API and stability*); so are the underscore validators and packers. Fuse equality and
|
|
257
275
|
hash now cover every attribute a fuse stores, not only its class and address (see
|
|
258
276
|
[Behavior changes](#behavior-changes)).
|
|
259
277
|
|
|
@@ -266,9 +284,7 @@ unchanged.
|
|
|
266
284
|
| 3.x import | 4.0 import |
|
|
267
285
|
|---|---|
|
|
268
286
|
| `ipor_fusion.fuses.crosschain` | `ipor_fusion.crosschain.fuses` (or `ipor_fusion.crosschain`) |
|
|
269
|
-
| `ipor_fusion.fuses.crosschain.base` | `ipor_fusion.crosschain.fuses
|
|
270
|
-
| `ipor_fusion.fuses.crosschain.ccip` | `ipor_fusion.crosschain.fuses.ccip` |
|
|
271
|
-
| `ipor_fusion.fuses.crosschain.stargate` | `ipor_fusion.crosschain.fuses.stargate` |
|
|
287
|
+
| `ipor_fusion.fuses.crosschain.base`, `.ccip`, `.stargate` | `ipor_fusion.crosschain.fuses` (its submodules `base`, `ccip` and `stargate` exist but are internal) |
|
|
272
288
|
| `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 ...` |
|
|
273
289
|
|
|
274
290
|
`ipor_fusion.crosschain` now exports the whole crosschain surface: besides the
|
|
@@ -279,8 +295,9 @@ the transports and chains, `discover_deployment`, `open_lane(s)`, `LANES` and
|
|
|
279
295
|
and wrappers.
|
|
280
296
|
|
|
281
297
|
**Moved, still importable.** `FuseAction` lives in `ipor_fusion.core.fuse_action` and
|
|
282
|
-
`ZERO_ADDRESS` in `ipor_fusion.types`; both
|
|
283
|
-
`ipor_fusion.fuses
|
|
298
|
+
`ZERO_ADDRESS` in `ipor_fusion.types`; import both from `ipor_fusion` (`FuseAction`
|
|
299
|
+
also from `ipor_fusion.fuses`, `ZERO_ADDRESS` from the public module
|
|
300
|
+
`ipor_fusion.types`). The internal `ipor_fusion.fuses.base` still re-exports them. The CLI's internal
|
|
284
301
|
`ipor_fusion.cli.vault_cmd` was split into `options`, `vault_info_view`,
|
|
285
302
|
`vault_markets_view` and `oracle_mapping_view` (private names, not API).
|
|
286
303
|
|
|
@@ -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.dev126
|
|
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
|
|
|
@@ -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 (
|
|
@@ -69,11 +69,13 @@ from ipor_fusion.core.rewards_manager import RewardsManager, VestingData
|
|
|
69
69
|
from ipor_fusion.core.simulation import (
|
|
70
70
|
SimulatedCallResult,
|
|
71
71
|
SimulationResult,
|
|
72
|
+
StateOverrideProvider,
|
|
72
73
|
VaultSimulator,
|
|
73
74
|
erc20_balance_slot,
|
|
74
75
|
is_simulate_v1_supported,
|
|
75
76
|
)
|
|
76
77
|
from ipor_fusion.core.withdraw_manager import (
|
|
78
|
+
AccountRequest,
|
|
77
79
|
PendingRequestsInfo,
|
|
78
80
|
WithdrawManager,
|
|
79
81
|
WithdrawRequestInfo,
|
|
@@ -183,6 +185,7 @@ from ipor_fusion.crosschain import (
|
|
|
183
185
|
encode_oft_compose_msg,
|
|
184
186
|
fetch_verifier_result,
|
|
185
187
|
find_ccip_events,
|
|
188
|
+
log_bytes,
|
|
186
189
|
lz_compose_calldata,
|
|
187
190
|
lz_receive_calldata,
|
|
188
191
|
manual_execution,
|
|
@@ -332,9 +335,14 @@ from ipor_fusion.morpho_api import (
|
|
|
332
335
|
fetch_vault,
|
|
333
336
|
)
|
|
334
337
|
from ipor_fusion.readers import (
|
|
338
|
+
HYPERCORE_MARKET,
|
|
339
|
+
HYPERCORE_PENDING_READERS,
|
|
340
|
+
HYPEREVM_CHAIN_ID,
|
|
335
341
|
AaveV3FuseReader,
|
|
336
342
|
AaveV3PoolAddressesProvider,
|
|
343
|
+
AaveV3PositionBreakdown,
|
|
337
344
|
AaveV3Reader,
|
|
345
|
+
AaveV3ReserveTokens,
|
|
338
346
|
AaveV3UserAccountData,
|
|
339
347
|
AaveV4OracleReader,
|
|
340
348
|
AaveV4SpokeReader,
|
|
@@ -375,6 +383,7 @@ from ipor_fusion.readers import (
|
|
|
375
383
|
PositionData,
|
|
376
384
|
RamsesV2Position,
|
|
377
385
|
RamsesV2Reader,
|
|
386
|
+
TransferDirection,
|
|
378
387
|
UniswapV3Position,
|
|
379
388
|
UniswapV3Reader,
|
|
380
389
|
VaultLendingHealth,
|
|
@@ -404,6 +413,7 @@ from ipor_fusion.types import (
|
|
|
404
413
|
AssetId,
|
|
405
414
|
AssetSource,
|
|
406
415
|
ChainId,
|
|
416
|
+
Check,
|
|
407
417
|
CommandId,
|
|
408
418
|
Decimals,
|
|
409
419
|
DeploymentRequestId,
|
|
@@ -432,12 +442,14 @@ from ipor_fusion.types import (
|
|
|
432
442
|
ProposalId,
|
|
433
443
|
ReturnRequestId,
|
|
434
444
|
RoleId,
|
|
445
|
+
Severity,
|
|
435
446
|
Shares,
|
|
436
447
|
StargateAssetId,
|
|
437
448
|
Tick,
|
|
438
449
|
TokenId,
|
|
439
450
|
TransferId,
|
|
440
451
|
TxHash,
|
|
452
|
+
Verdict,
|
|
441
453
|
parse_access_manager_address,
|
|
442
454
|
parse_fuse_address,
|
|
443
455
|
parse_hex_address,
|
|
@@ -497,6 +509,7 @@ __all__ = [
|
|
|
497
509
|
"read_changelog",
|
|
498
510
|
"repository_url",
|
|
499
511
|
"Web3Context",
|
|
512
|
+
"InFlightLimit",
|
|
500
513
|
"Call",
|
|
501
514
|
"get_logs_adaptive",
|
|
502
515
|
"find_creation_block",
|
|
@@ -504,6 +517,7 @@ __all__ = [
|
|
|
504
517
|
"Multicall3",
|
|
505
518
|
"MULTICALL3_ADDRESS",
|
|
506
519
|
"VaultSimulator",
|
|
520
|
+
"StateOverrideProvider",
|
|
507
521
|
"SimulationResult",
|
|
508
522
|
"SimulatedCallResult",
|
|
509
523
|
"is_simulate_v1_supported",
|
|
@@ -517,6 +531,7 @@ __all__ = [
|
|
|
517
531
|
"VestingData",
|
|
518
532
|
"ERC20",
|
|
519
533
|
"WithdrawManager",
|
|
534
|
+
"AccountRequest",
|
|
520
535
|
"FeeAccount",
|
|
521
536
|
"FeeManager",
|
|
522
537
|
"RecipientFee",
|
|
@@ -563,6 +578,7 @@ __all__ = [
|
|
|
563
578
|
"CcipChain",
|
|
564
579
|
"CrosschainSimulator",
|
|
565
580
|
"CrosschainLane",
|
|
581
|
+
"log_bytes",
|
|
566
582
|
"StargateLane",
|
|
567
583
|
"CcipLane",
|
|
568
584
|
"LaneFuses",
|
|
@@ -820,12 +836,17 @@ __all__ = [
|
|
|
820
836
|
"morpho_blue_address",
|
|
821
837
|
"AaveV3FuseReader",
|
|
822
838
|
"AaveV3PoolAddressesProvider",
|
|
839
|
+
"AaveV3PositionBreakdown",
|
|
823
840
|
"AaveV3Reader",
|
|
841
|
+
"AaveV3ReserveTokens",
|
|
824
842
|
"AaveV3UserAccountData",
|
|
825
843
|
"AaveV4OracleReader",
|
|
826
844
|
"AaveV4SpokeReader",
|
|
827
845
|
"AaveV4UserAccountData",
|
|
828
846
|
"CompoundV3Reader",
|
|
847
|
+
"HYPERCORE_MARKET",
|
|
848
|
+
"HYPERCORE_PENDING_READERS",
|
|
849
|
+
"HYPEREVM_CHAIN_ID",
|
|
829
850
|
"HyperCoreAccountMarginSummary",
|
|
830
851
|
"HyperCoreActionClass",
|
|
831
852
|
"HyperCoreEvmExitCeiling",
|
|
@@ -843,6 +864,7 @@ __all__ = [
|
|
|
843
864
|
"HyperCoreTransferOutcome",
|
|
844
865
|
"HyperCoreTransferSnapshot",
|
|
845
866
|
"HyperCoreTransferStatus",
|
|
867
|
+
"TransferDirection",
|
|
846
868
|
"compare_hypercore_transfer",
|
|
847
869
|
"read_hypercore_evm_exit_ceiling",
|
|
848
870
|
"read_hypercore_transfer_outcome",
|
|
@@ -871,6 +893,9 @@ __all__ = [
|
|
|
871
893
|
"Erc20Holding",
|
|
872
894
|
"Erc20Holdings",
|
|
873
895
|
"Finding",
|
|
896
|
+
"Severity",
|
|
897
|
+
"Verdict",
|
|
898
|
+
"Check",
|
|
874
899
|
"Reconciliation",
|
|
875
900
|
"UnpriceableToken",
|
|
876
901
|
"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
|
{ipor_fusion-4.0.0.dev120 → ipor_fusion-4.0.0.dev126}/src/ipor_fusion/crosschain/__init__.py
RENAMED
|
@@ -101,6 +101,7 @@ from ipor_fusion.crosschain.fuses.stargate import (
|
|
|
101
101
|
StargateSendParams,
|
|
102
102
|
)
|
|
103
103
|
from ipor_fusion.crosschain.lane import CrosschainLane, LaneFuses, LaneObservation
|
|
104
|
+
from ipor_fusion.crosschain.logs import log_bytes
|
|
104
105
|
from ipor_fusion.crosschain.messages import (
|
|
105
106
|
CCIP_VERSION,
|
|
106
107
|
CODEC_VERSION,
|
|
@@ -173,6 +174,7 @@ __all__ = [
|
|
|
173
174
|
"open_lane",
|
|
174
175
|
"open_lanes",
|
|
175
176
|
"CrosschainLane",
|
|
177
|
+
"log_bytes",
|
|
176
178
|
"LaneFuses",
|
|
177
179
|
"LaneObservation",
|
|
178
180
|
"CrosschainSimulator",
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
from ipor_fusion.readers.aave_v3 import (
|
|
2
2
|
AaveV3FuseReader,
|
|
3
3
|
AaveV3PoolAddressesProvider,
|
|
4
|
+
AaveV3PositionBreakdown,
|
|
4
5
|
AaveV3Reader,
|
|
6
|
+
AaveV3ReserveTokens,
|
|
5
7
|
AaveV3UserAccountData,
|
|
6
8
|
)
|
|
7
9
|
from ipor_fusion.readers.aave_v4 import (
|
|
@@ -11,6 +13,9 @@ from ipor_fusion.readers.aave_v4 import (
|
|
|
11
13
|
)
|
|
12
14
|
from ipor_fusion.readers.compound_v3 import CompoundV3Reader
|
|
13
15
|
from ipor_fusion.readers.hypercore import (
|
|
16
|
+
HYPERCORE_MARKET,
|
|
17
|
+
HYPERCORE_PENDING_READERS,
|
|
18
|
+
HYPEREVM_CHAIN_ID,
|
|
14
19
|
HyperCoreAccountMarginSummary,
|
|
15
20
|
HyperCoreActionClass,
|
|
16
21
|
HyperCoreNav,
|
|
@@ -35,6 +40,7 @@ from ipor_fusion.readers.hypercore_outcome import (
|
|
|
35
40
|
HyperCoreTransferOutcome,
|
|
36
41
|
HyperCoreTransferSnapshot,
|
|
37
42
|
HyperCoreTransferStatus,
|
|
43
|
+
TransferDirection,
|
|
38
44
|
compare_hypercore_transfer,
|
|
39
45
|
read_hypercore_evm_exit_ceiling,
|
|
40
46
|
read_hypercore_transfer_outcome,
|
|
@@ -80,12 +86,17 @@ __all__ = [
|
|
|
80
86
|
"morpho_blue_address",
|
|
81
87
|
"AaveV3FuseReader",
|
|
82
88
|
"AaveV3PoolAddressesProvider",
|
|
89
|
+
"AaveV3PositionBreakdown",
|
|
83
90
|
"AaveV3Reader",
|
|
91
|
+
"AaveV3ReserveTokens",
|
|
84
92
|
"AaveV3UserAccountData",
|
|
85
93
|
"AaveV4OracleReader",
|
|
86
94
|
"AaveV4SpokeReader",
|
|
87
95
|
"AaveV4UserAccountData",
|
|
88
96
|
"CompoundV3Reader",
|
|
97
|
+
"HYPERCORE_MARKET",
|
|
98
|
+
"HYPERCORE_PENDING_READERS",
|
|
99
|
+
"HYPEREVM_CHAIN_ID",
|
|
89
100
|
"HyperCoreAccountMarginSummary",
|
|
90
101
|
"HyperCoreActionClass",
|
|
91
102
|
"HyperCoreNav",
|
|
@@ -105,6 +116,7 @@ __all__ = [
|
|
|
105
116
|
"HyperCoreTransferOutcome",
|
|
106
117
|
"HyperCoreTransferSnapshot",
|
|
107
118
|
"HyperCoreTransferStatus",
|
|
119
|
+
"TransferDirection",
|
|
108
120
|
"compare_hypercore_transfer",
|
|
109
121
|
"read_hypercore_evm_exit_ceiling",
|
|
110
122
|
"read_hypercore_transfer_outcome",
|
|
@@ -245,9 +245,10 @@ def validate_vault(
|
|
|
245
245
|
else the context's numeric default block, else the latest) and validate
|
|
246
246
|
it; ``ctx`` itself is not modified.
|
|
247
247
|
|
|
248
|
-
The checks need no
|
|
249
|
-
|
|
250
|
-
cached
|
|
248
|
+
The checks need no display metadata, so by default the snapshot has no
|
|
249
|
+
`token_symbols` / `token_decimals` and the ERC20 holdings are named
|
|
250
|
+
``"?"``; ``metadata=True`` adds one batched, cached read that names them
|
|
251
|
+
in the holdings and findings."""
|
|
251
252
|
return validate_vault_state(
|
|
252
253
|
fetch_vault_data(ctx, vault, block=block, metadata=metadata)
|
|
253
254
|
)
|
|
@@ -549,8 +549,10 @@ def fetch_vault_data(
|
|
|
549
549
|
``lending=False`` skips lending health, the Morpho / Aave position
|
|
550
550
|
breakdowns, their token prices and the unpriceable-token check.
|
|
551
551
|
``metadata=False`` skips the token symbols and decimals the ``vault info``
|
|
552
|
-
document shows (validation does not need them) and
|
|
553
|
-
the ERC20 holdings are
|
|
552
|
+
document shows (validation does not need them): `token_symbols` and
|
|
553
|
+
`token_decimals` stay empty and the ERC20 holdings are named ``"?"``. The
|
|
554
|
+
underlying asset's symbol and decimals and the decimals the valuation needs
|
|
555
|
+
are read either way.
|
|
554
556
|
|
|
555
557
|
Raises `UnsupportedChainError` on a chain the tooling is not validated on
|
|
556
558
|
and `UnsupportedVaultVersionError` when the vault predates a getter the
|