commit e77f0c98e774f1566ec7f0cb78ac41f2d462c608
parent 1e668209dcbec5ccf32121e9199f3ff2bc671e81
Author: ThomasV <thomasv@gitorious>
Date: Tue, 21 Jul 2015 11:40:55 +0200
extend bitcoin: URI with signature data, instead of serialized format
Diffstat:
6 files changed, 54 insertions(+), 54 deletions(-)
diff --git a/gui/qt/__init__.py b/gui/qt/__init__.py
@@ -57,7 +57,7 @@ class OpenFileEventFilter(QObject):
def eventFilter(self, obj, event):
if event.type() == QtCore.QEvent.FileOpen:
if len(self.windows) >= 1:
- self.windows[0].pay_from_URI(event.url().toEncoded())
+ self.windows[0].pay_to_URI(event.url().toEncoded())
return True
return False
@@ -140,7 +140,7 @@ class ElectrumGui:
return int(qtVersion[0]) >= 4 and int(qtVersion[2]) >= 7
def set_url(self, uri):
- self.current_window.pay_from_URI(uri)
+ self.current_window.pay_to_URI(uri)
def run_wizard(self, storage, action):
import installwizard
diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py
@@ -698,26 +698,29 @@ class ElectrumWindow(QMainWindow):
self.update_receive_tab()
self.clear_receive_tab()
- def get_receive_URI(self):
- addr = str(self.receive_address_e.text())
- amount = self.receive_amount_e.get_amount()
- message = unicode(self.receive_message_e.text())
+ def get_request_URI(self, addr):
+ req = self.wallet.receive_requests[addr]
+ message = self.wallet.labels.get(addr, '')
+ amount = req['amount']
URI = util.create_URI(addr, amount, message)
- return URI
+ if req.get('id') and req.get('sig'):
+ sig = req.get('sig').decode('hex')
+ sig = bitcoin.base_encode(sig, base=58)
+ URI += "&id=" + req['id'] + "&sig="+sig
+ if req.get('timestamp'):
+ URI += "×tamp=%d"%req.get('timestamp')
+ if req.get('expiration'):
+ URI += "&expiration=%d"%req.get('expiration')
+ return str(URI)
def receive_list_menu(self, position):
item = self.receive_list.itemAt(position)
addr = str(item.text(2))
req = self.wallet.receive_requests[addr]
- time, amount = req['timestamp'], req['amount']
- message = self.wallet.labels.get(addr, '')
- URI = util.create_URI(addr, amount, message)
menu = QMenu()
- menu.addAction(_("Copy Address"), lambda: self.app.clipboard().setText(addr))
- menu.addAction(_("Copy URI"), lambda: self.app.clipboard().setText(str(URI)))
- if req.get('signature'):
- menu.addAction(_("Copy Signed URI"), lambda: self.view_signed_request(addr))
- menu.addAction(_("Save as BIP70 file"), lambda: self.export_payment_request(addr)) #.setEnabled(amount is not None)
+ menu.addAction(_("Copy Address"), lambda: self.view_and_paste(_('Address'), '', addr))
+ menu.addAction(_("Copy URI"), lambda: self.view_and_paste('URI', '', self.get_request_URI(addr)))
+ menu.addAction(_("Save as BIP70 file"), lambda: self.export_payment_request(addr))
menu.addAction(_("Delete"), lambda: self.delete_payment_request(item))
run_hook('receive_list_menu', menu, addr)
menu.exec_(self.receive_list.viewport().mapToGlobal(position))
@@ -745,8 +748,8 @@ class ElectrumWindow(QMainWindow):
return
pr, requestor = paymentrequest.make_request(self.config, req, alias, alias_privkey)
if requestor:
- req['requestor'] = requestor
- req['signature'] = pr.signature.encode('hex')
+ req['id'] = requestor
+ req['sig'] = pr.signature.encode('hex')
self.wallet.add_payment_request(req, self.config)
def save_payment_request(self):
@@ -765,29 +768,20 @@ class ElectrumWindow(QMainWindow):
self.update_address_tab()
self.save_request_button.setEnabled(False)
- def view_signed_request(self, addr):
- import urllib
- r = self.wallet.receive_requests.get(addr)
- pr = paymentrequest.serialize_request(r).SerializeToString()
- pr_text = 'bitcoin:?s=' + bitcoin.base_encode(pr, base=58)
+ def view_and_paste(self, title, msg, data):
dialog = QDialog(self)
- dialog.setWindowTitle(_("Signed Request"))
+ dialog.setWindowTitle(title)
vbox = QVBoxLayout()
- pr_e = ShowQRTextEdit(text=pr_text)
- pr_e.addCopyButton(self.app)
- msg = ' '.join([_('The following URI contains your payment request signed with your OpenAlias key.'),
- _('The signature is a proof that the payment was requested by you.')])
- l = QLabel(msg)
- l.setWordWrap(True)
- vbox.addWidget(l)
+ label = QLabel(msg)
+ label.setWordWrap(True)
+ vbox.addWidget(label)
+ pr_e = ShowQRTextEdit(text=data)
vbox.addWidget(pr_e)
- msg = _('Note: This format is experimental and may not be supported by other Bitcoin clients.')
- vbox.addWidget(QLabel(msg))
vbox.addLayout(Buttons(CopyCloseButton(pr_e.text, self.app, dialog)))
dialog.setLayout(vbox)
+ #print len(data), data
dialog.exec_()
-
def export_payment_request(self, addr):
r = self.wallet.receive_requests.get(addr)
pr = paymentrequest.serialize_request(r).SerializeToString()
@@ -883,8 +877,8 @@ class ElectrumWindow(QMainWindow):
message = req.get('memo', '')
date = format_time(timestamp)
status = req.get('status')
- signature = req.get('signature')
- requestor = req.get('requestor', '')
+ signature = req.get('sig')
+ requestor = req.get('id', '')
amount_str = self.format_amount(amount) if amount else ""
account = ''
item = QTreeWidgetItem([date, account, address, '', message, amount_str, pr_tooltips.get(status,'')])
@@ -1343,7 +1337,7 @@ class ElectrumWindow(QMainWindow):
self.show_message(self.payment_request.error)
self.payment_request = None
- def pay_from_URI(self,URI):
+ def pay_to_URI(self, URI):
if not URI:
return
try:
@@ -1354,13 +1348,14 @@ class ElectrumWindow(QMainWindow):
self.tabs.setCurrentIndex(1)
r = out.get('r')
- s = out.get('s')
- if r or s:
+ sig = out.get('sig')
+ _id = out.get('id')
+ if r or (_id and sig):
def get_payment_request_thread():
- if s:
+ if _id and sig:
from electrum import paymentrequest
- data = bitcoin.base_decode(s, None, base=58)
- self.payment_request = paymentrequest.PaymentRequest(data)
+ pr = paymentrequest.serialize_request(out).SerializeToString()
+ self.payment_request = paymentrequest.PaymentRequest(pr)
else:
self.payment_request = get_payment_request(r)
if self.payment_request.verify(self.contacts):
@@ -1394,19 +1389,16 @@ class ElectrumWindow(QMainWindow):
self.amount_e.textEdited.emit("")
-
def do_clear(self):
self.not_enough_funds = False
self.payto_e.is_pr = False
for e in [self.payto_e, self.message_e, self.amount_e, self.fee_e]:
e.setText('')
e.setFrozen(False)
-
self.set_pay_from([])
self.update_status()
run_hook('do_clear')
-
def set_frozen_state(self, addrs, freeze):
self.wallet.set_frozen_state(addrs, freeze)
self.update_address_tab()
@@ -2215,7 +2207,7 @@ class ElectrumWindow(QMainWindow):
return
# if the user scanned a bitcoin URI
if data.startswith("bitcoin:"):
- self.pay_from_URI(data)
+ self.pay_to_URI(data)
return
# else if the user scanned an offline signed tx
# transactions are binary, but qrcode seems to return utf8...
diff --git a/gui/qt/paytoedit.py b/gui/qt/paytoedit.py
@@ -47,7 +47,7 @@ class PayToEdit(ScanQRTextEdit):
self.errors = []
self.is_pr = False
self.is_alias = False
- self.scan_f = win.pay_from_URI
+ self.scan_f = win.pay_to_URI
self.update_size()
self.payto_address = None
diff --git a/lib/paymentrequest.py b/lib/paymentrequest.py
@@ -318,7 +318,6 @@ def sign_request_with_alias(pr, alias, alias_privkey):
address = bitcoin.address_from_private_key(alias_privkey)
compressed = bitcoin.is_compressed(alias_privkey)
pr.signature = ec_key.sign_message(message, compressed, address)
- return pr
def sign_request_with_x509(pr, key_path, cert_path):
@@ -336,14 +335,13 @@ def sign_request_with_x509(pr, key_path, cert_path):
hashBytes = bytearray(hashlib.sha256(msgBytes).digest())
sig = rsakey.sign(x509.PREFIX_RSA_SHA256 + hashBytes)
pr.signature = bytes(sig)
- return pr
def serialize_request(req):
pr = make_unsigned_request(req)
- signature = req.get('signature')
- if signature:
- requestor = req.get('requestor')
+ signature = req.get('sig')
+ requestor = req.get('id')
+ if requestor and signature:
pr.signature = signature.decode('hex')
pr.pki_type = 'dnssec+btc'
pr.pki_data = str(requestor)
diff --git a/lib/util.py b/lib/util.py
@@ -261,7 +261,7 @@ def parse_URI(uri):
for k, v in pq.items():
if len(v)!=1:
raise Exception('Duplicate Key', k)
- if k not in ['amount', 'label', 'message', 'r', 's']:
+ if k not in ['amount', 'label', 'message', 'r', 'id', 'sig', 'timestamp', 'expiration']:
raise BaseException('Unknown key', k)
out = {k: v[0] for k, v in pq.items()}
@@ -276,9 +276,16 @@ def parse_URI(uri):
amount = Decimal(m.group(1)) * pow( Decimal(10) , k)
else:
amount = Decimal(am) * COIN
- out['amount'] = amount
+ out['amount'] = int(amount)
if 'message' in out:
out['message'] = out['message'].decode('utf8')
+ out['memo'] = out['message']
+ if 'timestamp' in out:
+ out['timestamp'] = int(out['timestamp'])
+ out['expiration'] = int(out['expiration'])
+ if 'sig' in out:
+ out['sig'] = bitcoin.base_decode(out['sig'], None, base=58).encode('hex')
+
return out
diff --git a/plugins/email.py b/plugins/email.py
@@ -148,7 +148,10 @@ class Plugin(BasePlugin):
from electrum import paymentrequest
r = self.wallet.receive_requests.get(addr)
message = r.get('memo', '')
- pr, requestor = paymentrequest.make_request(self.config, r)
+ if r.get('signature'):
+ pr = paymentrequest.serialize_request(r)
+ else:
+ pr, requestor = paymentrequest.make_request(self.config, r)
if not pr:
return
recipient, ok = QtGui.QInputDialog.getText(self.win, 'Send request', 'Send request to:')