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 on Radiant — a UTXO chain with Bitcoin-style script plus induction (recursive covenants) and a native, consensus-enforced token layer. It ships transaction construction, HD wallets, the Glyph token protocol (NFT / FT / dMint), trustless cross-chain atomic swaps, SPV verification, and an ElectrumX client.

What you can build

Things that need a custodian or a bridge elsewhere — on Radiant they're trustless and enforced on-chain:

  • On-chain Glyph tokens (NFT / FT). Supply and transfers enforced by Radiant consensus, not an indexer or a sidecar. → mint an NFT · deploy an FT
  • Permissionless PoW token issuance (dMint). Deploy a token that anyone can mine — distributed issuance, no premine, secured by proof-of-work. Radiant-unique. → pyrxd glyph deploy-dmint / claim-dmint
  • Trustless cross-chain atomic swaps. Trade a Radiant asset (RXD / FT / NFT) against BTC or ETH — and EVM L2s (Base, Optimism, Arbitrum, Linea) — with no bridge and no custodian: a hash-timelock swap driven by a chain-neutral coordinator. Proven end-to-end on regtest and on small real-value mainnet / Sepolia runs. → build a cross-chain swap
  • Recursive covenants. Bitcoin-style script + induction lets a coin constrain the coin that spends it — soulbound NFTs, swap covenants, PoW-mint contracts. → covenant building blocks

New here? The 5-minute quickstart goes from pip install to a real on-chain token on a local regtest chain — no faucet, nothing at risk.

Status

Pre-1.0 software. APIs may change between minor versions before 1.0. pyrxd is open-source software, provided as-is, without warranty of any kind — see the LICENSE (Apache 2.0, §7–8). Cryptographic primitives have not been independently audited. See SECURITY.md for security policy and disclosure.

As with any wallet software on a young chain, 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 (pyrxd address / balance / utxos)
  • BIP32 / BIP39 / BIP44 HD wallets with optional encrypted persistence (HdWallet, pyrxd wallet)
  • Glyph NFT — mint (two-phase commit + reveal) and transfer (pyrxd glyph mint-nft / transfer-nft)
  • Glyph FT — premine deploy and conservation-enforced transfer (pyrxd glyph deploy-ft / transfer-ft)
  • dMint permissionless PoW tokens (V1) — deploy (byte-equal to the live Glyph-protocol deploy, node-consensus-validated) and mine/claim from live mainnet contracts (pyrxd glyph deploy-dmint / claim-dmint)
  • List your Glyph tokens (pyrxd glyph list)
  • pyrxd agent — a per-spend-confirmed signing daemon that keeps the key out of the short-lived CLI process
  • ElectrumX async client with reconnect, balance, UTXOs, history, broadcast

Experimental — newer surface, proven on regtest / testnet (and small real-value runs):

  • Cross-chain HTLC atomic swaps (pyrxd.gravity) — RXD covenant + BTC Taproot + ETH Solidity legs driven by a chain-neutral coordinator; proven end-to-end on regtest (plus small real-value dust runs), against BTC, ETH, and EVM L2s (Base / Optimism / Arbitrum / Linea). This cross-chain swap stack is unaudited — verify it yourself before moving real value.
  • dMint V2 (canonical Photonic redesign — FIXED plus ASERT / LWMA adaptive difficulty) — byte-matched to upstream Photonic and consensus-validated on radiant-core v3.1.1 regtest AND Radiant mainnet (3.1.2): the first V2 dMint deploy + PoW mint confirmed on mainnet, plus an LWMA mint that advanced difficulty on-chain — adaptive difficulty proven on mainnet (#219). V2 deploys are gated behind allow_v2_deploy=True as a deliberate opt-in for the newer format.

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.9.0.tar.gz (633.3 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.9.0-py3-none-any.whl (721.9 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for pyrxd-0.9.0.tar.gz
Algorithm Hash digest
SHA256 03eead4d0c74aa76c6c7c86d7d129c32f65949fa48b48d765484031d7e32302a
MD5 b387f490b7633cc0ff5ac57106e87a3f
BLAKE2b-256 54f86bfa5ddf655249b0efa36d154ab82c38e8c69f3211471dd5c37492599e2f

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyrxd-0.9.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.9.0-py3-none-any.whl.

File metadata

  • Download URL: pyrxd-0.9.0-py3-none-any.whl
  • Upload date:
  • Size: 721.9 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.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e2790237cd98c005153bc4df40ea83509d01934f8c76db7720d03204cbedec28
MD5 10aec51f4a22bd3fe49e82bef7055acf
BLAKE2b-256 c11b5039849fb2dcd0c3d16af5749977ad5aa8a8c4ec5d96d6fdb44fa5cd7576

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyrxd-0.9.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