Skip to main content

Python SDK for the Radiant (RXD) blockchain — transactions, HD wallets, Glyph tokens (NFT/FT/dMint), Gravity cross-chain atomic swaps, SPV, and ElectrumX.

Project description

pyrxd

Python SDK for the Radiant (RXD) blockchain.

License Python Docs

A typed, async-first SDK for building applications on Radiant. Includes transaction construction, HD wallets, the Glyph token protocol (NFT, FT, dMint), Gravity cross-chain atomic swaps, SPV verification, and an ElectrumX network client.

Status

Pre-1.0 software. APIs may change between minor versions before 1.0. Cryptographic primitives have not been independently audited. See SECURITY.md for security policy and disclosure.

⚠️ Use at your own risk. pyrxd is alpha-quality software written primarily by one person; cryptographic code has not been independently audited. Do not use it to handle funds you cannot afford to lose. Verify your derivation paths and transaction outputs against an independent wallet before broadcasting on mainnet. If you find a bug that affects funds, report it via the security policy.

Working on mainnet today:

  • RXD send / send-max, balance and UTXO queries
  • Glyph NFT mint (two-phase commit + reveal) and transfer — see examples/glyph_mint_demo.py
  • Glyph FT premine deploy via prepare_ft_deploy_reveal — entire supply at vout[0]
  • Glyph FT transfer via FtUtxoSet.build_transfer_tx (conservation-enforcing)
  • BIP32/BIP39/BIP44 HD wallets with optional encrypted persistence (HdWallet)
  • ElectrumX async client with reconnect, balance, UTXOs, history, broadcast

Experimental:

  • Gravity cross-chain BTC↔RXD atomic swaps (pyrxd.gravity) — mainnet-proven for sentinel artifact paths; covenant variants still being hardened.
  • dMint PoW-based distributed FT mint — premine-only deploys ship today; the full PoW mint covenant is documented in docs/dmint-followup.md as future work.

Upgrading

Pin pyrxd to a specific version in production and move versions deliberately. Between minor versions before 1.0, APIs can change in breaking ways (see CHANGELOG).

Do not downgrade after creating a wallet with a non-default coin_type. Since 0.3.0, HdWallet stores the derivation coin_type in the wallet file and validates it on load. If you:

  1. Create a wallet at coin_type=0 (e.g. for Photonic recovery)
  2. Downgrade to a pre-0.3.0 pyrxd
  3. Save the wallet under the old code

…the old code will overwrite the stored coin_type with its hardcoded default (512) while the derived keys remain rooted at m/44'/0'/…. A subsequent upgrade and load(..., coin_type=0) will fail validation against the now-corrupted 512 value, locking you out of the friendly recovery path. The underlying funds are still recoverable from the mnemonic, but you will need to re-create the wallet file explicitly with coin_type=0.

Mitigation: pin all machines accessing the same wallet to the same pyrxd version. Downgrading is unsupported once 0.3.0 has written a coin_type-annotated wallet file.

Installation

pip install pyrxd

Requires Python 3.10 or newer.

Quick start

Generate a key and check a balance

import asyncio
from pyrxd.keys import PrivateKey
from pyrxd.network.electrumx import ElectrumXClient, script_hash_for_address

async def main():
    priv = PrivateKey()  # no-arg constructor generates a fresh key
    addr = priv.public_key().address()
    print(f"address: {addr}")

    sh = script_hash_for_address(addr)
    async with ElectrumXClient(["wss://electrumx.radiant4people.com:50022/"]) as client:
        confirmed, unconfirmed = await client.get_balance(sh)
        print(f"balance: {confirmed:,} photons confirmed, {unconfirmed:,} unconfirmed")

asyncio.run(main())

Send RXD

from pyrxd.keys import PrivateKey
from pyrxd.transaction.transaction import Transaction, TransactionInput, TransactionOutput
from pyrxd.script.type import P2PKH

