Skip to main content

Python SDK for the shield swap AMM Dex on Aleo

Project description

shield-swap-sdk

Typed Python client for the shield_swap AMM on Aleo. Sits on top of the Aleo Python SDK's facade (aleo.Aleo): signer, record provider, proving configuration, and network all come from the client you bind — this package adds the DEX verbs, the typed results, and the off-chain DEX API, nothing else.

from aleo import Aleo
from aleo_shield_swap import ShieldSwap

aleo = Aleo(Aleo.HTTPProvider("https://api.provable.com"))
aleo.default_account = account
dex = ShieldSwap(aleo)

pools = dex.api.get_pools()                      # requires a live DEX API
handle = dex.swap(pool_key=pools[0].key,
                  token_in_id=pools[0].token0,
                  amount_in=10**9).delegate()    # broadcasts; spends funds
out = dex.claim_swap_output(handle).delegate()   # broadcasts; spends funds

Install

pip install -e shield-swap-sdk                 # from the repo root
pip install -e "shield-swap-sdk[async]"        # + AsyncShieldSwap (httpx)
pip install -e "shield-swap-sdk[mcp]"          # + the MCP server

Requires aleo-sdk>=0.2 (this repo's SDK; imports as aleo) and Python 3.10+.

Agents

AGENTS.md (generated from the SDK's docstrings — always current) is the one page an agent needs: the five-verb lifecycle, the conversation pattern, and the building-block reference. It ships in the wheel:

pip install shield-swap-sdk
python -m aleo_shield_swap          # prints the agent guide

Claude Code users get it via the shield-swap skill (packaged under aleo_shield_swap/skills/, copy into .claude/skills/); any MCP client can run the same lifecycle through python -m aleo_shield_swap.mcp.

How calls work

Every read returns a value immediately. Every write returns a prepared DexCall — nothing touches the network until you invoke a terminal verb:

call = dex.swap(pool_key=key, token_in_id=token, amount_in=10**9)

call.simulate()             # runs locally; no broadcast, no fee
call.transact(account)      # proves locally, broadcasts, pays the fee
call.delegate(account)      # proves via the delegated proving service

transact and delegate return the verb's typed result (a SwapHandle, MintResult, ClaimResult, …) built from the transaction's root-transition outputs — not a bare transaction id. Local proving downloads SNARK parameters on first use and takes minutes for the larger entrypoints; delegate is the practical path and requires DPS credentials on the provider (api_key=, network_client.consumer_id).

Chain reads and writes live directly on ShieldSwap; the off-chain DEX API is namespaced under .api, so a call site always shows whether a value came from the chain or the service.

The verb surface

Chain reads (node REST API):

Verb Returns
get_pool(pool_key) The pool struct from the pools mapping.
get_slot(pool_key) SlotView — current tick, sqrt price, liquidity, spacing.
get_swap_output(swap_id) The finalized swap outcome; raises SwapOutputNotFinalizedError until the finalize lands (and again after the claim consumes it).
is_pool_initialized(pool_key) Whether the pool exists on chain.
get_private_balances(programs) Summed unspent record amounts per token program (needs a registered record provider).
get_balances() Public + private balances in one shape.
derive_pool_key(token0, token1, fee) / derive_tick_key(pool_key, tick) Mapping keys derived locally — no network.

Writes (each returns a DexCall):

Verb What it does
swap(...) Phase one of the two-transaction private swap: locks the input record against a blinded identity. Returns a SwapHandle — persist it if the process might die before the claim.
claim_swap_output(handle) Phase two: claims the finalized output as a private record.
create_pool(...) Initializes a pool for a token pair + fee tier.
mint(...) Opens a position in a tick range; returns a MintResult with the position's token id.
increase_liquidity(...) / decrease_liquidity(...) Resizes a position (spends the position NFT record and returns a fresh one).
collect(...) Pays out tokens_owed as private records.
burn(...) Closes an emptied position and removes it from the positions mapping.

Quote before you swap: pass expected_out from dex.api.get_route(...) — without it a spot estimate is used, which ignores fees and price impact. Amounts are u128 base units of the token; fees are microcredits.

DEX API (dex.api, standalone as ApiClient): get_pools, get_tokens, get_route, get_swap, get_ohlcv, get_public_balances. Route quoting, OHLCV, and balances are auth-gated — call api.authenticate(address, sign) once (challenge/verify by signature, no funds required); some deployments additionally gate them behind an invite code.

Privacy

The swap flow never puts your address on chain next to the output. swap derives a single-use blinded identity from the signer's view key (derive_blinding_factor / derive_blinded_address are exported for verification against the TS SDK's vectors); the claim proves knowledge of the blinding factor instead of revealing the owner.

Two conveniences trade secret material for service:

  • delegate sends the transaction authorization to the proving service — it can see the transaction's contents (not your private key). Prove locally with transact if that is unacceptable.
  • The hosted record scanner behind get_private_balances / aleo.records.register shares the account's view key with the scanning service, which can then see everything the account owns. Self-host the scanner if that is unacceptable.

Async

AsyncShieldSwap / AsyncApiClient mirror the sync surface verb-for-verb on aleo.AsyncAleo (install the [async] extra):

from aleo_shield_swap import AsyncShieldSwap

dex = AsyncShieldSwap(async_aleo)
handle = await (await dex.swap(pool_key=key, token_in_id=token,
                               amount_in=10**9)).delegate()

Agent tools and MCP

shield_swap_tools() returns JSON-schema tool definitions for the whole verb surface; dispatch_tool(dex, name, args) executes one. For MCP hosts, the [mcp] extra ships a stdio server over the same definitions:

ALEO_PRIVATE_KEY=APrivateKey1... python -m aleo_shield_swap.mcp

Omit ALEO_PRIVATE_KEY for a read-only server. See the module docstring for the full environment (ALEO_ENDPOINT, ALEO_NETWORK, DPS credentials).

Generated bindings

The contract surface is pinned, not hand-written: codegen/ holds the deployed program source, its ABI, and the DEX API's OpenAPI document. _generated.py (program structs + entrypoints via aleo.codegen) and _api_models.py (API response models) are built from those pins. When the deployed contract or API drifts, rerun codegen/regen-abi.sh / codegen/regen-openapi.sh and reconcile.

Tests

python -m pytest                        # hermetic tier — no network
python -m pytest -m live               # read-only against the REAL testnet + DEX API
python -m pytest -m "live and slow"    # spends real testnet funds (DPS proving)
ALEO_DEVNODE_UNPROVEN=1 \
python -m pytest -m devnode            # full AMM lifecycle on a local aleo-devnode

The devnode tier deploys the vendored shield_swap_v3.aleo stack and drives pool creation, liquidity, swaps, and burn end-to-end, hermetically. It needs the aleo-devnode binary (ALEO_DEVNODE_BIN or on PATH) and skips otherwise. Deployments are proofless (dummy verifying keys — the devnode skips certificate verification); ALEO_DEVNODE_UNPROVEN=1 extends that to executions and is the fast path (~5 minutes). Without it, executions are fully proven locally: expect SNARK parameter downloads and key synthesis on first use.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

shield_swap_sdk-0.2.2.tar.gz (228.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

shield_swap_sdk-0.2.2-py3-none-any.whl (67.8 kB view details)

Uploaded Python 3

File details

Details for the file shield_swap_sdk-0.2.2.tar.gz.

File metadata

  • Download URL: shield_swap_sdk-0.2.2.tar.gz
  • Upload date:
  • Size: 228.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for shield_swap_sdk-0.2.2.tar.gz
Algorithm Hash digest
SHA256 c635c188575da65d22d73b7a8a57bde28b6abe7d5a293ee6cc7a7206ed53793b
MD5 d86c7d330343e875b4b0e67747cc318e
BLAKE2b-256 9e0700340d84d8a2251ddaceacb1e12772fd432e4c56111a4502e4941f0c282d

See more details on using hashes here.

Provenance

The following attestation bundles were made for shield_swap_sdk-0.2.2.tar.gz:

Publisher: sdk-wheels.yml on ProvableHQ/python-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file shield_swap_sdk-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: shield_swap_sdk-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 67.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for shield_swap_sdk-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 48c5c08e420bf2b39adc74a3c6f90e22c7e3d5214999ea047a8e030608e9523a
MD5 f7788f31ebd756f5578235775e392132
BLAKE2b-256 82bc8710e92e6317c722baade04b407707c0353be97916afc30e810f3699449c

See more details on using hashes here.

Provenance

The following attestation bundles were made for shield_swap_sdk-0.2.2-py3-none-any.whl:

Publisher: sdk-wheels.yml on ProvableHQ/python-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page