Browse Source

Add unlock command to CLI (stores wallet password in memory)

master
ThomasV 2 years ago
parent
commit
4e80ef818d
  1. 12
      electrum/commands.py
  2. 12
      electrum/wallet.py
  3. 3
      run_electrum

12
electrum/commands.py

@ -146,6 +146,12 @@ def command(s):
if wallet is None:
raise Exception('wallet not loaded')
kwargs['wallet'] = wallet
if cmd.requires_password and password is None:
password = wallet.get_unlocked_password()
if password:
kwargs['password'] = password
else:
raise Exception('Password required. Unlock the wallet, or add a --password option to your command')
wallet = kwargs.get('wallet') # type: Optional[Abstract_Wallet]
if cmd.requires_wallet and not wallet:
raise Exception('wallet not loaded')
@ -621,6 +627,12 @@ class Commands:
return ret
@command('w')
async def unlock(self, password=None, wallet: Abstract_Wallet = None):
"""Unlock the wallet. The wallet password will be stored in memory"""
wallet.unlock(password)
return "wallet unlocked" if password else "wallet locked"
@command('w')
async def getmpk(self, wallet: Abstract_Wallet = None):
"""Get master public key. Return your wallet\'s master public key"""

12
electrum/wallet.py

@ -318,6 +318,7 @@ class Abstract_Wallet(ABC, Logger, EventListener):
# load addresses needs to be called before constructor for sanity checks
db.load_addresses(self.wallet_type)
self.keystore = None # type: Optional[KeyStore] # will be set by load_keystore
self._password_in_memory = None # see self.unlock
Logger.__init__(self)
self.network = None
@ -2786,6 +2787,7 @@ class Abstract_Wallet(ABC, Logger, EventListener):
encrypt_keystore = self.can_have_keystore_encryption()
self.db.set_keystore_encryption(bool(new_pw) and encrypt_keystore)
self.save_db()
self.unlock(None)
@abstractmethod
def _update_password_for_keystore(self, old_pw: Optional[str], new_pw: Optional[str]) -> None:
@ -3035,6 +3037,16 @@ class Abstract_Wallet(ABC, Logger, EventListener):
"""Returns the number of new addresses we generated."""
return 0
def unlock(self, password):
self.logger.info(f'unlocking wallet')
if password:
self.check_password(password)
self._password_in_memory = password
def get_unlocked_password(self):
return self._password_in_memory
class Simple_Wallet(Abstract_Wallet):
# wallet with a single keystore

3
run_electrum

@ -155,7 +155,8 @@ def init_cmdline(config_options, wallet_path, *, rpcserver: bool, config: 'Simpl
# commands needing password
if ((cmd.requires_wallet and storage.is_encrypted() and not rpcserver)
or (cmdname == 'load_wallet' and storage.is_encrypted())
or cmd.requires_password):
or (cmdname in ['password', 'unlock'])
or (cmd.requires_password and not rpcserver)):
if storage.is_encrypted_with_hw_device():
# this case is handled later in the control flow
password = None

Loading…
Cancel
Save