Browse Source

rpc: new `RemoteRPCClient` class

The MMGen Project 6 months ago
parent
commit
32581129d5
4 changed files with 68 additions and 28 deletions
  1. 32 24
      mmgen/rpc/__init__.py
  2. 1 0
      mmgen/rpc/local.py
  3. 24 0
      mmgen/rpc/remote.py
  4. 11 4
      mmgen/tw/view.py

+ 32 - 24
mmgen/rpc/__init__.py

@@ -31,30 +31,38 @@ async def rpc_init(
 	if not 'rpc_init' in proto.mmcaps:
 		die(1, f'rpc_init() not supported for {proto.name} protocol!')
 
+	mod, clsname = (
+		('local', 'RPCClient') if 'rpc' in proto.mmcaps else
+		('remote', 'RemoteRPCClient') if 'rpc_remote' in proto.mmcaps else
+		(None, None))
+
 	cls = getattr(
-		importlib.import_module(f'mmgen.proto.{proto.base_proto_coin.lower()}.rpc.local'),
-			proto.base_proto + 'RPCClient')
-
-	from ..daemon import CoinDaemon
-	rpc = await cls(
-		cfg           = cfg,
-		proto         = proto,
-		daemon        = daemon or CoinDaemon(cfg, proto=proto, test_suite=cfg.test_suite),
-		backend       = backend or cfg.rpc_backend,
-		ignore_wallet = ignore_wallet)
-
-	if rpc.daemon_version > rpc.daemon.coind_version:
-		rpc.handle_unsupported_daemon_version(
-			proto.name,
-			ignore_daemon_version or proto.ignore_daemon_version or cfg.ignore_daemon_version)
-
-	if rpc.chain not in proto.chain_names:
-		die('RPCChainMismatch', '\n' + fmt(f"""
-			Protocol:           {proto.cls_name}
-			Valid chain names:  {fmt_list(proto.chain_names, fmt='bare')}
-			RPC client chain:   {rpc.chain}
-			""", indent='  ').rstrip())
-
-	rpc.blockcount = NonNegativeInt(rpc.blockcount)
+		importlib.import_module(f'mmgen.proto.{proto.base_proto_coin.lower()}.rpc.{mod}'),
+			proto.base_proto + clsname)
+
+	if mod == 'local':
+		from ..daemon import CoinDaemon
+		rpc = await cls(
+			cfg           = cfg,
+			proto         = proto,
+			daemon        = daemon or CoinDaemon(cfg, proto=proto, test_suite=cfg.test_suite),
+			backend       = backend or cfg.rpc_backend,
+			ignore_wallet = ignore_wallet)
+
+		if rpc.daemon_version > rpc.daemon.coind_version:
+			rpc.handle_unsupported_daemon_version(
+				proto.name,
+				ignore_daemon_version or proto.ignore_daemon_version or cfg.ignore_daemon_version)
+
+		if rpc.chain not in proto.chain_names:
+			die('RPCChainMismatch', '\n' + fmt(f"""
+				Protocol:           {proto.cls_name}
+				Valid chain names:  {fmt_list(proto.chain_names, fmt='bare')}
+				RPC client chain:   {rpc.chain}
+				""", indent='  ').rstrip())
+
+		rpc.blockcount = NonNegativeInt(rpc.blockcount)
+	else:
+		rpc = cls(cfg=cfg, proto=proto)
 
 	return rpc

+ 1 - 0
mmgen/rpc/local.py

@@ -20,6 +20,7 @@ from . import util
 
 class RPCClient:
 
+	is_remote = False
 	auth_type = None
 	has_auth_cookie = False
 	network_proto = 'http'

+ 24 - 0
mmgen/rpc/remote.py

@@ -0,0 +1,24 @@
+#!/usr/bin/env python3
+#
+# MMGen Wallet, a terminal-based cryptocurrency wallet
+# Copyright (C)2013-2025 The MMGen Project <mmgen@tuta.io>
+# Licensed under the GNU General Public License, Version 3:
+#   https://www.gnu.org/licenses
+# Public project repositories:
+#   https://github.com/mmgen/mmgen-wallet
+#   https://gitlab.com/mmgen/mmgen-wallet
+
+"""
+rpc.remote: remote RPC client class for the MMGen Project
+"""
+
+class RemoteRPCClient:
+
+	is_remote = True
+
+	def __init__(self, cfg, proto):
+		self.cfg = cfg
+		self.proto = proto
+
+	def get_block_from_minconf(self, minconf):
+		return None

+ 11 - 4
mmgen/tw/view.py

@@ -26,7 +26,7 @@ from collections import namedtuple
 from ..cfg import gv
 from ..objmethods import MMGenObject
 from ..obj import get_obj, MMGenIdx, MMGenList
-from ..color import nocolor, yellow, green, red, blue
+from ..color import nocolor, yellow, orange, green, red, blue
 from ..util import msg, msg_r, fmt, die, capfirst, suf, make_timestr
 from ..rpc import rpc_init
 from ..base_obj import AsyncInit
@@ -385,7 +385,13 @@ class TwView(MMGenObject, metaclass=AsyncInit):
 			return do_ret(get_freews(self.cols, varws, varw, minw))
 
 	def gen_subheader(self, cw, color):
+		c_orange = (nocolor, orange)[color]
 		c_yellow = (nocolor, yellow)[color]
+		if self.rpc.is_remote:
+			yield (
+				c_orange(f'WARNING: Connecting to public {self.rpc.server_proto} node at ') +
+				self.rpc.server_domain.hl(color=color))
+			yield c_orange('         To improve anonymity, proxy requests via Tor or I2P')
 		if self.twctl.use_cached_balances:
 			yield c_yellow('Using cached balances. These may be out of date!')
 		else:
@@ -434,9 +440,10 @@ class TwView(MMGenObject, metaclass=AsyncInit):
 				yield 'Network: {}'.format(Green(
 					self.proto.coin + ' ' + self.proto.chain_name.upper()))
 
-				yield 'Block {} [{}]'.format(
-					self.rpc.blockcount.hl(color=color),
-					make_timestr(self.rpc.cur_date))
+				if not self.rpc.is_remote:
+					yield 'Block {} [{}]'.format(
+						self.rpc.blockcount.hl(color=color),
+						make_timestr(self.rpc.cur_date))
 
 				if hasattr(self, 'total'):
 					yield 'Total {}: {}'.format(self.proto.dcoin, self.total.hl(color=color))