From 7455cf9dec20d07015ecd6d72224e2ef30c6d396 Mon Sep 17 00:00:00 2001 From: SomberNight Date: Fri, 5 Sep 2025 18:23:49 +0000 Subject: [PATCH] commands: add clear error that plugin commands cannot be run with -o note that atm none of the plugin commands are explicitly marked with 'n' but all require it. Also note that 'w' for plugin commands kind of implies 'n' anyway, as the 'load_wallet' hook relies on having a daemon. ``` $ ./run_electrum -o --testnet labels_pull Password: 1.96 | E | __main__ | error running command (without daemon) Traceback (most recent call last): File "/home/user/wspace/electrum/./run_electrum", line 587, in handle_cmd result = fut.result() File "/usr/lib/python3.13/concurrent/futures/_base.py", line 456, in result return self.__get_result() ~~~~~~~~~~~~~~~~~^^ File "/usr/lib/python3.13/concurrent/futures/_base.py", line 401, in __get_result raise self._exception File "/home/user/wspace/electrum/./run_electrum", line 267, in run_offline_command result = await func(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/user/wspace/electrum/electrum/commands.py", line 202, in func_wrapper return await func(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/user/wspace/electrum/electrum/commands.py", line 2214, in func_wrapper kwargs['plugin'] = daemon._plugins.get_plugin(plugin_name) ^^^^^^^^^^^^^^^ AttributeError: 'NoneType' object has no attribute '_plugins' ``` --- electrum/commands.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/electrum/commands.py b/electrum/commands.py index 9d2cf9a86..f5c4887f1 100644 --- a/electrum/commands.py +++ b/electrum/commands.py @@ -114,7 +114,7 @@ def format_satoshis(x: Union[float, int, Decimal, None]) -> Optional[str]: class Command: def __init__(self, func, name, s): self.name = name - self.requires_network = 'n' in s + self.requires_network = 'n' in s # better name would be "requires daemon" self.requires_wallet = 'w' in s self.requires_password = 'p' in s self.requires_lightning = 'l' in s @@ -2198,6 +2198,9 @@ class Commands(Logger): def plugin_command(s, plugin_name): """Decorator to register a cli command inside a plugin. To be used within a commands.py file in the plugins root.""" + # atm all plugin commands require a daemon, cannot be run in 'offline' mode: + if 'n' not in s: + s += 'n' def decorator(func): assert len(plugin_name) > 0, "Plugin name must not be empty" func.plugin_name = plugin_name @@ -2211,6 +2214,7 @@ def plugin_command(s, plugin_name): async def func_wrapper(*args, **kwargs): cmd_runner = args[0] # type: Commands daemon = cmd_runner.daemon + assert daemon is not None kwargs['plugin'] = daemon._plugins.get_plugin(plugin_name) return await func(*args, **kwargs)