Major refactoring
- separation between Wallet and key management (Keystore) - simplification of wallet classes - remove support for multiple accounts in the same wallet - add support for OP_RETURN to Trezor plugin - split multi-accounts wallets for backward compatibility
This commit is contained in:
@@ -163,8 +163,8 @@ class ElectrumGui:
|
||||
wallet = wizard.run_and_get_wallet()
|
||||
if not wallet:
|
||||
return
|
||||
if wallet.get_action():
|
||||
return
|
||||
#if wallet.get_action():
|
||||
# return
|
||||
self.daemon.add_wallet(wallet)
|
||||
w = self.create_window_for_wallet(wallet)
|
||||
if uri:
|
||||
|
||||
@@ -41,26 +41,14 @@ class AddressList(MyTreeWidget):
|
||||
|
||||
def on_update(self):
|
||||
self.wallet = self.parent.wallet
|
||||
self.accounts_expanded = self.wallet.storage.get('accounts_expanded', {})
|
||||
item = self.currentItem()
|
||||
current_address = item.data(0, Qt.UserRole).toString() if item else None
|
||||
self.clear()
|
||||
accounts = self.wallet.get_accounts()
|
||||
if self.parent.current_account is None:
|
||||
account_items = sorted(accounts.items())
|
||||
else:
|
||||
account_items = [(self.parent.current_account, accounts.get(self.parent.current_account))]
|
||||
for k, account in account_items:
|
||||
if len(accounts) > 1:
|
||||
name = self.wallet.get_account_name(k)
|
||||
c, u, x = self.wallet.get_account_balance(k)
|
||||
account_item = QTreeWidgetItem([ name, '', self.parent.format_amount(c + u + x), ''])
|
||||
account_item.setData(0, Qt.UserRole, k)
|
||||
self.addTopLevelItem(account_item)
|
||||
account_item.setExpanded(self.accounts_expanded.get(k, True))
|
||||
else:
|
||||
account_item = self
|
||||
sequences = [0,1] if account.has_change() else [0]
|
||||
receiving_addresses = self.wallet.get_receiving_addresses()
|
||||
change_addresses = self.wallet.get_change_addresses()
|
||||
if True:
|
||||
account_item = self
|
||||
sequences = [0,1] if change_addresses else [0]
|
||||
for is_change in sequences:
|
||||
if len(sequences) > 1:
|
||||
name = _("Receiving") if not is_change else _("Change")
|
||||
@@ -72,7 +60,7 @@ class AddressList(MyTreeWidget):
|
||||
seq_item = account_item
|
||||
used_item = QTreeWidgetItem( [ _("Used"), '', '', '', ''] )
|
||||
used_flag = False
|
||||
addr_list = account.get_addresses(is_change)
|
||||
addr_list = change_addresses if is_change else receiving_addresses
|
||||
for address in addr_list:
|
||||
num = len(self.wallet.history.get(address,[]))
|
||||
is_used = self.wallet.is_used(address)
|
||||
@@ -85,7 +73,7 @@ class AddressList(MyTreeWidget):
|
||||
address_item.setData(0, Qt.UserRole+1, True) # label can be edited
|
||||
if self.wallet.is_frozen(address):
|
||||
address_item.setBackgroundColor(0, QColor('lightblue'))
|
||||
if self.wallet.is_beyond_limit(address, account, is_change):
|
||||
if self.wallet.is_beyond_limit(address, is_change):
|
||||
address_item.setBackgroundColor(0, QColor('red'))
|
||||
if is_used:
|
||||
if not used_flag:
|
||||
@@ -107,8 +95,9 @@ class AddressList(MyTreeWidget):
|
||||
address_item.addChild(utxo_item)
|
||||
|
||||
def create_menu(self, position):
|
||||
from electrum.wallet import Multisig_Wallet
|
||||
from electrum.wallet import Multisig_Wallet, Imported_Wallet
|
||||
is_multisig = isinstance(self.wallet, Multisig_Wallet)
|
||||
is_imported = isinstance(self.wallet, Imported_Wallet)
|
||||
selected = self.selectedItems()
|
||||
multi_select = len(selected) > 1
|
||||
addrs = [unicode(item.text(0)) for item in selected]
|
||||
@@ -142,7 +131,7 @@ class AddressList(MyTreeWidget):
|
||||
if not is_multisig and not self.wallet.is_watching_only():
|
||||
menu.addAction(_("Sign/verify message"), lambda: self.parent.sign_verify_message(addr))
|
||||
menu.addAction(_("Encrypt/decrypt message"), lambda: self.parent.encrypt_message(addr))
|
||||
if self.wallet.is_imported(addr):
|
||||
if is_imported:
|
||||
menu.addAction(_("Remove from wallet"), lambda: self.parent.delete_imported_key(addr))
|
||||
addr_URL = block_explorer_URL(self.config, 'addr', addr)
|
||||
if addr_URL:
|
||||
@@ -161,18 +150,3 @@ class AddressList(MyTreeWidget):
|
||||
run_hook('receive_menu', menu, addrs, self.wallet)
|
||||
menu.exec_(self.viewport().mapToGlobal(position))
|
||||
|
||||
def create_account_menu(self, position, k, item):
|
||||
menu = QMenu()
|
||||
exp = item.isExpanded()
|
||||
menu.addAction(_("Minimize") if exp else _("Maximize"), lambda: self.set_account_expanded(item, k, not exp))
|
||||
menu.addAction(_("Rename"), lambda: self.parent.edit_account_label(k))
|
||||
if self.wallet.seed_version > 4:
|
||||
menu.addAction(_("View details"), lambda: self.parent.show_account_details(k))
|
||||
menu.exec_(self.viewport().mapToGlobal(position))
|
||||
|
||||
def set_account_expanded(self, item, k, b):
|
||||
item.setExpanded(b)
|
||||
self.accounts_expanded[k] = b
|
||||
|
||||
def on_close(self):
|
||||
self.wallet.storage.put('accounts_expanded', self.accounts_expanded)
|
||||
|
||||
@@ -61,7 +61,7 @@ class HistoryList(MyTreeWidget):
|
||||
|
||||
def get_domain(self):
|
||||
'''Replaced in address_dialog.py'''
|
||||
return self.wallet.get_account_addresses(self.parent.current_account)
|
||||
return self.wallet.get_addresses()
|
||||
|
||||
def on_update(self):
|
||||
self.wallet = self.parent.wallet
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import sys
|
||||
import os
|
||||
|
||||
from PyQt4.QtGui import *
|
||||
from PyQt4.QtCore import *
|
||||
@@ -156,22 +157,47 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
|
||||
if self.config.get('auto_connect') is None:
|
||||
self.choose_server(self.network)
|
||||
|
||||
action = self.get_action()
|
||||
if action != 'new':
|
||||
path = self.storage.path
|
||||
if self.storage.requires_split():
|
||||
self.hide()
|
||||
msg = _("The wallet '%s' contains multiple accounts, which are no longer supported in Electrum 2.7.\n\n"
|
||||
"Do you want to split your wallet into multiple files?"%path)
|
||||
if not self.question(msg):
|
||||
return
|
||||
file_list = '\n'.join(self.storage.split_accounts())
|
||||
msg = _('Your accounts have been moved to:\n %s.\n\nDo you want to delete the old file:\n%s' % (file_list, path))
|
||||
if self.question(msg):
|
||||
os.remove(path)
|
||||
self.show_warning(_('The file was removed'))
|
||||
return
|
||||
|
||||
if self.storage.requires_upgrade():
|
||||
self.hide()
|
||||
msg = _("The format of your wallet '%s' must be upgraded for Electrum. This change will not be backward compatible"%path)
|
||||
if not self.question(msg):
|
||||
return
|
||||
self.storage.upgrade()
|
||||
self.show_warning(_('Your wallet was upgraded successfully'))
|
||||
self.wallet = Wallet(self.storage)
|
||||
self.terminate()
|
||||
return self.wallet
|
||||
|
||||
action = self.storage.get_action()
|
||||
if action and action != 'new':
|
||||
self.hide()
|
||||
path = self.storage.path
|
||||
msg = _("The file '%s' contains an incompletely created wallet.\n"
|
||||
"Do you want to complete its creation now?") % path
|
||||
if not self.question(msg):
|
||||
if self.question(_("Do you want to delete '%s'?") % path):
|
||||
import os
|
||||
os.remove(path)
|
||||
self.show_warning(_('The file was removed'))
|
||||
return
|
||||
return
|
||||
self.show()
|
||||
self.run(action)
|
||||
return self.wallet
|
||||
if action:
|
||||
# self.wallet is set in run
|
||||
self.run(action)
|
||||
return self.wallet
|
||||
|
||||
|
||||
def finished(self):
|
||||
'''Ensure the dialog is closed.'''
|
||||
|
||||
@@ -51,7 +51,7 @@ from electrum.util import (block_explorer, block_explorer_info, format_time,
|
||||
from electrum import Transaction, mnemonic
|
||||
from electrum import util, bitcoin, commands, coinchooser
|
||||
from electrum import SimpleConfig, paymentrequest
|
||||
from electrum.wallet import Wallet, BIP32_RD_Wallet, Multisig_Wallet
|
||||
from electrum.wallet import Wallet, Multisig_Wallet
|
||||
|
||||
from amountedit import BTCAmountEdit, MyLineEdit, BTCkBEdit
|
||||
from network_dialog import NetworkDialog
|
||||
@@ -248,21 +248,9 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
|
||||
def update_account_selector(self):
|
||||
# account selector
|
||||
accounts = self.wallet.get_account_names()
|
||||
self.account_selector.clear()
|
||||
if len(accounts) > 1:
|
||||
self.account_selector.addItems([_("All accounts")] + accounts.values())
|
||||
self.account_selector.setCurrentIndex(0)
|
||||
self.account_selector.show()
|
||||
else:
|
||||
self.account_selector.hide()
|
||||
|
||||
def close_wallet(self):
|
||||
if self.wallet:
|
||||
self.print_error('close_wallet', self.wallet.storage.path)
|
||||
self.address_list.on_close()
|
||||
run_hook('close_wallet', self.wallet)
|
||||
|
||||
def load_wallet(self, wallet):
|
||||
@@ -270,13 +258,11 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
self.wallet = wallet
|
||||
self.update_recently_visited(wallet.storage.path)
|
||||
# address used to create a dummy transaction and estimate transaction fee
|
||||
self.current_account = self.wallet.storage.get("current_account", None)
|
||||
self.history_list.update()
|
||||
self.need_update.set()
|
||||
# Once GUI has been initialized check if we want to announce something since the callback has been called before the GUI was initialized
|
||||
self.notify_transactions()
|
||||
# update menus
|
||||
self.update_new_account_menu()
|
||||
self.seed_menu.setEnabled(self.wallet.has_seed())
|
||||
self.mpk_menu.setEnabled(self.wallet.is_deterministic())
|
||||
self.update_lock_icon()
|
||||
@@ -391,8 +377,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
|
||||
wallet_menu = menubar.addMenu(_("&Wallet"))
|
||||
wallet_menu.addAction(_("&New contact"), self.new_contact_dialog)
|
||||
self.new_account_menu = wallet_menu.addAction(_("&New account"), self.new_account_dialog)
|
||||
|
||||
wallet_menu.addSeparator()
|
||||
|
||||
self.password_menu = wallet_menu.addAction(_("&Password"), self.change_password_dialog)
|
||||
@@ -569,7 +553,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
text = _("Server is lagging (%d blocks)"%server_lag)
|
||||
icon = QIcon(":icons/status_lagging.png")
|
||||
else:
|
||||
c, u, x = self.wallet.get_account_balance(self.current_account)
|
||||
c, u, x = self.wallet.get_balance()
|
||||
text = _("Balance" ) + ": %s "%(self.format_amount_and_units(c))
|
||||
if u:
|
||||
text += " [%s unconfirmed]"%(self.format_amount(u, True).strip())
|
||||
@@ -593,8 +577,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
self.update_status()
|
||||
if self.wallet.up_to_date or not self.network or not self.network.is_connected():
|
||||
self.update_tabs()
|
||||
if self.wallet.up_to_date:
|
||||
self.check_next_account()
|
||||
|
||||
def update_tabs(self):
|
||||
self.history_list.update()
|
||||
@@ -788,7 +770,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
self.saved = True
|
||||
|
||||
def new_payment_request(self):
|
||||
addr = self.wallet.get_unused_address(self.current_account)
|
||||
addr = self.wallet.get_unused_address(None)
|
||||
if addr is None:
|
||||
from electrum.wallet import Imported_Wallet
|
||||
if isinstance(self.wallet, Imported_Wallet):
|
||||
@@ -796,7 +778,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
return
|
||||
if not self.question(_("Warning: The next address will not be recovered automatically if you restore your wallet from seed; you may need to add it manually.\n\nThis occurs because you have too many unused addresses in your wallet. To avoid this situation, use the existing addresses first.\n\nCreate anyway?")):
|
||||
return
|
||||
addr = self.wallet.create_new_address(self.current_account, False)
|
||||
addr = self.wallet.create_new_address(None, False)
|
||||
self.set_receive_address(addr)
|
||||
self.expires_label.hide()
|
||||
self.expires_combo.show()
|
||||
@@ -809,7 +791,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
self.receive_amount_e.setAmount(None)
|
||||
|
||||
def clear_receive_tab(self):
|
||||
addr = self.wallet.get_unused_address(self.current_account)
|
||||
addr = self.wallet.get_unused_address()
|
||||
self.receive_address_e.setText(addr if addr else '')
|
||||
self.receive_message_e.setText('')
|
||||
self.receive_amount_e.setAmount(None)
|
||||
@@ -1102,7 +1084,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
def request_password(self, *args, **kwargs):
|
||||
parent = self.top_level_window()
|
||||
password = None
|
||||
while self.wallet.use_encryption:
|
||||
while self.wallet.has_password():
|
||||
password = self.password_dialog(parent=parent)
|
||||
try:
|
||||
if password:
|
||||
@@ -1208,7 +1190,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
if tx.get_fee() >= self.config.get('confirm_fee', 100000):
|
||||
msg.append(_('Warning')+ ': ' + _("The fee for this transaction seems unusually high."))
|
||||
|
||||
if self.wallet.use_encryption:
|
||||
if self.wallet.has_password():
|
||||
msg.append("")
|
||||
msg.append(_("Enter your password to proceed"))
|
||||
password = self.password_dialog('\n'.join(msg))
|
||||
@@ -1237,7 +1219,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
'''Sign the transaction in a separate thread. When done, calls
|
||||
the callback with a success code of True or False.
|
||||
'''
|
||||
if self.wallet.use_encryption and not password:
|
||||
if self.wallet.has_password() and not password:
|
||||
callback(False) # User cancelled password input
|
||||
return
|
||||
|
||||
@@ -1438,7 +1420,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
if self.pay_from:
|
||||
return self.pay_from
|
||||
else:
|
||||
domain = self.wallet.get_account_addresses(self.current_account)
|
||||
domain = self.wallet.get_addresses()
|
||||
return self.wallet.get_spendable_coins(domain)
|
||||
|
||||
|
||||
@@ -1561,18 +1543,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
console.updateNamespace(methods)
|
||||
|
||||
|
||||
def change_account(self,s):
|
||||
if s == _("All accounts"):
|
||||
self.current_account = None
|
||||
else:
|
||||
accounts = self.wallet.get_account_names()
|
||||
for k, v in accounts.items():
|
||||
if v == s:
|
||||
self.current_account = k
|
||||
self.history_list.update()
|
||||
self.update_status()
|
||||
self.address_list.update()
|
||||
self.request_list.update()
|
||||
|
||||
def create_status_bar(self):
|
||||
|
||||
@@ -1583,11 +1553,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
self.balance_label = QLabel("")
|
||||
sb.addWidget(self.balance_label)
|
||||
|
||||
self.account_selector = QComboBox()
|
||||
self.account_selector.setSizeAdjustPolicy(QComboBox.AdjustToContents)
|
||||
self.connect(self.account_selector, SIGNAL("activated(QString)"), self.change_account)
|
||||
sb.addPermanentWidget(self.account_selector)
|
||||
|
||||
self.search_box = QLineEdit()
|
||||
self.search_box.textChanged.connect(self.do_search)
|
||||
self.search_box.hide()
|
||||
@@ -1606,7 +1571,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
self.setStatusBar(sb)
|
||||
|
||||
def update_lock_icon(self):
|
||||
icon = QIcon(":icons/lock.png") if self.wallet.use_encryption else QIcon(":icons/unlock.png")
|
||||
icon = QIcon(":icons/lock.png") if self.wallet.has_password() else QIcon(":icons/unlock.png")
|
||||
self.password_button.setIcon(icon)
|
||||
|
||||
def update_buttons_on_seed(self):
|
||||
@@ -1619,7 +1584,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
|
||||
msg = (_('Your wallet is encrypted. Use this dialog to change your '
|
||||
'password. To disable wallet encryption, enter an empty new '
|
||||
'password.') if self.wallet.use_encryption
|
||||
'password.') if self.wallet.has_password()
|
||||
else _('Your wallet keys are not encrypted'))
|
||||
d = PasswordDialog(self, self.wallet, msg, PW_CHANGE)
|
||||
ok, password, new_password = d.run()
|
||||
@@ -1684,48 +1649,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
if self.set_contact(unicode(line2.text()), str(line1.text())):
|
||||
self.tabs.setCurrentIndex(4)
|
||||
|
||||
def update_new_account_menu(self):
|
||||
self.new_account_menu.setVisible(self.wallet.can_create_accounts())
|
||||
self.new_account_menu.setEnabled(self.wallet.permit_account_naming())
|
||||
self.update_account_selector()
|
||||
|
||||
def new_account_dialog(self):
|
||||
dialog = WindowModalDialog(self, _("New Account Name"))
|
||||
vbox = QVBoxLayout()
|
||||
msg = _("Enter a name to give the account. You will not be "
|
||||
"permitted to create further accounts until the new account "
|
||||
"receives at least one transaction.") + "\n"
|
||||
label = QLabel(msg)
|
||||
label.setWordWrap(True)
|
||||
vbox.addWidget(label)
|
||||
e = QLineEdit()
|
||||
vbox.addWidget(e)
|
||||
vbox.addLayout(Buttons(CancelButton(dialog), OkButton(dialog)))
|
||||
dialog.setLayout(vbox)
|
||||
if dialog.exec_():
|
||||
self.wallet.set_label(self.wallet.last_account_id(), str(e.text()))
|
||||
self.address_list.update()
|
||||
self.tabs.setCurrentIndex(3)
|
||||
self.update_new_account_menu()
|
||||
|
||||
def check_next_account(self):
|
||||
if self.wallet.needs_next_account() and not self.checking_accounts:
|
||||
self.checking_accounts = True
|
||||
msg = _("All the accounts in your wallet have received "
|
||||
"transactions. Electrum must check whether more "
|
||||
"accounts exist; one will only be shown if "
|
||||
"it has been used or you give it a name.")
|
||||
self.show_message(msg, title=_("Check Accounts"))
|
||||
self.create_next_account()
|
||||
|
||||
@protected
|
||||
def create_next_account(self, password):
|
||||
def on_done():
|
||||
self.checking_accounts = False
|
||||
self.update_new_account_menu()
|
||||
task = partial(self.wallet.create_next_account, password)
|
||||
self.wallet.thread.add(task, on_done=on_done)
|
||||
|
||||
def show_master_public_keys(self):
|
||||
dialog = WindowModalDialog(self, "Master Public Keys")
|
||||
mpk_dict = self.wallet.get_master_public_keys()
|
||||
@@ -1741,7 +1664,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
if len(mpk_dict) > 1:
|
||||
def label(key):
|
||||
if isinstance(self.wallet, Multisig_Wallet):
|
||||
is_mine = self.wallet.master_private_keys.has_key(key)
|
||||
is_mine = False#self.wallet.master_private_keys.has_key(key)
|
||||
mine_text = [_("cosigner"), _("self")]
|
||||
return "%s (%s)" % (key, mine_text[is_mine])
|
||||
return key
|
||||
@@ -1759,19 +1682,19 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
|
||||
@protected
|
||||
def show_seed_dialog(self, password):
|
||||
if self.wallet.use_encryption and password is None:
|
||||
return # User cancelled password input
|
||||
if self.wallet.has_password() and password is None:
|
||||
# User cancelled password input
|
||||
return
|
||||
if not self.wallet.has_seed():
|
||||
self.show_message(_('This wallet has no seed'))
|
||||
return
|
||||
|
||||
try:
|
||||
mnemonic = self.wallet.get_mnemonic(password)
|
||||
except BaseException as e:
|
||||
self.show_error(str(e))
|
||||
return
|
||||
from seed_dialog import SeedDialog
|
||||
d = SeedDialog(self, mnemonic, self.wallet.has_imported_keys())
|
||||
d = SeedDialog(self, mnemonic)
|
||||
d.exec_()
|
||||
|
||||
|
||||
@@ -1795,9 +1718,9 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
d.setMinimumSize(600, 200)
|
||||
vbox = QVBoxLayout()
|
||||
vbox.addWidget( QLabel(_("Address") + ': ' + address))
|
||||
if isinstance(self.wallet, BIP32_RD_Wallet):
|
||||
derivation = self.wallet.address_id(address)
|
||||
vbox.addWidget(QLabel(_("Derivation") + ': ' + derivation))
|
||||
#if isinstance(self.wallet, BIP32_RD_Wallet):
|
||||
# derivation = self.wallet.address_id(address)
|
||||
# vbox.addWidget(QLabel(_("Derivation") + ': ' + derivation))
|
||||
vbox.addWidget(QLabel(_("Public key") + ':'))
|
||||
keys_e = ShowQRTextEdit(text='\n'.join(pubkey_list))
|
||||
keys_e.addCopyButton(self.app)
|
||||
@@ -2045,7 +1968,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
if self.wallet.is_watching_only():
|
||||
self.show_message(_("This is a watching-only wallet"))
|
||||
return
|
||||
|
||||
try:
|
||||
self.wallet.check_password(password)
|
||||
except Exception as e:
|
||||
@@ -2235,7 +2157,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
keys_e.setTabChangesFocus(True)
|
||||
vbox.addWidget(keys_e)
|
||||
|
||||
addresses = self.wallet.get_unused_addresses(self.current_account)
|
||||
addresses = self.wallet.get_unused_addresses(None)
|
||||
h, address_e = address_field(addresses)
|
||||
vbox.addLayout(h)
|
||||
|
||||
@@ -2271,19 +2193,16 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
|
||||
@protected
|
||||
def do_import_privkey(self, password):
|
||||
if not self.wallet.has_imported_keys():
|
||||
if not self.question('<b>'+_('Warning') +':\n</b><br/>'+ _('Imported keys are not recoverable from seed.') + ' ' \
|
||||
+ _('If you ever need to restore your wallet from its seed, these keys will be lost.') + '<p>' \
|
||||
+ _('Are you sure you understand what you are doing?'), title=_('Warning')):
|
||||
return
|
||||
|
||||
if not self.wallet.keystore.can_import():
|
||||
return
|
||||
text = text_dialog(self, _('Import private keys'), _("Enter private keys")+':', _("Import"))
|
||||
if not text: return
|
||||
|
||||
if not text:
|
||||
return
|
||||
text = str(text).split()
|
||||
badkeys = []
|
||||
addrlist = []
|
||||
for key in text:
|
||||
addr = self.wallet.import_key(key, password)
|
||||
try:
|
||||
addr = self.wallet.import_key(key, password)
|
||||
except Exception as e:
|
||||
@@ -2673,25 +2592,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
vbox.addLayout(Buttons(CloseButton(d)))
|
||||
d.exec_()
|
||||
|
||||
def show_account_details(self, k):
|
||||
account = self.wallet.accounts[k]
|
||||
d = WindowModalDialog(self, _('Account Details'))
|
||||
vbox = QVBoxLayout(d)
|
||||
name = self.wallet.get_account_name(k)
|
||||
label = QLabel('Name: ' + name)
|
||||
vbox.addWidget(label)
|
||||
vbox.addWidget(QLabel(_('Address type') + ': ' + account.get_type()))
|
||||
vbox.addWidget(QLabel(_('Derivation') + ': ' + k))
|
||||
vbox.addWidget(QLabel(_('Master Public Key:')))
|
||||
text = QTextEdit()
|
||||
text.setReadOnly(True)
|
||||
text.setMaximumHeight(170)
|
||||
vbox.addWidget(text)
|
||||
mpk_text = '\n'.join(account.get_master_pubkeys())
|
||||
text.setText(mpk_text)
|
||||
vbox.addLayout(Buttons(CloseButton(d)))
|
||||
d.exec_()
|
||||
|
||||
def bump_fee_dialog(self, tx):
|
||||
is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(tx)
|
||||
d = WindowModalDialog(self, _('Bump Fee'))
|
||||
|
||||
@@ -94,7 +94,7 @@ class PasswordLayout(object):
|
||||
|
||||
m1 = _('New Password:') if kind == PW_NEW else _('Password:')
|
||||
msgs = [m1, _('Confirm Password:')]
|
||||
if wallet and wallet.use_encryption:
|
||||
if wallet and wallet.has_password():
|
||||
grid.addWidget(QLabel(_('Current Password:')), 0, 0)
|
||||
grid.addWidget(self.pw, 0, 1)
|
||||
lockfile = ":icons/lock.png"
|
||||
|
||||
@@ -36,20 +36,19 @@ from util import MyTreeWidget, pr_tooltips, pr_icons
|
||||
class RequestList(MyTreeWidget):
|
||||
|
||||
def __init__(self, parent):
|
||||
MyTreeWidget.__init__(self, parent, self.create_menu, [_('Date'), _('Account'), _('Address'), '', _('Description'), _('Amount'), _('Status')], 4)
|
||||
MyTreeWidget.__init__(self, parent, self.create_menu, [_('Date'), _('Address'), '', _('Description'), _('Amount'), _('Status')], 3)
|
||||
self.currentItemChanged.connect(self.item_changed)
|
||||
self.itemClicked.connect(self.item_changed)
|
||||
self.setSortingEnabled(True)
|
||||
self.setColumnWidth(0, 180)
|
||||
self.hideColumn(1)
|
||||
self.hideColumn(2)
|
||||
|
||||
def item_changed(self, item):
|
||||
if item is None:
|
||||
return
|
||||
if not self.isItemSelected(item):
|
||||
return
|
||||
addr = str(item.text(2))
|
||||
addr = str(item.text(1))
|
||||
req = self.wallet.receive_requests[addr]
|
||||
expires = age(req['time'] + req['exp']) if req.get('exp') else _('Never')
|
||||
amount = req['amount']
|
||||
@@ -72,13 +71,10 @@ class RequestList(MyTreeWidget):
|
||||
self.parent.expires_label.hide()
|
||||
self.parent.expires_combo.show()
|
||||
|
||||
# check if it is necessary to show the account
|
||||
self.setColumnHidden(1, len(self.wallet.get_accounts()) == 1)
|
||||
|
||||
# update the receive address if necessary
|
||||
current_address = self.parent.receive_address_e.text()
|
||||
domain = self.wallet.get_account_addresses(self.parent.current_account, include_change=False)
|
||||
addr = self.wallet.get_unused_address(self.parent.current_account)
|
||||
domain = self.wallet.get_receiving_addresses()
|
||||
addr = self.wallet.get_unused_address()
|
||||
if not current_address in domain and addr:
|
||||
self.parent.set_receive_address(addr)
|
||||
self.parent.new_request_button.setEnabled(addr != current_address)
|
||||
@@ -98,11 +94,10 @@ class RequestList(MyTreeWidget):
|
||||
signature = req.get('sig')
|
||||
requestor = req.get('name', '')
|
||||
amount_str = self.parent.format_amount(amount) if amount else ""
|
||||
account = ''
|
||||
item = QTreeWidgetItem([date, account, address, '', message, amount_str, pr_tooltips.get(status,'')])
|
||||
item = QTreeWidgetItem([date, address, '', message, amount_str, pr_tooltips.get(status,'')])
|
||||
if signature is not None:
|
||||
item.setIcon(3, QIcon(":icons/seal.png"))
|
||||
item.setToolTip(3, 'signed by '+ requestor)
|
||||
item.setIcon(2, QIcon(":icons/seal.png"))
|
||||
item.setToolTip(2, 'signed by '+ requestor)
|
||||
if status is not PR_UNKNOWN:
|
||||
item.setIcon(6, QIcon(pr_icons.get(status)))
|
||||
self.addTopLevelItem(item)
|
||||
|
||||
@@ -39,19 +39,13 @@ def icon_filename(sid):
|
||||
return ":icons/seed.png"
|
||||
|
||||
class SeedDialog(WindowModalDialog):
|
||||
def __init__(self, parent, seed, imported_keys):
|
||||
def __init__(self, parent, seed):
|
||||
WindowModalDialog.__init__(self, parent, ('Electrum - ' + _('Seed')))
|
||||
self.setMinimumWidth(400)
|
||||
vbox = QVBoxLayout(self)
|
||||
vbox.addLayout(SeedWarningLayout(seed).layout())
|
||||
if imported_keys:
|
||||
warning = ("<b>" + _("WARNING") + ":</b> " +
|
||||
_("Your wallet contains imported keys. These keys "
|
||||
"cannot be recovered from your seed.") + "</b><p>")
|
||||
vbox.addWidget(WWLabel(warning))
|
||||
vbox.addLayout(Buttons(CloseButton(self)))
|
||||
|
||||
|
||||
class SeedLayoutBase(object):
|
||||
def _seed_layout(self, seed=None, title=None, sid=None):
|
||||
logo = QLabel()
|
||||
|
||||
Reference in New Issue
Block a user