electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit cb2bc54f96fe5863e8038b7f7b6352b14f7e432f
parent affd64125c3cdbc51cc37c12c1e9fa076670fc69
Author: ThomasV <thomasv@gitorious>
Date:   Thu,  9 Jul 2015 14:15:30 +0200

store and display signatures of own requests

Diffstat:
Mgui/qt/main_window.py | 44+++++++++++++++++++++++++++-----------------
Mlib/paymentrequest.py | 6+++++-
Mlib/wallet.py | 14++++++++++----
Mplugins/email.py | 10++++------
4 files changed, 46 insertions(+), 28 deletions(-)

diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py @@ -629,17 +629,17 @@ class ElectrumWindow(QMainWindow): buttons.addWidget(self.new_request_button) 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.itemClicked.connect(self.receive_item_changed) self.receive_list.setSortingEnabled(True) self.receive_list.setColumnWidth(0, 180) - self.receive_list.hideColumn(1) # the update will show it if necessary - self.receive_list.hideColumn(2) # don't show address - self.receive_list.setColumnWidth(2, 340) + self.receive_list.hideColumn(1) + self.receive_list.hideColumn(2) + #self.receive_list.setColumnWidth(2, 340) h = self.receive_list.header() h.setStretchLastSection(False) - h.setResizeMode(3, QHeaderView.Stretch) + h.setResizeMode(4, QHeaderView.Stretch) # layout vbox_g = QVBoxLayout() @@ -714,28 +714,34 @@ class ElectrumWindow(QMainWindow): return False i = self.expires_combo.currentIndex() 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_address_tab() 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_privkey = None if alias: alias_info = self.contacts.resolve_openalias(alias) 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): - password = self.password_dialog() - alias_privkey = self.wallet.get_private_key(alias_addr, password)[0] - r = self.wallet.get_payment_request(addr, self.config) - pr = paymentrequest.make_request(self.config, r, alias, alias_privkey) - return pr + password = self.password_dialog(_('Please enter your password in order to sign your payment request.')) + if password: + alias_privkey = self.wallet.get_private_key(alias_addr, password)[0] + return paymentrequest.make_request(self.config, req, alias, alias_privkey) 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' fileName = self.getSaveFileName(_("Select where to save your payment request"), name, "*.bip70") if fileName: @@ -828,9 +834,13 @@ class ElectrumWindow(QMainWindow): message = req.get('memo', '') date = format_time(timestamp) 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 "" - 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: item.setIcon(5, QIcon(pr_icons.get(status))) self.receive_list.addTopLevelItem(item) diff --git a/lib/paymentrequest.py b/lib/paymentrequest.py @@ -297,6 +297,7 @@ def make_payment_request(outputs, memo, time, expires, key_path, cert_path, alia pr = pb2.PaymentRequest() pr.serialized_payment_details = pd.SerializeToString() pr.signature = '' + requestor = None if alias and alias_privkey: 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) compressed = bitcoin.is_compressed(alias_privkey) pr.signature = ec_key.sign_message(message, compressed, address) + requestor = alias if key_path and cert_path: 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()) sig = rsakey.sign(x509.PREFIX_RSA_SHA256 + hashBytes) pr.signature = bytes(sig) - return pr.SerializeToString() + requestor = 'x' + + return pr, requestor def make_request(config, req, alias=None, alias_privkey=None): diff --git a/lib/wallet.py b/lib/wallet.py @@ -1256,16 +1256,22 @@ class Abstract_Wallet(object): status = PR_UNKNOWN return status - def add_payment_request(self, addr, amount, message, expiration, config): - import paymentrequest, shutil, os + def make_payment_request(self, addr, amount, message, expiration): timestamp = int(time.time()) _id = Hash(addr + "%d"%timestamp).encode('hex')[0:10] 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.set_label(addr, message) # should be a default label + rdir = config.get('requests_dir') - req = self.get_payment_request(addr, config) if rdir and amount is not None: if not os.path.exists(rdir): os.mkdir(rdir) diff --git a/plugins/email.py b/plugins/email.py @@ -146,19 +146,17 @@ class Plugin(BasePlugin): def send(self): addr = str(self.win.receive_address_e.text()) message = unicode(self.win.receive_message_e.text()) - payment_request = self.win.make_payment_request(addr) - - if not self.win.save_payment_request(): + payment_request = self.win.save_payment_request() + if not payment_request: return - recipient, ok = QtGui.QInputDialog.getText(self.win, 'Send request', 'Send request to:') if not ok: return - recipient = str(recipient) + payload = payment_request.SerializeToString() self.print_error('sending mail to', recipient) try: - self.processor.send(recipient, message, payment_request) + self.processor.send(recipient, message, payload) except BaseException as e: self.win.show_message(str(e)) return