Skip to main content

Python CDK for Rialo blockchain - wallet management, transactions, and RPC client

Project description

rialo-py-cdk

Python bindings for the Rialo CDK, generated with PyO3 and built via Maturin. The extension wraps rialo-cdk and exposes its full client-side surface — keyring management, transaction building, JSON-RPC communication, program deployment, and TEE secret encryption — as a synchronous Python API. All async Rust operations are bridged internally through a shared Tokio runtime; callers do not use async/await. Requires Python ≥ 3.10 (targets the Python Stable ABI abi3-py310, so a single wheel per platform covers CPython 3.10 and later).

Installation

pip install rialo-py-cdk

Pre-built wheels are published for Linux (x86_64/aarch64), macOS (x86_64/arm64), and Windows. See Building from source if no wheel is available for your platform.

Key public types

Primitive types

Python name Purpose
PublicKey (PyPublicKey) Ed25519 public key; construct from 32 bytes or base58 string
Hash (PyHash) 32-byte hash (config hash prefix); construct from bytes or base58 string
Signature (PySignature) Ed25519 signature (64 bytes); construct from bytes or base58 string
AccountMeta (PyAccountMeta) Account reference in an instruction (pubkey, is_signer, is_writable)
Instruction (PyInstruction) Custom instruction: program ID, accounts, and opaque data bytes
RialoException Base exception for all CDK errors; carries .code and .message

Keyring management

Python name Purpose
Keyring Named collection of Ed25519 keypairs; one is the active signing key
DerivedKeypair Single keypair with index, public key, and optional HD derivation path
InMemoryKeyringProvider Ephemeral keyring storage (testing; no persistence)
FileKeyringProvider Encrypted on-disk keyring storage (file-storage feature)

Transaction and RPC

Python name Purpose
TransactionBuilder Builds and optionally signs serialised transactions
HttpRpcClient HTTP JSON-RPC client for Rialo nodes (rpc-client feature)
RialoRPCClient Typed wrapper over HttpRpcClient with dataclass return types
ProgramDeployment Deploys an eBPF or RISC-V program binary (bincode feature)
ProgramInvocation Builds and submits a program-call instruction
Config Lightweight network/RPC URL configuration helper

Note: Wallet, InMemoryWalletProvider, FileWalletProvider, and Account are retained as deprecated aliases; prefer the Keyring/KeyringProvider names in new code.

Warning: Keypair bytes in the low-level API are always 64 bytes: 32-byte Ed25519 secret key followed by 32-byte public key. Provider methods that accept a secret_key argument take the raw 32-byte secret only. Passing the wrong length raises RialoException at call time.

Usage

Create a keyring and send a transfer

import time
from rialo_py_cdk import (
    InMemoryKeyringProvider,
    HttpRpcClient,
    TransactionBuilder,
    get_devnet_url,
    rlo_to_kelvin,
)

provider = InMemoryKeyringProvider()
keyring, mnemonic = provider.create_with_mnemonic("main", 128, "password")
print("Save mnemonic:", mnemonic)

client = HttpRpcClient(get_devnet_url())
config_hash = client.get_config_hash_prefix()   # required by every transaction

recipient = keyring.get_public_key()            # replace with the real recipient

valid_from = int(time.time() * 1000)
tx_bytes = (
    TransactionBuilder(keyring.get_public_key(), valid_from, config_hash)
    .add_transfer_instruction(keyring.get_public_key(), recipient, int(rlo_to_kelvin(1.0)))
    .sign_with_keyring(keyring)   # signs and serialises; use .build() for unsigned bytes
)
sig = client.send_transaction(tx_bytes)
print("Transaction signature:", sig)            # base58 string

Recover a keyring from a mnemonic

recovered = provider.recover_from_mnemonic("main", mnemonic, "password")
print("Recovered public key:", recovered.get_public_key())

Manage multiple keypairs

Each keyring can hold several derived keypairs. Use derive_keypair to add more at the next available BIP44 index, set_active_keypair to switch between them, and sign_with_keypair to sign with a specific one without switching the active key.

# Derive an additional keypair (index assigned automatically)
info = provider.derive_keypair("main", 1, "password")
print("New keypair pubkey:", info["pubkey_string"])

# Switch the active signing key
keyring.set_active_keypair(1)
print("Now signing with:", keyring.get_public_key_string())

