URI: 
       tfix #2400 - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 255458da0af34d75f7b49803cf5e90fdf3bf26c5
   DIR parent b1083572cafbe6ae7f489dcf12843068dac95ab1
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Sun,  2 Jul 2017 11:44:48 +0200
       
       fix #2400
       
       Diffstat:
         M electrum                            |       6 ++----
         M lib/commands.py                     |      68 +++++++++++++++----------------
         M lib/daemon.py                       |       4 ++--
       
       3 files changed, 36 insertions(+), 42 deletions(-)
       ---
   DIR diff --git a/electrum b/electrum
       t@@ -280,10 +280,8 @@ def run_offline_command(config, config_options):
            # decode json arguments
            args = map(json_decode, args)
            # options
       -    args += map(lambda x: config.get(x), cmd.options)
       -    cmd_runner = Commands(config, wallet, None,
       -                          password=config_options.get('password'),
       -                          new_password=config_options.get('new_password'))
       +    args += map(lambda x: (config_options.get(x) if x in ['password', 'new_password'] else config.get(x)), cmd.options)
       +    cmd_runner = Commands(config, wallet, None)
            func = getattr(cmd_runner, cmd.name)
            result = func(*args)
            # save wallet
   DIR diff --git a/lib/commands.py b/lib/commands.py
       t@@ -87,23 +87,21 @@ def command(s):
        
        class Commands:
        
       -    def __init__(self, config, wallet, network, callback = None, password=None, new_password=None):
       +    def __init__(self, config, wallet, network, callback = None):
                self.config = config
                self.wallet = wallet
                self.network = network
                self._callback = callback
       -        self._password = password
       -        self.new_password = new_password
        
            def _run(self, method, args, password_getter):
       +        # this wrapper is called from the python console
                cmd = known_commands[method]
                if cmd.requires_password and self.wallet.has_password():
       -            self._password = apply(password_getter,())
       -            if self._password is None:
       +            password = apply(password_getter, ())
       +            if password is None:
                        return
                f = getattr(self, method)
       -        result = f(*args)
       -        self._password = None
       +        result = f(*args, **{'password':password})
                if self._callback:
                    apply(self._callback, ())
                return result
       t@@ -127,11 +125,11 @@ class Commands:
                raise BaseException('Not a JSON-RPC command')
        
            @command('wp')
       -    def password(self):
       +    def password(self, password=None, new_password=None):
                """Change wallet password. """
       -        self.wallet.update_password(self._password, self.new_password)
       +        self.wallet.update_password(password, new_password)
                self.wallet.storage.write()
       -        return {'password':self.wallet.use_encryption}
       +        return {'password':self.wallet.has_password()}
        
            @command('')
            def getconfig(self, key):
       t@@ -225,7 +223,7 @@ class Commands:
                return tx.as_dict()
        
            @command('wp')
       -    def signtransaction(self, tx, privkey=None):
       +    def signtransaction(self, tx, privkey=None, password=None):
                """Sign a transaction. The wallet keys will be used unless a private key is provided."""
                tx = Transaction(tx)
                if privkey:
       t@@ -234,7 +232,7 @@ class Commands:
                    x_pubkey = 'fd' + (chr(0) + h160).encode('hex')
                    tx.sign({x_pubkey:privkey})
                else:
       -            self.wallet.sign_transaction(tx, self._password)
       +            self.wallet.sign_transaction(tx, password)
                return tx.as_dict()
        
            @command('')
       t@@ -268,12 +266,12 @@ class Commands:
                return self.wallet.set_frozen_state([address], False)
        
            @command('wp')
       -    def getprivatekeys(self, address):
       +    def getprivatekeys(self, address, password=None):
                """Get private keys of addresses. You may pass a single wallet address, or a list of wallet addresses."""
                if is_address(address):
       -            return self.wallet.get_private_key(address, self._password)
       +            return self.wallet.get_private_key(address, password)
                domain = address
       -        return [self.wallet.get_private_key(address, self._password) for address in domain]
       +        return [self.wallet.get_private_key(address, password) for address in domain]
        
            @command('w')
            def ismine(self, address):
       t@@ -348,23 +346,23 @@ class Commands:
                return self.wallet.get_master_public_key()
        
            @command('wp')
       -    def getmasterprivate(self):
       +    def getmasterprivate(self, password=None):
                """Get master private key. Return your wallet\'s master private key"""
       -        return str(self.wallet.keystore.get_master_private_key(self._password))
       +        return str(self.wallet.keystore.get_master_private_key(password))
        
            @command('wp')
       -    def getseed(self):
       +    def getseed(self, password=None):
                """Get seed phrase. Print the generation seed of your wallet."""
       -        s = self.wallet.get_seed(self._password)
       +        s = self.wallet.get_seed(password)
                return s.encode('utf8')
        
            @command('wp')
       -    def importprivkey(self, privkey):
       +    def importprivkey(self, privkey, password=None):
                """Import a private key. """
                if not self.wallet.can_import_privkey():
                    return "Error: This type of wallet cannot import private keys. Try to create a new wallet with that key."
                try:
       -            addr = self.wallet.import_key(privkey, self._password)
       +            addr = self.wallet.import_key(privkey, password)
                    out = "Keypair imported: " + addr
                except BaseException as e:
                    out = "Error: " + str(e)
       t@@ -391,10 +389,10 @@ class Commands:
                return tx.as_dict() if tx else None
        
            @command('wp')
       -    def signmessage(self, address, message):
       +    def signmessage(self, address, message, password=None):
                """Sign a message with a key. Use quotes if your message contains
                whitespaces"""
       -        sig = self.wallet.sign_message(address, message, self._password)
       +        sig = self.wallet.sign_message(address, message, password)
                return base64.b64encode(sig)
        
            @command('')
       t@@ -403,7 +401,7 @@ class Commands:
                sig = base64.b64decode(signature)
                return bitcoin.verify_message(address, sig, message)
        
       -    def _mktx(self, outputs, fee, change_addr, domain, nocheck, unsigned, rbf):
       +    def _mktx(self, outputs, fee, change_addr, domain, nocheck, unsigned, rbf, password):
                self.nocheck = nocheck
                change_addr = self._resolver(change_addr)
                domain = None if domain is None else map(self._resolver, domain)
       t@@ -418,23 +416,23 @@ class Commands:
                if rbf:
                    tx.set_rbf(True)
                if not unsigned:
       -            self.wallet.sign_transaction(tx, self._password)
       +            self.wallet.sign_transaction(tx, password)
                return tx
        
            @command('wp')
       -    def payto(self, destination, amount, tx_fee=None, from_addr=None, change_addr=None, nocheck=False, unsigned=False, rbf=False):
       +    def payto(self, destination, amount, tx_fee=None, from_addr=None, change_addr=None, nocheck=False, unsigned=False, rbf=False, password=None):
                """Create a transaction. """
                tx_fee = satoshis(tx_fee)
                domain = [from_addr] if from_addr else None
       -        tx = self._mktx([(destination, amount)], tx_fee, change_addr, domain, nocheck, unsigned, rbf)
       +        tx = self._mktx([(destination, amount)], tx_fee, change_addr, domain, nocheck, unsigned, rbf, password)
                return tx.as_dict()
        
            @command('wp')
       -    def paytomany(self, outputs, tx_fee=None, from_addr=None, change_addr=None, nocheck=False, unsigned=False, rbf=False):
       +    def paytomany(self, outputs, tx_fee=None, from_addr=None, change_addr=None, nocheck=False, unsigned=False, rbf=False, password=None):
                """Create a multi-output transaction. """
                tx_fee = satoshis(tx_fee)
                domain = [from_addr] if from_addr else None
       -        tx = self._mktx(outputs, tx_fee, change_addr, domain, nocheck, unsigned, rbf)
       +        tx = self._mktx(outputs, tx_fee, change_addr, domain, nocheck, unsigned, rbf, password)
                return tx.as_dict()
        
            @command('w')
       t@@ -546,9 +544,9 @@ class Commands:
                return bitcoin.encrypt_message(message, pubkey)
        
            @command('wp')
       -    def decrypt(self, pubkey, encrypted):
       +    def decrypt(self, pubkey, encrypted, password=None):
                """Decrypt a message encrypted with a public key."""
       -        return self.wallet.decrypt_message(pubkey, encrypted, self._password)
       +        return self.wallet.decrypt_message(pubkey, encrypted, password)
        
            def _format_request(self, out):
                pr_str = {
       t@@ -620,13 +618,13 @@ class Commands:
                return self._format_request(out)
        
            @command('wp')
       -    def signrequest(self, address):
       +    def signrequest(self, address, password=None):
                "Sign payment request with an OpenAlias"
                alias = self.config.get('alias')
                if not alias:
                    raise BaseException('No alias in your configuration')
                alias_addr = self.wallet.contacts.resolve(alias)['address']
       -        self.wallet.sign_payment_request(address, alias, alias_addr, self._password)
       +        self.wallet.sign_payment_request(address, alias, alias_addr, password)
        
            @command('w')
            def rmrequest(self, address):
       t@@ -685,6 +683,7 @@ param_descriptions = {
        
        command_options = {
            'password':    ("-W", "--password",    "Password"),
       +    'new_password':(None, "--new_password","New Password"),
            'receiving':   (None, "--receiving",   "Show only receiving addresses"),
            'change':      (None, "--change",      "Show only change addresses"),
            'frozen':      (None, "--frozen",      "Show only frozen addresses"),
       t@@ -840,9 +839,6 @@ def get_parser():
                add_global_options(p)
                if cmdname == 'restore':
                    p.add_argument("-o", "--offline", action="store_true", dest="offline", default=False, help="Run offline")
       -        #p.set_defaults(func=run_cmdline)
       -        if cmd.requires_password:
       -            p.add_argument("-W", "--password", dest="password", default=None, help="password")
                for optname, default in zip(cmd.options, cmd.defaults):
                    a, b, help = command_options[optname]
                    action = "store_true" if type(default) is bool else 'store'
   DIR diff --git a/lib/daemon.py b/lib/daemon.py
       t@@ -252,8 +252,8 @@ class Daemon(DaemonThread):
                # decode json arguments
                args = map(json_decode, args)
                # options
       -        args += map(lambda x: config.get(x), cmd.options)
       -        cmd_runner = Commands(config, wallet, self.network, password=password, new_password=new_password)
       +        args += map(lambda x: (config_options.get(x) if x in ['password', 'new_password'] else config.get(x)), cmd.options)
       +        cmd_runner = Commands(config, wallet, self.network)
                func = getattr(cmd_runner, cmd.name)
                result = func(*args)
                return result