URI: 
       tkivy: fix paying onchain invoices - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit c7346c1eb8f790ad71d14c634097fa67d2839ac5
   DIR parent 1f305bba3994cbdcaed1c47cca201396690fe1e6
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Fri, 13 Sep 2019 15:00:34 +0200
       
       kivy: fix paying onchain invoices
       
       when pasting a new invoice and paying it
       Traceback (most recent call last):
         File "/home/user/wspace/electrum/electrum/gui/kivy/uix/screens.py", line 358, in _do_send_onchain
           tx = self.app.wallet.make_unsigned_transaction(coins, outputs, None)
         File "/home/user/wspace/electrum/electrum/wallet.py", line 849, in make_unsigned_transaction
           if o.type == TYPE_ADDRESS:
       AttributeError: 'tuple' object has no attribute 'type'
       
       when loading back a saved invoice
       Traceback (most recent call last):
         File "/home/user/wspace/electrum/electrum/gui/kivy/uix/screens.py", line 358, in _do_send_onchain
           tx = self.app.wallet.make_unsigned_transaction(coins, outputs, None)
         File "/home/user/wspace/electrum/electrum/wallet.py", line 849, in make_unsigned_transaction
           if o.type == TYPE_ADDRESS:
       AttributeError: 'list' object has no attribute 'type'
       
       Diffstat:
         M electrum/gui/kivy/uix/dialogs/invo… |       7 ++++++-
         M electrum/gui/kivy/uix/screens.py    |      12 ++++++++----
         M electrum/paymentrequest.py          |       2 +-
         M electrum/wallet.py                  |       6 ++++++
       
       4 files changed, 21 insertions(+), 6 deletions(-)
       ---
   DIR diff --git a/electrum/gui/kivy/uix/dialogs/invoice_dialog.py b/electrum/gui/kivy/uix/dialogs/invoice_dialog.py
       t@@ -1,3 +1,5 @@
       +from typing import TYPE_CHECKING
       +
        from kivy.factory import Factory
        from kivy.lang import Builder
        from kivy.core.clipboard import Clipboard
       t@@ -7,6 +9,9 @@ from kivy.clock import Clock
        from electrum.gui.kivy.i18n import _
        from electrum.util import pr_tooltips
        
       +if TYPE_CHECKING:
       +    from electrum.gui.kivy.main_window import ElectrumWindow
       +
        
        Builder.load_string('''
        <InvoiceDialog@Popup>
       t@@ -58,7 +63,7 @@ class InvoiceDialog(Factory.Popup):
        
            def __init__(self, title, data, key):
                Factory.Popup.__init__(self)
       -        self.app = App.get_running_app()
       +        self.app = App.get_running_app()  # type: ElectrumWindow
                self.title = title
                self.data = data
                self.key = key
   DIR diff --git a/electrum/gui/kivy/uix/screens.py b/electrum/gui/kivy/uix/screens.py
       t@@ -4,6 +4,7 @@ from decimal import Decimal
        import re
        import threading
        import traceback, sys
       +from typing import TYPE_CHECKING, List
        
        from kivy.app import App
        from kivy.cache import Cache
       t@@ -39,6 +40,9 @@ from .dialogs.lightning_open_channel import LightningOpenChannelDialog
        
        from electrum.gui.kivy.i18n import _
        
       +if TYPE_CHECKING:
       +    from electrum.gui.kivy.main_window import ElectrumWindow
       +
        
        class HistoryRecycleView(RecycleView):
            pass
       t@@ -54,7 +58,7 @@ class CScreen(Factory.Screen):
            action_view = ObjectProperty(None)
            loaded = False
            kvname = None
       -    app = App.get_running_app()
       +    app = App.get_running_app()  # type: ElectrumWindow
        
            def _change_action_view(self):
                app = App.get_running_app()
       t@@ -310,7 +314,7 @@ class SendScreen(CScreen):
                    if not bitcoin.is_address(address):
                        self.app.show_error(_('Invalid Bitcoin Address') + ':\n' + address)
                        return
       -            outputs = [(TYPE_ADDRESS, address, amount)]
       +            outputs = [TxOutput(TYPE_ADDRESS, address, amount)]
                    return self.app.wallet.create_invoice(outputs, message, self.payment_request, self.parsed_URI)
        
            def do_save(self):
       t@@ -336,8 +340,8 @@ class SendScreen(CScreen):
                    return
                elif invoice['type'] == PR_TYPE_ONCHAIN:
                    message = invoice['message']
       -            outputs = invoice['outputs']
       -            amount = sum(map(lambda x:x[2], outputs))
       +            outputs = invoice['outputs']  # type: List[TxOutput]
       +            amount = sum(map(lambda x: x.value, outputs))
                    do_pay = lambda rbf: self._do_send_onchain(amount, message, outputs, rbf)
                    if self.app.electrum_config.get('use_rbf'):
                        d = Question(_('Should this transaction be replaceable?'), do_pay)
   DIR diff --git a/electrum/paymentrequest.py b/electrum/paymentrequest.py
       t@@ -248,7 +248,7 @@ class PaymentRequest:
                return self.details.expires
        
            def get_amount(self):
       -        return sum(map(lambda x:x[2], self.outputs))
       +        return sum(map(lambda x:x.value, self.outputs))
        
            def get_address(self):
                o = self.outputs[0]
   DIR diff --git a/electrum/wallet.py b/electrum/wallet.py
       t@@ -228,6 +228,12 @@ class Abstract_Wallet(AddressSynchronizer):
                self.receive_requests      = storage.get('payment_requests', {})
                self.invoices              = storage.get('invoices', {})
        
       +        # convert invoices
       +        for invoice_key, invoice in self.invoices.items():
       +            if invoice['type'] == PR_TYPE_ONCHAIN:
       +                outputs = [TxOutput(*output) for output in invoice.get('outputs')]
       +                invoice['outputs'] = outputs
       +
                self.calc_unused_change_addresses()
        
                # save wallet type the first time