# Sign with a specific keypair without changing the active key
sig_bytes = keyring.sign_with_keypair(message_bytes, 1)

# List all keypairs in the keyring
for kp in keyring.get_keypairs_info():
    print(f"  index={kp['index']}  pubkey={kp['pubkey_string']}")

# Import an existing 32-byte secret key at a custom derivation path
provider.import_secret_key("main", secret_key_bytes, "m/44'/756'/5'", "password")

Deploy a program

from rialo_py_cdk import ProgramDeployment, PyLoaderType

deployment = ProgramDeployment("/path/to/program.so")
deployment.with_loader_type(PyLoaderType.RiscV)   # default is LoaderV4
program_id = deployment.deploy_with_keyring(client, keyring)
print("Deployed program:", program_id)

Invoke a program

from rialo_py_cdk import ProgramInvocation

invocation = ProgramInvocation(program_id)
invocation.add_writable_account(state_account_pubkey)
invocation.add_readonly_account(config_account_pubkey)
invocation.with_data(instruction_data_bytes)

sig = invocation.invoke_with_keyring(client, keyring)
print("Invocation signature:", sig)

# Build an instruction without submitting, e.g. to include in a larger transaction
ix = invocation.into_instruction()

Encrypt a secret for TEE execution

from rialo_py_cdk import encrypt_secret, PublicKey

sk_pub = PublicKey.from_string(client.get_secret_sharing_pubkey())
ciphertext = encrypt_secret("Bearer sk-…", keyring.get_public_key(), sk_pub)
# Pass ciphertext in your instruction data; the TEE program decrypts it.

Configure the network

Config lets you persist the active network URL without threading a client everywhere. It defaults to localnet.

from rialo_py_cdk import Config

cfg = Config("devnet")          # sets rpc_url automatically
print(cfg.rpc_url)              # https://api.devnet.rialo.xyz
cfg.set_network("testnet")      # switch network; rpc_url updates
print(cfg.network)              # "testnet" (read-only)

d = cfg.to_dict()
cfg2 = Config.from_dict(d)

Subscription workflows (REX)

subscription = client.get_subscription(subscriber_pubkey_str, nonce)
print("Topic:", subscription["topic"])

triggered = client.get_triggered_transactions(subscription_account_str, 10)
for tx in triggered:
    print(f"sig={tx['signature']}  block={tx['block_number']}")

Workflow lineage

lineage = client.get_workflow_lineage("5UfDuX...")
# lineage["nodes"] contains the DAG of related transactions.

Typed RPC client

rialo_py_cdk.generated ships a fully typed RialoRPCClient that wraps the PyO3 HttpRpcClient with dataclass return types — useful when you want IDE autocompletion and static analysis with mypy/pyright.

from rialo_py_cdk import HttpRpcClient, get_devnet_url
from rialo_py_cdk.generated import RialoRPCClient
from rialo_py_cdk.generated.types import AccountInfo, EpochInfo

raw_client = HttpRpcClient(get_devnet_url())
client = RialoRPCClient(raw_client)

# Return types are dataclasses, not raw dicts
epoch: EpochInfo = client.get_epoch_info()
print(f"Epoch {epoch.epoch}, slot {epoch.absolute_slot}")

account: AccountInfo = client.get_account_info(pubkey_string)
print(f"Balance: {account.kelvin} kelvin, owner: {account.owner}")

Tip: The underlying HttpRpcClient is still accessible via client._client when you need methods not yet promoted to the typed layer.

Error handling

All CDK errors surface as RialoException. The .code attribute carries the numeric error code for programmatic handling.

from rialo_py_cdk import RialoException

try:
    sig = client.send_transaction(tx_bytes)
except RialoException as exc:
    if exc.code == 1001:                    # example: insufficient funds
        print("Funding required before sending")
    else:
        raise                               # re-raise unexpected errors

Tip: exc.message contains a human-readable description with the error category and code, e.g. [Transaction:1001] insufficient funds.

Error code ranges

Range Category
1000–1999 Transaction errors
2000–2999 RPC errors
3000–3999 Configuration errors
4000–4999 Keyring/wallet errors
5000–5999 Encryption errors

RPC reference

