Releases: ProvableHQ/python-sdk
Release list
v0.6.1
This release extends the bridge package: ten new Hyperlane warp routes for BAT, USDG and ZEC between Aleo, Ethereum and Solana (including SPL-collateral transfers on Solana), and signing the Ethereum and Solana legs with Privy or Dynamic server wallets. The core SDK, the ABI generator and the Shield Swap SDK are version bumps only.
python -m pip install aleo-sdk==0.6.1
python -m pip install aleo-contract-abi-generator==0.6.1
python -m pip install "shield-swap-sdk[async,mcp]==0.6.1"
python -m pip install "aleo-bridge-sdk[mcp]==0.6.1"Aleo Bridge SDK
BAT, USDG and ZEC Hyperlane warp routes
Port of Veil #169.
- Registry version
2026-09-30.hyperlane-bat-usdg-zec.1adds eight assets (Aleo BAT/USDG/ZEC as ARC-22 tokens with theirshield_arc22_*programs, Ethereum BAT/USDG, Solana BAT/USDG/ZEC mints) and ten active mainnet routes, pinned from hyperlane-registrydd03567. Plans and checkpoints saved under the previous2026-09-28.cctp-arc.1snapshot stay valid for unchanged routes; an older client still rejects a newer registry version, so upgrade recovery services first. - Solana routes gain a
native | spl-collateralrouter type. SPL transfers use the 18-accountTransferRemotelayout (token program, mint, sender associated token account and escrow PDA), reproduced byte-for-byte from a recorded ZEC deposit, with escrow PDAs re-derived from each warp program. bridge.sol.quote / send / balance / statustakeasset=(SOL by default) and follow the plan's route. SPL quotes report fees in SOL and keep the token amount out oftotal_lamports;send()checks the sender's token account before broadcasting; Aleo-to-Solana SPL delivery is tracked through the recipient's associated token account.- Because BAT and USDG leave Aleo towards both Ethereum and Solana, Aleo-origin legs now resolve by route instead of by asset.
bridge.hyperlane.quote_gas_paymentandtransfer_remoteaccept an asset ref, aRouteor a route id. Hyperlane approval steps apply to EVM token sources only. examples/bridge_arc22_hyperlane.py --route <id>covers all ten directions with quote, execute, journal and recovery. Read-only live checks cover SPL quotes, Ethereum collateral routers and Solana program/mint/escrow layouts.- All ten routes were delivered end to end on mainnet before merge. Solana SPL legs cost about 0.0056 SOL each; Aleo-origin legs paid roughly 7.7 (to Solana) and 9.1 (to Ethereum) credits in interchain gas.
Privy and Dynamic server wallets
Port of Veil #170. A backend can now bridge without holding a chain private key by letting an existing server wallet sign the Ethereum or Solana leg. Both adapters use the providers' official Python SDKs (privy-client, dynamic-wallet-sdk), which install with the package; dynamic-wallet-sdk needs Python 3.11 or newer.
aleo_bridge.privy:PrivyEvmSignerandPrivySolanaSigner. EVM signs viaeth_signTransaction(type 2, or legacy when the connection preparedgasPrice) and recovers the sender from the returned transaction, refusing a mismatch. Solana wraps the compiled message in a wire transaction, rejects a response whose message changed, and verifies only the wallet's signature slot. Optionalauthorization_private_keyssupport owner policies.aleo_bridge.dynamic:DynamicEvmSignerandDynamicSolanaSigner. The Dynamic SDK is async-only, so the signers run it on a private loop thread, resolve the wallet by address (chain and optionalwallet_idchecked), and re-authenticate hourly. Dynamic signs legacy EVM transactions only, soEthereum.send_transactionhonours alegacy_transactions_onlysigner flag and preparesgasPricewith the same tip floor.- Both plug into the existing
Ethereum(rpc, signer=...)/Solana(rpc, signer=...)seam. TheBridgelifecycle, journal and recovery are unchanged, andsigner.resolve()is an optional fail-fast identity check. The adapters add no signing or broadcast retries. - Examples
privy_wallets.pyanddynamic_wallets.py(--chain ethereum|solana, quote by default,--executeto submit), README sections and a regenerated agent guide. Four mainnet transfers (ETH and SOL to Aleo, one per provider and chain) reacheddone.
Core SDK, ABI generator, Shield Swap SDK
- Version bump only (#77).
The release contains BAT, USDG and ZEC Hyperlane warp routes #75, Privy and Dynamic server wallets #76 and the 0.6.1 version bump #77.
Full diff: v0.6.0...v0.6.1
v0.6.0
This release upgrades the SDKs to snarkVM 4.11.0, derives the Varuna proof version from the chain instead of hardcoding it, and adds Arc xReserve and CCTP routes to the bridge package.
python -m pip install aleo-sdk==0.6.0
python -m pip install aleo-contract-abi-generator==0.6.0
python -m pip install "shield-swap-sdk[async,mcp]==0.6.0"
python -m pip install "aleo-bridge-sdk[mcp]==0.6.0"Core SDK
- Upgrades the crates.io snarkVM dependency from 4.10.0 to 4.11.0 in
aleo-sdk. - Derives the Varuna proof-system version from the consensus version active at the proving height, the same way snarkVM's ledger does. Previously the bindings proved with a fixed
VarunaVersion::V2, which fails verification once consensus V21 activates Varuna V3. - Adds
consensus_version(block_height=None)andvaruna_version(block_height=None)toaleo.mainnetandaleo.testnet. prove_execution()andprove_fee()accept an optionalblock_height. The Web3.py-style facade passes the chain head automatically on the hosted Provable API, so proofs and fee estimates use the version in force now rather than the newest one the network has scheduled.- When no height is available, the fallback resolves the newest scheduled version one block below
u32::MAX, matching how snarkVM parks unscheduled versions.
ABI generator
- Bumps
aleo-contract-abi-generatorto 0.6.0. It stays on snarkVM 4.10.0 because it must shareProcess/Programtypes with its pinned Leo revision, which still pins 4.10.0.
Aleo Bridge SDK
- Adds Arc support based on Veil #148: USDC/USDCx between Arc and Aleo through xReserve, and native-USDC CCTP V2 in all six directions between Arc and Ethereum, Base, and Arbitrum. All eight directions are mainnet routes.
- Selects the EVM connection by route. Existing
ethereum=andbridge.ethcalling forms and checkpoints for the 22 original routes keep working; usebridge.evm("arc")to read the Arc connection. Environment-based setup recognizesARC_RPC_URL,BASE_RPC_URL, andARBITRUM_RPC_URL. - Preserves CCTP fee ceilings through execution and recovery, quotes 10% default fee headroom without raising explicit or saved caps, and returns resumable approval-only progress when fees rise.
- Verifies source intent, Circle attestation, and the exact destination mint before reporting completion. Supports explicit manual minting, approval replacement, and durable broadcast checkpoints.
- Retries Circle 429/5xx and truncated responses while keeping malformed attestation evidence fatal. Scan cursors check block-hash anchors and restart safely after a process restart.
- Adds agent and MCP options, resumable Arc examples, deployment reads, and documentation for the new routes.
Shield Swap SDK
- Version bump only.
The release contains Arc xReserve and CCTP support #73 and snarkVM 4.11.0 upgrade #74.
Full diff: v0.5.1...v0.6.0
v0.5.1
This release adds the Python bridge package, makes the Shield Swap first-swap flow runnable from the installed package, and upgrades the SDKs to snarkVM 4.10.0.
python -m pip install aleo-sdk==0.5.1
python -m pip install aleo-contract-abi-generator==0.5.1
python -m pip install "shield-swap-sdk[async,mcp]==0.5.1"
python -m pip install "aleo-bridge-sdk[mcp]==0.5.1"Aleo Bridge SDK
aleo-bridge-sdk is now part of the Python SDK release. Import it as aleo_bridge to move supported assets between Aleo, Ethereum, and Solana.
- Supports Hyperlane routes for ETH, WBTC, USDT, and SOL, plus Circle xReserve routes between Ethereum USDC and Aleo USDCx.
- Provides
quote,execute,wait,get_status,recover,resume, andcompletelifecycle methods. - Saves versioned checkpoints without secrets so interrupted transfers can be recovered without submitting the source transaction again.
- Includes Ethereum and Solana clients, private USDCx delivery, freeze-list proofs, ARC-20 shield and unshield operations, agent tools, and an optional MCP server.
- Packages runnable examples for quotes, inbound and outbound transfers, shielding, and recovery. Start with
python -m aleo_bridge.examples.quote_transfer --help.
Shield Swap SDK
- Adds
quote()for direct and multi-hop routes. The returnedSwapQuotecan be passed directly toswap(quote). - Adds exact token-symbol lookup, decimal token amounts, swap-balance checks, and an explicit
confirm_airdrop()flow that waits for accepted transfers to become spendable records. - Packages a complete first-swap example. Run it with
python -m aleo_shield_swap.examples.first_swap.swap. - Makes the first account imported with
account.from_private_key()the default account when none is set. - Re-registers scanner accounts and retries once when owned-record reads return the scanner's unregistered-account response.
- Preserves swap recovery data before confirmation, waits for a confirmed swap output before preparing a claim when requested, and records confirmed claims in the journal automatically.
Core SDK and ABI generator
- Upgrades the crates.io snarkVM dependency from 4.9.1 to 4.10.0 across
aleo-sdkandaleo-contract-abi-generator. - Keeps delegated proving encryption available in the base
aleo-sdkinstallation.
The release contains Python Bridge SDK #71 and Shield Swap setup and snarkVM upgrade #72.
Full diff: v0.5.0...v0.5.1
v0.5.0
This release bumps aleo-sdk, aleo-contract-abi-generator, and shield-swap-sdk to 0.5.0. The big items are a move to snarkVM 4.9.1, mainnet support in shield-swap-sdk, and catching up with the September changes to the Shield Swap API. There are a number of breaking changes in shield-swap-sdk, so read that section before upgrading.
pip install aleo-sdk==0.5.0
pip install aleo-contract-abi-generator==0.5.0
pip install "shield-swap-sdk[async,mcp]==0.5.0"
aleo-sdk
The SDK now builds against snarkVM 4.9.1 from crates.io instead of the v4.8.1 git tag. This picks up consensus versions V18 and V19, which changed how deployments are priced. Previously the bindings hard-coded V17 for cost estimates, which would have underpriced deployments on both live networks. Now execution_cost, deployment_cost, verify_execution, and verify_fee look up the right consensus version from the network's activation table. They take an optional block_height if you want to price against a specific height, and the facade passes the chain head automatically when estimating fees.
The default API host is now https://edge.provable.com/api. It doesn't need an API key, consumer ID, or JWT for reads, the delegated prover, or the hosted record scanner. If you're on api.provable.com with credentials, nothing changes for you.
There's a new Deployment type, with Process.deploy and Process.deployment_cost to go with it.
The two credits conversion helpers, credits_to_microcredits and microcredits_to_credits, used to go through floating point and lose money on the way. 1.005 credits came out as 1,004,999 microcredits, for example. They now use Decimal and are exact. If you pass a value with sub-microcredit precision you'll get a ValueError unless you opt in with allow_rounding=True. from_microcredits returns a Decimal now rather than a float.
Codegen understands fixed-length arrays in ABIs. And most of the public surface that had no docstrings now does.
shield-swap-sdk
Breaking changes
Shield Swap retired a batch of API routes on September 8, so these ApiClient methods are gone: access_status, my_referral_codes, get_tick_spacings, get_swaps, get_swap, get_position, and get_public_balances. Swap and position details are now read from the chain. Tick spacing comes back with the fee tiers. referral_status() tells you whether an account has access and whether the session is alive.
Public balances are chain reads too. ShieldSwap.get_public_balances(programs, address=...) reads each token program's balances mapping directly, and get_balances() has an include_private flag.
Invite codes no longer exist. Signing in is the whole gate. onboard() takes referral_code= instead of invite_code=, and referral codes are optional. NotRedeemedError, redeem_access_code, and generate_access_codes are removed.
The API host is resolved per network. DEFAULT_API_URL is replaced by SHIELD_SWAP_API_URLS and api_url_for(network), and clients pick the host that matches the network they're connected to. SHIELD_SWAP_API_URL still overrides everything.
get_ohlcv takes unix seconds as integers for from_ts and to_ts. It used to accept strings, which the API rejected.
mint() takes a withdrawal address that's stored on the position NFT, and collect() always pays to it. The old recipient argument on collect() is gone.
Amounts are raw token units everywhere. No more 9-decimal normalization or dust rule.
What's new
This is a full cutover from shield_swap_v3.aleo to the deployed shield_swap.aleo. Nothing carries over from v3. The wire layer is regenerated from the deployed bytecode, tick math is Q128.128 with limits pinned from the contract, and freezelist proofs are wired in with empty-tree defaults.
Mainnet works. from_profile() takes network and endpoint, and the API host follows along. The airdrop step is testnet-only, so on mainnet onboard() raises NotFundedError and tells you to fund the account yourself.
Wrapped tokens are handled automatically. Every method checks whether each token is wrapped or plain and routes through the right router entrypoint, so you don't have to know which one to call.
You can now ask what positions you hold and what they're worth without sending a transaction. get_owned_positions() and get_owned_position(token_id) join your private position records with the public pool state and compute amounts and fees owed using the same math the contract uses.
Rebalancing is available on testnet through plan_rebalance and rebalance_position.
swap() is safe to call concurrently. It reserves its blinding counter under the journal lock and writes the claim handle to the journal as soon as the broadcast is accepted, so two swaps in flight can't collide, and a crash mid-swap doesn't lose the claim. Counter reservation also skips past counters already used on chain, so accounts with a lot of history don't hit a scan limit.
A quote failure is now an error rather than a silent fallback to a spot price that ignores the pool fee. That fallback used to produce minimums the pool couldn't pay, which meant paying for a proof that got rejected at finalize. swap_many accepts expected_out if you have your own price source.
get_swap_execution returns the header and per-hop fills for a swap. There are also wrappers for session management (get_session, refresh_session, list_sessions, revoke_session, logout, logout_all), compliance reads, batch pool stats, liquidity distribution, route topology, and referral issuance and reporting. DexApiError exposes the API's error code and ref.
Fixes
increase_liquidity was deriving its tick insert hints from the current slot, which only works for the first position in a pool. Every later call was rejected at finalize after the fee was spent. It now walks the on-chain tick list, the same way mint already did.
The async get_owned_positions wasn't awaiting the record scan and could never have worked.
Profile didn't expand ~, so SHIELD_SWAP_HOME=~/x created a literal ~ directory in the working directory and put the private key there.
Onboarding is idempotent under cookie auth, only reclaims stale tokens that have been idle for a day, and doesn't re-mint on repeated calls when you're at the token cap.
aleo-contract-abi-generator
The Leo crates are pinned to Leo master at c82f149e, which is the first Leo that uses snarkVM 4.9.1. That version of Leo also fixes a bug where record field modes were emitted swapped, so regenerated ABIs now correctly report record owners as private. The generate_abi type stub had three parameters when the function takes four; it's now generated from the Rust signature.
Testing
sdk: 884 unit tests plus the proving and devnode suites. sdk-abi: 8. shield-swap: 351 unit tests, the live read tier against testnet and mainnet, the devnode lifecycle, and the funded testnet write tier, which exercises real swaps and liquidity operations end to end. pyright strict is clean on both Python packages.
Full diff: v0.4.0...v0.5.0