Skip to content

Core API Reference

The core module provides the primary interface for communicating with the Midnight network, configuration management, and health checking.

Noxipher Client

noxipher.core.client.NoxipherClient

Main entry point for the Noxipher SDK. Coordinates the Indexer, Node, and Proof Server clients.

Source code in src/noxipher/core/client.py
class NoxipherClient:
    """
    Main entry point for the Noxipher SDK.
    Coordinates the Indexer, Node, and Proof Server clients.
    """

    def __init__(
        self, network: Network = Network.PREPROD, custom_config: NetworkConfig | None = None
    ) -> None:
        self.config = custom_config or NETWORK_CONFIGS[network]
        logger.info("Initializing NoxipherClient", network=self.config.name)

        self.node = NodeClient(self.config)
        self.indexer = IndexerClient(self.config)
        self.proof = ProofServerClient(self.config.proof_server_url)
        self.tx = TransactionBuilder(self)

    async def __aenter__(self) -> "NoxipherClient":
        await self.connect()
        return self

    async def __aexit__(self, *args: object) -> None:
        await self.disconnect()

    async def connect(self) -> None:
        """Establishes connections to all Midnight network components."""
        logger.info("Connecting to Midnight network components...")
        await self.node.connect()
        await self.indexer.__aenter__()
        await self.proof.__aenter__()
        logger.info("Connected to Node, Indexer, and Proof Server")

    async def disconnect(self) -> None:
        """Closes all network connections gracefully."""
        logger.info("Disconnecting NoxipherClient...")
        await self.node.disconnect()
        await self.indexer.__aexit__(None, None, None)
        await self.proof.__aexit__(None, None, None)

    async def check_health(self) -> ServiceHealth:
        """Checks the health of all network components."""
        node_health = await self.node.get_health()

        try:
            proof_health = await self.proof.health()
        except Exception:
            proof_health = {}

        # Simple heuristic for indexer health
        try:
            await self.indexer.get_block(height=0)
            indexer_ok = True
        except Exception:
            indexer_ok = False

        status = HealthStatus.OK if (node_health and indexer_ok) else HealthStatus.DOWN

        return ServiceHealth(
            status=status,
            node_connected=node_health is not None,
            indexer_connected=indexer_ok,
            proof_server_connected="version" in proof_health or proof_health.get("status") == "ok",
            details={"node": node_health, "proof_server": proof_health},
        )

    async def get_balance(self, wallet: "MidnightWallet") -> dict[str, int]:
        """Gets the unshielded balance of the given wallet."""
        return await wallet.unshielded.get_balance(self.indexer)

    async def send_unshielded_transaction(
        self, wallet: "MidnightWallet", recipient_address: str, amount: int
    ) -> "TransactionReceipt":
        """Sends an unshielded NIGHT transfer transaction."""
        return await self.tx.transfer(
            wallet=wallet, to=recipient_address, amount=amount, shielded=False
        )

check_health() async

Checks the health of all network components.

Source code in src/noxipher/core/client.py
async def check_health(self) -> ServiceHealth:
    """Checks the health of all network components."""
    node_health = await self.node.get_health()

    try:
        proof_health = await self.proof.health()
    except Exception:
        proof_health = {}

    # Simple heuristic for indexer health
    try:
        await self.indexer.get_block(height=0)
        indexer_ok = True
    except Exception:
        indexer_ok = False

    status = HealthStatus.OK if (node_health and indexer_ok) else HealthStatus.DOWN

    return ServiceHealth(
        status=status,
        node_connected=node_health is not None,
        indexer_connected=indexer_ok,
        proof_server_connected="version" in proof_health or proof_health.get("status") == "ok",
        details={"node": node_health, "proof_server": proof_health},
    )

connect() async

Establishes connections to all Midnight network components.

Source code in src/noxipher/core/client.py
async def connect(self) -> None:
    """Establishes connections to all Midnight network components."""
    logger.info("Connecting to Midnight network components...")
    await self.node.connect()
    await self.indexer.__aenter__()
    await self.proof.__aenter__()
    logger.info("Connected to Node, Indexer, and Proof Server")

