tRename send_tx() to sign_tx() - electrum - Electrum Bitcoin wallet
 (HTM) git clone https://git.parazyd.org/electrum
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Submodules
       ---
 (DIR) commit 15632adb40aef519933dc210638b359990c458da
 (DIR) parent b2bfd5af1f7f44337e69655c9ef86fbd44a316fc
 (HTM) Author: Neil Booth <kyuupichan@gmail.com>
       Date:   Sat,  4 Jul 2015 16:45:08 +0900
       
       Rename send_tx() to sign_tx()
       
       Because it signs, and it doesn't send.
       
       Diffstat:
         M gui/qt/main_window.py               |       6 +++---
         M gui/qt/transaction_dialog.py        |       2 +-
         M plugins/btchipwallet.py             |      89 +++++++++++++++----------------
         M plugins/trustedcoin.py              |      42 ++++++++++++++++----------------
       
       4 files changed, 69 insertions(+), 70 deletions(-)
       ---
 (DIR) diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py
       t@@ -1137,18 +1137,18 @@ class ElectrumWindow(QMainWindow):
                                self.do_clear()
                            else:
                                self.broadcast_transaction(tx, tx_desc)
       -            self.send_tx(tx, sign_done)
       +            self.sign_tx(tx, sign_done)
        
        
            @protected
       -    def send_tx(self, tx, callback, password):
       +    def sign_tx(self, tx, callback, password):
                '''Sign the transaction in a separate thread.  When done, calls
                the callback with a success code of True or False.
                '''
                self.send_button.setDisabled(True)
        
                # call hook to see if plugin needs gui interaction
       -        run_hook('send_tx', tx)
       +        run_hook('sign_tx', tx)
        
                # sign the tx
                success = [False]  # Array to work around python scoping
 (DIR) diff --git a/gui/qt/transaction_dialog.py b/gui/qt/transaction_dialog.py
       t@@ -145,7 +145,7 @@ class TxDialog(QWidget):
                    self.prompt_if_unsaved = True
                    self.saved = False
                    self.update()
       -        self.parent.send_tx(self.tx, sign_done)
       +        self.parent.sign_tx(self.tx, sign_done)
        
            def save(self):
                name = 'signed_%s.txn' % (self.tx.hash()[0:8]) if self.tx.is_complete() else 'unsigned.txn'
 (DIR) diff --git a/plugins/btchipwallet.py b/plugins/btchipwallet.py
       t@@ -28,7 +28,7 @@ try:
            from btchip.btchipFirmwareWizard import checkFirmware, updateFirmware
            from btchip.btchipException import BTChipException
            BTCHIP = True
       -    BTCHIP_DEBUG = False 
       +    BTCHIP_DEBUG = False
        except ImportError:
            BTCHIP = False
        
       t@@ -45,7 +45,7 @@ class Plugin(BasePlugin):
            def _init(self):
                return BTCHIP
        
       -    def is_available(self):        
       +    def is_available(self):
                if not self._is_available:
                    return False
                if not self.wallet:
       t@@ -82,7 +82,7 @@ class Plugin(BasePlugin):
                else:
                    QMessageBox.information(self.window, _('Error'), _("BTChip device not detected.\nContinuing in watching-only mode."), _('OK'))
                    self.wallet.force_watching_only = True
       -    
       +
            @hook
            def installwizard_restore(self, wizard, storage):
                if storage.get('wallet_type') != 'btchip':
       t@@ -96,7 +96,7 @@ class Plugin(BasePlugin):
                return wallet
        
            @hook
       -    def send_tx(self, tx):
       +    def sign_tx(self, tx):
                tx.error = None
                try:
                    self.wallet.sign_transaction(tx, None)
       t@@ -124,7 +124,7 @@ class BTChipWallet(BIP32_HD_Wallet):
                if clear_client and self.client is not None:
                    self.client.bad = True
                    self.device_checked = False
       -        raise Exception(message)                
       +        raise Exception(message)
        
            def get_action(self):
                if not self.accounts:
       t@@ -155,7 +155,7 @@ class BTChipWallet(BIP32_HD_Wallet):
                        d.setWaitImpl(DongleWaitQT(d))
                        self.client = btchip(d)
                        firmware = self.client.getFirmwareVersion()['version'].split(".")
       -                if not checkFirmware(firmware):                    
       +                if not checkFirmware(firmware):
                            d.close()
                            try:
                                updateFirmware()
       t@@ -164,13 +164,13 @@ class BTChipWallet(BIP32_HD_Wallet):
                                raise e
                            d = getDongle(BTCHIP_DEBUG)
                            d.setWaitImpl(DongleWaitQT(d))
       -                    self.client = btchip(d)                    
       +                    self.client = btchip(d)
                        try:
                            self.client.getOperationMode()
                        except BTChipException, e:
                            if (e.sw == 0x6985):
                                d.close()
       -                        dialog = StartBTChipPersoDialog()                        
       +                        dialog = StartBTChipPersoDialog()
                                dialog.exec_()
                                # Then fetch the reference again  as it was invalidated
                                d = getDongle(BTCHIP_DEBUG)
       t@@ -178,18 +178,18 @@ class BTChipWallet(BIP32_HD_Wallet):
                                self.client = btchip(d)
                            else:
                                raise e
       -                if not noPin:                    
       +                if not noPin:
                            # Immediately prompts for the PIN
       -                    remaining_attempts = self.client.getVerifyPinRemainingAttempts()                    
       +                    remaining_attempts = self.client.getVerifyPinRemainingAttempts()
                            if remaining_attempts <> 1:
                                msg = "Enter your BTChip PIN - remaining attempts : " + str(remaining_attempts)
                            else:
                                msg = "Enter your BTChip PIN - WARNING : LAST ATTEMPT. If the PIN is not correct, the dongle will be wiped."
       -                    confirmed, p, pin = self.password_dialog(msg)                
       +                    confirmed, p, pin = self.password_dialog(msg)
                            if not confirmed:
                                aborted = True
                                raise Exception('Aborted by user - please unplug the dongle and plug it again before retrying')
       -                    pin = pin.encode()                   
       +                    pin = pin.encode()
                            self.client.verifyPin(pin)
        
                    except BTChipException, e:
       t@@ -197,18 +197,18 @@ class BTChipWallet(BIP32_HD_Wallet):
                            self.client.dongle.close()
                        except:
                            pass
       -                self.client = None                
       +                self.client = None
                        if (e.sw == 0x6faa):
       -                    raise Exception("Dongle is temporarily locked - please unplug it and replug it again")                    
       +                    raise Exception("Dongle is temporarily locked - please unplug it and replug it again")
                        if ((e.sw & 0xFFF0) == 0x63c0):
                            raise Exception("Invalid PIN - please unplug the dongle and plug it again before retrying")
                        raise e
                    except Exception, e:
       -                try:                 
       +                try:
                            self.client.dongle.close()
                        except:
       -                    pass                
       -                self.client = None                                
       +                    pass
       +                self.client = None
                        if not aborted:
                            raise Exception("Could not connect to your BTChip dongle. Please verify access permissions, PIN, or unplug the dongle and plug it again")
                        else:
       t@@ -234,20 +234,20 @@ class BTChipWallet(BIP32_HD_Wallet):
                return []
        
            def get_public_key(self, bip32_path):
       -        # S-L-O-W - we don't handle the fingerprint directly, so compute it manually from the previous node        
       +        # S-L-O-W - we don't handle the fingerprint directly, so compute it manually from the previous node
                # This only happens once so it's bearable
       -        self.get_client() # prompt for the PIN before displaying the dialog if necessary        
       +        self.get_client() # prompt for the PIN before displaying the dialog if necessary
                waitDialog.start("Computing master public key")
       -        try:            
       +        try:
                    splitPath = bip32_path.split('/')
       -            fingerprint = 0        
       +            fingerprint = 0
                    if len(splitPath) > 1:
                        prevPath = "/".join(splitPath[0:len(splitPath) - 1])
                        nodeData = self.get_client().getWalletPublicKey(prevPath)
                        publicKey = compress_public_key(nodeData['publicKey'])
                        h = hashlib.new('ripemd160')
                        h.update(hashlib.sha256(publicKey).digest())
       -                fingerprint = unpack(">I", h.digest()[0:4])[0]            
       +                fingerprint = unpack(">I", h.digest()[0:4])[0]
                    nodeData = self.get_client().getWalletPublicKey(bip32_path)
                    publicKey = compress_public_key(nodeData['publicKey'])
                    depth = len(splitPath)
       t@@ -255,7 +255,7 @@ class BTChipWallet(BIP32_HD_Wallet):
                    if len(lastChild) == 1:
                        childnum = int(lastChild[0])
                    else:
       -                childnum = 0x80000000 | int(lastChild[0])        
       +                childnum = 0x80000000 | int(lastChild[0])
                    xpub = "0488B21E".decode('hex') + chr(depth) + self.i4b(fingerprint) + self.i4b(childnum) + str(nodeData['chainCode']) + str(publicKey)
                except Exception, e:
                    self.give_error(e, True)
       t@@ -270,7 +270,7 @@ class BTChipWallet(BIP32_HD_Wallet):
                        self.mpk = self.get_public_key("44'/0'")
                    return self.mpk
                except Exception, e:
       -            self.give_error(e, True)        
       +            self.give_error(e, True)
        
            def i4b(self, x):
                return pack('>I', x)
       t@@ -287,13 +287,13 @@ class BTChipWallet(BIP32_HD_Wallet):
                self.signing = True
                self.get_client() # prompt for the PIN before displaying the dialog if necessary
                if not self.check_proper_device():
       -            self.give_error('Wrong device or password')        
       +            self.give_error('Wrong device or password')
                address_path = self.address_id(address)
                waitDialog.start("Signing Message ...")
                try:
                    info = self.get_client().signMessagePrepare(address_path, message)
                    pin = ""
       -            if info['confirmationNeeded']:                
       +            if info['confirmationNeeded']:
                        # TODO : handle different confirmation types. For the time being only supports keyboard 2FA
                        use2FA = True
                        confirmed, p, pin = self.password_dialog()
       t@@ -307,8 +307,8 @@ class BTChipWallet(BIP32_HD_Wallet):
                except BTChipException, e:
                    if e.sw == 0x6a80:
                        self.give_error("Unfortunately, this message cannot be signed by BTChip. Only alphanumerical messages shorter than 140 characters are supported. Please remove any extra characters (tab, carriage return) and retry.")
       -            else:                
       -                self.give_error(e, True)            
       +            else:
       +                self.give_error(e, True)
                except Exception, e:
                    self.give_error(e, True)
                finally:
       t@@ -332,22 +332,22 @@ class BTChipWallet(BIP32_HD_Wallet):
        
                # And convert it
        
       -        return b64encode(chr(27 + 4 + (signature[0] & 0x01)) + r + s) 
       +        return b64encode(chr(27 + 4 + (signature[0] & 0x01)) + r + s)
        
            def sign_transaction(self, tx, password):
                if tx.is_complete():
                    return
                if tx.error:
                    raise BaseException(tx.error)
       -        self.signing = True        
       +        self.signing = True
                inputs = []
                inputsPaths = []
                pubKeys = []
                trustedInputs = []
       -        redeemScripts = []        
       +        redeemScripts = []
                signatures = []
                preparedTrustedInputs = []
       -        changePath = "" 
       +        changePath = ""
                changeAmount = None
                output = None
                outputAmount = None
       t@@ -358,8 +358,8 @@ class BTChipWallet(BIP32_HD_Wallet):
                for txinput in tx.inputs:
                    if ('is_coinbase' in txinput and txinput['is_coinbase']):
                        self.give_error("Coinbase not supported")     # should never happen
       -            inputs.append([ self.transactions[txinput['prevout_hash']].raw, 
       -                             txinput['prevout_n'] ])        
       +            inputs.append([ self.transactions[txinput['prevout_hash']].raw,
       +                             txinput['prevout_n'] ])
                    address = txinput['address']
                    inputsPaths.append(self.address_id(address))
                    pubKeys.append(self.get_public_keys(address))
       t@@ -367,7 +367,7 @@ class BTChipWallet(BIP32_HD_Wallet):
                # Recognize outputs - only one output and one change is authorized
                if len(tx.outputs) > 2: # should never happen
                    self.give_error("Transaction with more than 2 outputs not supported")
       -        for type, address, amount in tx.outputs:        
       +        for type, address, amount in tx.outputs:
                    assert type == 'address'
                    if self.is_change(address):
                        changePath = self.address_id(address)
       t@@ -386,7 +386,7 @@ class BTChipWallet(BIP32_HD_Wallet):
                try:
                    # Get trusted inputs from the original transactions
                    for utxo in inputs:
       -                txtmp = bitcoinTransaction(bytearray(utxo[0].decode('hex')))            
       +                txtmp = bitcoinTransaction(bytearray(utxo[0].decode('hex')))
                        trustedInputs.append(self.get_client().getTrustedInput(txtmp, utxo[1]))
                        # TODO : Support P2SH later
                        redeemScripts.append(txtmp.outputs[utxo[1]].script)
       t@@ -394,13 +394,13 @@ class BTChipWallet(BIP32_HD_Wallet):
                    firstTransaction = True
                    inputIndex = 0
                    while inputIndex < len(inputs):
       -                self.get_client().startUntrustedTransaction(firstTransaction, inputIndex, 
       +                self.get_client().startUntrustedTransaction(firstTransaction, inputIndex,
                        trustedInputs, redeemScripts[inputIndex])
       -                outputData = self.get_client().finalizeInput(output, format_satoshis_plain(outputAmount), 
       +                outputData = self.get_client().finalizeInput(output, format_satoshis_plain(outputAmount),
                        format_satoshis_plain(self.get_tx_fee(tx)), changePath, bytearray(rawTx.decode('hex')))
                        if firstTransaction:
                            transactionOutput = outputData['outputData']
       -                if outputData['confirmationNeeded']:                
       +                if outputData['confirmationNeeded']:
                            use2FA = True
                            # TODO : handle different confirmation types. For the time being only supports keyboard 2FA
                            waitDialog.emit(SIGNAL('dongle_done'))
       t@@ -410,16 +410,16 @@ class BTChipWallet(BIP32_HD_Wallet):
                                    msg = "Do not enter your device PIN here !\r\n\r\n" + \
                                        "Your BTChip wants to talk to you and tell you a unique second factor code.\r\n" + \
                                        "For this to work, please match the character between stars of the output address using your security card\r\n\r\n" + \
       -                                "Output address : " 
       +                                "Output address : "
                                    for index in range(len(output)):
                                        if index == outputData['keycardData'][keycardIndex]:
                                            msg = msg + "*" + output[index] + "*"
                                        else:
                                            msg = msg + output[index]
       -                            msg = msg + "\r\n"                        
       +                            msg = msg + "\r\n"
                                    confirmed, p, pin = self.password_dialog(msg)
                                    if not confirmed:
       -                                raise Exception('Aborted by user') 
       +                                raise Exception('Aborted by user')
                                    try:
                                        pin2 = pin2 + chr(int(pin[0], 16))
                                    except:
       t@@ -428,7 +428,7 @@ class BTChipWallet(BIP32_HD_Wallet):
                            else:
                                confirmed, p, pin = self.password_dialog()
                                if not confirmed:
       -                            raise Exception('Aborted by user')                                            
       +                            raise Exception('Aborted by user')
                                pin = pin.encode()
                                self.client.bad = True
                                self.device_checked = False
       t@@ -452,7 +452,7 @@ class BTChipWallet(BIP32_HD_Wallet):
                inputIndex = 0
                while inputIndex < len(inputs):
                    # TODO : Support P2SH later
       -            inputScript = get_regular_input_script(signatures[inputIndex], pubKeys[inputIndex][0].decode('hex'))        
       +            inputScript = get_regular_input_script(signatures[inputIndex], pubKeys[inputIndex][0].decode('hex'))
                    preparedTrustedInputs.append([ trustedInputs[inputIndex]['value'], inputScript ])
                    inputIndex = inputIndex + 1
                updatedTransaction = format_transaction(transactionOutput, preparedTrustedInputs)
       t@@ -525,4 +525,3 @@ if BTCHIP:
        
                def waitFirstResponse(self, timeout):
                    return self.dongle.waitFirstResponse(timeout)
       -
 (DIR) diff --git a/plugins/trustedcoin.py b/plugins/trustedcoin.py
       t@@ -62,7 +62,7 @@ class TrustedCoinCosignerClient(object):
                self.base_url = base_url
                self.debug = debug
                self.user_agent = user_agent
       -        
       +
            def send_request(self, method, relative_url, data=None):
                kwargs = {'headers': {}}
                if self.user_agent:
       t@@ -85,12 +85,12 @@ class TrustedCoinCosignerClient(object):
                        r = response.json()
                        if 'message' in r:
                            message = r['message']
       -            raise TrustedCoinException(message, response.status_code)        
       +            raise TrustedCoinException(message, response.status_code)
                if response.headers.get('content-type') == 'application/json':
                    return response.json()
                else:
                    return response.text
       -        
       +
            def get_terms_of_service(self, billing_plan='electrum-per-tx-otp'):
                """
                Returns the TOS for the given billing plan as a plain/text unicode string.
       t@@ -98,13 +98,13 @@ class TrustedCoinCosignerClient(object):
                """
                payload = {'billing_plan': billing_plan}
                return self.send_request('get', 'tos', payload)
       -        
       +
            def create(self, xpubkey1, xpubkey2, email, billing_plan='electrum-per-tx-otp'):
                """
                Creates a new cosigner resource.
                :param xpubkey1: a bip32 extended public key (customarily the hot key)
                :param xpubkey2: a bip32 extended public key (customarily the cold key)
       -        :param email: a contact email 
       +        :param email: a contact email
                :param billing_plan: the billing plan for the cosigner
                """
                payload = {
       t@@ -114,7 +114,7 @@ class TrustedCoinCosignerClient(object):
                    'billing_plan': billing_plan,
                }
                return self.send_request('post', 'cosigner', payload)
       -        
       +
            def auth(self, id, otp):
                """
                Attempt to authenticate for a particular cosigner.
       t@@ -123,7 +123,7 @@ class TrustedCoinCosignerClient(object):
                """
                payload = {'otp': otp}
                return self.send_request('post', 'cosigner/%s/auth' % quote(id), payload)
       -        
       +
            def get(self, id):
                """
                Attempt to authenticate for a particular cosigner.
       t@@ -131,7 +131,7 @@ class TrustedCoinCosignerClient(object):
                :param otp: the one time password
                """
                return self.send_request('get', 'cosigner/%s' % quote(id))
       -        
       +
            def sign(self, id, transaction, otp):
                """
                Attempt to authenticate for a particular cosigner.
       t@@ -157,7 +157,7 @@ class TrustedCoinCosignerClient(object):
                    'otp': otp,
                    'recipient': recipient,
                    'timestamp': int(time.time()),
       -            
       +
                }
                relative_url = 'cosigner/%s/transfer' % quote(id)
                full_url = urljoin(self.base_url, relative_url)
       t@@ -282,7 +282,7 @@ class Plugin(BasePlugin):
                wallet.add_cosigner_seed(' '.join(words[0:n]), 'x1/', password)
                wallet.add_cosigner_xpub(' '.join(words[n:]), 'x2/')
        
       -        msg = [ 
       +        msg = [
                    _('Your wallet file is:') + " %s"%os.path.abspath(wallet.storage.path),
                    _('You need to be online in order to complete the creation of your wallet.'),
                    _('If you generated your seed on an offline computer, click on "%s" to close this window, move your wallet file to an online computer and reopen it with Electrum.') % _('Close'),
       t@@ -350,14 +350,14 @@ class Plugin(BasePlugin):
            def get_wizard_action(self, window, wallet, action):
                if hasattr(self, action):
                    return getattr(self, action)
       -            
       +
            @hook
            def installwizard_restore(self, window, storage):
       -        if storage.get('wallet_type') != '2fa': 
       +        if storage.get('wallet_type') != '2fa':
                    return
        
                seed = window.enter_seed_dialog("Enter your seed", None, func=self.seed_func)
       -        if not seed: 
       +        if not seed:
                    return
                wallet = Wallet_2fa(storage)
                self.wallet = wallet
       t@@ -380,7 +380,7 @@ class Plugin(BasePlugin):
                self.wallet = wallet
                self.window = window
        
       -        if wallet.storage.get('wallet_type') != '2fa': 
       +        if wallet.storage.get('wallet_type') != '2fa':
                    raise
                    return
        
       t@@ -444,8 +444,8 @@ class Plugin(BasePlugin):
                return False
        
            @hook
       -    def send_tx(self, tx):
       -        self.print_error("twofactor:send_tx")
       +    def sign_tx(self, tx):
       +        self.print_error("twofactor:sign_tx")
                if self.wallet.storage.get('wallet_type') != '2fa':
                    return
        
       t@@ -514,7 +514,7 @@ class Plugin(BasePlugin):
        
                self.print_error( "received answer", r)
                if not r:
       -            return 
       +            return
        
                raw_tx = r.get('transaction')
                tx.update(raw_tx)
       t@@ -534,7 +534,7 @@ class Plugin(BasePlugin):
                grid.addWidget(pw, 1, 1)
                vbox.addLayout(grid)
                vbox.addLayout(Buttons(CancelButton(d), OkButton(d)))
       -        if not d.exec_(): 
       +        if not d.exec_():
                    return
                return pw.get_amount()
        
       t@@ -562,7 +562,7 @@ class Plugin(BasePlugin):
                      + _("For more information, visit") + " <a href=\"https://api.trustedcoin.com/#/electrum-help\">https://api.trustedcoin.com/#/electrum-help</a>"
                label = QLabel(msg)
                label.setOpenExternalLinks(1)
       -        
       +
                hbox.addStretch(10)
                hbox.addWidget(logo)
                hbox.addStretch(10)
       t@@ -656,7 +656,7 @@ class Plugin(BasePlugin):
                    tos = server.get_terms_of_service()
                    self.TOS = tos
                    window.emit(SIGNAL('twofactor:TOS'))
       -            
       +
                def on_result():
                    tos_e.setText(self.TOS)
        
       t@@ -669,7 +669,7 @@ class Plugin(BasePlugin):
                email_e.textChanged.connect(lambda: accept_button.setEnabled(re.match(regexp,email_e.text()) is not None))
                email_e.setFocus(True)
        
       -        if not window.exec_(): 
       +        if not window.exec_():
                    return
        
                email = str(email_e.text())