RPC

basicnanoclient.rpc.RPC

Nano RPC Client.

>>> from basicnanoclient.rpc import RPC
>>> client = RPC("http://127.0.0.1:17076")
>>> client.send(...)
Source code in basicnanoclient/rpc.py
class RPC():
    """Nano RPC Client.

    ```py
    >>> from basicnanoclient.rpc import RPC
    >>> client = RPC("http://127.0.0.1:17076")
    >>> client.send(...)
    ```
    """

    def __init__(self: Self, rpc_network: str) -> None:
        """Constructor."""
        self.rpc_network = rpc_network

    def account_info(self: Self, account: str) -> Dict[str, Any]:
        """Retrieve information about a Nano account.

        Including its balance and representative.

        Args:
            account (str): The Nano account address.

        Returns:
            A dictionary with various account information, including:
                'frontier', 'balance', 'representative', and 'block_count'.

        Raises:
            requests.exceptions.RequestException: due to the RPC request.
        """
        return session.post(self.rpc_network, json={
            "action": "account_info",
            "representative": "true",
            "account": account
        }).json()

    def ledger(self: Self, account: str, count: int) -> Dict[str, Any]:
        """Retrieve the transaction history for a Nano account.

        Args:
            account (str): The Nano account address.
            count (int): The maximum number of transactions to retrieve.

        Returns:
            A dictionary containing the transaction history
                for the Nano account.
        """
        return session.post(self.rpc_network, json={
            "action": "ledger",
            "account": account,
            "count": count
        }).json()

    def receivable(
            self: Self,
            account: str,
            count: int = 1,
            threshold: int = 1) -> Dict[str, Any]:
        """Retrieve a list of pending Nano transactions for an account.

        Args:
            account (str): The Nano account address.
            count (int): The maximum number of transactions to retrieve
                (default is 1).
            threshold (int): The minimum amount of Nano pending in raw units
                (default is 1 raw Nano).

        Returns:
            A dictionary containing a list of pending Nano transactions
                for the account.
        """
        return session.post(self.rpc_network, json={
            "action": "receivable",
            "account": account,
            "count": count,
            "threshold": threshold,
            "source": "true"
        }).json()

    def block_info(self: Self, block: str) -> dict:
        """Retrieve information about a Nano block.

        Args:
            block (str): The block hash.

        Returns:
            dict: A dictionary containing information about the block.
        """
        return session.post(self.rpc_network, json={
            "action": "block_info",
            "json_block": "true",
            "hash": block
        }).json()

    def account_representative(self: Self, account: str) -> dict:
        """Retrieve the representative for a Nano account.

        Args:
            account (str): The Nano account address.

        Returns:
            dict: A dictionary containing the representative for the account.
        """
        return session.post(self.rpc_network, json={
            "action": "account_representative",
            "account": account
        }).json()

    def work_validate(self: Self, work: str, hash: str) -> dict:
        """Validate a proof of work.

        Args:
            work (str): The proof of work.
            hash (str): The block hash.

        Returns:
            dict: A dictionary containing information about the proof of work.
        """
        return session.post(self.rpc_network, json={
            "action": "work_validate",
            "work": work,
            "hash": hash
        }).json()

    def process(self: Self, block: dict, sub_type: str = "send") -> dict:
        """Process a block.

        Args:
            block (dict): The block to be processed.

        Returns:
            dict: A dictionary containing information about the block.
        """
        request = {
            "action": "process",
            "json_block": "true",
            "sub_type": sub_type,
            "block": block
        }
        response = requests.post(self.rpc_network, json=request)
        return response.json()

    def receive_all(self: Self):
        """Not Implemented."""
        print("Not Implemented")

    def receive(
            self: Self,
            account: str,
            private_key: str,
            source_hash: str,
            received_amount: int,
            work: str = None) -> Dict[str, Any]:
        """Create a receive block for an already open Nano account.

        Args:
            account (str): The Nano account address to receive into.
            private_key (str): The private key of the account receiving the Nano.
            source_hash (str): The hash of the block being received.
            received_amount (int): The amount of Nano being received in raw units.
            work (str): The proof of work for the block.

        Returns:
            A dictionary containing information about the transaction.
        """
        account_info = self.account_info(account)
        previous = account_info["frontier"]
        balance = account_info["balance"]

        # Calculate the new balance after receiving
        new_balance = str(int(balance) + int(received_amount))

        # Representative can be the same as the account or a dedicated representative
        representative = account

        # Generate work for the previous block
        if work is None:
            work = Wallet.generate_work_rpc(previous, self.rpc_network)

        # Create the receive block
        block = {
            "type": "state",
            "account": account,
            "previous": previous,
            "representative": representative,
            "balance": new_balance,
            "link": source_hash,
            "signature": "",
            "work": work
        }

        # Sign the block
        block["signature"] = Wallet.sign_block(block, private_key)

        # Process the block
        response = self.process(block, "receive")
        return response

    def send(
            self: Self,
            source: str,
            destination: str,
            amount: int,
            key: str,
            work: str = None) -> Dict[str, Any]:
        """Send a specified amount of Nano from one account to another.

        Args:
            source (str): The Nano account address to send from.
            destination (str): The Nano account address to send to.
            amount (int): The amount of Nano to send in raw units.
            key (str): The private key of the account sending the Nano.
            work (str): The proof of work for the block.

        Returns:
            A dictionary containing information about the transaction.
        """
        account_info = self.account_info(source)
        previous = account_info["frontier"]
        balance = int(account_info["balance"])

        # Calculate the new balance after sending
        new_balance = balance - amount

        # Representative can be the same as the source account or a dedicated representative
        representative = source

        # Generate work for the previous block
        if work is None:
            work = Wallet.generate_work_rpc(previous, self.rpc_network)

        # Get public key for the destination account
        destination_public_key = Utils.nano_address_to_public_key(destination)

        # Create the send block
        block = {
            "type": "state",
            "account": source,
            "previous": previous,
            "representative": representative,
            "balance": str(new_balance),
            "link": destination_public_key,
            "signature": "",
            "work": work
        }

        # Sign the block
        block["signature"] = Wallet.sign_block(block, key)

        # Process the block
        response = self.process(block, "send")
        return response

    def open_account(
            self: Self,
            account: str,
            private_key: str,
            public_key: str,
            send_block_hash: str,
            received_amount: str,
            work: str = None) -> dict:
        """Open a new Nano account.

        Args:
            account (str): The account to open.
            private_key (str): The private key of the account.
            public_key (str): The public key of the account.
            send_block_hash (str): The hash of the first block.
            received_amount (str): The balance of the account.
            work (str): The proof of work for the block.

        Returns:
            dict: A dictionary containing information about the transaction.
        """
        previous = '0000000000000000000000000000000000000000000000000000000000000000'
        representative = account

        # Generate work using public key
        if work is None:
            work = Wallet.generate_work_rpc(public_key, self.rpc_network)

        # Create the block
        block = {
            "type": "state",
            "account": account,
            "previous": previous,
            "representative": representative,
            "balance": received_amount,
            "link": send_block_hash,
            "signature": "",
            "work": work
        }

        # Add the signature
        block["signature"] = Wallet.sign_block(block, private_key)

        # Process the block
        response = self.process(block, "open")
        return response

