Skip to content

v0.8.0

Latest

Choose a tag to compare

@iamalwaysuncomfortable iamalwaysuncomfortable released this 23 Oct 17:17
79e280b

This release adds private record inventory to the core SDK and Shield Swap: a view of an account's spendable records, a planner for the joins and splits that reach a chosen layout, and a shared reservation journal that keeps concurrent writers from spending the same record. It is a port of Veil PR #172 without the CLI.

python -m pip install aleo-sdk==0.8.0
python -m pip install aleo-contract-abi-generator==0.8.0
python -m pip install "shield-swap-sdk[async,mcp]==0.8.0"
python -m pip install "aleo-bridge-sdk[mcp]==0.8.0"

Core SDK

Record inventory

One transaction spends whole records, so a large payment needs one record that covers it and several payments submitted together need one record each. The new aleo.inventory module reads an asset's spendable records, plans the joins and splits that reach a target layout, and executes that plan one confirmed transaction at a time, over credits.aleo and ARC-20/ARC-22 tokens. The actions keep Veil's names in snake_case: get_record_inventory, plan_record_inventory, rebalance_record_inventory, reconcile_record_inventory, join_records, split_record, and auto_join.

  • RecordInventory and AsyncRecordInventory behave identically; one engine drives both. Delegated proving is the default, and proving="local" proves in process.
  • The planner follows Veil's and passes Veil's planner tests. It differs in one case: when halving a record would leave a lot below the minimum, the split cuts whole lots instead, so a reachable target is never rejected (#83). Every plan Veil accepts is unchanged.
  • The join-helper registry covers the credits and stablecoin static helpers and the main_/test_aj_arc20_2_15.aleo dynamic routers. Each helper is checked against its deployed signature before use.
  • The journal is a RecordInventoryStore, a three-method protocol (list, acquire, update), so it can live in any backend. Three ship with the SDK. MemoryRecordInventoryStore lasts for one process. JsonFileRecordInventoryStore(path) keeps one JSON file under a file lock and can be read in an editor. SqliteRecordInventoryStore(path) uses the standard library's sqlite3 with the same table layout and row JSON as Veil's store, so the two SDKs can share a journal; scope strings match Veil's. The two file-backed stores release a reservation left by an SDK process on the same machine that exited before proving, and keep entries a Veil wallet wrote.

Managed writes on the facade

Enable record management on a client and every write reserves its record inputs before proving, so writers that share a journal never spend the same record. Build the client with Aleo(provider, record_management=RecordManagementConfig(enabled=True, store=...)); aleo.inventory is the same journal. The journal follows the two halves of a write: build_transaction reserves the inputs and saves the proved transaction, submit_transaction records the broadcast, transact is the two in sequence, and delegate does both through the prover (it asks the prover not to broadcast and submits from the SDK). TransactionResult.discard() releases a built transaction that was never sent. Under a private fee, the fee record is chosen once the exact fee is known, held in the same journal entry as the execution inputs, checked against the proved transaction, and kept after a rejected execution. Clients that do not enable record management behave as before.

The rules that protect funds: a record another writer holds raises RecordReservationConflictError before any proof is built. A broadcast the node refuses outright on its first attempt releases the reservation. A timeout, a lost response, a 5xx, or a refusal that follows one of those keeps it, because the transaction may be in the node; reconcile_record_inventory() settles such a spend against the chain. discard() does nothing once a broadcast has started, and submit_transaction refuses a result that was discarded. Overlapping submissions of one result are counted, so a duplicate refused while the first request is pending releases nothing.

Other

  • AleoNetworkClient.submit_transaction and its async twin take retry= (default True). The managed broadcast makes single attempts so each outcome reaches the journal.
  • Nineteen new top-level exports: RecordInventory, RecordManagementConfig, the three stores, the plan and record types, InventoryError, and RecordReservationConflictError. Both stub files carry them.

Shield Swap SDK

  • dex.inventory is the facade's inventory. plan_inventory(token, target) and rebalance_inventory(...) target the token's underlying record program, the records a trader holds.
  • Record selection skips reserved nonces. With management enabled and automatic selection, a swap that loses its record to another writer moves to the next eligible record from the same scan, smallest first, before any proof is built. An explicit token_record is never replaced, and execution errors are never retried.
  • examples/concurrent-swaps/ rebalances to six equal USDCx records, submits six swaps at once, claims each output, and shows the recovery steps after an interruption, on the SQLite store.
  • import aleo_shield_swap raises an ImportError naming the pip upgrade when the installed aleo-sdk predates aleo.inventory. The aleo-sdk floor is >=0.8.0.
  • The agent guide gained plan_inventory and rebalance_inventory; its size budget is now 36k characters.

Verified on testnet with the e2e account (tests/integration/test_record_inventory_live.py): rebalance to six equal USDCx and ETH records, an explicit round trip followed by a seven-record stablecoin helper join, six concurrent swaps in each direction where all six first chose the same record and 15 reservation conflicts were resolved by reselection, every output claimed, and the journal reopened with 28 confirmed transactions and no input spent twice. The suite passed five times on 2026-10-23, the last run at the merged head.

Aleo Bridge SDK

Version bump. The aleo-sdk floor stays at >=0.7.0.

ABI generator

Version bump. sdk-abi/ stays on snarkvm 4.11.0 behind Leo's pin.

CI

sccache on the macOS and Windows wheel builds uses the current GitHub Actions cache API (#81).

The release contains record inventory #82, which includes the 0.8.0 version bump (#84), and #81.

Full diff: v0.7.0...v0.8.0