Official Python client for the WaveLedger post-quantum testnet. Includes the Fourier compiler for local contract compilation.
Project description
waveledger-sdk — Python client
Official Python SDK for the WaveLedger
post-quantum chain. One Client class for every messenger surface
(auth, chat, wallet, explorer, playground, admin) plus an iterator
over the SSE event stream. Ships with the Fourier compiler
vendored in-process so contracts compile locally without a network
round-trip.
Install
pip install waveledger-sdk
The PyPI distribution is waveledger-sdk; the importable module is
waveledger, so your code stays from waveledger import Client. The
only runtime dependency is requests.
From the WaveLedger source tree:
pip install -e clients/python
Quickstart
from waveledger import Client
c = Client("https://api.waveledger.net")
# Sign up with an invite (instant approval + 100 testnet WAVE)
c.signup("alice", invite_code="WAVE-ABC123")
# Post a chat message — real on-chain ML-DSA-87 tx
c.send_message("hello world")
# Send WAVE to another address
c.wallet_send(to="34378b1ba5be9d0999acd60be3a8a1f1", amount=1.0)
# Subscribe to every block as it lands
for ev in c.subscribe(types=["block"]):
b = ev["block"]
print(f"block {b['height']} from {b['miner'][:16]}")
API surface
# Auth / session
c.signup(name, invite_code=None)
c.login(name, token)
c.me()
c.logout()
# Chat
c.send_message(text)
c.messages(limit=50)
# Wallet
c.wallet()
c.wallet_send(to=..., amount=..., memo=None)
c.wallet_export(passphrase=...)
c.wallet_import(name=..., encrypted=..., passphrase=...)
# Explorer (public, no auth)
c.explorer.stats()
c.explorer.blocks(limit=25, offset=0)
c.explorer.block(height)
c.explorer.tx(tx_id)
c.explorer.address(address)
# Playground (Fourier)
c.playground.compile(source) # server-side
c.playground.compile_local(source) # in-process — no network call
c.playground.deploy(source)
c.playground.call(contract=..., method=..., args=[...])
c.playground.receipt(tx_id)
c.playground.contracts()
# SSE event stream — block / tx / message / receipt
for ev in c.subscribe(types=None, address=None):
handle(ev)
# Admin (HTTP Basic — pass admin=(user, password) at construction)
ac = Client("https://api.waveledger.net",
admin=("admin", "PASSWORD"))
ac.admin.pending()
ac.admin.approve(name)
ac.admin.block(name, reason=None)
ac.admin.unblock(name)
ac.admin.invite_create(max_uses=25)
ac.admin.invite_revoke(code)
ac.admin.invites_list()
ac.admin.token_create(label=..., name=..., scope="playground")
ac.admin.tokens_list()
ac.admin.token_revoke(token="wlg_...")
API token auth
For CI pipelines and unattended use, an administrator mints a Bearer token bound to an approved user. The token's user owns any contracts deployed or called through it; that user's wallet pays the fees.
# Operator (one-off): mint a token bound to ci-bot.
admin = Client("https://api.waveledger.net",
admin=("admin", "PASSWORD"))
admin.admin.approve("ci-bot")
out = admin.admin.token_create(label="release-pipeline",
name="ci-bot",
scope="playground")
print(out["token"]) # wlg_… — save this once; not recoverable
# Pipeline: use the token, no signup/login required.
c = Client("https://api.waveledger.net", api_token="wlg_…")
c.playground.deploy(source)
Tokens are stored as their SHA3-256 hash. The raw value is returned exactly once; revocation is the only recovery for a lost or leaked token.
Local Fourier compile
The package vendors the Fourier compiler. compile_local() runs
in-process and returns the same shape as the server compile:
out = c.playground.compile_local("""
contract Counter {
storage value: uint @ 0;
pub fn inc() -> uint { value = value + 1; return value; }
}
""")
print(out["bytecode_size"], out["abi"]["contract"])
The vendored compiler is pinned with the SDK release, so a given
waveledger-sdk version produces byte-identical bytecode regardless
of when or where it runs. Lex / parse / codegen / ABI errors raise
ValidationError with payload={"phase": "compile", "error": ...},
matching the server's 400 response shape.
Filtering the event stream
# Block events only
for ev in c.subscribe(types=["block"]):
print(ev["block"]["height"])
# Everything that touches one address
for ev in c.subscribe(address="34378b1ba5be9d0999acd60be3a8a1f1"):
print(ev["type"], ev)
# Both filters AND'd
for ev in c.subscribe(types=["tx", "receipt"],
address="34378b1ba5be9d0999acd60be3a8a1f1"):
print(ev)
Filtering is server-side, so the client pays no bandwidth or CPU cost for events outside the filter.
Errors
from waveledger import (
AuthError, NotFoundError, RateLimitedError,
ValidationError, ServerError, WaveLedgerError,
)
| HTTP | Exception |
|---|---|
| 400 | ValidationError |
| 401 / 403 | AuthError |
| 404 | NotFoundError |
| 429 | RateLimitedError |
| 5xx | ServerError |
| anything else | WaveLedgerError |
Each exception carries .status (int) and .payload (decoded JSON if
any).
Security notes
- The SDK emits a
UserWarningat construction time ifapi_tokenoradmin=is configured against a non-loopbackhttp://URL. Loopback hosts (localhost,127.0.0.1,::1) stay quiet — that is normal local development. - Bearer tokens and admin credentials are sent on a per-request basis;
requestsstrips theAuthorizationheader on cross-origin redirects so a redirect to a different host does not leak the credential. - Wallet backups are AES-256-GCM with Argon2id KDF (server-side); the
SDK never sees the user's passphrase except as a value passed
through to
/api/wallet/export.
Self-hosted nodes
c = Client("http://localhost:8081")
The messenger serves on 8081 by default (node.py --messenger-port).
Tests
cd clients/python
python3 -m pytest tests/ -q
The suite uses a mock requests.Session plus the vendored Fourier
compiler — no network, no fixtures, no extra test deps.
Versioning
Pre-1.0. Method names and response shapes track the REST API. Latest
release: waveledger-sdk 0.2.0.
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 Distribution
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 waveledger_sdk-0.2.0.tar.gz.
File metadata
- Download URL: waveledger_sdk-0.2.0.tar.gz
- Upload date:
- Size: 51.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
32f69bc2d6e4308d5316bd888b7b9626b697e42d2a4be04235b84ef53c3956ef
|
|
| MD5 |
40b89a5408f659ea8e2fec90fdf6329b
|
|
| BLAKE2b-256 |
d2e873dcb85b48838ed77c2d9cb85b6e1984741624546e0eb3037a89669babe8
|
File details
Details for the file waveledger_sdk-0.2.0-py3-none-any.whl.
File metadata
- Download URL: waveledger_sdk-0.2.0-py3-none-any.whl
- Upload date:
- Size: 49.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0b1b11a985777cf4e64145bdf78277c05ed5485399ffa8795479de2a77a0f8fe
|
|
| MD5 |
01f08ca75fcb8f8a1a4d7dd7fb58982c
|
|
| BLAKE2b-256 |
e9bfee4daa3ffea8fa88615613f0d7554e1718f6169f28ded806ca55c281f015
|