store and display signatures of own requests

This commit is contained in:
ThomasV 2015-07-09 14:15:30 +02:00
parent affd64125c
commit cb2bc54f96
4 changed files with 46 additions and 28 deletions

View File

@ -629,17 +629,17 @@ class ElectrumWindow(QMainWindow):
buttons.addWidget(self.new_request_button) buttons.addWidget(self.new_request_button)
self.receive_requests_label = QLabel(_('My Requests')) self.receive_requests_label = QLabel(_('My Requests'))
self.receive_list = MyTreeWidget(self, self.receive_list_menu, [_('Date'), _('Account'), _('Address'), _('Description'), _('Amount'), _('Status')], 3) self.receive_list = MyTreeWidget(self, self.receive_list_menu, [_('Date'), _('Account'), _('Address'), _('Requestor'), _('Description'), _('Amount'), _('Status')], 4)
self.receive_list.currentItemChanged.connect(self.receive_item_changed) self.receive_list.currentItemChanged.connect(self.receive_item_changed)
self.receive_list.itemClicked.connect(self.receive_item_changed) self.receive_list.itemClicked.connect(self.receive_item_changed)
self.receive_list.setSortingEnabled(True) self.receive_list.setSortingEnabled(True)
self.receive_list.setColumnWidth(0, 180) self.receive_list.setColumnWidth(0, 180)
self.receive_list.hideColumn(1) # the update will show it if necessary self.receive_list.hideColumn(1)
self.receive_list.hideColumn(2) # don't show address self.receive_list.hideColumn(2)
self.receive_list.setColumnWidth(2, 340) #self.receive_list.setColumnWidth(2, 340)
h = self.receive_list.header() h = self.receive_list.header()
h.setStretchLastSection(False) h.setStretchLastSection(False)
h.setResizeMode(3, QHeaderView.Stretch) h.setResizeMode(4, QHeaderView.Stretch)
# layout # layout
vbox_g = QVBoxLayout() vbox_g = QVBoxLayout()
@ -714,28 +714,34 @@ class ElectrumWindow(QMainWindow):
return False return False
i = self.expires_combo.currentIndex() i = self.expires_combo.currentIndex()
expiration = map(lambda x: x[1], expiration_values)[i] expiration = map(lambda x: x[1], expiration_values)[i]
self.wallet.add_payment_request(addr, amount, message, expiration, self.config) req = self.wallet.make_payment_request(addr, amount, message, expiration)
pr, requestor = self.make_bip70_request(req)
if requestor:
req['requestor'] = requestor
req['signature'] = pr.signature.encode('hex')
self.wallet.add_payment_request(req, self.config)
self.update_receive_tab() self.update_receive_tab()
self.update_address_tab() self.update_address_tab()
self.save_request_button.setEnabled(False) self.save_request_button.setEnabled(False)
return True return pr
def make_payment_request(self, addr): def make_bip70_request(self, req):
alias = str(self.config.get('alias')) alias = str(self.config.get('alias'))
alias_privkey = None alias_privkey = None
if alias: if alias:
alias_info = self.contacts.resolve_openalias(alias) alias_info = self.contacts.resolve_openalias(alias)
if alias_info: if alias_info:
alias_addr, alias_name = alias_info alias_addr, alias_name, validated = alias_info
if alias_addr and self.wallet.is_mine(alias_addr): if alias_addr and self.wallet.is_mine(alias_addr):
password = self.password_dialog() password = self.password_dialog(_('Please enter your password in order to sign your payment request.'))
alias_privkey = self.wallet.get_private_key(alias_addr, password)[0] if password:
r = self.wallet.get_payment_request(addr, self.config) alias_privkey = self.wallet.get_private_key(alias_addr, password)[0]
pr = paymentrequest.make_request(self.config, r, alias, alias_privkey) return paymentrequest.make_request(self.config, req, alias, alias_privkey)
return pr
def export_payment_request(self, addr): def export_payment_request(self, addr):
pr = self.make_payment_request(addr) r = self.wallet.receive_requests.get(addr)
pr, requestor = paymentrequest.make_request(self.config, r)
pr = pr.SerializeToString()
name = r['id'] + '.bip70' name = r['id'] + '.bip70'
fileName = self.getSaveFileName(_("Select where to save your payment request"), name, "*.bip70") fileName = self.getSaveFileName(_("Select where to save your payment request"), name, "*.bip70")
if fileName: if fileName:
@ -828,9 +834,13 @@ class ElectrumWindow(QMainWindow):
message = req.get('memo', '') message = req.get('memo', '')
date = format_time(timestamp) date = format_time(timestamp)
status = req.get('status') status = req.get('status')
account = self.wallet.get_account_name(self.wallet.get_account_from_address(address)) signature = req.get('signature')
requestor = req.get('requestor', '')
amount_str = self.format_amount(amount) if amount else "" amount_str = self.format_amount(amount) if amount else ""
item = QTreeWidgetItem([date, account, address, message, amount_str, pr_tooltips.get(status,'')]) account = ''
item = QTreeWidgetItem([date, account, address, requestor, message, amount_str, pr_tooltips.get(status,'')])
if signature is not None:
item.setIcon(3, QIcon(":icons/confirmed.png"))
if status is not PR_UNKNOWN: if status is not PR_UNKNOWN:
item.setIcon(5, QIcon(pr_icons.get(status))) item.setIcon(5, QIcon(pr_icons.get(status)))
self.receive_list.addTopLevelItem(item) self.receive_list.addTopLevelItem(item)

View File

@ -297,6 +297,7 @@ def make_payment_request(outputs, memo, time, expires, key_path, cert_path, alia
pr = pb2.PaymentRequest() pr = pb2.PaymentRequest()
pr.serialized_payment_details = pd.SerializeToString() pr.serialized_payment_details = pd.SerializeToString()
pr.signature = '' pr.signature = ''
requestor = None
if alias and alias_privkey: if alias and alias_privkey:
pr.pki_type = 'dnssec+btc' pr.pki_type = 'dnssec+btc'
@ -306,6 +307,7 @@ def make_payment_request(outputs, memo, time, expires, key_path, cert_path, alia
address = bitcoin.address_from_private_key(alias_privkey) address = bitcoin.address_from_private_key(alias_privkey)
compressed = bitcoin.is_compressed(alias_privkey) compressed = bitcoin.is_compressed(alias_privkey)
pr.signature = ec_key.sign_message(message, compressed, address) pr.signature = ec_key.sign_message(message, compressed, address)
requestor = alias
if key_path and cert_path: if key_path and cert_path:
import tlslite import tlslite
@ -322,7 +324,9 @@ def make_payment_request(outputs, memo, time, expires, key_path, cert_path, alia
hashBytes = bytearray(hashlib.sha256(msgBytes).digest()) hashBytes = bytearray(hashlib.sha256(msgBytes).digest())
sig = rsakey.sign(x509.PREFIX_RSA_SHA256 + hashBytes) sig = rsakey.sign(x509.PREFIX_RSA_SHA256 + hashBytes)
pr.signature = bytes(sig) pr.signature = bytes(sig)
return pr.SerializeToString() requestor = 'x'
return pr, requestor
def make_request(config, req, alias=None, alias_privkey=None): def make_request(config, req, alias=None, alias_privkey=None):

View File

@ -1256,16 +1256,22 @@ class Abstract_Wallet(object):
status = PR_UNKNOWN status = PR_UNKNOWN
return status return status
def add_payment_request(self, addr, amount, message, expiration, config): def make_payment_request(self, addr, amount, message, expiration):
import paymentrequest, shutil, os
timestamp = int(time.time()) timestamp = int(time.time())
_id = Hash(addr + "%d"%timestamp).encode('hex')[0:10] _id = Hash(addr + "%d"%timestamp).encode('hex')[0:10]
r = {'timestamp':timestamp, 'amount':amount, 'expiration':expiration, 'address':addr, 'memo':message, 'id':_id} r = {'timestamp':timestamp, 'amount':amount, 'expiration':expiration, 'address':addr, 'memo':message, 'id':_id}
self.receive_requests[addr] = r return r
def add_payment_request(self, req, config):
import paymentrequest, shutil, os
addr = req['address']
amount = req.get('amount')
message = req.get('memo')
self.receive_requests[addr] = req
self.storage.put('payment_requests', self.receive_requests) self.storage.put('payment_requests', self.receive_requests)
self.set_label(addr, message) # should be a default label self.set_label(addr, message) # should be a default label
rdir = config.get('requests_dir') rdir = config.get('requests_dir')
req = self.get_payment_request(addr, config)
if rdir and amount is not None: if rdir and amount is not None:
if not os.path.exists(rdir): if not os.path.exists(rdir):
os.mkdir(rdir) os.mkdir(rdir)

View File

@ -146,19 +146,17 @@ class Plugin(BasePlugin):
def send(self): def send(self):
addr = str(self.win.receive_address_e.text()) addr = str(self.win.receive_address_e.text())
message = unicode(self.win.receive_message_e.text()) message = unicode(self.win.receive_message_e.text())
payment_request = self.win.make_payment_request(addr) payment_request = self.win.save_payment_request()
if not payment_request:
if not self.win.save_payment_request():
return return
recipient, ok = QtGui.QInputDialog.getText(self.win, 'Send request', 'Send request to:') recipient, ok = QtGui.QInputDialog.getText(self.win, 'Send request', 'Send request to:')
if not ok: if not ok:
return return
recipient = str(recipient) recipient = str(recipient)
payload = payment_request.SerializeToString()
self.print_error('sending mail to', recipient) self.print_error('sending mail to', recipient)
try: try:
self.processor.send(recipient, message, payment_request) self.processor.send(recipient, message, payload)
except BaseException as e: except BaseException as e:
self.win.show_message(str(e)) self.win.show_message(str(e))
return return