electrum

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

commit 9bd94e5062d6214c0cb21180836517bc3cd4b354
parent 572a4638062ee8fc020fee3e6d99f0edffed2ce6
Author: ThomasV <thomasv@gitorious>
Date:   Mon,  8 Jun 2015 12:51:45 +0200

refactor payment requests

Diffstat:
Mgui/qt/main_window.py | 8++++----
Mlib/commands.py | 60+++++++++++++-----------------------------------------------
Mlib/paymentrequest.py | 12++++++++----
Mlib/wallet.py | 60+++++++++++++++++++++++++++++++++++++++---------------------
Rlib/payrequest.html -> lib/www/index.html | 0
5 files changed, 64 insertions(+), 76 deletions(-)

diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py @@ -681,7 +681,7 @@ class ElectrumWindow(QMainWindow): def delete_payment_request(self, item): addr = str(item.text(2)) - self.wallet.remove_payment_request(addr) + self.wallet.remove_payment_request(addr, self.config) self.update_receive_tab() self.clear_receive_tab() @@ -715,13 +715,13 @@ class ElectrumWindow(QMainWindow): return i = self.expires_combo.currentIndex() expiration = map(lambda x: x[1], expiration_values)[i] - self.wallet.save_payment_request(self.config, addr, amount, message, expiration) + self.wallet.add_payment_request(addr, amount, message, expiration, self.config) self.update_receive_tab() self.update_address_tab() self.save_request_button.setEnabled(False) def export_payment_request(self, addr): - r = self.wallet.get_payment_request(addr) + r = self.wallet.get_payment_request(addr, self.config) pr = paymentrequest.make_request(self.config, r) name = r['key'] + '.bip70' fileName = self.getSaveFileName(_("Select where to save your payment request"), name, "*.bip70") @@ -805,7 +805,7 @@ class ElectrumWindow(QMainWindow): # clear the list and fill it again self.receive_list.clear() - for req in self.wallet.get_sorted_requests(): + for req in self.wallet.get_sorted_requests(self.config): address = req['address'] if address not in domain: continue diff --git a/lib/commands.py b/lib/commands.py @@ -491,7 +491,7 @@ class Commands: if show_balance: item += ", "+ format_satoshis(sum(self.wallet.get_addr_balance(addr))) if show_labels: - item += ', ' + self.wallet.labels.get(addr,'') + item += ', ' + repr(self.wallet.labels.get(addr, '')) out.append(item) return out @@ -517,7 +517,7 @@ class Commands: """Decrypt a message encrypted with a public key.""" return self.wallet.decrypt_message(pubkey, encrypted, self.password) - def _format_request(self, v): + def _format_request(self, out): from paymentrequest import PR_PAID, PR_UNPAID, PR_UNKNOWN, PR_EXPIRED pr_str = { PR_UNKNOWN: 'Unknown', @@ -525,40 +525,14 @@ class Commands: PR_PAID: 'Paid', PR_EXPIRED: 'Expired', } - key = v['key'] - addr = v.get('address') - amount = v.get('amount') - timestamp = v.get('time') - expiration = v.get('expiration') - out = { - 'key': key, - 'address': addr, - 'amount': format_satoshis(amount), - 'timestamp': timestamp, - 'memo': v.get('memo', ''), - 'expiration': expiration, - 'URI':'bitcoin:' + addr + '?amount=' + format_satoshis(amount), - 'status': pr_str[v.get('status', PR_UNKNOWN)] - } - # check if bip70 file exists - rdir = self.config.get('requests_dir') - path = os.path.join(rdir, key + '.bip70') - if rdir and os.path.exists(path): - out['path'] = path - baseurl = 'file://' + rdir - rewrite = self.config.get('url_rewrite') - if rewrite: - baseurl = baseurl.replace(*rewrite) - out['request_url'] = os.path.join(baseurl, key + '.bip70') - out['URI'] += '&r=' + out['request_url'] - out['index_url'] = os.path.join(baseurl, 'index.html') + '?id=' + key - + out['amount'] = format_satoshis(out.get('amount')) + out['status'] = pr_str[out.get('status', PR_UNKNOWN)] return out @command('wn') def getrequest(self, key): """Return a payment request""" - r = self.wallet.get_payment_request(key) + r = self.wallet.get_payment_request(key, self.config) if not r: raise BaseException("Request not found") return self._format_request(r) @@ -571,30 +545,22 @@ class Commands: @command('w') def listrequests(self): """List the payment requests you made, and their status""" - return map(self._format_request, self.wallet.get_sorted_requests()) + return map(self._format_request, self.wallet.get_sorted_requests(self.config)) @command('w') def addrequest(self, requested_amount, memo='', expiration=60*60): """Create a payment request.""" + addr = self.wallet.get_unused_address(None) + if addr is None: + return False amount = int(Decimal(requested_amount)*COIN) - key = self.wallet.add_payment_request(amount, memo, expiration) - if key is None: - return - req = self.wallet.get_payment_request(key) - rdir = self.config.get('requests_dir') - if rdir: - path = paymentrequest.publish_request(self.config, key, req) - req['path'] = path - req = self._format_request(req) - if rdir: - with open(os.path.join(rdir, key + '.json'), 'w') as f: - f.write(json.dumps(req)) - return req + req = self.wallet.add_payment_request(addr, amount, memo, expiration, self.config) + return self._format_request(req) @command('w') - def rmrequest(self, address): + def rmrequest(self, key): """Remove a payment request""" - return self.wallet.remove_payment_request(address) + return self.wallet.remove_payment_request(key, self.config) param_descriptions = { 'privkey': 'Private key. Type \'?\' to get a prompt.', diff --git a/lib/paymentrequest.py b/lib/paymentrequest.py @@ -299,7 +299,7 @@ def make_request(config, req): time = req['time'] amount = req['amount'] expiration = req['expiration'] - message = req['reason'] + message = req['memo'] script = Transaction.pay_script('address', addr).decode('hex') outputs = [(script, amount)] key_path = config.get('ssl_privkey') @@ -307,7 +307,7 @@ def make_request(config, req): return make_payment_request(outputs, message, time, time + expiration if expiration else None, key_path, cert_path) -def publish_request(config, key, req): +def publish_request(config, addr, req): import shutil, os rdir = config.get('requests_dir') if not rdir: @@ -316,13 +316,17 @@ def publish_request(config, key, req): os.mkdir(rdir) index = os.path.join(rdir, 'index.html') if not os.path.exists(index): - src = os.path.join(os.path.dirname(__file__), 'payrequest.html') + src = os.path.join(os.path.dirname(__file__), 'www', 'index.html') shutil.copy(src, index) + key = req.get('id', addr) pr = make_request(config, req) path = os.path.join(rdir, key + '.bip70') with open(path, 'w') as f: f.write(pr) - return path + with open(os.path.join(rdir, key + '.json'), 'w') as f: + f.write(json.dumps(req)) + req['path'] = path + return req diff --git a/lib/wallet.py b/lib/wallet.py @@ -1231,14 +1231,27 @@ class Abstract_Wallet(object): if not self.history.get(addr) and addr not in self.receive_requests.keys(): return addr - def get_payment_request(self, key): - r = self.receive_requests.get(key) + def get_payment_request(self, addr, config): + import util + r = self.receive_requests.get(addr) if not r: return - r['reason'] = self.labels.get(key, '') - r['status'] = self.get_request_status(key) - r['key'] = key - return r + out = copy.copy(r) + out['URI'] = 'bitcoin:' + addr + '?amount=' + util.format_satoshis(out.get('amount')) + out['status'] = self.get_request_status(addr) + # check if bip70 file exists + rdir = config.get('requests_dir') + key = out.get('id', addr) + path = os.path.join(rdir, key + '.bip70') + if rdir and os.path.exists(path): + baseurl = 'file://' + rdir + rewrite = config.get('url_rewrite') + if rewrite: + baseurl = baseurl.replace(*rewrite) + out['request_url'] = os.path.join(baseurl, key + '.bip70') + out['URI'] += '&r=' + out['request_url'] + out['index_url'] = os.path.join(baseurl, 'index.html') + '?id=' + key + return out def get_request_status(self, key): from paymentrequest import PR_PAID, PR_UNPAID, PR_UNKNOWN, PR_EXPIRED @@ -1256,29 +1269,34 @@ class Abstract_Wallet(object): status = PR_UNKNOWN return status - def save_payment_request(self, addr, amount, message, expiration): - self.set_label(addr, message) - now = int(time.time()) - r = {'time':now, 'amount':amount, 'expiration':expiration, 'address':addr} + def add_payment_request(self, addr, amount, message, expiration, config): + import paymentrequest + timestamp = int(time.time()) + _id = Hash(addr + "%d"%timestamp).encode('hex')[0:10] + r = {'time':timestamp, 'amount':amount, 'expiration':expiration, 'address':addr, 'memo':message, 'id':_id} self.receive_requests[addr] = r + self.set_label(addr, message) # should be a default label + if config.get('requests_dir'): + paymentrequest.publish_request(config, addr, r) self.storage.put('receive_requests2', self.receive_requests) + return self.get_payment_request(addr, config) - def add_payment_request(self, amount, message, expiration): - addr = self.get_unused_address(None) - if addr is None: - return - self.save_payment_request(addr, amount, message, expiration) - return addr - - def remove_payment_request(self, addr): + def remove_payment_request(self, addr, config): if addr not in self.receive_requests: return False - self.receive_requests.pop(addr) + r = self.receive_requests.pop(addr) + rdir = config.get('requests_dir') + if rdir: + key = r.get('id', addr) + for s in ['.json', '.bip70']: + n = os.path.join(rdir, key + s) + if os.path.exists(n): + os.unlink(n) self.storage.put('receive_requests2', self.receive_requests) return True - def get_sorted_requests(self): - return sorted(map(self.get_payment_request, self.receive_requests.keys()), key=itemgetter('time')) + def get_sorted_requests(self, config): + return sorted(map(lambda x: self.get_payment_request(x, config), self.receive_requests.keys()), key=itemgetter('time')) diff --git a/lib/payrequest.html b/lib/www/index.html