shield-swap-sdk: typed Python client for the shield_swap AMM - #49
Merged
Conversation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
snarkVM validation is contextual: a program whose imports are not loaded into the Process first is rejected (e.g. shield_swap_v3.aleo imports test_shield_swap_multisig_core.aleo). generate_abi now takes an optional (program_id, bytecode) list in topological order, loads each into the Process, then disassembles the target — same pattern leo-disassembler documents for multi-program validation. Python hook passes it through. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Pinned from the live testnet deployment (12 structs — two more than the TS package's snapshot: SwapIterCfg/SwapIterState; Slot is still Q64). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Live /pools responses carry undocumented token0_info/token1_info; the client builds models tolerantly (filter to declared fields) and reads token info via TokenDoc, which does document wrapper_program. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Poseidon8 blinding factor + blinded address with the 252-bit LE repacking (Plaintext::Array::to_fields_raw emulation), matching amm-v3-tests feat/q128 and the TS SDK's pinned vectors exactly. next_blinded_identity scans used_blinded_addresses for the first free counter. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nges) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rd selection Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… ladder, swap verb Reads decode mapping values via the generated classes (quoted/null node variants handled); swap resolves params against live pool state, derives the counter-scanned blinded identity, auto-selects the token record, and returns a DexCall whose transact/delegate build a complete SwapHandle (outputs pre-broadcast on transact; recovered from the confirmed transaction on delegate). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…check) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
create_pool (fee-tier validated pre-submit), mint (spacing-aligned range, generated MintPositionRequest encoder, slot-neighbor insert hints with the lower-inserted-first upper-hint rule), increase/decrease/collect/burn with PositionNFT auto-selection by pool. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Async covers reads, balances, and the two-transaction swap flow the agent/MCP layer needs; async liquidity verbs are a documented follow-up — the sync client has the full surface. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…xports - framework-neutral tool defs + dispatcher (writes run delegate) - FastMCP server behind [mcp] extra (sync client in worker threads) - live read tier: pools/slots + local-pool-key-vs-indexer invariant; drift test (pinned ABI vs deployed, via aleo.abi imports=) — both PASS against production; write tier gated on funded creds; devnode tier is an explicit module-level skip (record-version skew) - pyright caught mint's missing generate_field_nonce import (default-nonce path); test added Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… shapes, root-transition scoping Critical (all verbs were broken against a real facade; stubs had been shaped to the bugs): - register the DEX program, its static imports, and token wrapper programs with the snarkVM process before authorization (ensure_programs / register_program_sources; sync + async; imports= override now real) - TransactionResult.outputs is a property — transact() crashed with TypeError after proving; now uses decoded() - scope output harvesting to the ROOT transition (executions are child-first; first-field-output picked token-transfer outputs, stranding swap_id/position ids); delegate reads the confirmed tx's transitions High: - MCP: low-level Server with exact per-tool JSON schemas (FastMCP inference collapsed every tool to one opaque args object) - agent: expected_out=0 no longer treated as absent; full liquidity tool set (increase/decrease/collect/burn/create_pool) - get_balances no longer conflates the caller's private records into a third party's balance report - get_swap_output accepts the SwapHandle (spec surface); uninitialized pools raise PoolNotInitializedError, not PoolNotFoundError - create_pool rejects disabled fee tiers (value false, not just presence) Cleanup: - stubs now mirror real facade shapes (property outputs, decoded(), child-first transitions, process registration recorded) - async client: dead imports dropped, shared _core helpers (no duplicated selection/normalization logic), honest surface docstring - typed get_ohlcv (OhlcvDoc); untrack committed .pyc files; slow marker on the funded write-tier test Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Every read action against the live API + testnet chain: pools/tokens/ route/ohlcv/balances/swap-404 on the service side; pool/slot invariants, initialization, absent-entry errors on the chain side; pool-key and tick-key derivation parity against live state. ApiClient/AsyncApiClient gain the signature challenge/verify handshake (authenticate/set_token, bearer attachment). Route/OHLCV/balances are additionally invite-gated per account upstream — those tests authenticate with ALEO_E2E_PRIVATE_KEY when present and skip with the documented reason otherwise. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Directory and PyPI distribution are now both shield-swap-sdk; the import module stays aleo_shield_swap. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Process.deploy / Process.deployment_cost — synthesize and price a real deployment (V17 semantics: checksum + owner set). - Transaction.from_deployment — deployer signs program ownership over the deployment ID. - Deployment.from_program_unproven — dummy verifying key + certificate per function/record, mirroring the wasm SDK's buildDevnodeDeploymentTransaction; devnode-only (no key synthesis). - Execution/Fee.from_authorization_unproven — proofless transactions for devnodes, which skip proof verification. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Python analog of the TS suite's devnodeLifecycle.actions.e2e test: deploys the vendored shield_swap_v3 stack (proofless dummy-VK deployments), runs admin setup, then drives pools, liquidity, swaps + claims, collect, and burn through the ShieldSwap verbs with mappings asserted at every step. Two execution ladders: fully proven, or ALEO_DEVNODE_UNPROVEN=1 (fast, ~5 min end to end). Marked devnode; excluded from the default run. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kpandl
approved these changes
Jul 14, 2026
…generator), bump SDKs to 0.2.0 - Distribution names only; import modules stay aleo / aleo_abi / aleo_shield_swap. - aleo-sdk 0.2.0, aleo-contract-abi-generator 0.2.0, shield-swap-sdk 0.2.0 (shield-swap now depends on aleo-sdk>=0.2). - package_version() resolves aleo-sdk with a fallback to the pre-0.2 aleo dist so older installs keep reporting their real version. - Install hints, CI pip installs, and docs swept to the new names. - New README for the ABI package. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
shield-swap-sdk(new sibling package,shield-swap-sdk/): a typed Python client forshield_swap_v3.aleo, bound to the facade — the Python analog of aleo-viem's@provablehq/shield-swap-sdk. Built onaleo.codegen(#47). Also extends the ABI package (dist nowaleo-contract-abi-generator) with an optionalimports=parameter (snarkVM validation is contextual; the deployed contract importstest_shield_swap_multisig_core.aleo), and adds deployment + proofless-devnode APIs to the main SDK's bindings.Surface
aleo.codegenbindings):get_pool,get_slot(semanticSlotView: Q64price(),tick_range()),get_swap_output,is_pool_initialized; purederive_pool_key/derive_tick_key(BHP256, vector-verified against the TS SDK)simulate/transact/delegate) with a typed result:swap→claim_swap_output(two-transaction private flow, serializableSwapHandle),create_pool,mint,increase/decrease_liquidity,collect,burnused_blinded_addressescounter scandex.api: typed REST client for amm-api (generated OpenAPI models; pools/tokens/route/swaps/ohlcv/balances; challenge/verify JWT auth for the gated endpoints), sync + async[mcp]extra): all 12 verbs with exact JSON schemasAsyncShieldSwap: reads, balances, swap lifecycle (liquidity verbs are sync-only for now, documented)Renames + versions
Distribution names changed (imports unchanged): main SDK
aleo→aleo-sdk(imports asaleo),aleo-abi→aleo-contract-abi-generator(imports asaleo_abi), package dirsdk-shield-swap/→shield-swap-sdk/(distshield-swap-sdk, imports asaleo_shield_swap). All three SDKs are 0.2.0;package_version()falls back to the oldaleodist so existing installs report real versions. READMEs added for shield-swap-sdk and the ABI package.Main-SDK bindings (
sdk/src)Process.deploy/Process.deployment_cost— synthesize and price a real deployment (V17: checksum + owner)Transaction.from_deployment— deployer signs program ownership over the deployment IDDeployment.from_program_unproven— dummy VK + certificate per function/record, mirroring the wasm SDK'sbuildDevnodeDeploymentTransaction; devnode-only (skips ~14 min of key synthesis for the AMM)Execution/Fee.from_authorization_unproven— proofless transactions for devnodes, which skip proof verificationPinned upstream + drift safety
codegen/regen-abi.shregenerates the pinned ABI from the deployed program (fetches the import closure; that's the ABI-package change) and re-emits_generated.py;regen-openapi.shdoes the API models. A live-tier drift test (check_compatibility(deployed, pinned)) fails our CI on redeploys instead of consumers. The pinned ABI comes from the live deployment — two structs newer than the TS package's snapshot.Verification
outputs, child-first transitions, process registration)-m live): 10 passed, 3 skipped (invite-gated route/ohlcv/balances skip with a clear message) — pools/slots against testnet, local pool-key derivation matches the indexer's keys, ABI drift test green against production-m devnode): 9/9 green in ~5 min (ALEO_DEVNODE_UNPROVEN=1) — deploys the vendored stack proofless, then drives pools, liquidity, swaps + claims, collect, and burn end-to-end with mappings asserted at every step; Python analog of the TSdevnodeLifecycle.actions.e2esuite-m "live and slow", spends testnet funds) is credential-gated and not yet run — needsALEO_E2E_PRIVATE_KEY/ALEO_E2E_API_KEY/ALEO_E2E_CONSUMER_ID