diff --git a/README.md b/README.md index 82b0864..835de61 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,8 @@ node = pnrw.Node("nodeIp") # Create a new node instance `headers` (dict): Custom headers that are sent with each request, default value is "Default" +`banano` (bool): Ensures correct configuration when using PNRW for Banano, default is False + --- ## Examples diff --git a/pnrw/exceptions.py b/pnrw/exceptions.py index e7f6db0..2d2b20e 100644 --- a/pnrw/exceptions.py +++ b/pnrw/exceptions.py @@ -1,10 +1,69 @@ +class Error(Exception): + """Base class for other exceptions""" + pass + class AddressInvalid(Exception): def __init__(self, address, message="This address is not valid."): self.message = message super().__init__(self.message) + class BlockInvalid(Exception): def __init__(self, address, message="This block is not valid, are you sure you are sending the right variable?"): self.message = message super().__init__(self.message) + + +class InvalidServerResponseHTML(Exception): + def __init__(self, message="Received invalid response from node (type HTML, expected JSON)"): + self.message = message + super().__init__(self.message) + + +class CannotConnect(Exception): + def __init__(self, message="Failed to establish a new connection to the node"): + self.message = message + super().__init__(self.message) + + +class ActionNotSupported(Exception): + def __init__(self, message="Node does not support the requested function"): + self.message = message + super().__init__(self.message) + + +class WalletNotFound(Exception): + def __init__(self, message="Wallet not found"): + self.message = message + super().__init__(self.message) + + +class InvalidBlockHash(Exception): + def __init__(self, message="Invalid block hash."): + self.message = message + super().__init__(self.message) + + +class UnknownError(Exception): + def __init__(self, message="The node returned an unknown error"): + self.message = message + super().__init__(self.message) + + +class RPCdisabled(Exception): + def __init__(self, message="RPC control is disabled on the node"): + self.message = message + super().__init__(self.message) + + +class InvalidBalanceNumber(Exception): + def __init__(self, message="Invalid balance number"): + self.message = message + super().__init__(self.message) + + +class EmptyResponse(Exception): + def __init__(self, message="Empty server response"): + self.message = message + super().__init__(self.message) diff --git a/pnrw/pnrwf.py b/pnrw/pnrwf.py index 435e2e5..a85d778 100644 --- a/pnrw/pnrwf.py +++ b/pnrw/pnrwf.py @@ -54,14 +54,25 @@ def _validate_block(s): class Node: - def __init__(self, ip, port=7076, dontUseHTTPS=False, headers="Default"): - self.ip = ip - self.port = port - self.secure = "s" if dontUseHTTPS == False else "" + def __init__(self, ip, port="Default", dontUseHTTPS=False, headers="Default", banano=False): + self.ip = ip.lower().replace("https", "").replace("http", "") + self.secure = "https" if dontUseHTTPS == False else "http" + + if port == "Default": + if banano == False: + self.port = 7076 + else: + self.port = 7072 + else: + self.port = port + + self.banano = banano + if _validate_ip(self.ip) == True: - self.target = f"http{self.secure}://{self.ip}:{self.port}" + self.target = f"{self.secure}://{self.ip}:{self.port}" else: - self.target = f"http{self.secure}://{self.ip}" + self.target = f"{self.secure}://{self.ip}" + if headers == "Default": self.headers = {'Content-type': 'application/json', 'Accept': '*/*', "Accept-Encoding": "gzip, deflate, br", "Connection": "keep-alive"} @@ -73,10 +84,34 @@ def _request(self, data): _validate_address(data["account"]) if "block" in data: _validate_block(data["block"]) - - response = requests.post(self.target, data=json.dumps( - data), headers=self.headers).text - return json.loads(response) + try: + response = requests.post(self.target, data=json.dumps( + data), headers=self.headers).text + except requests.exceptions.ConnectionError: + raise CannotConnect() + if response.startswith(""): + raise InvalidServerResponseHTML() + jsload = json.loads(response) + if "message" in jsload: + if jsload["message"] == "Action is not supported": + raise ActionNotSupported() + if "error" in jsload: + if jsload["error"] == "Wallet not found": + raise WalletNotFound() + elif jsload["error"] == "Invalid block hash": + raise InvalidBlockHash() + elif jsload["error"] == "Unknown error": + raise UnknownError() + elif jsload["error"] == "RPC control is disabled": + raise RPCdisabled() + elif jsload["error"] == "Invalid balance number": + raise InvalidBalanceNumber() + elif jsload["error"] == "Empty response": + raise EmptyResponse() + else: + raise UnknownError() + + return jsload def account_balance(self, account): response = self._request(