move payment requests logic to wallet, add basic commands
This commit is contained in:
parent
e5b6b05482
commit
0938299e9b
|
@ -666,7 +666,7 @@ class ElectrumWindow(QMainWindow):
|
||||||
if not self.receive_list.isItemSelected(item):
|
if not self.receive_list.isItemSelected(item):
|
||||||
return
|
return
|
||||||
addr = str(item.text(2))
|
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'])
|
expires = _('Never') if req.get('expiration') is None else format_time(req['time'] + req['expiration'])
|
||||||
amount = req['amount']
|
amount = req['amount']
|
||||||
message = self.wallet.labels.get(addr, '')
|
message = self.wallet.labels.get(addr, '')
|
||||||
|
@ -680,8 +680,7 @@ class ElectrumWindow(QMainWindow):
|
||||||
|
|
||||||
def delete_payment_request(self, item):
|
def delete_payment_request(self, item):
|
||||||
addr = str(item.text(2))
|
addr = str(item.text(2))
|
||||||
self.receive_requests.pop(addr)
|
self.wallet.remove_payment_request(addr)
|
||||||
self.wallet.storage.put('receive_requests2', self.receive_requests)
|
|
||||||
self.update_receive_tab()
|
self.update_receive_tab()
|
||||||
self.clear_receive_tab()
|
self.clear_receive_tab()
|
||||||
|
|
||||||
|
@ -695,7 +694,7 @@ class ElectrumWindow(QMainWindow):
|
||||||
def receive_list_menu(self, position):
|
def receive_list_menu(self, position):
|
||||||
item = self.receive_list.itemAt(position)
|
item = self.receive_list.itemAt(position)
|
||||||
addr = str(item.text(2))
|
addr = str(item.text(2))
|
||||||
req = self.receive_requests[addr]
|
req = self.wallet.receive_requests[addr]
|
||||||
time, amount = req['time'], req['amount']
|
time, amount = req['time'], req['amount']
|
||||||
message = self.wallet.labels.get(addr, '')
|
message = self.wallet.labels.get(addr, '')
|
||||||
URI = util.create_URI(addr, amount, message)
|
URI = util.create_URI(addr, amount, message)
|
||||||
|
@ -713,35 +712,15 @@ class ElectrumWindow(QMainWindow):
|
||||||
if not message and not amount:
|
if not message and not amount:
|
||||||
QMessageBox.warning(self, _('Error'), _('No message or amount'), _('OK'))
|
QMessageBox.warning(self, _('Error'), _('No message or amount'), _('OK'))
|
||||||
return
|
return
|
||||||
self.receive_requests = self.wallet.storage.get('receive_requests2', {})
|
i = self.expires_combo.currentIndex()
|
||||||
if addr in self.receive_requests:
|
expiration = map(lambda x: x[1], expiration_values)[i]
|
||||||
self.receive_requests[addr]['amount'] = amount
|
self.wallet.save_payment_request(addr, amount, message, expiration)
|
||||||
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)
|
|
||||||
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)
|
||||||
|
|
||||||
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):
|
def export_payment_request(self, addr):
|
||||||
pr = self.make_payment_request(addr)
|
pr = self.wallet.make_bip70_request(self.config, addr)
|
||||||
name = 'request.bip70'
|
name = 'request.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:
|
||||||
|
@ -750,14 +729,8 @@ class ElectrumWindow(QMainWindow):
|
||||||
self.show_message(_("Request saved successfully"))
|
self.show_message(_("Request saved successfully"))
|
||||||
self.saved = True
|
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):
|
def new_payment_request(self):
|
||||||
addr = self.get_receive_address()
|
addr = self.wallet.get_unused_address(self.current_account)
|
||||||
if addr is None:
|
if addr is None:
|
||||||
if isinstance(self.wallet, Imported_Wallet):
|
if isinstance(self.wallet, Imported_Wallet):
|
||||||
self.show_message(_('No more addresses in your wallet.'))
|
self.show_message(_('No more addresses in your wallet.'))
|
||||||
|
@ -777,14 +750,8 @@ class ElectrumWindow(QMainWindow):
|
||||||
self.receive_amount_e.setAmount(None)
|
self.receive_amount_e.setAmount(None)
|
||||||
|
|
||||||
def clear_receive_tab(self):
|
def clear_receive_tab(self):
|
||||||
self.receive_requests = self.wallet.storage.get('receive_requests2',{})
|
addr = self.wallet.get_unused_address(self.current_account)
|
||||||
domain = self.wallet.get_account_addresses(self.current_account, include_change=False)
|
self.receive_address_e.setText(addr if addr else '')
|
||||||
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)
|
|
||||||
self.receive_message_e.setText('')
|
self.receive_message_e.setText('')
|
||||||
self.receive_amount_e.setAmount(None)
|
self.receive_amount_e.setAmount(None)
|
||||||
self.expires_label.hide()
|
self.expires_label.hide()
|
||||||
|
@ -814,10 +781,9 @@ class ElectrumWindow(QMainWindow):
|
||||||
self.new_request_button.setEnabled(True)
|
self.new_request_button.setEnabled(True)
|
||||||
|
|
||||||
def update_receive_tab(self):
|
def update_receive_tab(self):
|
||||||
self.receive_requests = self.wallet.storage.get('receive_requests2',{})
|
|
||||||
|
|
||||||
# hide receive tab if no receive requests available
|
# 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_list.setVisible(b)
|
||||||
self.receive_requests_label.setVisible(b)
|
self.receive_requests_label.setVisible(b)
|
||||||
if not b:
|
if not b:
|
||||||
|
@ -830,14 +796,14 @@ class ElectrumWindow(QMainWindow):
|
||||||
# update the receive address if necessary
|
# update the receive address if necessary
|
||||||
current_address = self.receive_address_e.text()
|
current_address = self.receive_address_e.text()
|
||||||
domain = self.wallet.get_account_addresses(self.current_account, include_change=False)
|
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:
|
if not current_address in domain and addr:
|
||||||
self.set_receive_address(addr)
|
self.set_receive_address(addr)
|
||||||
self.new_request_button.setEnabled(addr != current_address)
|
self.new_request_button.setEnabled(addr != current_address)
|
||||||
|
|
||||||
# clear the list and fill it again
|
# clear the list and fill it again
|
||||||
self.receive_list.clear()
|
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']
|
timestamp, amount = req['time'], req['amount']
|
||||||
expiration = req.get('expiration', None)
|
expiration = req.get('expiration', None)
|
||||||
message = self.wallet.labels.get(address, '')
|
message = self.wallet.labels.get(address, '')
|
||||||
|
|
|
@ -506,7 +506,34 @@ class Commands:
|
||||||
"""Decrypt a message encrypted with a public key."""
|
"""Decrypt a message encrypted with a public key."""
|
||||||
return self.wallet.decrypt_message(pubkey, encrypted, self.password)
|
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 = {
|
param_descriptions = {
|
||||||
'privkey': 'Private key. Type \'?\' to get a prompt.',
|
'privkey': 'Private key. Type \'?\' to get a prompt.',
|
||||||
|
@ -548,6 +575,8 @@ command_options = {
|
||||||
'unsigned': ("-u", "--unsigned", "Do not sign transaction"),
|
'unsigned': ("-u", "--unsigned", "Do not sign transaction"),
|
||||||
'domain': ("-D", "--domain", "List of addresses"),
|
'domain': ("-D", "--domain", "List of addresses"),
|
||||||
'account': (None, "--account", "Account"),
|
'account': (None, "--account", "Account"),
|
||||||
|
'reason': (None, "--reason", "Description of the request"),
|
||||||
|
'expiration': (None, "--expiration", "Time in seconds"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -164,6 +164,9 @@ class Abstract_Wallet(object):
|
||||||
self.load_accounts()
|
self.load_accounts()
|
||||||
self.load_transactions()
|
self.load_transactions()
|
||||||
|
|
||||||
|
# load requests
|
||||||
|
self.receive_requests = self.storage.get('receive_requests2', {})
|
||||||
|
|
||||||
# spv
|
# spv
|
||||||
self.verifier = None
|
self.verifier = None
|
||||||
# Transactions pending verification. Each value is the transaction height. Access with self.lock.
|
# 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):
|
def can_change_password(self):
|
||||||
return not self.is_watching_only()
|
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):
|
class Imported_Wallet(Abstract_Wallet):
|
||||||
wallet_type = 'imported'
|
wallet_type = 'imported'
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue