All Developer News

v3.7.0

SDK/CLI

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.