Browse Source

Kivy: Lightning support in Receive tab

dependabot/pip/contrib/deterministic-build/ecdsa-0.13.3
Janus 6 years ago
committed by ThomasV
parent
commit
9d32031ca2
  1. 4
      .gitignore
  2. 4
      electrum/gui/kivy/Makefile
  3. 9
      electrum/gui/kivy/main_window.py
  4. 6
      electrum/gui/kivy/theming/light/lightning.svg
  5. 288
      electrum/gui/kivy/theming/light/lightning_switch.svg
  6. 65
      electrum/gui/kivy/uix/dialogs/lightning_invoices.py
  7. 51
      electrum/gui/kivy/uix/screens.py
  8. 27
      electrum/gui/kivy/uix/ui_screens/receive.kv
  9. 5
      electrum/lnworker.py

4
.gitignore

@ -17,8 +17,12 @@ bin/
# icons # icons
electrum/gui/kivy/theming/light-0.png electrum/gui/kivy/theming/light-0.png
electrum/gui/kivy/theming/light-1.png
electrum/gui/kivy/theming/light.atlas electrum/gui/kivy/theming/light.atlas
electrum/gui/kivy/theming/light/network.png electrum/gui/kivy/theming/light/network.png
electrum/gui/kivy/theming/light/lightning_switch_off.png
electrum/gui/kivy/theming/light/lightning_switch_on.png
electrum/gui/kivy/theming/light/lightning.png
# tests/tox # tests/tox
.tox/ .tox/

4
electrum/gui/kivy/Makefile

