commit 0938299e9bf858817d3c391ebcdca3d48d5dd3d4
parent e5b6b05482dffb2d6370dad3f0fd21276fff5747
Author: ThomasV <thomasv@gitorious>
Date: Mon, 1 Jun 2015 13:02:09 +0200
move payment requests logic to wallet, add basic commands
Diffstat:
3 files changed, 82 insertions(+), 47 deletions(-)
diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py
@@ -666,7 +666,7 @@ class ElectrumWindow(QMainWindow):
if not self.receive_list.isItemSelected(item):
return
addr = str(item.text(2))
- req = self.receive_requests[addr]
+ req = self.wallet.receive_requests[addr]
expires = _('Never') if req.get('expiration') is None else format_time(req['time'] + req['expiration'])
amount = req['amount']
message = self.wallet.labels.get(addr, '')
@@ -680,8 +680,7 @@ class ElectrumWindow(QMainWindow):
def delete_payment_request(self, item):
addr = str(item.text(2))
- self.receive_requests.pop(addr)
- self.wallet.storage.put('receive_requests2', self.receive_requests)
+ self.wallet.remove_payment_request(addr)
self.update_receive_tab()
self.clear_receive_tab()
@@ -695,7 +694,7 @@ class ElectrumWindow(QMainWindow):
def receive_list_menu(self, position):
item = self.receive_list.itemAt(position)
addr = str(item.text(2))
- req = self.receive_requests[addr]
+ req = self.wallet.receive_requests[addr]
time, amount = req['time'], req['amount']
message = self.wallet.labels.get(addr, '')
URI = util.create_URI(addr, amount, message)
@@ -713,35 +712,15 @@ class ElectrumWindow(QMainWindow):
if not message and not amount:
QMessageBox.warning(self, _('Error'), _('No message or amount'), _('OK'))
return
- self.receive_requests = self.wallet.storage.get('receive_requests2', {})
- if addr in self.receive_requests:
- self.receive_requests[addr]['amount'] = amount
- else:
- now = int(time.time())
- i = self.expires_combo.currentIndex()
- expiration = map(lambda x: x[1], expiration_values)[i]
- self.receive_requests[addr] = {'time':now, 'amount':amount, 'expiration':expiration}
-
- self.wallet.storage.put('receive_requests2', self.receive_requests)
- self.wallet.set_label(addr, message)
+ i = self.expires_combo.currentIndex()
+ expiration = map(lambda x: x[1], expiration_values)[i]
+ self.wallet.save_payment_request(addr, amount, message, expiration)
self.update_receive_tab()
self.update_address_tab()
self.save_request_button.setEnabled(False)
- def make_payment_request(self, addr):
- req = self.receive_requests[addr]
- time = req['time']
- amount = req['amount']
- expiration = req['expiration']
- message = self.wallet.labels.get(addr, '')
- script = Transaction.pay_script('address', addr).decode('hex')
- outputs = [(script, amount)]
- key_path = self.config.get('ssl_key_path')
- cert_path = self.config.get('ssl_cert_path')
- return make_payment_request(outputs, message, time, time + expiration, key_path, cert_path)
-
def export_payment_request(self, addr):
- pr = self.make_payment_request(addr)
+ pr = self.wallet.make_bip70_request(self.config, addr)
name = 'request.bip70'
fileName = self.getSaveFileName(_("Select where to save your payment request"), name, "*.bip70")
if fileName:
@@ -750,14 +729,8 @@ class ElectrumWindow(QMainWindow):
self.show_message(_("Request saved successfully"))
self.saved = True
- def get_receive_address(self):
- domain = self.wallet.get_account_addresses(self.current_account, include_change=False)
- for addr in domain:
- if not self.wallet.history.get(addr) and addr not in self.receive_requests.keys():
- return addr
-
def new_payment_request(self):
- addr = self.get_receive_address()
+ addr = self.wallet.get_unused_address(self.current_account)
if addr is None:
if isinstance(self.wallet, Imported_Wallet):
self.show_message(_('No more addresses in your wallet.'))
@@ -777,14 +750,8 @@ class ElectrumWindow(QMainWindow):
self.receive_amount_e.setAmount(None)
def clear_receive_tab(self):
- self.receive_requests = self.wallet.storage.get('receive_requests2',{})
- domain = self.wallet.get_account_addresses(self.current_account, include_change=False)
- for addr in domain:
- if not self.wallet.history.get(addr) and addr not in self.receive_requests.keys():
- break
- else:
- addr = ''
- self.receive_address_e.setText(addr)
+ addr = self.wallet.get_unused_address(self.current_account)
+ self.receive_address_e.setText(addr if addr else '')
self.receive_message_e.setText('')
self.receive_amount_e.setAmount(None)
self.expires_label.hide()
@@ -814,10 +781,9 @@ class ElectrumWindow(QMainWindow):
self.new_request_button.setEnabled(True)
def update_receive_tab(self):
- self.receive_requests = self.wallet.storage.get('receive_requests2',{})
# hide receive tab if no receive requests available
- b = len(self.receive_requests) > 0
+ b = len(self.wallet.receive_requests) > 0
self.receive_list.setVisible(b)
self.receive_requests_label.setVisible(b)
if not b:
@@ -830,14 +796,14 @@ class ElectrumWindow(QMainWindow):
# update the receive address if necessary
current_address = self.receive_address_e.text()
domain = self.wallet.get_account_addresses(self.current_account, include_change=False)
- addr = self.get_receive_address()
+ addr = self.wallet.get_unused_address(self.current_account)
if not current_address in domain and addr:
self.set_receive_address(addr)
self.new_request_button.setEnabled(addr != current_address)
# clear the list and fill it again
self.receive_list.clear()
- for address, req in self.receive_requests.viewitems():
+ for address, req in self.wallet.receive_requests.viewitems():
timestamp, amount = req['time'], req['amount']
expiration = req.get('expiration', None)
message = self.wallet.labels.get(address, '')
diff --git a/lib/commands.py b/lib/commands.py
@@ -506,7 +506,34 @@ class Commands:
"""Decrypt a message encrypted with a public key."""
return self.wallet.decrypt_message(pubkey, encrypted, self.password)
+ @command('w')
+ def listrequests(self):
+ """List the payment requests you made"""
+ out = []
+ for addr, v in self.wallet.receive_requests.items():
+ out.append({
+ 'address': addr,
+ 'amount': format_satoshis(v.get('amount')),
+ 'time': v.get('time'),
+ 'reason': self.wallet.get_label(addr)[0],
+ 'expiration': v.get('expiration'),
+ })
+ return out
+ @command('w')
+ def addrequest(self, amount, reason='', expiration=60*60):
+ """Create a payment request"""
+ addr = self.wallet.get_unused_address(None)
+ if addr is None:
+ return False
+ amount = int(Decimal(amount)*COIN)
+ self.wallet.save_payment_request(addr, amount, reason, expiration)
+ return addr
+
+ @command('w')
+ def removerequest(self, address):
+ """Remove a payment request"""
+ return self.wallet.remove_payment_request(address)
param_descriptions = {
'privkey': 'Private key. Type \'?\' to get a prompt.',
@@ -548,6 +575,8 @@ command_options = {
'unsigned': ("-u", "--unsigned", "Do not sign transaction"),
'domain': ("-D", "--domain", "List of addresses"),
'account': (None, "--account", "Account"),
+ 'reason': (None, "--reason", "Description of the request"),
+ 'expiration': (None, "--expiration", "Time in seconds"),
}
diff --git a/lib/wallet.py b/lib/wallet.py
@@ -164,6 +164,9 @@ class Abstract_Wallet(object):
self.load_accounts()
self.load_transactions()
+ # load requests
+ self.receive_requests = self.storage.get('receive_requests2', {})
+
# spv
self.verifier = None
# Transactions pending verification. Each value is the transaction height. Access with self.lock.
@@ -1221,6 +1224,43 @@ class Abstract_Wallet(object):
def can_change_password(self):
return not self.is_watching_only()
+ def get_unused_address(self, account):
+ # fixme: use slots from expired requests
+ domain = self.get_account_addresses(account, include_change=False)
+ for addr in domain:
+ if not self.history.get(addr) and addr not in self.receive_requests.keys():
+ return addr
+
+ def remove_payment_request(self, addr):
+ if addr not in self.receive_requests:
+ return False
+ self.receive_requests.pop(addr)
+ self.storage.put('receive_requests2', self.receive_requests)
+ return True
+
+ def save_payment_request(self, addr, amount, message, expiration):
+ self.set_label(addr, message)
+ if addr in self.receive_requests:
+ self.receive_requests[addr]['amount'] = amount
+ else:
+ now = int(time.time())
+ self.receive_requests[addr] = {'time':now, 'amount':amount, 'expiration':expiration}
+ self.storage.put('receive_requests2', self.receive_requests, True)
+
+ def make_bip70_request(self, config, addr):
+ from paymentrequest import make_payment_request
+ req = self.receive_requests[addr]
+ time = req['time']
+ amount = req['amount']
+ expiration = req['expiration']
+ message = self.labels.get(addr, '')
+ script = Transaction.pay_script('address', addr).decode('hex')
+ outputs = [(script, amount)]
+ key_path = config.get('ssl_key_path')
+ cert_path = config.get('ssl_cert_path')
+ return make_payment_request(outputs, message, time, time + expiration, key_path, cert_path)
+
+
class Imported_Wallet(Abstract_Wallet):
wallet_type = 'imported'