__init__(rpc_network)

Constructor.

Source code in basicnanoclient/rpc.py
def __init__(self: Self, rpc_network: str) -> None:
    """Constructor."""
    self.rpc_network = rpc_network

account_info(account)

Retrieve information about a Nano account.

Including its balance and representative.

Parameters:
  • account (str) –

    The Nano account address.

Returns:
  • Dict[str, Any]

    A dictionary with various account information, including: 'frontier', 'balance', 'representative', and 'block_count'.

Raises:
  • RequestException

    due to the RPC request.

Source code in basicnanoclient/rpc.py
def account_info(self: Self, account: str) -> Dict[str, Any]:
    """Retrieve information about a Nano account.

    Including its balance and representative.

    Args:
        account (str): The Nano account address.

    Returns:
        A dictionary with various account information, including:
            'frontier', 'balance', 'representative', and 'block_count'.

    Raises:
        requests.exceptions.RequestException: due to the RPC request.
    """
    return session.post(self.rpc_network, json={
        "action": "account_info",
        "representative": "true",
        "account": account
    }).json()

ledger(account, count)

Retrieve the transaction history for a Nano account.

Parameters:
  • account (str) –

    The Nano account address.

  • count (int) –

    The maximum number of transactions to retrieve.

Returns:
  • Dict[str, Any]

    A dictionary containing the transaction history for the Nano account.

Source code in basicnanoclient/rpc.py
def ledger(self: Self, account: str, count: int) -> Dict[str, Any]:
    """Retrieve the transaction history for a Nano account.

    Args:
        account (str): The Nano account address.
        count (int): The maximum number of transactions to retrieve.

    Returns:
        A dictionary containing the transaction history
            for the Nano account.
    """
    return session.post(self.rpc_network, json={
        "action": "ledger",
        "account": account,
        "count": count
    }).json()