Method Returns Notes
get_config_hash_prefix() int Required for every TransactionBuilder
get_balance(pubkey) int Balance in kelvin
send_transaction(tx_bytes) PySignature Submit signed bytes
send_and_confirm_transaction(tx_bytes) dict Submit and poll for confirmation
confirm_transaction(sig_str) dict Poll for an already-submitted transaction
get_account_info(pubkey) dict Raw account data
get_multiple_accounts(pubkeys) list Batch query
get_accounts_by_owner(owner) list Program accounts
get_block_height() int Finalized block height
get_transaction(sig) dict By signature
get_epoch_info() dict Current epoch
get_signatures_for_address(address) list Transaction history for an account
request_airdrop(pubkey, kelvin) PySignature Devnet/testnet only
request_airdrop_and_confirm(pubkey, kelvin) dict Airdrop + wait
get_fee_for_message(msg_base64) dict Estimate fee before sending
get_minimum_balance_for_rent_exemption(size) int Rent-exempt threshold
get_secret_sharing_pubkey() str TEE HPKE public key (base58)
get_subscription(subscriber, nonce) dict REX subscription lookup
get_triggered_transactions(account, limit?) list Subscription-triggered txs
get_workflow_lineage(request) dict Workflow DAG traversal

Tip: Use RialoRPCClient from rialo_py_cdk.generated to get typed dataclass return values instead of raw dict/list from HttpRpcClient.

Low-level utilities

The module exposes a stateless, provider-free API for scripts and tools:

Function Purpose
generate_keypair() Generate a random Ed25519 keypair (64 bytes)
keypair_from_seed(seed) Derive a keypair from a 32-byte seed
keypair_from_mnemonic(phrase, passphrase?) Derive a keypair from a BIP39 mnemonic
generate_mnemonic() Generate a fresh BIP39 mnemonic phrase
keypair_from_file(path) Load a Solana-compatible JSON keypair file
public_key_from_keypair(keypair) Extract PublicKey from a 64-byte keypair
sign(keypair, message) Sign a message; returns Signature
verify(pubkey, message, sig) Verify an Ed25519 signature; returns bool
encrypt_secret(secret, sender_pubkey, tee_pubkey) HPKE-encrypt a string secret for TEE programs
transfer_instruction(from, to, kelvin) Build a system-program transfer Instruction
rlo_to_kelvin(rlo) Convert RLO (float) to kelvin (int)
kelvin_to_rlo(kelvin) Convert kelvin (int) to RLO (float)
airdrop_rlo(client, pubkey, rlo_amount) Request airdrop in RLO units

airdrop_rlo is a convenience wrapper that converts RLO to kelvin before calling request_airdrop. Prefer it over calling request_airdrop with a manual conversion.

from rialo_py_cdk import airdrop_rlo, HttpRpcClient, get_devnet_url

client = HttpRpcClient(get_devnet_url())
sig = airdrop_rlo(client, pubkey, 2.5)    # request 2.5 RLO; devnet/testnet only
print("Airdrop:", sig)

Network helpers

from rialo_py_cdk import (
    get_localnet_url,    # "http://127.0.0.1:4104"
    get_devnet_url,      # "https://api.devnet.rialo.xyz"
    get_testnet_url,     # "https://api.testnet.rialo.xyz"
    get_mainnet_url,     # "https://api.mainnet.rialo.xyz"
    get_rpc_url_for_network,
    list_available_networks,
)

url = get_rpc_url_for_network("devnet")
networks = list_available_networks()   # ["localnet", "devnet", "testnet", "mainnet"]

Constants

from rialo_py_cdk import KELVIN_PER_RLO, FILE_STORAGE_AVAILABLE

# Currency: 1 RLO = 1_000_000_000 kelvin
kelvin = int(1.5 * KELVIN_PER_RLO)     # 1_500_000_000

# True when the wheel was compiled with the file-storage feature
if FILE_STORAGE_AVAILABLE:
    from rialo_py_cdk import FileKeyringProvider

Feature flags

All features are enabled by default in the shipped wheel. They can be toggled on the underlying rialo-cdk dependency when building from source with default-features = false.

Feature Enables
file-storage FileKeyringProvider
encryption AES-GCM keyring encryption at rest
hd-wallet BIP32/SLIP-10 HD key derivation
mnemonic BIP39 mnemonic generation and recovery
rpc-client HttpRpcClient
bincode ProgramDeployment, ProgramInvocation, PyLoaderType

FILE_STORAGE_AVAILABLE is exposed as a module-level boolean constant reflecting whether file-storage was compiled in.

