pyrxd.network — ElectrumX + BTC sources

pyrxd.network — network layer for Radiant / Bitcoin SPV.

Re-exports the public surface of the sub-modules so callers can do:

from pyrxd.network import ElectrumXClient, ChainTracker, …

class pyrxd.network.BitcoinCoreRpcSource[source]

Bases: BtcDataSource

BtcDataSource backed by a Bitcoin Core JSON-RPC endpoint.

Credentials are stored as SecretBytes and never logged.

Parameters:
  • url – RPC endpoint URL, e.g. http://localhost:8332/.

  • user – RPC username.

  • password – RPC password (stored securely as SecretBytes).

__init__(url, user, password)[source]
Parameters:
Return type:

None

async close()[source]

Close any underlying connections held by this source.

Return type:

None

async get_block_hash(height)[source]

Return the 32-byte block hash at height.

Parameters:

height (BlockHeight)

Return type:

Hex32

async get_block_header_hex(height)[source]

Return the raw 80-byte block header at height.

Parameters:

height (BlockHeight)

Return type:

bytes

async get_header_chain(start_height, count)[source]

Return count consecutive 80-byte headers starting at start_height.

Parameters:
Return type:

list[bytes]

async get_merkle_proof(txid, height)[source]

Return (branch_hashes_hex, leaf_position) for txid at height.

Parameters:
Return type:

tuple[list[str], int]

async get_raw_tx(txid, min_confirmations=6)[source]

Return raw transaction bytes, enforcing min_confirmations.

Parameters:
  • txid (Txid)

  • min_confirmations (int)

Return type:

RawTx

async get_tip_height()[source]

Return the current chain tip block height.

Return type:

BlockHeight

async get_tx_block_height(txid)[source]

Return the block height at which txid was confirmed.

Raises NetworkError if the transaction is unconfirmed or not found.

Parameters:

txid (Txid)

Return type:

BlockHeight

async get_tx_output_script_type(txid, output_index)[source]

Return the output script type: p2pkh, p2wpkh, p2sh, p2tr, or unknown.

Parameters:
Return type:

str

class pyrxd.network.BlockstreamSource[source]

Bases: BtcDataSource

BtcDataSource backed by the blockstream.info HTTP API.

__init__(base_url='https://blockstream.info/api')[source]
Parameters:

base_url (str)

Return type:

None

async close()[source]

Close any underlying connections held by this source.

Return type:

None

async get_block_hash(height)[source]

Return the 32-byte block hash at height.

Parameters:

height (BlockHeight)

Return type:

Hex32

async get_block_header_hex(height)[source]

Return the raw 80-byte block header at height.

Parameters:

height (BlockHeight)

Return type:

bytes

async get_header_chain(start_height, count)[source]

Return count consecutive 80-byte headers starting at start_height.

Parameters:
Return type:

list[bytes]

async get_merkle_proof(txid, height)[source]

Return (branch_hashes_hex, leaf_position) for txid at height.

Parameters:
Return type:

tuple[list[str], int]

async get_raw_tx(txid, min_confirmations=6)[source]

Return raw transaction bytes, enforcing min_confirmations.

Parameters:
  • txid (Txid)

  • min_confirmations (int)

Return type:

RawTx

async get_tip_height()[source]

Return the current chain tip block height.

Return type:

BlockHeight

async get_tx_block_height(txid)[source]

Return the block height at which txid was confirmed.

Raises NetworkError if the transaction is unconfirmed or not found.

Parameters:

txid (Txid)

Return type:

BlockHeight

async get_tx_output_script_type(txid, output_index)[source]

Return the output script type: p2pkh, p2wpkh, p2sh, p2tr, or unknown.

Parameters:
Return type:

str

class pyrxd.network.BtcDataSource[source]

Bases: ABC

Abstract interface for blockchain data providers.

abstractmethod async close()[source]

Close any underlying connections held by this source.

Return type:

None

abstractmethod async get_block_hash(height)[source]

Return the 32-byte block hash at height.

Parameters:

height (BlockHeight)

Return type:

Hex32

abstractmethod async get_block_header_hex(height)[source]

Return the raw 80-byte block header at height.

Parameters:

height (BlockHeight)

Return type:

bytes

abstractmethod async get_header_chain(start_height, count)[source]

Return count consecutive 80-byte headers starting at start_height.

Parameters:
Return type:

list[bytes]

abstractmethod async get_merkle_proof(txid, height)[source]

Return (branch_hashes_hex, leaf_position) for txid at height.

Parameters:
Return type:

tuple[list[str], int]

abstractmethod async get_raw_tx(txid, min_confirmations=6)[source]

Return raw transaction bytes, enforcing min_confirmations.

Parameters:
  • txid (Txid)

  • min_confirmations (int)

Return type:

RawTx

abstractmethod async get_tip_height()[source]

Return the current chain tip block height.

Return type:

BlockHeight

abstractmethod async get_tx_block_height(txid)[source]

Return the block height at which txid was confirmed.

Raises NetworkError if the transaction is unconfirmed or not found.

Parameters:

txid (Txid)

Return type:

BlockHeight

abstractmethod async get_tx_output_script_type(txid, output_index)[source]

Return the output script type: p2pkh, p2wpkh, p2sh, p2tr, or unknown.

Parameters:
Return type:

str

class pyrxd.network.ChainTracker[source]

Bases: object

Verifies Merkle inclusion proofs against confirmed block headers.

Bitcoin block header layout (80 bytes, all fields little-endian):
  • version : 4 bytes [0:4]

  • prev_hash : 32 bytes [4:36]

  • merkle_root : 32 bytes [36:68] ← compared here

  • time : 4 bytes [68:72]

  • bits : 4 bytes [72:76]

  • nonce : 4 bytes [76:80]

The merkle_root in the header is stored in little-endian byte order, matching the convention used by MerklePath.compute_root().

__init__(btc_source)[source]
Parameters:

btc_source (BtcDataSource)

Return type:

None

async is_valid_root(merkle_root, height)[source]

Fetch the block header at height and check its Merkle root.

Parameters:
  • merkle_root (Hex32) – The 32-byte Merkle root to verify (as Hex32).

  • height (BlockHeight) – Block height of the header to check against.

Returns:

True if the header’s Merkle root matches merkle_root.

Return type:

bool

async is_valid_root_for_height(root_hex, height)[source]

Convenience wrapper accepting hex string root and plain int height.

This matches the signature expected by MerklePath.verify().

Parameters:
  • root_hex (str) – 64-char lowercase hex string (big-endian display order, as returned by MerklePath.compute_root()).

  • height (int) – Block height as a plain int.

Return type:

bool

class pyrxd.network.ElectrumXClient[source]

Bases: object

Async ElectrumX JSON-RPC client.

Parameters:
  • urls – One or more ElectrumX server URLs. The client uses the first URL; on disconnect it attempts one reconnect, then raises NetworkError.

  • allow_insecure – If False (default) ws:// URLs raise NetworkError immediately. Set to True only for local testing.

  • timeout – Per-request timeout in seconds (default 30).

__init__(urls, *, allow_insecure=False, timeout=30.0)[source]
Parameters:
Return type:

None

async broadcast(raw_tx)[source]

Broadcast a raw transaction to the network.

Parameters:

raw_tx (bytes) – Serialised transaction bytes.

Returns:

The transaction id returned by the server.

Return type:

Txid

async close()[source]

Close the underlying WebSocket connection.

Cancels the reader task, fails any in-flight requests with NetworkError, and closes the socket.

Return type:

None

async get_balance(script_hash)[source]

Return the confirmed and unconfirmed balance for script_hash.

The script_hash is sha256(locking_script) with bytes reversed (ElectrumX little-endian convention). Accepts Hex32, raw bytes (length 32), or a hex str (length 64).

Returns:

(confirmed, unconfirmed)

Return type:

tuple[Satoshis, Satoshis]

Parameters:

script_hash (Hex32 | bytes | str)

async get_block_header(height)[source]

Return the raw 80-byte block header at height.

Parameters:

height (BlockHeight)

Return type:

bytes

async get_history(script_hash)[source]

Return the transaction history for script_hash.

Returns a list of {"tx_hash": str, "height": int} dicts. Unconfirmed transactions have height of 0 or negative.

Parameters:

script_hash (Hex32 | bytes | str)

Return type:

list[dict]

async get_tip_height()[source]

Return the current chain tip block height.

Uses blockchain.block.header with cp_height=0, which is a proper one-shot RPC call. The subscription method blockchain.headers.subscribe is avoided here because it installs a server-side push subscription; subsequent push notifications would arrive interleaved with other _call() responses on a long-lived connection.

Response format: {“height”: N, “hex”: “…”}

Return type:

BlockHeight

async get_transaction(txid)[source]

Fetch the raw transaction bytes for txid.

Returns:

The serialised transaction (> 64 bytes, Merkle-forgery safe).

Return type:

RawTx

Parameters:

