Python SDK for building zero-knowledge apps and DeFi on the Aleo network
Project description
Aleo Python SDK (MainnetV0)
The Aleo Python SDK provides Python bindings to Aleo's zero-knowledge cryptographic primitives, built with snarkvm 4.8.1.
It ships two layers:
- A Web3.py-style facade (
aleo.Aleo/aleo.AsyncAleo) — a high-level, batteries-included client for connecting to a node, managing accounts, reading state, and building/proving/broadcasting transactions. - Low-level primitives (
aleo.mainnet,aleo.testnet) — direct Python bindings to Aleo's cryptographic types, for when you need full control.
Quick Start (facade)
from aleo import Aleo
# Connect (construction is offline — no I/O until you make a call)
aleo = Aleo(Aleo.HTTPProvider("https://api.provable.com/v2"))
print(aleo.network_name) # "mainnet"
print(aleo.network_id) # 0
# Create an account (local)
account = aleo.account.create()
print(account.address) # aleo1…
# Read a public balance # requires a live node
balance = aleo.get_balance(str(account.address))
print(aleo.from_microcredits(balance), "credits")
Aleo.HTTPProvider is also importable directly as from aleo import HTTPProvider; the two are equivalent.
The verb ladder (sync)
The facade follows a clean top-to-bottom narrative: connect → account → read → build a call → inspect → send. Each rung does a little more than the one above it.
1. Connect
from aleo import Aleo
aleo = Aleo(Aleo.HTTPProvider("https://api.provable.com/v2"))
# Optional: check reachability # requires a live node
if aleo.is_connected():
print("connected to", aleo.network_name)
HTTPProvider is a config object, not a live connection — it is safe to construct without a network. It accepts network= ("mainnet" / "testnet"), api_key=, prover_uri= (the DPS endpoint), headers=, and a custom transport= callable.
2. Account — create or import (local)
# Fresh random account
account = aleo.account.create()
# Import from a private-key string (or a PrivateKey object)
account = aleo.account.from_private_key("APrivateKey1zkp…")
# Derive deterministically from a field seed
account = aleo.account.from_seed("123field")
# Sign / verify (bytes)
sig = aleo.account.sign(b"hello aleo", account)
assert aleo.account.verify(str(account.address), b"hello aleo", sig)
# Sign / verify a typed Aleo value
sv = aleo.account.sign_value("100u64", account)
assert aleo.account.verify_value(str(account.address), "100u64", sv)
Set aleo.default_account = account and the verbs below will use it whenever you omit the signer.
Note: the facade deliberately has no "recover signer from signature" verb. Aleo is a privacy chain — surfacing "which address signed this?" is a de-anonymisation vector. The low-level
Signature.to_address()primitive remains available directly if you truly need it.
3. Read — balance and mappings
# Public credits balance in microcredits (0 if the address is unfunded) # requires a live node
micro = aleo.get_balance(str(account.address))
print(aleo.from_microcredits(micro), "credits")
# Read any on-chain mapping through a bound Program # requires a live node
credits = aleo.programs.get("credits.aleo")
raw = credits.mapping("account").get(str(account.address))
print("account mapping value:", raw)
Unit helpers are local: aleo.to_microcredits(1.5) == 1_500_000 and aleo.from_microcredits(1_500_000) == 1.5. Address validation is local too: aleo.is_valid_address(s) -> bool.
4. Build a call
aleo.programs.get(...) fetches a program and exposes its transitions as program.functions.<name>, mirroring web3.py's ABI-driven contract.functions. Calling one coerces your Python arguments to Aleo values and returns a BoundCall:
# requires a live node (to fetch the program source)
credits = aleo.programs.get("credits.aleo")
call = credits.functions.transfer_public(str(account.address), 1_000_000)
print(call.signature) # "transfer_public(address, u64)"
print(call.args) # ['aleo1…', '1000000u64'] — coerced
You can also list/iterate the available functions: list(credits.functions), "transfer_public" in credits.functions.
5. Inspect — simulate / .decoded()
Before proving or broadcasting anything, build the authorization locally and look at what the call will produce. This is a proof-free, network-free dry run:
auth = call.simulate(account) # alias of .authorize(); .call() also works
print(auth.outputs) # per-transition output lists
print(auth.decoded()) # [{program, function, inputs, outputs}, …]
Both AuthorizationResult and TransactionResult expose the same .outputs / .decoded() surface, plus a .raw escape hatch to the underlying network object. You can also decode after the fact with aleo.decode_transition(tx_id_or_transition).
6. Transact — full prove + broadcast
build_transaction (alias prove) runs the whole ladder locally: authorize → execute → prepare trace → prove execution → authorize+prove fee → assemble. transact does that and broadcasts, returning the transaction id:
# requires a live node + funded private key
tx_id = credits.functions.transfer_public(
str(account.address), 100
).transact(account)
confirmed = aleo.network.wait_for_transaction(tx_id, timeout=60.0)
Fees are public by default (base cost from the execution). Pass priority_fee= for a tip, or opt into a private fee with private_fee=True (auto-sourced from aleo.record_provider) or by passing an explicit fee_record=.
7. Delegate — the flagship path (fee master pays by default)
delegate hands proving to a Delegated Proving Service (DPS): you build only the lightweight main authorization locally, and the DPS does the expensive SNARK proving. By default the prover's fee master pays the fee — no records, no public fee, no friction. That frictionlessness is the whole point.
# requires prover credentials; fee master pays
result = credits.functions.transfer_public(
str(account.address), 100
).delegate(account)
Want to pay your own fee instead? delegate(account, pay_own_fee=True) (public) or delegate(account, fee_record=<credits record>) (private). Both bind the fee to the real execution id, so they prove the execution locally first. broadcast=False returns the proven transaction without submitting it.
Private transfers — delegated proving + record discovery
A full private transfer combines the two trust-minimising paths: delegated proving (the prover's fee master pays) and a record provider to discover the private records you own. The default record provider (aleo.records) uses Provable's hosted scanner — registering shares your view key with that service so it can index your records. If you'd rather not share a view key, assign your own RecordProvider instead.
# requires prover credentials + hosted-scanner registration
credits = aleo.programs.get("credits.aleo")
# 1) Move public credits into a private record (delegated — fee master pays)
credits.functions.transfer_public_to_private(str(account.address), 100_000) \
.delegate(account)
# 2) Register with the record provider and find the new private record
aleo.records.register(account) # shares the view key with the scanner
record = aleo.records.get_unspent_credits_record()
# 3) Spend the private record with a private transfer (delegated)
credits.functions.transfer_private(record, str(recipient.address), 1) \
.delegate(account)
aleo.record_provider is swappable: set it to your own object implementing the RecordProvider protocol (get_unspent_credits_record / find) — e.g. a self-hosted scanner — and the whole facade (including private-fee auto-sourcing) uses it, with no view-key sharing.
Async (AsyncAleo)
The async facade mirrors the sync surface. Construction and the local, CPU-bound steps stay synchronous; everything that touches the network is awaitable.
import asyncio
from aleo import AsyncAleo
async def main():
aleo = AsyncAleo(AsyncAleo.HTTPProvider("https://api.provable.com/v2"))
print(aleo.network_name) # sync — no I/O
# Account ops are sync (purely local), even on AsyncAleo
account = aleo.account.create()
sig = aleo.account.sign(b"hi", account)
assert aleo.account.verify(str(account.address), b"hi", sig)
# Reads are awaited # requires a live node
micro = await aleo.get_balance(str(account.address))
print(aleo.from_microcredits(micro), "credits")
# Build a call — fetching the program is awaited # requires a live node
credits = await aleo.programs.get("credits.aleo")
call = credits.functions.transfer_public(str(account.address), 100)
# authorize / simulate / call are SYNC (local proof-free build)
auth = call.simulate(account)
print(auth.decoded())
# transact / delegate are awaited # requires a live node / prover creds
tx_id = await call.transact(account)
result = await call.delegate(account) # fee master pays by default
asyncio.run(main())
Sync vs async on the async facade:
- Sync (local, no I/O):
account.*(create/import/sign/verify),to_microcredits/from_microcredits/is_valid_address, andauthorize/simulate/callon a bound call. - Async (awaitable):
is_connected,get_balance,programs.get, mapping reads,build_transaction/transact/delegate. Heavy proving runs inasyncio.to_threadso it does not block the event loop.
Testing utilities (aleo.testing)
The SDK ships an eth-tester-style harness for fast, deterministic local testing.
Devnode — a local chain in a context manager
Devnode launches a local aleo-devnode with manual block creation, so tests control exactly when blocks are produced. It auto-picks a free port and tears the node down on exit.
from aleo.testing import Devnode
with Devnode() as dn:
aleo = dn.aleo # an Aleo client wired to the devnode
alice = dn.accounts[0] # 5 deterministic, pre-funded genesis accounts
tx_id = aleo.programs.get("credits.aleo").functions.transfer_public(
str(dn.accounts[1].address), 1_000_000
).transact(alice)
dn.advance(1) # produce 1 block to confirm the tx
snap = dn.snapshot() # capture chain state
dn.aleo— anAleoclient pointed at the devnode.dn.accounts— 5 deterministic, pre-funded genesis accounts.dn.advance(n)— producenblocks (the node runs with manual block creation).dn.snapshot()— capture the current chain state.
Requires the aleo-devnode binary on your PATH, or set $ALEO_DEVNODE_BIN to its location.
Live end-to-end tests
The -m slow live tests hit a real testnet and skip automatically when their environment variables are unset:
| Variable | Purpose |
|---|---|
ALEO_E2E_PRIVATE_KEY |
A funded testnet private key |
ALEO_E2E_ENDPOINT |
Node/API endpoint to test against |
ALEO_E2E_API_KEY |
Provable API key |
ALEO_E2E_CONSUMER_ID |
DPS consumer id for delegated proving |
The -m devnode tests additionally require the aleo-devnode binary (see Devnode above).
Low-level primitives
When you need direct control, import the network module and use the cryptographic types directly:
from aleo.mainnet import PrivateKey, Signature
# Generate a random private key
pk = PrivateKey.random()
address = pk.address
view_key = pk.view_key
# Sign a message
message = b"hello"
signature = Signature.sign(pk, message)
assert signature.verify(address, message)
aleo.mainnet (and aleo.testnet, when the extension is compiled) expose the full type set — Account, Program, Process, Authorization, Transaction, RecordPlaintext, Field, Address, and more.
Build & Install
bash install.sh
This creates a development environment and installs the aleo package with MainnetV0 bindings.
Contributing
If you wish to contribute, please follow the contribution guidelines outlined on GitHub.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aleo_sdk-0.2.0.tar.gz.
File metadata
- Download URL: aleo_sdk-0.2.0.tar.gz
- Upload date:
- Size: 281.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
36445e2f80d804b464c5ac3f5420e2dacb0695ebc09e6e9acd3c70b8e2c8399c
|
|
| MD5 |
b24dffe50ed6ad801999a669c22fca52
|
|
| BLAKE2b-256 |
a527c9f6d784741610dba823b35df19c5a8546b5d02cbe3344812e6f18ee4e9a
|
Provenance
The following attestation bundles were made for aleo_sdk-0.2.0.tar.gz:
Publisher:
sdk-wheels.yml on ProvableHQ/python-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aleo_sdk-0.2.0.tar.gz -
Subject digest:
36445e2f80d804b464c5ac3f5420e2dacb0695ebc09e6e9acd3c70b8e2c8399c - Sigstore transparency entry: 2169841589
- Sigstore integration time:
-
Permalink:
ProvableHQ/python-sdk@e2f05f607278834a631674cf15fa0d8e976fcd4d -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/ProvableHQ
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
sdk-wheels.yml@e2f05f607278834a631674cf15fa0d8e976fcd4d -
Trigger Event:
push
-
Statement type:
File details
Details for the file aleo_sdk-0.2.0-cp37-abi3-win_amd64.whl.
File metadata
- Download URL: aleo_sdk-0.2.0-cp37-abi3-win_amd64.whl
- Upload date:
- Size: 34.6 MB
- Tags: CPython 3.7+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0fa368395ef229d132c8c37c8d8aabeefb02e04cb9bbd6441682936899efdebe
|
|
| MD5 |
5ce72cc0dd3c8581fc3f15e7705c52a2
|
|
| BLAKE2b-256 |
e84f9aadd23878cf45991bb4e1a4e57f4a2eb4880fa47188a2027d877ea6f1e5
|
Provenance
The following attestation bundles were made for aleo_sdk-0.2.0-cp37-abi3-win_amd64.whl:
Publisher:
sdk-wheels.yml on ProvableHQ/python-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aleo_sdk-0.2.0-cp37-abi3-win_amd64.whl -
Subject digest:
0fa368395ef229d132c8c37c8d8aabeefb02e04cb9bbd6441682936899efdebe - Sigstore transparency entry: 2169841695
- Sigstore integration time:
-
Permalink:
ProvableHQ/python-sdk@e2f05f607278834a631674cf15fa0d8e976fcd4d -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/ProvableHQ
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
sdk-wheels.yml@e2f05f607278834a631674cf15fa0d8e976fcd4d -
Trigger Event:
push
-
Statement type:
File details
Details for the file aleo_sdk-0.2.0-cp37-abi3-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: aleo_sdk-0.2.0-cp37-abi3-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 37.1 MB
- Tags: CPython 3.7+, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
035f3f5f123245abc474d63fdc8124d8f567eb926d43fd8b72ff72cee382c3fb
|
|
| MD5 |
41a6fef220ebe61377e12eadb008158f
|
|
| BLAKE2b-256 |
1a7754d60f0925c06a9b66c3258e6a1244652ae4696dba3fd99a5cce1e83540a
|
Provenance
The following attestation bundles were made for aleo_sdk-0.2.0-cp37-abi3-manylinux_2_28_x86_64.whl:
Publisher:
sdk-wheels.yml on ProvableHQ/python-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aleo_sdk-0.2.0-cp37-abi3-manylinux_2_28_x86_64.whl -
Subject digest:
035f3f5f123245abc474d63fdc8124d8f567eb926d43fd8b72ff72cee382c3fb - Sigstore transparency entry: 2169841765
- Sigstore integration time:
-
Permalink:
ProvableHQ/python-sdk@e2f05f607278834a631674cf15fa0d8e976fcd4d -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/ProvableHQ
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
sdk-wheels.yml@e2f05f607278834a631674cf15fa0d8e976fcd4d -
Trigger Event:
push
-
Statement type:
File details
Details for the file aleo_sdk-0.2.0-cp37-abi3-manylinux_2_28_aarch64.whl.
File metadata
- Download URL: aleo_sdk-0.2.0-cp37-abi3-manylinux_2_28_aarch64.whl
- Upload date:
- Size: 37.3 MB
- Tags: CPython 3.7+, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
52c5cf3612b7f1b8f0dce4841d21d855b0ef78b8a248ddb729fcfa6b8349fbdd
|
|
| MD5 |
f4f8aaab3805b9d16e120086e857046c
|
|
| BLAKE2b-256 |
3d1a726467b4abbb686cbb5db696ef8b6e617ad2f4b82183d4cd347870c81776
|
Provenance
The following attestation bundles were made for aleo_sdk-0.2.0-cp37-abi3-manylinux_2_28_aarch64.whl:
Publisher:
sdk-wheels.yml on ProvableHQ/python-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aleo_sdk-0.2.0-cp37-abi3-manylinux_2_28_aarch64.whl -
Subject digest:
52c5cf3612b7f1b8f0dce4841d21d855b0ef78b8a248ddb729fcfa6b8349fbdd - Sigstore transparency entry: 2169841726
- Sigstore integration time:
-
Permalink:
ProvableHQ/python-sdk@e2f05f607278834a631674cf15fa0d8e976fcd4d -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/ProvableHQ
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
sdk-wheels.yml@e2f05f607278834a631674cf15fa0d8e976fcd4d -
Trigger Event:
push
-
Statement type:
File details
Details for the file aleo_sdk-0.2.0-cp37-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: aleo_sdk-0.2.0-cp37-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 36.0 MB
- Tags: CPython 3.7+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4281de59447a7c8a04bccc9c992b19a8b5563c87d30b458c032fef016d86ce98
|
|
| MD5 |
4ade188b2013d718efa8ec992bb94969
|
|
| BLAKE2b-256 |
2d28050b14022e2592ed6afe8928589297c278a0452e4506d9a316b5232719f0
|
Provenance
The following attestation bundles were made for aleo_sdk-0.2.0-cp37-abi3-macosx_11_0_arm64.whl:
Publisher:
sdk-wheels.yml on ProvableHQ/python-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aleo_sdk-0.2.0-cp37-abi3-macosx_11_0_arm64.whl -
Subject digest:
4281de59447a7c8a04bccc9c992b19a8b5563c87d30b458c032fef016d86ce98 - Sigstore transparency entry: 2169841658
- Sigstore integration time:
-
Permalink:
ProvableHQ/python-sdk@e2f05f607278834a631674cf15fa0d8e976fcd4d -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/ProvableHQ
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
sdk-wheels.yml@e2f05f607278834a631674cf15fa0d8e976fcd4d -
Trigger Event:
push
-
Statement type:
File details
Details for the file aleo_sdk-0.2.0-cp37-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: aleo_sdk-0.2.0-cp37-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 36.6 MB
- Tags: CPython 3.7+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f87862f05b08939a618991d8f32313188a5f84e62331ceaa13ebdf5204a969c5
|
|
| MD5 |
bc81649b57c3fe5f232013ff98197742
|
|
| BLAKE2b-256 |
e2f774c28a2bf523c50ff347a6d3bf8b72514f8a59f2cc5974d8837531ed8178
|
Provenance
The following attestation bundles were made for aleo_sdk-0.2.0-cp37-abi3-macosx_10_12_x86_64.whl:
Publisher:
sdk-wheels.yml on ProvableHQ/python-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aleo_sdk-0.2.0-cp37-abi3-macosx_10_12_x86_64.whl -
Subject digest:
f87862f05b08939a618991d8f32313188a5f84e62331ceaa13ebdf5204a969c5 - Sigstore transparency entry: 2169841623
- Sigstore integration time:
-
Permalink:
ProvableHQ/python-sdk@e2f05f607278834a631674cf15fa0d8e976fcd4d -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/ProvableHQ
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
sdk-wheels.yml@e2f05f607278834a631674cf15fa0d8e976fcd4d -
Trigger Event:
push
-
Statement type: