handle pending and imported accounts using account child classes
This commit is contained in:
parent
b7a60f02e0
commit
fdf8697e58
|
@ -1168,25 +1168,23 @@ class ElectrumWindow(QMainWindow):
|
||||||
|
|
||||||
def update_receive_tab(self):
|
def update_receive_tab(self):
|
||||||
l = self.receive_list
|
l = self.receive_list
|
||||||
|
# extend the syntax for consistency
|
||||||
|
l.addChild = l.addTopLevelItem
|
||||||
|
|
||||||
l.clear()
|
l.clear()
|
||||||
l.setColumnHidden(2, False)
|
|
||||||
l.setColumnHidden(3, False)
|
|
||||||
for i,width in enumerate(self.column_widths['receive']):
|
for i,width in enumerate(self.column_widths['receive']):
|
||||||
l.setColumnWidth(i, width)
|
l.setColumnWidth(i, width)
|
||||||
|
|
||||||
|
accounts = self.wallet.get_accounts()
|
||||||
if self.current_account is None:
|
if self.current_account is None:
|
||||||
account_items = sorted(self.wallet.accounts.items())
|
account_items = sorted(accounts.items())
|
||||||
elif self.current_account != -1:
|
|
||||||
account_items = [(self.current_account, self.wallet.accounts.get(self.current_account))]
|
|
||||||
else:
|
else:
|
||||||
account_items = []
|
account_items = [(self.current_account, accounts.get(self.current_account))]
|
||||||
|
|
||||||
pending_accounts = self.wallet.get_pending_accounts()
|
|
||||||
|
|
||||||
for k, account in account_items:
|
for k, account in account_items:
|
||||||
|
|
||||||
if len(account_items) + len(pending_accounts) > 1:
|
if len(accounts) > 1:
|
||||||
name = self.wallet.get_account_name(k)
|
name = self.wallet.get_account_name(k)
|
||||||
c,u = self.wallet.get_account_balance(k)
|
c,u = self.wallet.get_account_balance(k)
|
||||||
account_item = QTreeWidgetItem( [ name, '', self.format_amount(c+u), ''] )
|
account_item = QTreeWidgetItem( [ name, '', self.format_amount(c+u), ''] )
|
||||||
|
@ -1194,19 +1192,21 @@ class ElectrumWindow(QMainWindow):
|
||||||
account_item.setExpanded(self.accounts_expanded.get(k, True))
|
account_item.setExpanded(self.accounts_expanded.get(k, True))
|
||||||
account_item.setData(0, 32, k)
|
account_item.setData(0, 32, k)
|
||||||
else:
|
else:
|
||||||
account_item = None
|
account_item = l
|
||||||
|
|
||||||
for is_change in ([0,1]):
|
sequences = [0,1] if account.has_change() else [0]
|
||||||
name = _("Receiving") if not is_change else _("Change")
|
for is_change in sequences:
|
||||||
seq_item = QTreeWidgetItem( [ name, '', '', '', ''] )
|
if len(sequences) > 1:
|
||||||
if account_item:
|
name = _("Receiving") if not is_change else _("Change")
|
||||||
|
seq_item = QTreeWidgetItem( [ name, '', '', '', ''] )
|
||||||
account_item.addChild(seq_item)
|
account_item.addChild(seq_item)
|
||||||
|
if not is_change:
|
||||||
|
seq_item.setExpanded(True)
|
||||||
else:
|
else:
|
||||||
l.addTopLevelItem(seq_item)
|
seq_item = account_item
|
||||||
|
|
||||||
used_item = QTreeWidgetItem( [ _("Used"), '', '', '', ''] )
|
used_item = QTreeWidgetItem( [ _("Used"), '', '', '', ''] )
|
||||||
used_flag = False
|
used_flag = False
|
||||||
if not is_change: seq_item.setExpanded(True)
|
|
||||||
|
|
||||||
is_red = False
|
is_red = False
|
||||||
gap = 0
|
gap = 0
|
||||||
|
@ -1223,6 +1223,7 @@ class ElectrumWindow(QMainWindow):
|
||||||
|
|
||||||
c, u = self.wallet.get_addr_balance(address)
|
c, u = self.wallet.get_addr_balance(address)
|
||||||
num_tx = '*' if h == ['*'] else "%d"%len(h)
|
num_tx = '*' if h == ['*'] else "%d"%len(h)
|
||||||
|
|
||||||
item = QTreeWidgetItem( [ address, '', '', num_tx] )
|
item = QTreeWidgetItem( [ address, '', '', num_tx] )
|
||||||
self.update_receive_item(item)
|
self.update_receive_item(item)
|
||||||
if is_red:
|
if is_red:
|
||||||
|
@ -1235,30 +1236,6 @@ class ElectrumWindow(QMainWindow):
|
||||||
else:
|
else:
|
||||||
seq_item.addChild(item)
|
seq_item.addChild(item)
|
||||||
|
|
||||||
|
|
||||||
for k, addr in pending_accounts:
|
|
||||||
name = self.wallet.labels.get(k,'')
|
|
||||||
account_item = QTreeWidgetItem( [ name + " [ "+_('pending account')+" ]", '', '', ''] )
|
|
||||||
self.update_receive_item(item)
|
|
||||||
l.addTopLevelItem(account_item)
|
|
||||||
account_item.setExpanded(True)
|
|
||||||
account_item.setData(0, 32, k)
|
|
||||||
item = QTreeWidgetItem( [ addr, '', '', '', ''] )
|
|
||||||
account_item.addChild(item)
|
|
||||||
self.update_receive_item(item)
|
|
||||||
|
|
||||||
|
|
||||||
if self.wallet.imported_keys and (self.current_account is None or self.current_account == -1):
|
|
||||||
c,u = self.wallet.get_imported_balance()
|
|
||||||
account_item = QTreeWidgetItem( [ _('Imported'), '', self.format_amount(c+u), ''] )
|
|
||||||
l.addTopLevelItem(account_item)
|
|
||||||
account_item.setExpanded(True)
|
|
||||||
for address in self.wallet.imported_keys.keys():
|
|
||||||
item = QTreeWidgetItem( [ address, '', '', ''] )
|
|
||||||
self.update_receive_item(item)
|
|
||||||
account_item.addChild(item)
|
|
||||||
|
|
||||||
|
|
||||||
# we use column 1 because column 0 may be hidden
|
# we use column 1 because column 0 may be hidden
|
||||||
l.setCurrentItem(l.topLevelItem(0),1)
|
l.setCurrentItem(l.topLevelItem(0),1)
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ class ReceivingWidget(QTreeWidget):
|
||||||
|
|
||||||
|
|
||||||
def update_list(self):
|
def update_list(self):
|
||||||
|
return
|
||||||
self.clear()
|
self.clear()
|
||||||
addresses = self.owner.actuator.g.wallet.addresses(False)
|
addresses = self.owner.actuator.g.wallet.addresses(False)
|
||||||
for address in addresses:
|
for address in addresses:
|
||||||
|
|
|
@ -46,6 +46,23 @@ class Account(object):
|
||||||
def get_pubkeys(self, sequence):
|
def get_pubkeys(self, sequence):
|
||||||
return [ self.get_pubkey( *sequence )]
|
return [ self.get_pubkey( *sequence )]
|
||||||
|
|
||||||
|
def has_change(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
class PendingAccount(Account):
|
||||||
|
def __init__(self, v):
|
||||||
|
self.addresses = [ v['pending'] ]
|
||||||
|
self.change = []
|
||||||
|
|
||||||
|
def has_change(self):
|
||||||
|
return False
|
||||||
|
|
||||||
|
class ImportedAccount(Account):
|
||||||
|
def __init__(self, d):
|
||||||
|
self.addresses = d.keys()
|
||||||
|
|
||||||
|
def has_change(self):
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class OldAccount(Account):
|
class OldAccount(Account):
|
||||||
|
|
|
@ -177,6 +177,8 @@ class Abstract_Wallet:
|
||||||
self.addressbook = storage.get('contacts', [])
|
self.addressbook = storage.get('contacts', [])
|
||||||
|
|
||||||
self.imported_keys = storage.get('imported_keys',{})
|
self.imported_keys = storage.get('imported_keys',{})
|
||||||
|
self.imported_account = ImportedAccount(self.imported_keys)
|
||||||
|
|
||||||
self.history = storage.get('addr_history',{}) # address -> list(txid, height)
|
self.history = storage.get('addr_history',{}) # address -> list(txid, height)
|
||||||
|
|
||||||
self.fee = int(storage.get('fee_per_kb', 10000))
|
self.fee = int(storage.get('fee_per_kb', 10000))
|
||||||
|
@ -249,9 +251,6 @@ class Abstract_Wallet:
|
||||||
def synchronize(self):
|
def synchronize(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_pending_accounts(self):
|
|
||||||
return {}
|
|
||||||
|
|
||||||
def can_create_accounts(self):
|
def can_create_accounts(self):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -332,7 +331,7 @@ class Abstract_Wallet:
|
||||||
|
|
||||||
|
|
||||||
def is_mine(self, address):
|
def is_mine(self, address):
|
||||||
return address in self.addresses(True)
|
return address in self.addresses(True)
|
||||||
|
|
||||||
|
|
||||||
def is_change(self, address):
|
def is_change(self, address):
|
||||||
|
@ -564,7 +563,7 @@ class Abstract_Wallet:
|
||||||
|
|
||||||
|
|
||||||
def get_addr_balance(self, address):
|
def get_addr_balance(self, address):
|
||||||
assert self.is_mine(address)
|
#assert self.is_mine(address)
|
||||||
h = self.history.get(address,[])
|
h = self.history.get(address,[])
|
||||||
if h == ['*']: return 0,0
|
if h == ['*']: return 0,0
|
||||||
c = u = 0
|
c = u = 0
|
||||||
|
@ -636,7 +635,7 @@ class Abstract_Wallet:
|
||||||
o = self.addresses(True)
|
o = self.addresses(True)
|
||||||
elif a == -1:
|
elif a == -1:
|
||||||
o = self.imported_keys.keys()
|
o = self.imported_keys.keys()
|
||||||
else:
|
elif a in self.accounts:
|
||||||
ac = self.accounts[a]
|
ac = self.accounts[a]
|
||||||
o = ac.get_addresses(0)
|
o = ac.get_addresses(0)
|
||||||
if include_change: o += ac.get_addresses(1)
|
if include_change: o += ac.get_addresses(1)
|
||||||
|
@ -1132,6 +1131,10 @@ class Imported_Wallet(Abstract_Wallet):
|
||||||
address = address_from_private_key(sec)
|
address = address_from_private_key(sec)
|
||||||
assert address == k
|
assert address == k
|
||||||
|
|
||||||
|
def get_accounts(self):
|
||||||
|
return { -1:self.imported_account }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Deterministic_Wallet(Abstract_Wallet):
|
class Deterministic_Wallet(Abstract_Wallet):
|
||||||
|
|
||||||
|
@ -1277,6 +1280,8 @@ class Deterministic_Wallet(Abstract_Wallet):
|
||||||
self.check_pending_accounts()
|
self.check_pending_accounts()
|
||||||
new = []
|
new = []
|
||||||
for account in self.accounts.values():
|
for account in self.accounts.values():
|
||||||
|
if type(account) == PendingAccount:
|
||||||
|
continue
|
||||||
new += self.synchronize_account(account)
|
new += self.synchronize_account(account)
|
||||||
if new:
|
if new:
|
||||||
self.save_accounts()
|
self.save_accounts()
|
||||||
|
@ -1329,9 +1334,6 @@ class Deterministic_Wallet(Abstract_Wallet):
|
||||||
|
|
||||||
def add_account(self, account_id, account):
|
def add_account(self, account_id, account):
|
||||||
self.accounts[account_id] = account
|
self.accounts[account_id] = account
|
||||||
if account_id in self.pending_accounts:
|
|
||||||
self.pending_accounts.pop(account_id)
|
|
||||||
self.storage.put('pending_accounts', self.pending_accounts)
|
|
||||||
self.save_accounts()
|
self.save_accounts()
|
||||||
|
|
||||||
|
|
||||||
|
@ -1356,27 +1358,30 @@ class Deterministic_Wallet(Abstract_Wallet):
|
||||||
self.accounts[k] = BIP32_Account_2of2(v)
|
self.accounts[k] = BIP32_Account_2of2(v)
|
||||||
elif v.get('xpub'):
|
elif v.get('xpub'):
|
||||||
self.accounts[k] = BIP32_Account(v)
|
self.accounts[k] = BIP32_Account(v)
|
||||||
|
elif v.get('pending'):
|
||||||
|
self.accounts[k] = PendingAccount(v)
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
self.pending_accounts = self.storage.get('pending_accounts',{})
|
|
||||||
|
|
||||||
|
|
||||||
def delete_pending_account(self, k):
|
def delete_pending_account(self, k):
|
||||||
self.pending_accounts.pop(k)
|
assert self.is_pending_account(k)
|
||||||
self.storage.put('pending_accounts', self.pending_accounts)
|
self.accounts.pop(k)
|
||||||
|
self.save_accounts()
|
||||||
|
|
||||||
def account_is_pending(self, k):
|
def account_is_pending(self, k):
|
||||||
return k in self.pending_accounts
|
return type(self.accounts.get(k)) == PendingAccount
|
||||||
|
|
||||||
def create_pending_account(self, name, password):
|
def create_pending_account(self, name, password):
|
||||||
account_id, addr = self.next_account_address(password)
|
account_id, addr = self.next_account_address(password)
|
||||||
self.set_label(account_id, name)
|
self.set_label(account_id, name)
|
||||||
self.pending_accounts[account_id] = addr
|
self.accounts[account_id] = PendingAccount({'pending':addr})
|
||||||
self.storage.put('pending_accounts', self.pending_accounts)
|
self.save_accounts()
|
||||||
|
|
||||||
def get_pending_accounts(self):
|
def get_accounts(self):
|
||||||
return self.pending_accounts.items()
|
out = sorted(self.accounts.items())
|
||||||
|
if self.imported_keys:
|
||||||
|
out.append( (-1, self.imported_account ))
|
||||||
|
return dict(out)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1653,8 +1658,10 @@ class OldWallet(Deterministic_Wallet):
|
||||||
|
|
||||||
|
|
||||||
def get_account_name(self, k):
|
def get_account_name(self, k):
|
||||||
assert k == 0
|
if k == 0:
|
||||||
return 'Main account'
|
return 'Main account'
|
||||||
|
elif k == -1:
|
||||||
|
return 'Imported'
|
||||||
|
|
||||||
|
|
||||||
def get_private_key(self, address, password):
|
def get_private_key(self, address, password):
|
||||||
|
|
Loading…
Reference in New Issue