receivable(account, count=1, threshold=1)

Retrieve a list of pending Nano transactions for an account.

Parameters:
  • account (str) –

    The Nano account address.

  • count (int, default: 1 ) –

    The maximum number of transactions to retrieve (default is 1).

  • threshold (int, default: 1 ) –

    The minimum amount of Nano pending in raw units (default is 1 raw Nano).

Returns:
  • Dict[str, Any]

    A dictionary containing a list of pending Nano transactions for the account.

Source code in basicnanoclient/rpc.py
def receivable(
        self: Self,
        account: str,
        count: int = 1,
        threshold: int = 1) -> Dict[str, Any]:
    """Retrieve a list of pending Nano transactions for an account.

    Args:
        account (str): The Nano account address.
        count (int): The maximum number of transactions to retrieve
            (default is 1).
        threshold (int): The minimum amount of Nano pending in raw units
            (default is 1 raw Nano).

    Returns:
        A dictionary containing a list of pending Nano transactions
            for the account.
    """
    return session.post(self.rpc_network, json={
        "action": "receivable",
        "account": account,
        "count": count,
        "threshold": threshold,
        "source": "true"
    }).json()

block_info(block)

Retrieve information about a Nano block.

Parameters:
  • block (str) –

    The block hash.

Returns:
  • dict( dict ) –

    A dictionary containing information about the block.

Source code in basicnanoclient/rpc.py
def block_info(self: Self, block: str) -> dict:
    """Retrieve information about a Nano block.

    Args:
        block (str): The block hash.

    Returns:
        dict: A dictionary containing information about the block.
    """
    return session.post(self.rpc_network, json={
        "action": "block_info",
        "json_block": "true",
        "hash": block
    }).json()

account_representative(account)

Retrieve the representative for a Nano account.

Parameters:
  • account (str) –

    The Nano account address.

Returns:
  • dict( dict ) –

    A dictionary containing the representative for the account.

Source code in basicnanoclient/rpc.py
def account_representative(self: Self, account: str) -> dict:
    """Retrieve the representative for a Nano account.

    Args:
        account (str): The Nano account address.

    Returns:
        dict: A dictionary containing the representative for the account.
    """
    return session.post(self.rpc_network, json={
        "action": "account_representative",
        "account": account
    }).json()

work_validate(work, hash)

Validate a proof of work.

Parameters:
  • work (str) –

    The proof of work.

  • hash (str) –

    The block hash.

Returns:
  • dict( dict ) –

    A dictionary containing information about the proof of work.

Source code in basicnanoclient/rpc.py
def work_validate(self: Self, work: str, hash: str) -> dict:
    """Validate a proof of work.

    Args:
        work (str): The proof of work.
        hash (str): The block hash.

    Returns:
        dict: A dictionary containing information about the proof of work.
    """
    return session.post(self.rpc_network, json={
        "action": "work_validate",
        "work": work,
        "hash": hash
    }).json()

process(block, sub_type='send')

Process a block.

Parameters:
  • block (dict) –

    The block to be processed.

Returns:
  • dict( dict ) –

    A dictionary containing information about the block.

Source code in basicnanoclient/rpc.py
def process(self: Self, block: dict, sub_type: str = "send") -> dict:
    """Process a block.

    Args:
        block (dict): The block to be processed.

    Returns:
        dict: A dictionary containing information about the block.
    """
    request = {
        "action": "process",
        "json_block": "true",
        "sub_type": sub_type,
        "block": block
    }
    response = requests.post(self.rpc_network, json=request)
    return response.json()

receive_all()

Not Implemented.

Source code in basicnanoclient/rpc.py
def receive_all(self: Self):
    """Not Implemented."""
    print("Not Implemented")

receive(account, private_key, source_hash, received_amount, work=None)

Create a receive block for an already open Nano account.

Parameters:
  • account (str) –

    The Nano account address to receive into.

  • private_key (str) –

    The private key of the account receiving the Nano.

  • source_hash (str) –

    The hash of the block being received.

  • received_amount (int) –

    The amount of Nano being received in raw units.

  • work (str, default: None ) –

    The proof of work for the block.

Returns:
  • Dict[str, Any]

    A dictionary containing information about the transaction.

