diff --git a/electrum/commands.py b/electrum/commands.py index 8a099afa9..243461bea 100644 --- a/electrum/commands.py +++ b/electrum/commands.py @@ -116,8 +116,8 @@ def command(s): class Commands: - def __init__(self, config: 'SimpleConfig', - network: Optional['Network'], + def __init__(self, *, config: 'SimpleConfig', + network: 'Network' = None, daemon: 'Daemon' = None, callback=None): self.config = config self.daemon = daemon @@ -128,7 +128,8 @@ class Commands: """This wrapper is called from unit tests and the Qt python console.""" cmd = known_commands[method] password = kwargs.get('password', None) - if (cmd.requires_password and wallet.has_password() + wallet = kwargs.get('wallet', None) + if (cmd.requires_password and wallet and wallet.has_password() and password is None): password = password_getter() if password is None: diff --git a/electrum/daemon.py b/electrum/daemon.py index 23b836d45..4834c7d0b 100644 --- a/electrum/daemon.py +++ b/electrum/daemon.py @@ -339,7 +339,7 @@ class Daemon(Logger): self.methods = jsonrpcserver.methods.Methods() self.methods.add(self.ping) self.methods.add(self.gui) - self.cmd_runner = Commands(self.config, self.network, self) + self.cmd_runner = Commands(config=self.config, network=self.network, daemon=self) for cmdname in known_commands: self.methods.add(getattr(self.cmd_runner, cmdname)) self.methods.add(self.run_cmdline) diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py index 529a8c050..41cfc5a85 100644 --- a/electrum/gui/qt/main_window.py +++ b/electrum/gui/qt/main_window.py @@ -2168,10 +2168,15 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger): 'bitcoin': bitcoin, }) - c = commands.Commands(self.config, self.wallet, self.network, lambda: self.console.set_json(True)) + c = commands.Commands(config=self.config, + network=self.network, + callback=lambda: self.console.set_json(True)) methods = {} def mkfunc(f, method): - return lambda *args, **kwargs: f(method, args, self.password_dialog, **kwargs) + return lambda *args, **kwargs: f(method, + args, + self.password_dialog, + **{**kwargs, 'wallet': self.wallet}) for m in dir(c): if m[0]=='_' or m in ['network','wallet','config']: continue methods[m] = mkfunc(c._run, m) diff --git a/electrum/keystore.py b/electrum/keystore.py index 9678f97a2..f0f03ada1 100644 --- a/electrum/keystore.py +++ b/electrum/keystore.py @@ -264,6 +264,8 @@ class Deterministic_KeyStore(Software_KeyStore): self.seed = self.format_seed(seed) def get_seed(self, password): + if not self.has_seed(): + raise Exception("This wallet has no seed words") return pw_decode(self.seed, password, version=self.pw_hash_version) def get_passphrase(self, password): diff --git a/electrum/tests/test_commands.py b/electrum/tests/test_commands.py index 72ff6210a..ac3fa472c 100644 --- a/electrum/tests/test_commands.py +++ b/electrum/tests/test_commands.py @@ -56,7 +56,7 @@ class TestCommands(unittest.TestCase): self.assertTrue(eval_bool("1")) def test_convert_xkey(self): - cmds = Commands(config=None, wallet=None, network=None) + cmds = Commands(config=None) xpubs = { ("xpub6CCWFbvCbqF92kGwm9nV7t7RvVoQUKaq5USMdyVP6jvv1NgN52KAX6NNYCeE8Ca7JQC4K5tZcnQrubQcjJ6iixfPs4pwAQJAQgTt6hBjg11", "standard"), ("ypub6X2mZGb7kWnct3U4bWa7KyCw6TwrQwaKzaxaRNPGUkJo4UVbKgUj9A2WZQbp87E2i3Js4ZV85SmQnt2BSzWjXCLzjQXMkK7egQXXVHT4eKn", "p2wpkh-p2sh"), @@ -79,7 +79,7 @@ class TestCommands(unittest.TestCase): def test_encrypt_decrypt(self, mock_write): wallet = restore_wallet_from_text('p2wpkh:L4rYY5QpfN6wJEF4SEKDpcGhTPnCe9zcGs6hiSnhpprZqVywFifN', path='if_this_exists_mocking_failed_648151893')['wallet'] - cmds = Commands(config=None, wallet=wallet, network=None) + cmds = Commands(config=None) cleartext = "asdasd this is the message" pubkey = "021f110909ded653828a254515b58498a6bafc96799fb0851554463ed44ca7d9da" ciphertext = cmds._run('encrypt', (pubkey, cleartext)) @@ -89,7 +89,7 @@ class TestCommands(unittest.TestCase): def test_export_private_key_imported(self, mock_write): wallet = restore_wallet_from_text('p2wpkh:L4rYY5QpfN6wJEF4SEKDpcGhTPnCe9zcGs6hiSnhpprZqVywFifN p2wpkh:L4jkdiXszG26SUYvwwJhzGwg37H2nLhrbip7u6crmgNeJysv5FHL', path='if_this_exists_mocking_failed_648151893')['wallet'] - cmds = Commands(config=None, wallet=wallet, network=None) + cmds = Commands(config=None) # single address tests with self.assertRaises(Exception): cmds._run('getprivatekeys', ("asdasd",)) # invalid addr, though might raise "not in wallet" @@ -108,7 +108,7 @@ class TestCommands(unittest.TestCase): wallet = restore_wallet_from_text('bitter grass shiver impose acquire brush forget axis eager alone wine silver', gap_limit=2, path='if_this_exists_mocking_failed_648151893')['wallet'] - cmds = Commands(config=None, wallet=wallet, network=None) + cmds = Commands(config=None) # single address tests with self.assertRaises(Exception): cmds._run('getprivatekeys', ("asdasd",)) # invalid addr, though might raise "not in wallet" @@ -135,7 +135,7 @@ class TestCommandsTestnet(TestCaseForTestnet): self._loop_thread.join(timeout=1) def test_convert_xkey(self): - cmds = Commands(config=None, wallet=None, network=None) + cmds = Commands(config=None) xpubs = { ("tpubD8p5qNfjczgTGbh9qgNxsbFgyhv8GgfVkmp3L88qtRm5ibUYiDVCrn6WYfnGey5XVVw6Bc5QNQUZW5B4jFQsHjmaenvkFUgWtKtgj5AdPm9", "standard"), ("upub59wfQ8qJTg6ZSuvwtR313Qdp8gP8TSBwTof5dPQ3QVsYp1N9t29Rr9TGF1pj8kAXUg3mKbmrTKasA2qmBJKb1bGUzB6ApDZpVC7LoHhyvBo", "p2wpkh-p2sh"), diff --git a/run_electrum b/run_electrum index 39c564fce..4a016da12 100755 --- a/run_electrum +++ b/run_electrum @@ -232,7 +232,7 @@ async def run_offline_command(config, config_options, plugins): kwargs = {} for x in cmd.options: kwargs[x] = (config_options.get(x) if x in ['wallet', 'password', 'new_password'] else config.get(x)) - cmd_runner = Commands(config, None, None) + cmd_runner = Commands(config=config) func = getattr(cmd_runner, cmd.name) result = await func(*args, **kwargs) # save wallet