electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

request_dialog.py (5262B)


      1 from typing import TYPE_CHECKING
      2 
      3 from kivy.factory import Factory
      4 from kivy.lang import Builder
      5 from kivy.core.clipboard import Clipboard
      6 from kivy.app import App
      7 from kivy.clock import Clock
      8 
      9 from electrum.gui.kivy.i18n import _
     10 from electrum.invoices import pr_tooltips, pr_color
     11 from electrum.invoices import PR_UNKNOWN, PR_UNPAID, PR_FAILED, PR_TYPE_LN
     12 
     13 if TYPE_CHECKING:
     14     from ...main_window import ElectrumWindow
     15 
     16 
     17 Builder.load_string('''
     18 #:import KIVY_GUI_PATH electrum.gui.kivy.KIVY_GUI_PATH
     19 
     20 <RequestDialog@Popup>
     21     id: popup
     22     amount_str: ''
     23     title: ''
     24     description:''
     25     is_lightning: False
     26     key:''
     27     warning: ''
     28     status_str: ''
     29     status_color: 1,1,1,1
     30     shaded: False
     31     show_text: False
     32     AnchorLayout:
     33         anchor_x: 'center'
     34         BoxLayout:
     35             orientation: 'vertical'
     36             size_hint: 1, 1
     37             padding: '10dp'
     38             spacing: '10dp'
     39             QRCodeWidget:
     40                 id: qr
     41                 shaded: False
     42                 foreground_color: (0, 0, 0, 0.5) if self.shaded else (0, 0, 0, 0)
     43                 on_touch_down:
     44                     touch = args[1]
     45                     if self.collide_point(*touch.pos): self.shaded = not self.shaded
     46             TopLabel:
     47                 text: _('Description') + ': ' + root.description or _('None')
     48             TopLabel:
     49                 text: _('Amount') + ': ' + root.amount_str
     50             TopLabel:
     51                 text: (_('Address') if not root.is_lightning else _('Payment hash')) + ': '
     52             RefLabel:
     53                 data: root.key
     54                 name: (_('Address') if not root.is_lightning else _('Payment hash'))
     55             TopLabel:
     56                 text: _('Status') + ': ' + root.status_str
     57                 color: root.status_color
     58             TopLabel:
     59                 text: root.warning
     60                 color: (0.9, 0.6, 0.3, 1)
     61             Widget:
     62                 size_hint: 1, 0.2
     63             BoxLayout:
     64                 size_hint: 1, None
     65                 height: '48dp'
     66                 Button:
     67                     size_hint: 1, None
     68                     height: '48dp'
     69                     text: _('Delete')
     70                     on_release: root.delete_dialog()
     71                 IconButton:
     72                     icon: f'atlas://{KIVY_GUI_PATH}/theming/light/copy'
     73                     size_hint: 0.5, None
     74                     height: '48dp'
     75                     on_release: root.copy_to_clipboard()
     76                 IconButton:
     77                     icon: f'atlas://{KIVY_GUI_PATH}/theming/light/share'
     78                     size_hint: 0.5, None
     79                     height: '48dp'
     80                     on_release: root.do_share()
     81                 Button:
     82                     size_hint: 1, None
     83                     height: '48dp'
     84                     text: _('Close')
     85                     on_release: popup.dismiss()
     86 ''')
     87 
     88 class RequestDialog(Factory.Popup):
     89 
     90     def __init__(self, title, key):
     91         self.status = PR_UNKNOWN
     92         Factory.Popup.__init__(self)
     93         self.app = App.get_running_app()  # type: ElectrumWindow
     94         self.title = title
     95         self.key = key
     96         r = self.app.wallet.get_request(key)
     97         self.is_lightning = r.is_lightning()
     98         self.data = r.invoice if self.is_lightning else self.app.wallet.get_request_URI(r)
     99         self.amount_sat = r.get_amount_sat()
    100         self.amount_str = self.app.format_amount_and_units(self.amount_sat)
    101         self.description = r.message
    102         self.update_status()
    103 
    104     def on_open(self):
    105         data = self.data
    106         if self.is_lightning:
    107             # encode lightning invoices as uppercase so QR encoding can use
    108             # alphanumeric mode; resulting in smaller QR codes
    109             data = data.upper()
    110         self.ids.qr.set_data(data)
    111 
    112     def update_status(self):
    113         req = self.app.wallet.get_request(self.key)
    114         self.status = self.app.wallet.get_request_status(self.key)
    115         self.status_str = req.get_status_str(self.status)
    116         self.status_color = pr_color[self.status]
    117         if self.status == PR_UNPAID and self.is_lightning and self.app.wallet.lnworker:
    118             if self.amount_sat and self.amount_sat > self.app.wallet.lnworker.num_sats_can_receive():
    119                 self.warning = _('Warning') + ': ' + _('This amount exceeds the maximum you can currently receive with your channels')
    120         if self.status == PR_UNPAID and not self.is_lightning:
    121             address = req.get_address()
    122             if self.app.wallet.is_used(address):
    123                 self.warning = _('Warning') + ': ' + _('This address is being reused')
    124 
    125     def on_dismiss(self):
    126         self.app.request_popup = None
    127 
    128     def copy_to_clipboard(self):
    129         Clipboard.copy(self.data)
    130         msg = _('Text copied to clipboard.')
    131         Clock.schedule_once(lambda dt: self.app.show_info(msg))
    132 
    133     def do_share(self):
    134         self.app.do_share(self.data, _("Share Bitcoin Request"))
    135         self.dismiss()
    136 
    137     def delete_dialog(self):
    138         from .question import Question
    139         def cb(result):
    140             if result:
    141                 self.app.wallet.delete_request(self.key)
    142                 self.dismiss()
    143                 self.app.receive_screen.update()
    144         d = Question(_('Delete request?'), cb)
    145         d.open()