v3.7.0
v3.7.0 adds SDK support for more of the External State market (market 50), which values capital held off-chain. It applies to teams that hold vault positions at off-chain venues. Python 3.10 is no longer supported: installs on 3.10 resolve to the last release that supports it.
New
1. Executor creation for off-chain positions
Now: ExternalStateOperationFuse.create_executor() builds the createExecutor() fuse action. The vault’s executor can be deployed without an enter.
Usage: ExternalStateOperationFuse.create_executor() returns the createExecutor() fuse action for an attestation-only External State setup.
2. Executor balance reads
Before: the attested balance was reachable only by hand-encoding the selector.
Now: ExternalStateExecutor.balances(account) returns the attested figure the custodians agree on, which the balance fuse aggregates into NAV. ExternalStateExecutor.last_updated(account) returns the time of the last confirmed custodian update for that account.
Usage: both methods take an account address. last_updated returns zero for an account that was never confirmed or was cleared when it left the substrate cache.
3. Substrate sync
Now: ExternalStateExecutor.sync_substrates() refreshes the executor’s substrate cache after market-50 grants or revokes.
Usage: sync_substrates() is called on the executor wrapper. Its docstring describes how a revoke differs from a grant for a funded balance account.
4. Balance proposal readers
Now: parse_balance_proposed(log) and find_balance_proposed(logs) read a BalanceProposal from the BalanceProposed event. Both accept only logs the executor emitted and check the proposal hash against the log’s own fields.
Usage: parse_balance_proposed takes one log. find_balance_proposed scans a list of logs. Hash verification takes an optional chain_id, which defaults to the chain of the wrapper’s context. Code with no context reaches both readers through encoder(address).
5. Off-chain margin example on Base
Now: examples/external_state_margin_leg_base.py builds a vault, parks USDC at an off-chain venue through the per-vault executor, and has two custodians propose and confirm its value. It then brings the margin home for a scheduled withdrawal and shows the executor rejecting a confirmation that does not match its proposal.
Usage: the example runs as two eth_simulateV1 batches. The first learns the executor address and the request’s share count. The second runs the lifecycle.
Breaking changes
1. Python 3.11 or newer
Before: the SDK supported Python 3.10.
Now: the SDK runs on Python 3.11 or newer. Installs on 3.10 resolve to the last release that supports it.
Applies to: environments that install the SDK on Python 3.10.
Fixes
1. NAV mark checks
Before: mark_nav caught custodian contexts on different chains only after the propose transaction had landed.
Now: mark_nav rejects custodian contexts on different chains before it sends the propose. It refuses to confirm unless the receipt records the value and proposer it sent and a proposal hash over those fields.
Impact: a chain mismatch between the proposer and confirmer contexts stops mark_nav before any transaction is sent.
Upgrade with pip install -U ipor-fusion. Full changelog: v3.7.0 on GitHub.
These notes describe changes to the IPOR Fusion SDK. They are not operational or financial advice. Operators are responsible for testing changes against their own vaults and configuration before use.