import httpx class BaseRPCNode: def __init__(self, NODE_OPTION): self.rpcUser = NODE_OPTION.get("rpcUser") self.rpcHost = NODE_OPTION.get("rpcHost") self.rpcPassword = NODE_OPTION.get("rpcPassword") self.rpcPort = NODE_OPTION.get("rpcPort") self.base_url = f"http://{self.rpcHost}:{self.rpcPort}" self.client = httpx.AsyncClient( base_url=self.base_url, auth=(self.rpcUser, self.rpcPassword), timeout=5.0 ) async def callRpcMethod(self, method, params=None): if params is None: params = [] try: response = await self.client.post("/", json={ "jsonrpc": "1.0", "id": "testnet", "method": method, "params": params }) response.raise_for_status() return response.json()["result"] except httpx.HTTPStatusError as e: print("RPC Error:", e.response.text) raise except Exception as e: print("RPC Error:", str(e)) raise async def getblockcount(self): return await self.callRpcMethod("getblockcount", []) async def getblockhash(self, height): return await self.callRpcMethod("getblockhash", [height]) async def getblock(self, param): if isinstance(param, str): return await self.callRpcMethod("getblock", [param, 2]) elif isinstance(param, int): hash_ = await self.getblockhash(param) return await self.callRpcMethod("getblock", [hash_, 2]) else: raise ValueError("param must be str or int") # ================= NEXA ================= class NEXARPCNode(BaseRPCNode): async def verify_wallet(self, address): try: await self.callRpcMethod("getreceivedbyaddress", [address]) return True except Exception: return False async def getblock(self, height): return await self.callRpcMethod("getblock", [height, 2]) async def verify_block(self, height, address): block_data = await self.getblock(height) for item in block_data["tx"]: if len(item["vin"]) == 0: addresses = item["vout"][0]["scriptPubKey"]["addresses"] if address == addresses[0]: return block_data else: return False def block(self, block_data): tx = block_data["tx"] time = block_data["time"] hash_ = block_data["hash"] height = block_data["height"] block_fees = 0 block_reward = 0 for item in tx: if len(item["vin"]) == 0: block_reward = item["sends"] else: block_fees += item.get("fee", 0) return { "height": height, "hash": hash_, "time": time, "block_reward": block_reward, "block_fees": block_fees } # ================= GRS ================= class GRSRPCNode(BaseRPCNode): async def verify_block(self, height, REPORT_ADDRESS): block_data = await self.getblock(height) for item in block_data["tx"]: vin = item["vin"] vout = item["vout"] if vin[0].get("coinbase"): for value in vout: addr = value["scriptPubKey"].get("address") if addr: if addr == REPORT_ADDRESS: return block_data else: return False return False def block(self, data): hash_ = data["hash"] tx = data["tx"] height = data["height"] time = data["time"] reward = 0 fees = 0 for item in tx: vin = item["vin"] vout = item["vout"] if vin[0].get("coinbase"): for value in vout: reward += value["value"] else: fees += item.get("fee", 0) return { "height": height, "hash": hash_, "time": time, "block_reward": reward, "block_fees": fees } # ================= MONA ================= class MONARPCNode(BaseRPCNode): async def verify_block(self, height, REPORT_ADDRESS): block_data = await self.getblock(height) for item in block_data["tx"]: vin = item["vin"] vout = item["vout"] if vin[0].get("coinbase"): for value in vout: addresses = value["scriptPubKey"].get("addresses") if addresses: first = addresses.get("0") if isinstance(addresses, dict) else addresses[0] if first == REPORT_ADDRESS: return block_data else: return False return False def block(self, data): hash_ = data["hash"] tx = data["tx"] height = data["height"] time = data["time"] reward = 0 for item in tx: vin = item["vin"] vout = item["vout"] if vin[0].get("coinbase"): for value in vout: if value["scriptPubKey"].get("addresses"): reward += value["value"] return { "height": height, "hash": hash_, "time": time, "block_reward": reward, "block_fees": None } # ================= DGB ================= class DGBRPCNode(BaseRPCNode): async def verify_block(self, height, REPORT_ADDRESS): block_data = await self.getblock(height) for item in block_data["tx"]: vin = item["vin"] vout = item["vout"] if vin[0].get("coinbase"): for value in vout: addresses = value["scriptPubKey"].get("addresses") if addresses and addresses[0] == REPORT_ADDRESS: return block_data return False async def verify_block_with_algo(self, height, REPORT_ADDRESS, algorithm): block_data = await self.getblock(height) if block_data.get("pow_algo") == algorithm: for item in block_data["tx"]: vin = item["vin"] vout = item["vout"] if vin[0].get("coinbase"): for value in vout: addresses = value["scriptPubKey"].get("addresses") if addresses and addresses[0] == REPORT_ADDRESS: return block_data return False def block(self, data): hash_ = data["hash"] tx = data["tx"] height = data["height"] time = data["time"] reward = 0 for item in tx: vin = item["vin"] vout = item["vout"] if vin[0].get("coinbase"): for value in vout: if value["scriptPubKey"].get("addresses"): reward += value["value"] return { "height": height, "hash": hash_, "time": time, "block_reward": reward, "block_fees": None } # ================= RXD ================= class RXDRPCNode(BaseRPCNode): async def verify_block(self, height, REPORT_ADDRESS): block_data = await self.getblock(height) for item in block_data["tx"]: vin = item["vin"] vout = item["vout"] if vin[0].get("coinbase"): for value in vout: addresses = value["scriptPubKey"].get("addresses") if addresses and addresses[0] == REPORT_ADDRESS: hash_ = await self.getblockhash(height) blockstats = await self.callRpcMethod("getblockstats", [hash_]) return { "height": blockstats["height"], "hash": blockstats["blockhash"], "time": blockstats["time"], "block_reward": blockstats["subsidy"] + blockstats["totalfee"], "block_fees": blockstats["totalfee"] } return False def block(self, data): return data __all__ = [ "NEXARPCNode", "GRSRPCNode", "MONARPCNode", "DGBRPCNode", "RXDRPCNode" ]