disconnect() async

Closes all network connections gracefully.

Source code in src/noxipher/core/client.py
async def disconnect(self) -> None:
    """Closes all network connections gracefully."""
    logger.info("Disconnecting NoxipherClient...")
    await self.node.disconnect()
    await self.indexer.__aexit__(None, None, None)
    await self.proof.__aexit__(None, None, None)

get_balance(wallet) async

Gets the unshielded balance of the given wallet.

Source code in src/noxipher/core/client.py
async def get_balance(self, wallet: "MidnightWallet") -> dict[str, int]:
    """Gets the unshielded balance of the given wallet."""
    return await wallet.unshielded.get_balance(self.indexer)

send_unshielded_transaction(wallet, recipient_address, amount) async

Sends an unshielded NIGHT transfer transaction.

Source code in src/noxipher/core/client.py
async def send_unshielded_transaction(
    self, wallet: "MidnightWallet", recipient_address: str, amount: int
) -> "TransactionReceipt":
    """Sends an unshielded NIGHT transfer transaction."""
    return await self.tx.transfer(
        wallet=wallet, to=recipient_address, amount=amount, shielded=False
    )

Configuration

noxipher.core.config

Health & Status

noxipher.core.health

Exceptions

noxipher.core.exceptions

AddressError

Bases: NoxipherError

Raised when an address format is invalid.

Source code in src/noxipher/core/exceptions.py
class AddressError(NoxipherError):
    """Raised when an address format is invalid."""

    pass

ConfigurationError

Bases: NoxipherError

Raised when configuration is invalid or missing.

Source code in src/noxipher/core/exceptions.py
class ConfigurationError(NoxipherError):
    """Raised when configuration is invalid or missing."""

    pass

ContractError

Bases: NoxipherError

Raised when a smart contract interaction fails.

Source code in src/noxipher/core/exceptions.py
class ContractError(NoxipherError):
    """Raised when a smart contract interaction fails."""

    pass

CryptographyError

Bases: NoxipherError

Raised during cryptographic failures (e.g. invalid keys).

Source code in src/noxipher/core/exceptions.py
class CryptographyError(NoxipherError):
    """Raised during cryptographic failures (e.g. invalid keys)."""

    pass

IndexerError

Bases: NoxipherError

Raised when the Indexer GraphQL API returns an error.

Source code in src/noxipher/core/exceptions.py
class IndexerError(NoxipherError):
    """Raised when the Indexer GraphQL API returns an error."""

    pass

NetworkError

Bases: NoxipherError

Raised when network requests fail.

Source code in src/noxipher/core/exceptions.py
class NetworkError(NoxipherError):
    """Raised when network requests fail."""

    pass

NodeError

Bases: NoxipherError

Raised when the Midnight Node returns an error.

Source code in src/noxipher/core/exceptions.py
class NodeError(NoxipherError):
    """Raised when the Midnight Node returns an error."""

    pass

NoxipherError

Bases: Exception

Base class for all Noxipher exceptions.

Source code in src/noxipher/core/exceptions.py
1
2
3
4
class NoxipherError(Exception):
    """Base class for all Noxipher exceptions."""

    pass

ProofServerError

Bases: NoxipherError

Raised when the ZK Proof Server returns an error.

Source code in src/noxipher/core/exceptions.py
class ProofServerError(NoxipherError):
    """Raised when the ZK Proof Server returns an error."""

    pass

TransactionError

Bases: NoxipherError

Raised during transaction construction or submission failures.

Source code in src/noxipher/core/exceptions.py
class TransactionError(NoxipherError):
    """Raised during transaction construction or submission failures."""

    pass

WalletError

Bases: NoxipherError

Raised for wallet-related issues (e.g. insufficient funds, locked wallet).

Source code in src/noxipher/core/exceptions.py
class WalletError(NoxipherError):
    """Raised for wallet-related issues (e.g. insufficient funds, locked wallet)."""

    pass