@ -5,7 +5,9 @@ PYTHON = python3
.PHONY: theming apk clean .PHONY: theming apk clean
theming: theming:
bash -c "convert -background none theming/light/network.{svg,png}" bash -c 'for i in network lightning; do convert -background none theming/light/$$i.{svg,png}; done'
convert -background none -crop +0+390 theming/light/lightning_switch.svg theming/light/lightning_switch_off.png
convert -background none -crop 840x390+0+0 theming/light/lightning_switch.svg theming/light/lightning_switch_on.png
$(PYTHON) -m kivy.atlas theming/light 1024 theming/light/*.png $(PYTHON) -m kivy.atlas theming/light 1024 theming/light/*.png
prepare: prepare:
# running pre build setup # running pre build setup

9
electrum/gui/kivy/main_window.py

@ -1016,6 +1016,15 @@ class ElectrumWindow(App):
popup = AmountDialog(show_max, amount, cb) popup = AmountDialog(show_max, amount, cb)
popup.open() popup.open()
def lightning_invoices_dialog(self, cb):
from .uix.dialogs.lightning_invoices import LightningInvoicesDialog
report = self.wallet.lnworker._list_invoices()
if not report['unsettled']:
self.show_info(_('No unsettled invoices. Type in an amount to generate a new one.'))
return
popup = LightningInvoicesDialog(report, cb)
popup.open()
def invoices_dialog(self, screen): def invoices_dialog(self, screen):
from .uix.dialogs.invoices import InvoicesDialog from .uix.dialogs.invoices import InvoicesDialog
if len(self.wallet.invoices.sorted_list()) == 0: if len(self.wallet.invoices.sorted_list()) == 0:

6
electrum/gui/kivy/theming/light/lightning.svg

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="210.01" height="258.6" version="1.1" viewBox="0 0 55.564 68.421" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(-37.066 -74.368)">
<path d="m38.127 110.58 40.719-34.163c1.8833-1.4037 4.6684-4.2048 2.3466 0.82819l-13.527 25.467 23.12 0.34508c1.0576 0.11762 2.8154-0.14879 1.1733 1.4493l-40.582 35.474c-2.6048 2.0742-6.2555 5.6722-2.6916-1.2423l13.251-25.398-22.913-0.55213c-2.1564 0.0996-2.6432-0.5521-0.8972-2.2085z" fill="#fff" fill-rule="evenodd" stroke-width=".13606"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 553 B

288
electrum/gui/kivy/theming/light/lightning_switch.svg

@ -0,0 +1,288 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="840"
height="820.04102"
viewBox="0 0 222.25 216.96919"
version="1.1"
id="svg8"
inkscape:version="0.92.3 (2405546, 2018-03-11)"
sodipodi:docname="lightning_switch.svg">
<defs
id="defs2">
<linearGradient
inkscape:collect="always"
id="linearGradient1019">
<stop
style="stop-color:#6464f6;stop-opacity:1;"
offset="0"
id="stop1015" />
<stop
style="stop-color:#76acff;stop-opacity:1"
offset="1"
id="stop1017" />
</linearGradient>
<filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter2183"
x="-0.023532996"
width="1.047066"
y="-0.030062485"
height="1.060125">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="0.92777831"
id="feGaussianBlur2185" />
</filter>
<linearGradient
id="linearGradient980"
x1="94.415001"
x2="166.42999"
y1="48.271999"
y2="-6.3376999"
gradientTransform="matrix(0.90487595,0,0,0.90487595,-32.116675,75.52401)"
gradientUnits="userSpaceOnUse">
<stop
id="stop973"
stop-color="#fff"
offset="0" />
<stop
id="stop975"
stop-color="#fff"
stop-opacity="0"
offset="1" />
</linearGradient>
<filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter3047"
x="-0.055550463"
width="1.1111009"
y="-0.068128757"
height="1.1362575">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="2.1025669"
id="feGaussianBlur3049" />
</filter>
<filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter3047-6"
x="-0.055550463"
width="1.1111009"
y="-0.068128757"
height="1.1362575">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="2.1025669"
id="feGaussianBlur3049-1" />
</filter>
<filter
style="color-interpolation-filters:sRGB"
inkscape:label="Color Shift"
id="filter3759">
<feColorMatrix
type="hueRotate"
values="330"
result="color1"
id="feColorMatrix3755" />
<feColorMatrix
type="saturate"
values="0"
result="color2"
id="feColorMatrix3757" />
</filter>
<filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter7464"
x="-0.085763194"
width="1.1715264"
y="-0.19973423"
height="1.3994684">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="6.6951018"
id="feGaussianBlur7466" />
</filter>
<filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter7532"
x="-0.042373311"
width="1.0847466"
y="-0.098647438"
height="1.197295">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="3.3066669"
id="feGaussianBlur7534" />
</filter>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient1019"
id="linearGradient861"
gradientUnits="userSpaceOnUse"
x1="68.955536"
y1="108.44135"
x2="68.688263"
y2="66.212761" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient980"
id="linearGradient863"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.90487595,0,0,0.90487595,-32.116675,75.52401)"
x1="94.415001"
y1="48.271999"
x2="166.42999"
y2="-6.3376999" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="256.4408"
inkscape:cy="683.69642"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:lockguides="true"
inkscape:window-width="3066"
inkscape:window-height="1689"
inkscape:window-x="134"
inkscape:window-y="55"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
units="px"
inkscape:pagecheckerboard="false" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-5.9067634,-55.147908)"
style="display:inline">
<use
x="0"
y="0"
xlink:href="#g6758"
id="use6798"
transform="translate(0,108.47917)"
width="100%"
height="100%" />
<g
id="g6758"
transform="matrix(1.0279896,0,0,1,-0.39555549,0)">
<rect
y="68.48455"
x="19.243406"
height="80.448128"
width="187.35594"
id="rect815"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#646464;fill-opacity:1;stroke:#555555;stroke-width:5;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate" />
<path
inkscape:connector-curvature="0"
id="path817"
d="M 19.243406,68.484551 H 206.59935 V 148.93268 H 19.243406 Z"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter7464)" />
<path
transform="matrix(1.0553762,0,0,1.123304,-2.8259824,-10.045808)"
inkscape:connector-curvature="0"
id="path817-5"
d="M 16.068404,65.838715 H 203.35612 V 146.28683 H 16.068404 Z"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:11.48041821;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.19002374;filter:url(#filter7532)"
sodipodi:nodetypes="ccccc" />
</g>
<g
id="g3255">
<rect
y="71.281387"
x="21.910538"
height="74.067993"
width="90.839211"
id="rect1013"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#linearGradient861);fill-opacity:1;stroke:none;stroke-width:5;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;filter:url(#filter2183);enable-background:accumulate" />
<path
d="M 38.12696,110.58365 78.846174,76.421035 c 1.883303,-1.403703 4.668394,-4.204849 2.34658,0.828194 l -13.527082,25.467191 23.120205,0.34508 c 1.057575,0.11762 2.815437,-0.14879 1.173278,1.44929 L 51.377359,139.985 c -2.604817,2.07419 -6.255505,5.67223 -2.69162,-1.2423 l 13.251022,-25.39781 -22.913402,-0.55213 c -2.156371,0.0996 -2.643184,-0.5521 -0.897201,-2.20849 z"
id="path817-3"
style="fill:url(#linearGradient863);fill-rule:evenodd;stroke-width:0.13605724"
inkscape:connector-curvature="0" />
<g
transform="rotate(180,67.330143,108.31538)"
id="g3148">
<path
style="fill:none;fill-rule:evenodd;stroke:#000976;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3047)"
d="M 112.74975,71.281387 V 145.34938 H 21.910537"
id="path2289"
inkscape:connector-curvature="0"
transform="rotate(-180,67.330143,108.31538)" />
<path
style="fill:none;fill-rule:evenodd;stroke:#91c5ff;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.50831353;filter:url(#filter3047-6)"
d="M 112.74975,71.281389 V 145.34938 H 21.910538"
id="path2289-8"
inkscape:connector-curvature="0" />
</g>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:37.21456909px;line-height:100%;font-family:FreeSans;-inkscape-font-specification:'Sans Bold';text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2.48097134px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="163.34431"
y="121.71754"
id="text3053"><tspan
sodipodi:role="line"
id="tspan3051"
x="163.34431"
y="121.71754"
style="fill:#ffffff;fill-opacity:1;stroke-width:2.48097134px">ON</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:37.21456909px;line-height:100%;font-family:FreeSans;-inkscape-font-specification:'Sans Bold';text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2.48097134px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="70.730072"
y="229.30695"
id="text3053-9"><tspan
sodipodi:role="line"
id="tspan3051-3"
x="70.730072"
y="229.30695"
style="fill:#ffffff;fill-opacity:1;stroke-width:2.48097134px">OFF</tspan></text>
<use
x="0"
y="0"
xlink:href="#g3255"
id="use3263"
transform="translate(96.165992,108.52486)"
width="100%"
height="100%"
style="filter:url(#filter3759)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

65
electrum/gui/kivy/uix/dialogs/lightning_invoices.py

@ -0,0 +1,65 @@
from kivy.factory import Factory
from kivy.lang import Builder
from electrum.gui.kivy.i18n import _
from kivy.uix.recycleview import RecycleView
from electrum.gui.kivy.uix.context_menu import ContextMenu
Builder.load_string('''
<Item@CardItem>
addr: ''
desc: ''
screen: None
BoxLayout:
orientation: 'vertical'
Label
text: root.addr
text_size: self.width, None
shorten: True
Label
text: root.desc if root.desc else _('No description')
text_size: self.width, None
shorten: True
font_size: '10dp'
<LightningInvoicesDialog@Popup>
id: popup
title: _('Lightning Invoices')
BoxLayout:
orientation: 'vertical'
id: box
RecycleView:
viewclass: 'Item'
id: recycleview
data: []
RecycleBoxLayout:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
''')
class LightningInvoicesDialog(Factory.Popup):
def __init__(self, report, callback):
super().__init__()
self.context_menu = None
self.callback = callback
self.menu_actions = [(_('Show'), self.do_show)]
for addr, preimage, pay_req in report['unsettled']:
self.ids.recycleview.data.append({'screen': self, 'addr': pay_req, 'desc': dict(addr.tags).get('d', '')})
def do_show(self, obj):
self.hide_menu()
self.dismiss()
self.callback(obj.addr)
def show_menu(self, obj):
self.hide_menu()
self.context_menu = ContextMenu(obj, self.menu_actions)
self.ids.box.add_widget(self.context_menu)
def hide_menu(self):
if self.context_menu is not None:
self.ids.box.remove_widget(self.context_menu)
self.context_menu = None

51
electrum/gui/kivy/uix/screens.py

@ -15,6 +15,8 @@ from kivy.properties import (ObjectProperty, DictProperty, NumericProperty,
from kivy.uix.recycleview import RecycleView from kivy.uix.recycleview import RecycleView
from kivy.uix.label import Label from kivy.uix.label import Label
from kivy.uix.behaviors import ToggleButtonBehavior
from kivy.uix.image import Image
from kivy.lang import Builder from kivy.lang import Builder
from kivy.factory import Factory from kivy.factory import Factory
@ -398,6 +400,7 @@ class ReceiveScreen(CScreen):
self.screen.address = '' self.screen.address = ''
self.screen.amount = '' self.screen.amount = ''
self.screen.message = '' self.screen.message = ''
self.screen.lnaddr = ''
def get_new_address(self) -> bool: def get_new_address(self) -> bool:
"""Sets the address field, and returns whether the set address """Sets the address field, and returns whether the set address
@ -440,18 +443,30 @@ class ReceiveScreen(CScreen):
@profiler @profiler
def update_qr(self): def update_qr(self):
uri = self.get_URI()
qr = self.screen.ids.qr qr = self.screen.ids.qr
qr.set_data(uri) if self.screen.ids.lnbutton.state == 'down':
qr.set_data(self.screen.lnaddr)
else:
uri = self.get_URI()
qr.set_data(uri)
def do_share(self): def do_share(self):
uri = self.get_URI() if self.screen.ids.lnbutton.state == 'down':
self.app.do_share(uri, _("Share Bitcoin Request")) if self.screen.lnaddr:
self.app.do_share('lightning://' + self.lnaddr, _('Share Lightning invoice'))
else:
uri = self.get_URI()
self.app.do_share(uri, _("Share Bitcoin Request"))
def do_copy(self): def do_copy(self):
uri = self.get_URI() if self.screen.ids.lnbutton.state == 'down':
self.app._clipboard.copy(uri) if self.screen.lnaddr:
self.app.show_info(_('Request copied to clipboard')) self.app._clipboard.copy(self.screen.lnaddr)
self.app.show_info(_('Invoice copied to clipboard'))
else:
uri = self.get_URI()
self.app._clipboard.copy(uri)
self.app.show_info(_('Request copied to clipboard'))
def save_request(self): def save_request(self):
addr = self.screen.address addr = self.screen.address
@ -472,6 +487,9 @@ class ReceiveScreen(CScreen):
return added_request return added_request
def on_amount_or_message(self): def on_amount_or_message(self):
if self.screen.ids.lnbutton.state == 'down':
if self.screen.amount:
self.screen.lnaddr = self.app.wallet.lnworker.add_invoice(self.app.get_amount(self.screen.amount), self.screen.message)
Clock.schedule_once(lambda dt: self.update_qr()) Clock.schedule_once(lambda dt: self.update_qr())
def do_new(self): def do_new(self):
@ -483,6 +501,13 @@ class ReceiveScreen(CScreen):
if self.save_request(): if self.save_request():
self.app.show_info(_('Request was saved.')) self.app.show_info(_('Request was saved.'))
def do_open_lnaddr(self, lnaddr):
self.clear()
self.screen.lnaddr = lnaddr
obj = lndecode(lnaddr, expected_hrp=constants.net.SEGWIT_HRP)
self.screen.message = dict(obj.tags).get('d', '')
self.screen.amount = self.app.format_amount_and_units(int(obj.amount * bitcoin.COIN))
self.on_amount_or_message()
class TabbedCarousel(Factory.TabbedPanel): class TabbedCarousel(Factory.TabbedPanel):
'''Custom TabbedPanel using a carousel used in the Main Screen '''Custom TabbedPanel using a carousel used in the Main Screen
@ -556,3 +581,15 @@ class TabbedCarousel(Factory.TabbedPanel):
self.carousel.add_widget(widget) self.carousel.add_widget(widget)
return return
super(TabbedCarousel, self).add_widget(widget, index=index) super(TabbedCarousel, self).add_widget(widget, index=index)
class LightningButton(ToggleButtonBehavior, Image):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.source = 'atlas://electrum/gui/kivy/theming/light/lightning_switch_off'
def on_state(self, widget, value):
self.state = value
if value == 'down':
self.source = 'atlas://electrum/gui/kivy/theming/light/lightning_switch_on'
else:
self.source = 'atlas://electrum/gui/kivy/theming/light/lightning_switch_off'

27
electrum/gui/kivy/uix/ui_screens/receive.kv

@ -14,6 +14,7 @@ ReceiveScreen:
amount: '' amount: ''
message: '' message: ''
status: '' status: ''
lnaddr: ''
on_address: on_address:
self.parent.on_address(self.address) self.parent.on_address(self.address)
@ -30,6 +31,7 @@ ReceiveScreen:
FloatLayout: FloatLayout:
id: bl id: bl
QRCodeWidget: QRCodeWidget:
opacity: 0 if lnbutton.state == 'down' and not s.lnaddr else 1
id: qr id: qr
size_hint: None, 1 size_hint: None, 1
width: min(self.height, bl.width) width: min(self.height, bl.width)
@ -62,15 +64,15 @@ ReceiveScreen:
height: blue_bottom.item_height height: blue_bottom.item_height
spacing: '5dp' spacing: '5dp'
Image: Image:
source: 'atlas://electrum/gui/kivy/theming/light/globe' source: 'atlas://electrum/gui/kivy/theming/light/lightning' if lnbutton.state == 'down' else 'atlas://electrum/gui/kivy/theming/light/globe'
size_hint: None, None size_hint: None, None
size: '22dp', '22dp' size: '22dp', '22dp'
pos_hint: {'center_y': .5} pos_hint: {'center_y': .5}
BlueButton: BlueButton:
id: address_label id: address_label
text: s.address if s.address else _('Bitcoin Address') text: (s.address if s.address else _('Bitcoin Address')) if lnbutton.state != 'down' else (s.lnaddr if s.lnaddr else _('Please enter amount'))
shorten: True shorten: True
on_release: Clock.schedule_once(lambda dt: app.addresses_dialog(s)) on_release: Clock.schedule_once(lambda dt: app.addresses_dialog(s) if lnbutton.state != 'down' else s.parent.do_copy())
CardSeparator: CardSeparator:
opacity: message_selection.opacity opacity: message_selection.opacity
color: blue_bottom.foreground_color color: blue_bottom.foreground_color
@ -111,15 +113,17 @@ ReceiveScreen:
size_hint: 1, None size_hint: 1, None
height: '48dp' height: '48dp'
IconButton: IconButton:
icon: 'atlas://electrum/gui/kivy/theming/light/save' opacity: 1 if lnbutton.state != 'down' else 0
size_hint: 0.6, None icon: 'atlas://electrum/gui/kivy/theming/light/save' if lnbutton.state != 'down' else ''
size_hint: (0 if lnbutton.state == 'down' else 0.6), None
height: '48dp' height: '48dp'
on_release: s.parent.do_save() on_release: s.parent.do_save() if lnbutton.state != 'down' else None
width: (0 if lnbutton.state == 'down' else 100)
Button: Button:
text: _('Requests') text: _('Requests') if lnbutton.state != 'down' else _('Lightning Invoices')
size_hint: 1, None size_hint: 1 + (.6 if lnbutton.state == 'down' else 0), None
height: '48dp' height: '48dp'
on_release: Clock.schedule_once(lambda dt: app.requests_dialog(s)) on_release: Clock.schedule_once(lambda dt: app.requests_dialog(s) if lnbutton.state != 'down' else app.lightning_invoices_dialog(s.parent.do_open_lnaddr))
Button: Button:
text: _('Copy') text: _('Copy')
size_hint: 1, None size_hint: 1, None
@ -133,8 +137,11 @@ ReceiveScreen:
BoxLayout: BoxLayout:
size_hint: 1, None size_hint: 1, None
height: '48dp' height: '48dp'
LightningButton
id: lnbutton
on_state: s.parent.on_amount_or_message()
Widget Widget
size_hint: 2, 1 size_hint: 1, 1
Button: Button:
text: _('New') text: _('New')
size_hint: 1, None size_hint: 1, None

5
electrum/lnworker.py

@ -115,7 +115,8 @@ class LNWorker(PrintError):
if report['unsettled']: if report['unsettled']:
yield 'Your unsettled invoices:' yield 'Your unsettled invoices:'
yield '------------------------' yield '------------------------'
for addr, preimage in report['unsettled']: for addr, preimage, pay_req in report['unsettled']:
yield pay_req
yield str(addr) yield str(addr)
yield 'Preimage: ' + bh2u(preimage) yield 'Preimage: ' + bh2u(preimage)
yield '' yield ''
@ -143,7 +144,7 @@ class LNWorker(PrintError):
settled.append((datetime.fromtimestamp(date, timezone.utc), HTLCOwner(direction), htlcobj, preimage)) settled.append((datetime.fromtimestamp(date, timezone.utc), HTLCOwner(direction), htlcobj, preimage))
for preimage, pay_req in invoices.values(): for preimage, pay_req in invoices.values():
addr = lndecode(pay_req, expected_hrp=constants.net.SEGWIT_HRP) addr = lndecode(pay_req, expected_hrp=constants.net.SEGWIT_HRP)
unsettled.append((addr, bfh(preimage))) unsettled.append((addr, bfh(preimage), pay_req))
for pay_req, amount_sat in self.paying.values(): for pay_req, amount_sat in self.paying.values():
addr = lndecode(pay_req, expected_hrp=constants.net.SEGWIT_HRP) addr = lndecode(pay_req, expected_hrp=constants.net.SEGWIT_HRP)
if amount_sat is not None: if amount_sat is not None:

Loading…
Cancel
Save