priv = PrivateKey("L1aW4aubDFB7yfras2S1mN3bqg9nwySY8nkoLmJebSLD5BWv3ENZ")
# ... build transaction with inputs and outputs ...
# See examples/ for full flows.

From a BIP39 seed phrase

If you already have a 12/24-word mnemonic (e.g. created by pyrxd wallet new or restored from another Radiant wallet), HdWallet.from_mnemonic gives you a full HD wallet at the correct Radiant BIP44 path (m/44'/512'/<account>').

⚠️ Radiant's BIP44 coin type per SLIP-0044 is 512. Bitcoin's is 0. Many Radiant-native software wallets historically used coin type 0 (a copy from upstream Bitcoin code) and addresses derived that way are different from spec-correct addresses. Tangem (the hardware wallet with Radiant integration) correctly uses coin type 512. As of pyrxd 0.3, the default is coin type 512 to align with the spec and with Tangem.

Migrating from older pyrxd? Earlier versions used coin type 236 (which is BSV's, not Radiant's). To recover funds derived at the old path, set RXD_PY_SDK_BIP44_DERIVATION_PATH=m/44'/236'/0' before running any pyrxd command. Sweep funds to a new spec-correct address, then unset the env var.

from pyrxd.hd import HdWallet

wallet = HdWallet.from_mnemonic("word1 word2 ... word12")
addr = wallet.next_receive_address()
print(f"first receive address: {addr}")

For a one-off private key at a specific path (the equivalent of the short mnemonic + bip32utils snippet some users start from), use the lower-level helpers directly:

from pyrxd.hd import bip44_derive_xprv_from_mnemonic

# Default path is m/44'/512'/0' — the Radiant account 0 key (SLIP-0044).
xprv = bip44_derive_xprv_from_mnemonic("word1 word2 ... word12")
child = xprv.ckd(0).ckd(0)  # m/44'/512'/0'/0/0  (external chain, index 0)
priv = child.private_key()
print(f"WIF:     {priv.wif()}")
print(f"address: {priv.public_key().address()}")

See examples/mnemonic_to_key.py for a runnable version of both flows.

Mint a Glyph NFT

from pyrxd.glyph import GlyphBuilder, GlyphMetadata, GlyphProtocol
from pyrxd.glyph.builder import CommitParams

metadata = GlyphMetadata(
    protocol=[GlyphProtocol.NFT],
    name="My NFT",
    description="A demo non-fungible token.",
)
builder = GlyphBuilder()
commit = builder.prepare_commit(CommitParams(metadata=metadata, owner_pkh=pkh, change_pkh=pkh, funding_satoshis=funding_amount))
# ... broadcast commit, then reveal ...

See examples/glyph_mint_demo.py for a complete end-to-end NFT mint, and examples/ft_deploy_premine.py for an FT premine deployment.

Deploy a fungible token (premine)

from pyrxd.glyph import GlyphBuilder, GlyphMetadata, GlyphProtocol

metadata = GlyphMetadata(
    protocol=[GlyphProtocol.FT],
    name="My Token",
    ticker="MTK",
    description="A premine fungible token.",
)
# Single commit + reveal mints the entire supply to one address.
# See examples/ft_deploy_premine.py for the full flow.

Command line

pip install pyrxd also installs a pyrxd CLI. The command surface is intentionally narrow — it covers wallet management and (in v0.3+) Glyph token operations, the things that don't have a clean equivalent in radiant-cli (the node wallet). For plain RXD sendtoaddress on a node, prefer radiant-cli.

# Create a fresh HD wallet. The mnemonic is shown ONCE — write it down.
pyrxd wallet new

# Show the next unused receive address.
pyrxd address

# Check balance via ElectrumX.
pyrxd balance --refresh

# Look up a deterministic index without scanning.
pyrxd address --index 5

# Quiet mode for scripting.
pyrxd --quiet balance --refresh

pyrxd <command> --help prints the full reference for any subcommand. JSON mode for scripting: pass --json (and --yes for any broadcasting operation).

Security: scripting wallet new with --json --yes

In --json --yes mode, pyrxd wallet new prints the mnemonic in the JSON payload on stdout — that's the only way scripted automation can capture a freshly-generated mnemonic. The user is responsible for ensuring the consumer of stdout is itself secure:

  • Never run pyrxd wallet new --json --yes | tee mnemonic.txt — that writes the mnemonic to disk unencrypted.
  • Never run it in a shell whose history is recorded with stdout — most shells don't capture stdout in history, but some configurations and tools (script, terminal recorders, CI log collectors) do.
  • Don't run it in a container where stdout is logged to a shared log aggregator — containerized stdout is captured by the orchestrator and ends up in centralized logging.

The interactive form (pyrxd wallet new without --json) shows the mnemonic in a clearly-flagged box and waits for the user to press Enter. Even then, terminal scrollback, tmux/screen buffers, and screen-sharing can expose the mnemonic — do not run wallet generation on a shared or recorded display.

Production architecture

If you're building a web app that interacts with Radiant in production, do not put private keys in your web tier. A web RCE in your app then becomes a wallet compromise.

The recommended pattern:

  1. Keep pyrxd as the cryptographic and protocol library — it's safe to import in any process that needs to read chain state.
  2. Run a separate signing service (a small HTTP service that wraps pyrxd) on a different process, ideally a different host, with the private key loaded only there.
  3. Have your web app talk to the signing service over an authenticated API (HMAC-signed requests, mutual TLS, or similar) for any operation that needs a signature.

This is the pattern used by major payment-rail SDKs (Stripe, Square, AWS) and is the correct shape for any application handling real funds.

Documentation

Hosted at mudwoodlabs.github.io/pyrxd (API reference + tutorials + how-to guides + concepts).

Other resources in this repo:

Contributing

See CONTRIBUTING.md for development setup, code style, and how to send a PR. We use the Developer Certificate of Origin for contributor sign-off — no CLA paperwork.

By contributing, you agree your contributions are licensed under Apache 2.0.

Security

Report vulnerabilities privately to security@mudwoodlabs.com. See SECURITY.md for the full policy and disclosure timeline.

License

Apache License 2.0 — see LICENSE and NOTICE.

Copyright 2026 Mudwood Labs.

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

pyrxd-0.6.0.tar.gz (510.2 kB view details)

Uploaded Source

Built Distribution

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

pyrxd-0.6.0-py3-none-any.whl (581.2 kB view details)

Uploaded Python 3

File details

Details for the file pyrxd-0.6.0.tar.gz.

File metadata

  • Download URL: pyrxd-0.6.0.tar.gz
  • Upload date:
  • Size: 510.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for pyrxd-0.6.0.tar.gz
Algorithm Hash digest
SHA256 d44d10db3aa8a20d51ad5493a9d7aa5de998cd7585cf1c2d3a3d65f5f600de33
MD5 f640b35de408dcd2cc8045effb2b09fd
BLAKE2b-256 56ce9c3e9876cc14c8c2bd96bdb9401ec2d45abec360fa897eaf325764a9a316

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyrxd-0.6.0.tar.gz:

Publisher: publish.yml on MudwoodLabs/pyrxd

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

File details

Details for the file pyrxd-0.6.0-py3-none-any.whl.

File metadata

  • Download URL: pyrxd-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 581.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for pyrxd-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 083207d8e63024736dfee53cd1267cb4bd856857306ba010a36957ee43e77818
MD5 6f98d4af5ad200196d7a16547a6f6321
BLAKE2b-256 67312ccc28443e1385e5b1f7ac92d6c0be690d3873d62dcfc78c2ceaac16bf5a

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyrxd-0.6.0-py3-none-any.whl:

Publisher: publish.yml on MudwoodLabs/pyrxd

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