Source code in basicnanoclient/rpc.py
def receive(
        self: Self,
        account: str,
        private_key: str,
        source_hash: str,
        received_amount: int,
        work: str = None) -> Dict[str, Any]:
    """Create a receive block for an already open Nano account.

    Args:
        account (str): The Nano account address to receive into.
        private_key (str): The private key of the account receiving the Nano.
        source_hash (str): The hash of the block being received.
        received_amount (int): The amount of Nano being received in raw units.
        work (str): The proof of work for the block.

    Returns:
        A dictionary containing information about the transaction.
    """
    account_info = self.account_info(account)
    previous = account_info["frontier"]
    balance = account_info["balance"]

    # Calculate the new balance after receiving
    new_balance = str(int(balance) + int(received_amount))

    # Representative can be the same as the account or a dedicated representative
    representative = account

    # Generate work for the previous block
    if work is None:
        work = Wallet.generate_work_rpc(previous, self.rpc_network)

    # Create the receive block
    block = {
        "type": "state",
        "account": account,
        "previous": previous,
        "representative": representative,
        "balance": new_balance,
        "link": source_hash,
        "signature": "",
        "work": work
    }

    # Sign the block
    block["signature"] = Wallet.sign_block(block, private_key)

    # Process the block
    response = self.process(block, "receive")
    return response

send(source, destination, amount, key, work=None)

Send a specified amount of Nano from one account to another.

Parameters:
  • source (str) –

    The Nano account address to send from.

  • destination (str) –

    The Nano account address to send to.

  • amount (int) –

    The amount of Nano to send in raw units.

  • key (str) –

    The private key of the account sending the Nano.

  • work (str, default: None ) –

    The proof of work for the block.

Returns:
  • Dict[str, Any]

    A dictionary containing information about the transaction.

Source code in basicnanoclient/rpc.py
def send(
        self: Self,
        source: str,
        destination: str,
        amount: int,
        key: str,
        work: str = None) -> Dict[str, Any]:
    """Send a specified amount of Nano from one account to another.

    Args:
        source (str): The Nano account address to send from.
        destination (str): The Nano account address to send to.
        amount (int): The amount of Nano to send in raw units.
        key (str): The private key of the account sending the Nano.
        work (str): The proof of work for the block.

    Returns:
        A dictionary containing information about the transaction.
    """
    account_info = self.account_info(source)
    previous = account_info["frontier"]
    balance = int(account_info["balance"])

    # Calculate the new balance after sending
    new_balance = balance - amount

    # Representative can be the same as the source account or a dedicated representative
    representative = source

    # Generate work for the previous block
    if work is None:
        work = Wallet.generate_work_rpc(previous, self.rpc_network)

    # Get public key for the destination account
    destination_public_key = Utils.nano_address_to_public_key(destination)

    # Create the send block
    block = {
        "type": "state",
        "account": source,
        "previous": previous,
        "representative": representative,
        "balance": str(new_balance),
        "link": destination_public_key,
        "signature": "",
        "work": work
    }

    # Sign the block
    block["signature"] = Wallet.sign_block(block, key)

    # Process the block
    response = self.process(block, "send")
    return response

open_account(account, private_key, public_key, send_block_hash, received_amount, work=None)

Open a new Nano account.

Parameters:
  • account (str) –

    The account to open.

  • private_key (str) –

    The private key of the account.

  • public_key (str) –

    The public key of the account.

  • send_block_hash (str) –

    The hash of the first block.

  • received_amount (str) –

    The balance of the account.

  • work (str, default: None ) –

    The proof of work for the block.

Returns:
  • dict( dict ) –

    A dictionary containing information about the transaction.

Source code in basicnanoclient/rpc.py
def open_account(
        self: Self,
        account: str,
        private_key: str,
        public_key: str,
        send_block_hash: str,
        received_amount: str,
        work: str = None) -> dict:
    """Open a new Nano account.

    Args:
        account (str): The account to open.
        private_key (str): The private key of the account.
        public_key (str): The public key of the account.
        send_block_hash (str): The hash of the first block.
        received_amount (str): The balance of the account.
        work (str): The proof of work for the block.

    Returns:
        dict: A dictionary containing information about the transaction.
    """
    previous = '0000000000000000000000000000000000000000000000000000000000000000'
    representative = account

    # Generate work using public key
    if work is None:
        work = Wallet.generate_work_rpc(public_key, self.rpc_network)

    # Create the block
    block = {
        "type": "state",
        "account": account,
        "previous": previous,
        "representative": representative,
        "balance": received_amount,
        "link": send_block_hash,
        "signature": "",
        "work": work
    }

    # Add the signature
    block["signature"] = Wallet.sign_block(block, private_key)

    # Process the block
    response = self.process(block, "open")
    return response