store invoices in a separate file, with their status
This commit is contained in:
@@ -78,13 +78,8 @@ class StatusBarButton(QPushButton):
|
||||
apply(self.func,())
|
||||
|
||||
|
||||
|
||||
# status of payment requests
|
||||
PR_UNPAID = 0
|
||||
PR_EXPIRED = 1
|
||||
PR_SENT = 2 # sent but not propagated
|
||||
PR_PAID = 3 # send and propagated
|
||||
PR_ERROR = 4 # could not parse
|
||||
from electrum.paymentrequest import PR_UNPAID, PR_PAID, PR_EXPIRED
|
||||
from electrum.paymentrequest import PaymentRequest, InvoiceStore, get_payment_request
|
||||
|
||||
pr_icons = {
|
||||
PR_UNPAID:":icons/unpaid.png",
|
||||
@@ -113,12 +108,13 @@ class ElectrumWindow(QMainWindow):
|
||||
self.lite = None
|
||||
self.app = gui_object.app
|
||||
|
||||
self.invoices = InvoiceStore(self.config)
|
||||
|
||||
self.create_status_bar()
|
||||
self.need_update = threading.Event()
|
||||
|
||||
self.decimal_point = config.get('decimal_point', 5)
|
||||
self.num_zeros = int(config.get('num_zeros',0))
|
||||
self.invoices = {}
|
||||
|
||||
self.completions = QStringListModel()
|
||||
|
||||
@@ -203,7 +199,6 @@ class ElectrumWindow(QMainWindow):
|
||||
a = self.wallet.addresses(False)
|
||||
self.dummy_address = a[0] if a else None
|
||||
|
||||
self.invoices = self.wallet.storage.get('invoices', {})
|
||||
self.accounts_expanded = self.wallet.storage.get('accounts_expanded',{})
|
||||
self.current_account = self.wallet.storage.get("current_account", None)
|
||||
title = 'Electrum ' + self.wallet.electrum_version + ' - ' + os.path.basename(self.wallet.storage.path)
|
||||
@@ -568,7 +563,8 @@ class ElectrumWindow(QMainWindow):
|
||||
|
||||
self.receive_address_e = QLineEdit()
|
||||
self.receive_address_e.setReadOnly(True)
|
||||
grid.addWidget(QLabel(_('Receiving address')), 0, 0)
|
||||
self.receive_address_label = QLabel(_('Receiving address'))
|
||||
grid.addWidget(self.receive_address_label, 0, 0)
|
||||
grid.addWidget(self.receive_address_e, 0, 1, 1, 3)
|
||||
self.receive_address_e.textChanged.connect(self.update_receive_qr)
|
||||
|
||||
@@ -1060,8 +1056,7 @@ class ElectrumWindow(QMainWindow):
|
||||
status, msg = self.wallet.sendtx(tx)
|
||||
if not status:
|
||||
return False, msg
|
||||
self.invoices[pr.get_id()] = (pr.get_domain(), pr.get_memo(), pr.get_amount(), pr.get_expiration_date(), PR_PAID, tx.hash())
|
||||
self.wallet.storage.put('invoices', self.invoices)
|
||||
pr.set_paid(tx.hash())
|
||||
self.payment_request = None
|
||||
refund_address = self.wallet.addresses()[0]
|
||||
ack_status, ack_msg = pr.send_ack(str(tx), refund_address)
|
||||
@@ -1096,15 +1091,9 @@ class ElectrumWindow(QMainWindow):
|
||||
|
||||
def payment_request_ok(self):
|
||||
pr = self.payment_request
|
||||
pr_id = pr.get_id()
|
||||
if pr_id not in self.invoices:
|
||||
self.invoices[pr_id] = (pr.get_domain(), pr.get_memo(), pr.get_amount(), pr.get_expiration_date(), PR_UNPAID, None)
|
||||
self.wallet.storage.put('invoices', self.invoices)
|
||||
self.update_invoices_tab()
|
||||
else:
|
||||
print_error('invoice already in list')
|
||||
|
||||
status = self.invoices[pr_id][4]
|
||||
status = pr.get_status()
|
||||
key = self.invoices.add(pr)
|
||||
self.update_invoices_tab()
|
||||
if status == PR_PAID:
|
||||
self.do_clear()
|
||||
self.show_message("invoice already paid")
|
||||
@@ -1113,7 +1102,6 @@ class ElectrumWindow(QMainWindow):
|
||||
|
||||
self.payto_help.show()
|
||||
self.payto_help.set_alt(lambda: self.show_pr_details(pr))
|
||||
|
||||
if not pr.has_expired():
|
||||
self.payto_e.setGreen()
|
||||
else:
|
||||
@@ -1159,16 +1147,14 @@ class ElectrumWindow(QMainWindow):
|
||||
self.amount_e.textEdited.emit("")
|
||||
return
|
||||
|
||||
from electrum import paymentrequest
|
||||
def payment_request():
|
||||
self.payment_request = paymentrequest.PaymentRequest(self.config)
|
||||
self.payment_request.read(request_url)
|
||||
def get_payment_request_thread():
|
||||
self.payment_request = get_payment_request(request_url)
|
||||
if self.payment_request.verify():
|
||||
self.emit(SIGNAL('payment_request_ok'))
|
||||
else:
|
||||
self.emit(SIGNAL('payment_request_error'))
|
||||
|
||||
self.pr_thread = threading.Thread(target=payment_request).start()
|
||||
self.pr_thread = threading.Thread(target=get_payment_request_thread).start()
|
||||
self.prepare_for_payment_request()
|
||||
|
||||
|
||||
@@ -1227,15 +1213,14 @@ class ElectrumWindow(QMainWindow):
|
||||
return self.create_list_tab(l)
|
||||
|
||||
def update_invoices_tab(self):
|
||||
invoices = self.wallet.storage.get('invoices', {})
|
||||
l = self.invoices_list
|
||||
l.clear()
|
||||
for key, value in sorted(invoices.items(), key=lambda x: -x[1][3]):
|
||||
domain, memo, amount, expiration_date, status, tx_hash = value
|
||||
if status == PR_UNPAID and expiration_date and expiration_date < time.time():
|
||||
status = PR_EXPIRED
|
||||
date_str = format_time(expiration_date)
|
||||
item = QTreeWidgetItem( [ date_str, domain, memo, self.format_amount(amount, whitespaces=True), ''] )
|
||||
for pr in self.invoices.sorted_list():
|
||||
key = pr.get_id()
|
||||
status = pr.get_status()
|
||||
domain = pr.get_domain()
|
||||
date_str = format_time(pr.get_expiration_date())
|
||||
item = QTreeWidgetItem( [ date_str, domain, pr.memo, self.format_amount(pr.get_amount(), whitespaces=True), ''] )
|
||||
icon = QIcon(pr_icons.get(status))
|
||||
item.setIcon(4, icon)
|
||||
item.setToolTip(4, pr_tooltips.get(status,''))
|
||||
@@ -1385,36 +1370,25 @@ class ElectrumWindow(QMainWindow):
|
||||
run_hook('create_contact_menu', menu, item)
|
||||
menu.exec_(self.contacts_list.viewport().mapToGlobal(position))
|
||||
|
||||
def delete_invoice(self, key):
|
||||
self.invoices.pop(key)
|
||||
self.wallet.storage.put('invoices', self.invoices)
|
||||
self.update_invoices_tab()
|
||||
|
||||
def show_invoice(self, key):
|
||||
from electrum.paymentrequest import PaymentRequest
|
||||
domain, memo, value, expiration, status, tx_hash = self.invoices[key]
|
||||
pr = PaymentRequest(self.config)
|
||||
pr.read_file(key)
|
||||
pr.domain = domain
|
||||
pr = self.invoices.get(key)
|
||||
pr.verify()
|
||||
self.show_pr_details(pr, tx_hash)
|
||||
self.show_pr_details(pr)
|
||||
|
||||
def show_pr_details(self, pr, tx_hash=None):
|
||||
msg = 'Domain: ' + pr.domain
|
||||
msg += '\nStatus: ' + pr.get_status()
|
||||
def show_pr_details(self, pr):
|
||||
msg = 'Requestor: ' + pr.get_domain()
|
||||
msg += '\nExpires: ' + format_time(pr.get_expiration_date())
|
||||
msg += '\nStatus: ' + pr.get_verify_status()
|
||||
msg += '\nMemo: ' + pr.get_memo()
|
||||
msg += '\nPayment URL: ' + pr.payment_url
|
||||
msg += '\n\nOutputs:\n' + '\n'.join(map(lambda x: x[1] + ' ' + self.format_amount(x[2])+ self.base_unit(), pr.get_outputs()))
|
||||
if tx_hash:
|
||||
msg += '\n\nTransaction ID: ' + tx_hash
|
||||
if pr.tx:
|
||||
msg += '\n\nTransaction ID: ' + pr.tx
|
||||
QMessageBox.information(self, 'Invoice', msg , 'OK')
|
||||
|
||||
def do_pay_invoice(self, key):
|
||||
from electrum.paymentrequest import PaymentRequest
|
||||
domain, memo, value, expiration, status, tx_hash = self.invoices[key]
|
||||
pr = PaymentRequest(self.config)
|
||||
pr.read_file(key)
|
||||
pr.domain = domain
|
||||
pr = self.invoices.get(key)
|
||||
self.payment_request = pr
|
||||
self.prepare_for_payment_request()
|
||||
if pr.verify():
|
||||
@@ -1428,12 +1402,16 @@ class ElectrumWindow(QMainWindow):
|
||||
if not item:
|
||||
return
|
||||
key = str(item.data(0, 32).toString())
|
||||
domain, memo, value, expiration, status, tx_hash = self.invoices[key]
|
||||
pr = self.invoices.get(key)
|
||||
status = pr.get_status()
|
||||
menu = QMenu()
|
||||
menu.addAction(_("Details"), lambda: self.show_invoice(key))
|
||||
if status == PR_UNPAID:
|
||||
menu.addAction(_("Pay Now"), lambda: self.do_pay_invoice(key))
|
||||
menu.addAction(_("Delete"), lambda: self.delete_invoice(key))
|
||||
def delete_invoice(key):
|
||||
self.wallet.delete_invoice(key)
|
||||
self.update_invoices_tab()
|
||||
menu.addAction(_("Delete"), lambda: delete_invoice(key))
|
||||
menu.exec_(self.invoices_list.viewport().mapToGlobal(position))
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user