Building from source

cd developer-frameworks/cdk/rialo-py-cdk
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"     # triggers maturin via PEP 517; requires Rust stable
pytest tests/

For faster incremental Rust rebuilds use maturin develop (included in the [dev] extras).

Caveats

  • config_hash_prefix — every TransactionBuilder requires a config hash prefix fetched live from client.get_config_hash_prefix(). There is no in-process example constant that live nodes will accept.

  • Currency units — the smallest unit is kelvin; 1 RLO = KELVIN_PER_RLO (1 000 000 000) kelvin. All RPC amounts are in kelvin. Use rlo_to_kelvin and kelvin_to_rlo to convert.

  • Derivation path — Rialo uses BIP44 coin type 756 (m/44'/756'/{index}'). Keys derived on other coin types are not compatible.

  • Synchronous API — all calls block the calling thread. Wrap with asyncio.get_event_loop().run_in_executor or use a thread pool if you need to drive multiple operations concurrently from an async Python application.

  • Keypair bytes — keypair bytes in the low-level API are 64 bytes (secret ++ public). Provider methods that accept secret_key take the raw 32-byte secret only. Passing the wrong length raises RialoException.

  • wallet moduleWallet, InMemoryWalletProvider, FileWalletProvider, and Account are deprecated aliases retained for backward compatibility. Prefer Keyring/KeyringProvider names in new code.

See also

  • rialo-cdk — the underlying Rust crate; source of truth for types and error codes
  • rialo-ts-cdk — TypeScript CDK with equivalent API surface
  • developer-frameworks/cdk/rialo-py-cdk/pyproject.toml — Python package metadata and Maturin build configuration
  • docs/developer/ — contributor setup guide including Rust toolchain requirements

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

rialo_py_cdk-0.16.0a0.tar.gz (978.1 kB view details)

Uploaded Source

Built Distributions

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

rialo_py_cdk-0.16.0a0-cp310-abi3-manylinux_2_28_x86_64.whl (3.7 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.28+ x86-64

rialo_py_cdk-0.16.0a0-cp310-abi3-manylinux_2_28_aarch64.whl (3.9 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.28+ ARM64

rialo_py_cdk-0.16.0a0-cp310-abi3-macosx_11_0_arm64.whl (3.3 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

File details

Details for the file rialo_py_cdk-0.16.0a0.tar.gz.

File metadata

  • Download URL: rialo_py_cdk-0.16.0a0.tar.gz
  • Upload date:
  • Size: 978.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for rialo_py_cdk-0.16.0a0.tar.gz
Algorithm Hash digest
SHA256 cc3a2e6e06d311c6fede4dea998f60569ffad56ab47b2b775e14d48a5f32913b
MD5 16068829758d1035cd05091cc03e751d
BLAKE2b-256 a5ccf0df8250d9b7a9c8b5de439a7f66f5b84f91827d2d80c0a671ef414fff7e

See more details on using hashes here.

File details

Details for the file rialo_py_cdk-0.16.0a0-cp310-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for rialo_py_cdk-0.16.0a0-cp310-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 f552ed900080047a995fd508855409fe0069cad7df38ab906d0584a5e1512a40
MD5 be9fa13d776b1266f27d08aa6d1c0fac
BLAKE2b-256 9b65220bad0ee743cf2d83320c8e001de153fc92c8e4b4c2a61ec6021e6d2313

See more details on using hashes here.

File details

Details for the file rialo_py_cdk-0.16.0a0-cp310-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for rialo_py_cdk-0.16.0a0-cp310-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 fef0b7b9c31a105e8bda37770f828fe69047d1c6ca3a2a034146efa3582d9b03
MD5 b83ea06fdb88e0d00ee8912960cce890
BLAKE2b-256 d890629909251f9a462238affd1a3a78508cc1499bf4859202bed61971af363b

See more details on using hashes here.

File details

Details for the file rialo_py_cdk-0.16.0a0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rialo_py_cdk-0.16.0a0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ca7ccf6e22f73e5c94c0962d46dcbaf3b53a7c6b2fb044c8eb1dd95a8b337f17
MD5 0766ac66625519f5cd66493c176b7fa2
BLAKE2b-256 45079cb6a0ff8d1f69ce0debfd9fec98f7d21ebf5e1b1eb83d4f09b606ba5529

See more details on using hashes here.

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