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.9 (targets the Python Stable ABI abi3-py39, so a single wheel per platform covers CPython 3.9 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.10.1.tar.gz (938.8 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.10.1-cp39-abi3-manylinux_2_28_x86_64.whl (3.7 MB view details)

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

rialo_py_cdk-0.10.1-cp39-abi3-manylinux_2_28_aarch64.whl (3.8 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.28+ ARM64

rialo_py_cdk-0.10.1-cp39-abi3-macosx_11_0_arm64.whl (3.3 MB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

File details

Details for the file rialo_py_cdk-0.10.1.tar.gz.

File metadata

  • Download URL: rialo_py_cdk-0.10.1.tar.gz
  • Upload date:
  • Size: 938.8 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.10.1.tar.gz
Algorithm Hash digest
SHA256 2f4d7ca9e71490b6adbab17c24f2b8e613f74e181ab44b552ad4e520dc9fdb9b
MD5 bd68c9f7ded1e65262bfca740790e0b6
BLAKE2b-256 2d023c5d10daf9143936a682d89217a95e96d408ccb88f6fcc829b3179be9c89

See more details on using hashes here.

File details

Details for the file rialo_py_cdk-0.10.1-cp39-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for rialo_py_cdk-0.10.1-cp39-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c683f47c638f39941e617f10abbe59ee2c0818f68a878c60b80eb01b03909823
MD5 c275a543bbc7e1172a50664f82505dd0
BLAKE2b-256 478ead2f9b03eea9dff9c7988332f25057a484e17d9c09719ac77b67f869775a

See more details on using hashes here.

File details

Details for the file rialo_py_cdk-0.10.1-cp39-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for rialo_py_cdk-0.10.1-cp39-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 a0b36637139e7e6a6b46ec1755ad20659b9a36c7e87099dda1f4a06fe776fffe
MD5 eb26d5bb020d4e4137714fa071effe39
BLAKE2b-256 0abee62e20fe0ec81e360cd9cec9474f79163681a91ef0123dffbfe93923e60b

See more details on using hashes here.

File details

Details for the file rialo_py_cdk-0.10.1-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rialo_py_cdk-0.10.1-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 29fbb13d801a8f088eb2d38345b83e4ed0a2b8ff49d47dbb279c14f5746ae550
MD5 fedcb3f3649174be2140bd876b1bd09c
BLAKE2b-256 4f7197dc25ea2194879e750a8b6ef5605442b072f8db70eb995f8b607b22db4b

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