SDK
Install, connect and execute with the Python SDK; the CLI, MCP server, agent skills, examples and module reference.
The official Python SDK for IPOR Fusion (pip install ipor-fusion; PyPI (opens in new tab), source (opens in new tab)). Use it to create vaults, construct contract calls, encode calldata and submit transactions through a configured signer — the only one of Fusion's public interfaces that can write, not just read (see MCP and the API for read-only surfaces).
For the full first-vault walkthrough, see Deploy your first Fusion vault. For revert selectors and the role table, see Common errors.
Install
pip install ipor-fusion
Connect and execute
from ipor_fusion import Web3Context, PlasmaVault, AaveV3SupplyFuse
from web3 import Web3
# 1. Create a Web3 context with your provider and private key
ctx = Web3Context.from_url(
url="https://arb-mainnet.g.alchemy.com/v2/YOUR_KEY",
private_key="0x...",
)
# 2. Wrap the PlasmaVault contract
vault = PlasmaVault(ctx, Web3.to_checksum_address("0xVAULT_ADDRESS"))
# 3. Build a fuse action (e.g. supply USDC to Aave V3)
fuse = AaveV3SupplyFuse(Web3.to_checksum_address("0xFUSE_ADDRESS"))
action = fuse.supply(
asset=Web3.to_checksum_address("0xUSDC_ADDRESS"),
amount=1_000_000, # 1 USDC (6 decimals)
)
# 4. Execute on-chain (execute() returns a Call; .send() signs and submits it)
receipt = vault.execute([action]).send()
Fuse, factory and manager addresses per chain are published in ipor-abi (opens in new tab) (mainnet/mainnet-<chain>-fusion/addresses.json) — see also Addresses. A fuse must also be registered on the vault; vault.get_fuses().call() lists the registered ones. Amounts are raw on-chain integers (Amount, Shares in ipor_fusion.types); the SDK never scales by decimals.
Read, send, or simulate
Every wrapper method returns a Call instead of executing immediately. The same Call powers all three modes — this is the SDK's read-only-vs-transaction-sending surface:
from ipor_fusion import VaultSimulator
total = vault.total_assets().call() # eth_call -> Amount, no key needed
receipt = vault.execute([action]).send() # signed tx -> TxReceipt, needs a private key
payload = vault.execute([action]).calldata # raw bytes for an external signer
# Simulate first via eth_simulateV1 (no local node); alpha is the account allowed to call execute()
sim = VaultSimulator(ctx.web3, vault=vault.address, alpha=Web3.to_checksum_address("0xALPHA"))
sim.observe("before", vault.total_assets())
sim.execute([action])
sim.observe("after", vault.total_assets())
result = sim.run()
if result.all_success:
print(result.get("after") - result.get("before"))
.send() signs locally and requires a private key in the Web3Context; .call() and .calldata need none — sending through a keyless context raises ValueError.
CLI: fusion
The SDK ships a fusion CLI for inspecting Plasma Vaults from the terminal — it does not deploy, configure or execute; that's the SDK's job above.
# Install with CLI extras (pipx keeps dependencies isolated)
pipx install 'ipor-fusion[cli]'
# Configure an RPC provider (auto-detects chain ID)
fusion config set-provider https://arb-mainnet.g.alchemy.com/v2/YOUR_KEY
# Inspect a vault (auto-saves to config on first use)
fusion vault info 0xB8a451107A9f87FDe481D4D686247D6e43Ed715e --chain-id ethereum
# List saved vaults
fusion vault list
# Inspect a Morpho Blue market or MetaMorpho vault
fusion market morpho-blue 0xMARKET_ID --chain ethereum
fusion market meta-morpho 0xVAULT_ADDRESS --chain ethereum
MCP: fusion-mcp
Two ways to reach Fusion from an MCP-compatible client — see MCP for the hosted server's full tool/resource/prompt reference.
- Hosted, no install:
https://mcp.ipor.io/mcp— public, unauthenticated, read-only. - Local, from the SDK:
pipx install 'ipor-fusion[mcp]'ships afusion-mcpserver that exposes the same CLI over MCP, against your own RPC providers and local config, plus the resourcesfusion://glossary,fusion://architecture,fusion://invariantsandfusion://quickstart, and the promptsquickstart,deploy_vault,analyze_vault,trace_oracle_pricingandexplain_fuse.
{
"mcpServers": {
"ipor-fusion": { "command": "fusion-mcp", "type": "stdio" }
}
}
Agent skills
skills/ipor-deploy-vault/SKILL.md (opens in new tab) teaches a coding agent the full clone -> roles -> market -> access posture -> deposit -> execute walk, with the invariants and the revert selectors, before it writes vault code — the same text as fusion://invariants / fusion://quickstart and Common errors, one text with several delivery paths. One install per machine:
# Claude Code -- plugin with the skill and the hosted MCP server
/plugin marketplace add IPOR-Labs/ipor-fusion.py
/plugin install ipor-fusion@ipor-fusion
# Codex CLI, Gemini CLI, Cursor -- the skill; add the MCP server as shown above
npx skills add IPOR-Labs/ipor-fusion.py -g -a codex # or gemini-cli, cursor
Vault construction examples
Runnable, canonical examples for building and configuring a vault from scratch live in examples/ (opens in new tab). They preview and simulate through eth_simulateV1 — nothing is ever signed or broadcast.
- Simple Aave V3 supply vault (opens in new tab) — start here for vault creation, role bootstrap, and configuring a single supported market.
- Advanced Euler V2 credit-market vault (opens in new tab) — continue here for composing multiple functional fuses, typed Euler substrates and sub-accounts, and an ordered collateral -> borrow -> repay -> unwind lifecycle.
For a strategy bot that operates an existing vault end to end, see ipor-fusion-alpha-example (opens in new tab).
Architecture
The SDK uses a fuse adapter pattern: Fuses encode protocol-specific calls into FuseAction objects (pure calldata, no state); PlasmaVault batches and executes FuseAction sequences on-chain via execute() (atomically); Web3Context manages provider connections, signing and transaction dispatch; Call is the lazy result of every wrapper method.
Fuse.method() --> FuseAction --> PlasmaVault.execute([actions]) --> Call --> .send() / simulate
Core modules (ipor_fusion.core)
| Module | Purpose |
|---|---|
Web3Context | Provider connection, signing, tx dispatch, gas estimation |
Call | Pre-encoded contract call; .call(), .send(), .calldata, .build_transaction() |
PlasmaVault | ERC-4626 vault — execute, deposit, withdraw, fuse and market configuration |
VaultSimulator | Batch execute + reads through eth_simulateV1, multi-block, no local node |
FusionFactory | Deploy a new vault (clone, clone_supervised) |
AccessManager | Role-based access control |
RewardsManager | Claim and vest rewards |
WithdrawManager | Time-windowed withdrawal requests |
FeeManager | Deposit, performance, and management fee configuration |
PriceOracleMiddleware / PriceOracleMiddlewareManager | Asset price feeds and per-vault overrides |
ERC20 | Token reads and approvals |
Supported protocols (ipor_fusion.fuses)
Aave V3, Morpho, Euler V2, Uniswap V3, Ramses V2, Compound V3, Gearbox V3, ERC-4626, Fluid Instadapp, Merkl, plus a Universal Token Swapper fuse. Full class list in the README (opens in new tab).
Supported networks
Ethereum, Arbitrum, Base, Unichain, Plasma, Avalanche, Katana, Monad and HyperEVM.
Development and contributing
Contributor and coding-agent instructions (commands, conventions, invariants, domain rules) live in AGENTS.md (opens in new tab) in the repository.