1
0

lightning GUI: use existing receive and send tabs with lightning invoices

This commit is contained in:
ThomasV
2018-05-31 12:38:02 +02:00
parent 7d2a6d83d5
commit 12d3877873
6 changed files with 144 additions and 88 deletions

View File

@@ -88,7 +88,6 @@ from .util import (read_QIcon, ColorScheme, text_dialog, icon_path, WaitingDialo
from .installwizard import WIF_HELP_TEXT
from .history_list import HistoryList, HistoryModel
from .update_checker import UpdateCheck, UpdateCheckThread
from .lightning_invoice_list import LightningInvoiceList
from .lightning_channels_list import LightningChannelsList
@@ -177,11 +176,8 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
tabs.addTab(self.send_tab, QIcon(":icons/tab_send.png"), _('Send'))
tabs.addTab(self.receive_tab, QIcon(":icons/tab_receive.png"), _('Receive'))
if config.get("lnbase", False):
self.lightning_invoices_tab = self.create_lightning_invoices_tab(wallet)
tabs.addTab(self.lightning_invoices_tab, _("Lightning Invoices"))
self.lightning_channels_tab = self.create_lightning_channels_tab(wallet)
tabs.addTab(self.lightning_channels_tab, _("Lightning Channels"))
tabs.addTab(self.lightning_channels_tab, QIcon(":icons/lightning.png"), _("Channels"))
def add_optional_tab(tabs, tab, icon, description, name):
tab.tab_icon = icon
@@ -881,10 +877,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
self.invoice_list.update()
self.update_completions()
def create_lightning_invoices_tab(self, wallet):
self.lightning_invoice_list = LightningInvoiceList(self, wallet.lnworker)
return self.lightning_invoice_list
def create_lightning_channels_tab(self, wallet):
self.lightning_channels_list = LightningChannelsList(self, wallet.lnworker)
return self.lightning_channels_list
@@ -915,17 +907,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
grid.setSpacing(8)
grid.setColumnStretch(3, 1)
self.receive_address_e = ButtonsLineEdit()
self.receive_address_e.addCopyButton(self.app)
self.receive_address_e.setReadOnly(True)
msg = _('Bitcoin address where the payment should be received. Note that each payment request uses a different Bitcoin address.')
self.receive_address_label = HelpLabel(_('Receiving address'), msg)
self.receive_address_e.textChanged.connect(self.update_receive_qr)
self.receive_address_e.textChanged.connect(self.update_receive_address_styling)
self.receive_address_e.setFocusPolicy(Qt.ClickFocus)
grid.addWidget(self.receive_address_label, 0, 0)
grid.addWidget(self.receive_address_e, 0, 1, 1, -1)
self.receive_message_e = QLineEdit()
grid.addWidget(QLabel(_('Description')), 1, 0)
grid.addWidget(self.receive_message_e, 1, 1, 1, -1)
@@ -960,23 +941,31 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
self.expires_label.hide()
grid.addWidget(self.expires_label, 3, 1)
self.save_request_button = QPushButton(_('Save'))
self.save_request_button.clicked.connect(self.save_payment_request)
self.receive_type = QComboBox()
self.receive_type.addItems([_('Bitcoin address'), _('Lightning')])
grid.addWidget(QLabel(_('Type')), 4, 0)
grid.addWidget(self.receive_type, 4, 1)
self.new_request_button = QPushButton(_('New'))
self.new_request_button.clicked.connect(self.new_payment_request)
self.save_request_button = QPushButton(_('Create'))
self.save_request_button.clicked.connect(self.create_invoice)
self.receive_buttons = buttons = QHBoxLayout()
buttons.addWidget(self.save_request_button)
buttons.addStretch(1)
grid.addLayout(buttons, 4, 2, 1, 2)
self.receive_address_e = ButtonsTextEdit()
self.receive_address_e.addCopyButton(self.app)
self.receive_address_e.setReadOnly(True)
self.receive_address_e.textChanged.connect(self.update_receive_qr)
self.receive_address_e.textChanged.connect(self.update_receive_address_styling)
self.receive_address_e.setFocusPolicy(Qt.ClickFocus)
self.receive_qr = QRCodeWidget(fixedSize=200)
self.receive_qr.mouseReleaseEvent = lambda x: self.toggle_qr_window()
self.receive_qr.enterEvent = lambda x: self.app.setOverrideCursor(QCursor(Qt.PointingHandCursor))
self.receive_qr.leaveEvent = lambda x: self.app.setOverrideCursor(QCursor(Qt.ArrowCursor))
self.receive_buttons = buttons = QHBoxLayout()
buttons.addStretch(1)
buttons.addWidget(self.save_request_button)
buttons.addWidget(self.new_request_button)
grid.addLayout(buttons, 4, 1, 1, 2)
self.receive_requests_label = QLabel(_('Requests'))
from .request_list import RequestList
@@ -987,14 +976,19 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
vbox_g.addLayout(grid)
vbox_g.addStretch()
hbox_r = QHBoxLayout()
hbox_r.addWidget(self.receive_qr)
hbox_r.addWidget(self.receive_address_e)
hbox = QHBoxLayout()
hbox.addLayout(vbox_g)
hbox.addWidget(self.receive_qr)
hbox.addLayout(hbox_r)
w = QWidget()
w.searchable_list = self.request_list
vbox = QVBoxLayout(w)
vbox.addLayout(hbox)
vbox.addStretch(1)
vbox.addWidget(self.receive_requests_label)
vbox.addWidget(self.request_list)
@@ -1047,15 +1041,34 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
else:
return
def save_payment_request(self):
addr = str(self.receive_address_e.text())
def create_invoice(self):
amount = self.receive_amount_e.get_amount()
message = self.receive_message_e.text()
if not message and not amount:
self.show_error(_('No message or amount'))
return False
i = self.expires_combo.currentIndex()
expiration = list(map(lambda x: x[1], expiration_values))[i]
if self.receive_type.currentIndex() == 1:
self.create_lightning_request(amount, message, expiration)
else:
self.create_bitcoin_request(amount, message, expiration)
self.request_list.update()
def create_lightning_request(self, amount, message, expiration):
req = self.wallet.lnworker.add_invoice(amount)
def create_bitcoin_request(self, amount, message, expiration):
addr = self.wallet.get_unused_address()
if addr is None:
if not self.wallet.is_deterministic():
msg = [
_('No more addresses in your wallet.'),
_('You are using a non-deterministic wallet, which cannot create new addresses.'),
_('If you want to create new addresses, use a deterministic wallet instead.')
]
self.show_message(' '.join(msg))
return
if not self.question(_("Warning: The next address will not be recovered automatically if you restore your wallet from seed; you may need to add it manually.\n\nThis occurs because you have too many unused addresses in your wallet. To avoid this situation, use the existing addresses first.\n\nCreate anyway?")):
return
addr = self.wallet.create_new_address(False)
req = self.wallet.make_payment_request(addr, amount, message, expiration)
try:
self.wallet.add_payment_request(req, self.config)
@@ -1066,7 +1079,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
self.sign_payment_request(addr)
self.save_request_button.setEnabled(False)
finally:
self.request_list.update()
self.address_list.update()
def view_and_paste(self, title, msg, data):
@@ -1092,26 +1104,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
self.show_message(_("Request saved successfully"))
self.saved = True
def new_payment_request(self):
addr = self.wallet.get_unused_address()
if addr is None:
if not self.wallet.is_deterministic():
msg = [
_('No more addresses in your wallet.'),
_('You are using a non-deterministic wallet, which cannot create new addresses.'),
_('If you want to create new addresses, use a deterministic wallet instead.')
]
self.show_message(' '.join(msg))
return
if not self.question(_("Warning: The next address will not be recovered automatically if you restore your wallet from seed; you may need to add it manually.\n\nThis occurs because you have too many unused addresses in your wallet. To avoid this situation, use the existing addresses first.\n\nCreate anyway?")):
return
addr = self.wallet.create_new_address(False)
self.set_receive_address(addr)
self.expires_label.hide()
self.expires_combo.show()
self.new_request_button.setEnabled(False)
self.receive_message_e.setFocus(1)
def set_receive_address(self, addr):
self.receive_address_e.setText(addr)
self.receive_message_e.setText('')
@@ -1158,11 +1150,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
self.new_request_button.setEnabled(True)
def update_receive_qr(self):
addr = str(self.receive_address_e.text())
amount = self.receive_amount_e.get_amount()
message = self.receive_message_e.text()
self.save_request_button.setEnabled((amount is not None) or (message != ""))
uri = util.create_bip21_uri(addr, amount, message)
uri = str(self.receive_address_e.text())
self.receive_qr.setData(uri)
if self.qr_window and self.qr_window.isVisible():
self.qr_window.qrw.setData(uri)
@@ -1876,6 +1864,23 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
else:
self.payment_request_error_signal.emit()
def parse_lightning_invoice(self, invoice):
from electrum.lightning_payencode.lnaddr import lndecode
lnaddr = lndecode(invoice, expected_hrp=constants.net.SEGWIT_HRP)
pubkey = bh2u(lnaddr.pubkey.serialize())
for k,v in lnaddr.tags:
if k == 'd':
description = v
break
else:
description = ''
self.payto_e.setFrozen(True)
self.payto_e.setGreen()
self.payto_e.setText(pubkey)
self.message_e.setText(description)
self.amount_e.setAmount(lnaddr.amount)
#self.amount_e.textEdited.emit("")
def pay_to_URI(self, URI):
if not URI:
return

View File

@@ -61,10 +61,8 @@ class PayToEdit(CompletionTextEdit, ScanQRTextEdit, Logger):
self.errors = []
self.is_pr = False
self.is_alias = False
self.scan_f = win.pay_to_URI
self.update_size()
self.payto_address = None
self.previous_payto = ''
def setFrozen(self, b):
@@ -130,7 +128,10 @@ class PayToEdit(CompletionTextEdit, ScanQRTextEdit, Logger):
if len(lines) == 1:
data = lines[0]
if data.startswith("bitcoin:"):
self.scan_f(data)
self.win.pay_to_URI(data)
return
if data.startswith("ln"):
self.win.parse_lightning_invoice(data)
return
try:
self.payto_address = self.parse_output(data)
@@ -204,7 +205,7 @@ class PayToEdit(CompletionTextEdit, ScanQRTextEdit, Logger):
def qr_input(self):
data = super(PayToEdit,self).qr_input()
if data.startswith("bitcoin:"):
self.scan_f(data)
self.win.pay_to_URI(data)
# TODO: update fee
def resolve(self):

View File

@@ -79,12 +79,19 @@ class RequestList(MyTreeView):
amount = req['amount']
message = req['memo']
self.parent.receive_address_e.setText(addr)
self.parent.receive_message_e.setText(message)
self.parent.receive_amount_e.setAmount(amount)
self.parent.expires_combo.hide()
self.parent.expires_label.show()
self.parent.expires_label.setText(expires)
self.parent.new_request_button.setEnabled(True)
#req = self.wallet.receive_requests.get(addr)
#if req is None:
# self.update()
# return
#expires = age(req['time'] + req['exp']) if req.get('exp') else _('Never')
#amount = req['amount']
#message = self.wallet.labels.get(addr, '')
#self.parent.receive_message_e.setText(message)
#self.parent.receive_amount_e.setAmount(amount)
#self.parent.expires_combo.hide()
#self.parent.expires_label.show()
#self.parent.expires_label.setText(expires)
#self.parent.new_request_button.setEnabled(True)
def update(self):
self.wallet = self.parent.wallet
@@ -98,7 +105,7 @@ class RequestList(MyTreeView):
self.parent.expires_combo.show()
# update the receive address if necessary
current_address = self.parent.receive_address_e.text()
#current_address = self.parent.receive_address_e.text()
domain = self.wallet.get_receiving_addresses()
try:
addr = self.wallet.get_unused_address()
@@ -126,7 +133,8 @@ class RequestList(MyTreeView):
signature = req.get('sig')
requestor = req.get('name', '')
amount_str = self.parent.format_amount(amount) if amount else ""
labels = [date, address, '', message, amount_str, pr_tooltips.get(status,'')]
URI = self.parent.get_request_URI(address)
labels = [date, URI, '', message, amount_str, pr_tooltips.get(status,'')]
items = [QStandardItem(e) for e in labels]
self.set_editability(items)
if signature is not None:
@@ -137,6 +145,22 @@ class RequestList(MyTreeView):
items[self.Columns.DESCRIPTION].setData(address, Qt.UserRole)
self.model().insertRow(self.model().rowCount(), items)
self.filter()
# lightning
for k, r in self.wallet.lnworker.invoices.items():
from electrum.lightning_payencode.lnaddr import lndecode
import electrum.constants as constants
lnaddr = lndecode(r, expected_hrp=constants.net.SEGWIT_HRP)
amount_str = self.parent.format_amount(lnaddr.amount*100000000)
for k,v in lnaddr.tags:
if k == 'd':
description = v
break
else:
description = ''
labels = [date, r, '', description, amount_str, '']
items = [QStandardItem(e) for e in labels]
items.setIcon(2, QIcon(":icons/lightning.png"))
self.model().insertRow(self.model().rowCount(), items)
def create_menu(self, position):
idx = self.indexAt(position)