URI: 
       tadd payment requests to kivy - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 0cef063ee231cc9459dff6829dc33ffc2ed499e2
   DIR parent 2a1fbf01fe63dee9f950f7ba7b4d68d456799262
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Fri, 11 Dec 2015 15:21:21 +0100
       
       add payment requests to kivy
       
       Diffstat:
         M gui/kivy/main_window.py             |      24 +++++++++++++++++-------
         M gui/kivy/uix/screens.py             |      37 ++++++++++++++++++++++---------
         M gui/kivy/uix/ui_screens/send.kv     |       2 +-
         M gui/qt/main_window.py               |      28 +++++++++-------------------
         M lib/util.py                         |      18 +++++++++++++++++-
       
       5 files changed, 71 insertions(+), 38 deletions(-)
       ---
   DIR diff --git a/gui/kivy/main_window.py b/gui/kivy/main_window.py
       t@@ -193,9 +193,24 @@ class ElectrumWindow(App):
                self._trigger_notify_transactions = \
                    Clock.create_trigger(self.notify_transactions, 5)
        
       +    def on_pr(self, pr):
       +        from electrum.paymentrequest import PR_UNPAID, PR_PAID, PR_UNKNOWN, PR_EXPIRED
       +        if pr.verify(self.contacts):
       +            key = self.invoices.add(pr)
       +            status = self.invoices.get_status(key)
       +            #self.invoices_screen.update()
       +            if status == PR_PAID:
       +                self.show_message("invoice already paid")
       +                self.send_screen.do_clear()
       +            else:
       +                self.send_screen.set_request(pr)
       +        else:
       +            self.show_message("invoice error:" + pr.error)
       +            self.send_screen.do_clear()
       +
            def set_URI(self, url):
                try:
       -            url = electrum.util.parse_URI(url)
       +            url = electrum.util.parse_URI(url, self.on_pr)
                except:
                    self.show_info("Invalid URI", url)
                    return
       t@@ -214,12 +229,7 @@ class ElectrumWindow(App):
                        if resultCode == -1: # RESULT_OK:
                            contents = intent.getStringExtra("SCAN_RESULT")
                            if intent.getStringExtra("SCAN_RESULT_FORMAT") == 'QR_CODE':
       -                        try:
       -                            uri = electrum.util.parse_URI(contents)
       -                        except:
       -                            self.show_info("Invalid URI", url)
       -                            return
       -                        on_complete(uri)
       +                        on_complete(contents)
                activity.bind(on_activity_result=on_qr_result)
                PythonActivity.mActivity.startActivityForResult(intent, 0)
        
   DIR diff --git a/gui/kivy/uix/screens.py b/gui/kivy/uix/screens.py
       t@@ -181,6 +181,7 @@ class ScreenPassword(Factory.Screen):
        class SendScreen(CScreen):
        
            kvname = 'send'
       +    payment_request = None
        
            def set_URI(self, uri):
                print "set uri", uri
       t@@ -195,6 +196,16 @@ class SendScreen(CScreen):
                self.screen.amount = ''
                self.screen.message = ''
                self.screen.address = ''
       +        self.payment_request = None
       +
       +    def set_request(self, pr):
       +        if pr.has_expired():
       +            self.app.show_error(_('Payment request has expired'))
       +            return
       +        self.payment_request = pr
       +        self.screen.address = pr.get_requestor()
       +        self.screen.amount = self.app.format_amount(pr.get_amount())
       +        self.screen.message = pr.get_memo()
        
            def do_paste(self):
                contents = unicode(self.app._clipboard.get())
       t@@ -206,18 +217,24 @@ class SendScreen(CScreen):
                self.set_URI(uri)
        
            def do_send(self):
       -        address = str(self.screen.address)
       -        if not bitcoin.is_address(address):
       -            self.app.show_error(_('Invalid Bitcoin Address') + ':\n' + address)
       -            return
       -        try:
       -            amount = self.app.get_amount(self.screen.amount)
       -        except:
       -            self.app.show_error(_('Invalid amount') + ':\n' + self.screen.amount)
       -            return
       +        if self.payment_request:
       +            if self.payment_request.has_expired():
       +                self.app.show_error(_('Payment request has expired'))
       +                return
       +            outputs = self.payment_request.get_outputs()
       +        else:
       +            address = str(self.screen.address)
       +            if not bitcoin.is_address(address):
       +                self.app.show_error(_('Invalid Bitcoin Address') + ':\n' + address)
       +                return
       +            try:
       +                amount = self.app.get_amount(self.screen.amount)
       +            except:
       +                self.app.show_error(_('Invalid amount') + ':\n' + self.screen.amount)
       +                return
       +            outputs = [('address', address, amount)]
                message = unicode(self.screen.message)
                fee = None
       -        outputs = [('address', address, amount)]
                self.app.protected(self.send_tx, (outputs, fee, message))
        
            def send_tx(self, *args):
   DIR diff --git a/gui/kivy/uix/ui_screens/send.kv b/gui/kivy/uix/ui_screens/send.kv
       t@@ -78,7 +78,7 @@ SendScreen:
                        id: qr
                        text: _('QR Code')
                        on_release:
       -                    app.scan_qr(on_complete=s.parent.set_URI)
       +                    app.scan_qr(on_complete=app.set_URI)
                    Button:
                        id: paste_button
                        text: _('Paste')
   DIR diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py
       t@@ -83,7 +83,6 @@ class StatusBarButton(QPushButton):
        
        
        from electrum.paymentrequest import PR_UNPAID, PR_PAID, PR_UNKNOWN, PR_EXPIRED
       -from electrum.paymentrequest import PaymentRequest, get_payment_request
        
        pr_icons = {
            PR_UNPAID:":icons/unpaid.png",
       t@@ -1346,37 +1345,28 @@ class ElectrumWindow(QMainWindow, PrintError):
                self.payment_request = None
                self.do_clear()
        
       +    def on_pr(self, request):
       +        self.payment_request = request
       +        if self.payment_request.verify(self.contacts):
       +            self.emit(SIGNAL('payment_request_ok'))
       +        else:
       +            self.emit(SIGNAL('payment_request_error'))
       +
            def pay_to_URI(self, URI):
                if not URI:
                    return
                try:
       -            out = util.parse_URI(unicode(URI))
       -        except Exception as e:
       +            out = util.parse_URI(unicode(URI), self.on_pr)
       +        except BaseException as e:
                    QMessageBox.warning(self, _('Error'), _('Invalid bitcoin URI:') + '\n' + str(e), _('OK'))
                    return
                self.tabs.setCurrentIndex(1)
       -
                r = out.get('r')
                sig = out.get('sig')
                name = out.get('name')
                if r or (name and sig):
       -            def get_payment_request_thread():
       -                if name and sig:
       -                    from electrum import paymentrequest
       -                    pr = paymentrequest.serialize_request(out).SerializeToString()
       -                    self.payment_request = paymentrequest.PaymentRequest(pr)
       -                else:
       -                    self.payment_request = get_payment_request(r)
       -                if self.payment_request.verify(self.contacts):
       -                    self.emit(SIGNAL('payment_request_ok'))
       -                else:
       -                    self.emit(SIGNAL('payment_request_error'))
       -            t = threading.Thread(target=get_payment_request_thread)
       -            t.setDaemon(True)
       -            t.start()
                    self.prepare_for_payment_request()
                    return
       -
                address = out.get('address')
                amount = out.get('amount')
                label = out.get('label')
   DIR diff --git a/lib/util.py b/lib/util.py
       t@@ -317,7 +317,7 @@ def block_explorer_URL(config, kind, item):
        #_ud = re.compile('%([0-9a-hA-H]{2})', re.MULTILINE)
        #urldecode = lambda x: _ud.sub(lambda m: chr(int(m.group(1), 16)), x)
        
       -def parse_URI(uri):
       +def parse_URI(uri, on_pr=None):
            import bitcoin
            from bitcoin import COIN
        
       t@@ -364,6 +364,22 @@ def parse_URI(uri):
            if 'sig' in out:
                out['sig'] = bitcoin.base_decode(out['sig'], None, base=58).encode('hex')
        
       +    r = out.get('r')
       +    sig = out.get('sig')
       +    name = out.get('name')
       +    if r or (name and sig):
       +        def get_payment_request_thread():
       +            import paymentrequest as pr
       +            if name and sig:
       +                s = pr.serialize_request(out).SerializeToString()
       +                request = pr.PaymentRequest(s)
       +            else:
       +                request = pr.get_payment_request(r)
       +            on_pr(request)
       +        t = threading.Thread(target=get_payment_request_thread)
       +        t.setDaemon(True)
       +        t.start()
       +
            return out