txid (Txid)

async get_transaction_merkle(txid, height)[source]

Fetch the Merkle proof for txid at block height.

Returns:

A parsed Merkle path object.

Return type:

MerklePath

Parameters:
async get_transaction_verbose(txid)[source]

Fetch the verbose JSON-decoded form of a transaction.

Calls blockchain.transaction.get with verbose=True and returns the dict the server provides — including confirmations, blockhash, blocktime. Used by confirmation polling.

Distinct from get_transaction() (which returns raw bytes for cryptographic operations like merkle-proof checks). Callers polling for “is this tx confirmed yet?” want THIS one.

Parameters:

txid (Txid)

Return type:

dict[str, Any]

async get_utxos(script_hash)[source]

Return the list of UTXOs for script_hash.

Accepts Hex32, raw bytes (length 32), or a hex str (length 64). Each UTXO is returned as a typed UtxoRecord.

Parameters:

script_hash (Hex32 | bytes | str)

Return type:

list[UtxoRecord]

class pyrxd.network.MempoolSpaceSource[source]

Bases: BtcDataSource

BtcDataSource backed by the mempool.space HTTP API.

Parameters:

base_url – Base URL of the API (default https://mempool.space/api).

__init__(base_url='https://mempool.space/api')[source]
Parameters:

base_url (str)

Return type:

None

async close()[source]

Close the underlying HTTP session.

Return type:

None

async get_block_hash(height)[source]

Return the 32-byte block hash at height.

Parameters:

height (BlockHeight)

Return type:

Hex32

async get_block_header_hex(height)[source]

Return the raw 80-byte block header at height.

Parameters:

height (BlockHeight)

Return type:

bytes

async get_header_chain(start_height, count)[source]

Return count consecutive 80-byte headers starting at start_height.

Parameters:
Return type:

list[bytes]

async get_merkle_proof(txid, height)[source]

Return (branch_hashes_hex, leaf_position) for txid at height.

Parameters:
Return type:

tuple[list[str], int]

async get_raw_tx(txid, min_confirmations=6)[source]

Return raw transaction bytes, enforcing min_confirmations.

Parameters:
  • txid (Txid)

  • min_confirmations (int)

Return type:

RawTx

async get_tip_height()[source]

Return the current chain tip block height.

Return type:

BlockHeight

async get_tx_block_height(txid)[source]

Return the block height at which txid was confirmed.

Raises NetworkError if the transaction is unconfirmed or not found.

Parameters:

txid (Txid)

Return type:

BlockHeight

async get_tx_output_script_type(txid, output_index)[source]

Return the output script type: p2pkh, p2wpkh, p2sh, p2tr, or unknown.

Parameters:
Return type:

str

class pyrxd.network.MultiSourceBtcDataSource[source]

Bases: BtcDataSource

A quorum-based composite data source.

For read operations, all sources are queried concurrently and the result is returned only if at least quorum sources agree. For broadcast-style operations, sources are tried in order until one succeeds.

Parameters:
  • sources – Two or more BtcDataSource instances.

  • quorum – Minimum number of agreeing sources required (default 2).

__init__(sources, quorum=2)[source]
Parameters:
Return type:

None

async close()[source]

Close all underlying sources.

Return type:

None

async get_block_hash(height)[source]

Return the 32-byte block hash at height.

Parameters:

height (BlockHeight)

Return type:

Hex32

async get_block_header_hex(height)[source]

Return the raw 80-byte block header at height.

Parameters:

height (BlockHeight)

Return type:

bytes

async get_header_chain(start_height, count)[source]

Return count consecutive 80-byte headers starting at start_height.

Parameters:
Return type:

list[bytes]

async get_merkle_proof(txid, height)[source]

Return (branch_hashes_hex, leaf_position) for txid at height.

Parameters:
Return type:

tuple[list[str], int]

async get_raw_tx(txid, min_confirmations=6)[source]

Return raw transaction bytes, enforcing min_confirmations.

Parameters:
  • txid (Txid)

  • min_confirmations (int)

Return type:

RawTx

async get_tip_height()[source]

Return the current chain tip block height.

Return type:

BlockHeight

async get_tx_block_height(txid)[source]

Return the block height at which txid was confirmed.

Raises NetworkError if the transaction is unconfirmed or not found.

Parameters:

txid (Txid)

Return type:

BlockHeight

async get_tx_output_script_type(txid, output_index)[source]

Return the output script type: p2pkh, p2wpkh, p2sh, p2tr, or unknown.

Parameters:
Return type:

str