Browse Source

Merge #986: Show "available balance" along side total balance.

015cb4a If there is unavailable fund, display 2 balances: total balance and unlocked balance. (Wukong)
master
Adam Gibson 4 years ago
parent
commit
d08985043b
No known key found for this signature in database
GPG Key ID: 141001A1AF77F20B
  1. 55
      jmclient/jmclient/wallet_utils.py
  2. 5
      scripts/joinmarket-qt.py

55
jmclient/jmclient/wallet_utils.py

@ -142,8 +142,16 @@ class WalletViewBase(object):
raise NotImplementedError("Separate conf/unconf balances not impl.") raise NotImplementedError("Separate conf/unconf balances not impl.")
return sum([x.get_balance() for x in self.children]) return sum([x.get_balance() for x in self.children])
def get_available_balance(self):
return sum([x.get_available_balance() for x in self.children])
def get_fmt_balance(self, include_unconf=True): def get_fmt_balance(self, include_unconf=True):
return "{0:.08f}".format(self.get_balance(include_unconf)) available_balance = self.get_available_balance()
total_balance = self.get_balance(include_unconf)
if available_balance != total_balance:
return "{0:.08f} ({1:.08f})".format(available_balance, total_balance)
else:
return "{0:.08f}".format(total_balance)
class WalletViewEntry(WalletViewBase): class WalletViewEntry(WalletViewBase):
def __init__(self, wallet_path_repr, account, address_type, aindex, addr, amounts, def __init__(self, wallet_path_repr, account, address_type, aindex, addr, amounts,
@ -166,6 +174,12 @@ class WalletViewEntry(WalletViewBase):
self.status = status self.status = status
self.label = label self.label = label
def is_locked(self):
return "[LOCKED]" in self.status
def is_frozen(self):
return "[FROZEN]" in self.status
def get_balance(self, include_unconf=True): def get_balance(self, include_unconf=True):
"""Overwrites base class since no children """Overwrites base class since no children
""" """
@ -173,6 +187,9 @@ class WalletViewEntry(WalletViewBase):
raise NotImplementedError("Separate conf/unconf balances not impl.") raise NotImplementedError("Separate conf/unconf balances not impl.")
return self.unconfirmed_amount/1e8 return self.unconfirmed_amount/1e8
def get_available_balance(self, include_unconf=True):
return 0 if self.is_locked() or self.is_frozen() else self.get_balance()
def serialize(self): def serialize(self):
left = self.serialize_wallet_position() left = self.serialize_wallet_position()
addr = self.serialize_address() addr = self.serialize_address()
@ -435,6 +452,22 @@ def wallet_showutxos(wallet_service, showprivkey):
return json.dumps(unsp, indent=4, ensure_ascii=False) return json.dumps(unsp, indent=4, ensure_ascii=False)
def get_utxo_status_string(utxos, utxos_enabled, path):
has_frozen_utxo = False
has_pending_utxo = False
for utxo, utxodata in utxos.items():
if path == utxodata["path"]:
if not utxo in utxos_enabled:
has_frozen_utxo = True
if utxodata['confs'] <= 0:
has_pending_utxo = True
utxo_status_string = ""
if has_frozen_utxo:
utxo_status_string += ' [FROZEN]'
if has_pending_utxo:
utxo_status_string += ' [PENDING]'
return utxo_status_string
def wallet_display(wallet_service, showprivkey, displayall=False, def wallet_display(wallet_service, showprivkey, displayall=False,
serialized=True, summarized=False, mixdepth=None, jsonified=False): serialized=True, summarized=False, mixdepth=None, jsonified=False):
@ -442,13 +475,15 @@ def wallet_display(wallet_service, showprivkey, displayall=False,
then return its serialization directly if serialized, then return its serialization directly if serialized,
else return the WalletView object. else return the WalletView object.
""" """
def get_addr_status(addr_path, utxos, is_new, is_internal): def get_addr_status(addr_path, utxos, utxos_enabled, is_new, is_internal):
addr_balance = 0 addr_balance = 0
status = [] status = []
for utxo, utxodata in utxos.items(): for utxo, utxodata in utxos.items():
if addr_path != utxodata['path']: if addr_path != utxodata['path']:
continue continue
addr_balance += utxodata['value'] addr_balance += utxodata['value']
#TODO it is a failure of abstraction here that #TODO it is a failure of abstraction here that
# the bitcoin core interface is used directly # the bitcoin core interface is used directly
#the function should either be removed or added to bci #the function should either be removed or added to bci
@ -472,12 +507,15 @@ def wallet_display(wallet_service, showprivkey, displayall=False,
elif len(status) == 1: elif len(status) == 1:
out_status = status[0] out_status = status[0]
out_status += get_utxo_status_string(utxos, utxos_enabled, addr_path)
return addr_balance, out_status return addr_balance, out_status
acctlist = [] acctlist = []
# TODO - either optionally not show disabled utxos, or
# mark them differently in display (labels; colors) utxos = wallet_service.get_utxos_by_mixdepth(include_disabled=True, includeconfs=True)
utxos = wallet_service.get_utxos_by_mixdepth(include_disabled=True) utxos_enabled = wallet_service.get_utxos_by_mixdepth()
if mixdepth: if mixdepth:
md_range = range(mixdepth, mixdepth + 1) md_range = range(mixdepth, mixdepth + 1)
else: else:
@ -502,7 +540,7 @@ def wallet_display(wallet_service, showprivkey, displayall=False,
gap_addrs.append(addr) gap_addrs.append(addr)
label = wallet_service.get_address_label(addr) label = wallet_service.get_address_label(addr)
balance, status = get_addr_status( balance, status = get_addr_status(
path, utxos[m], k >= unused_index, address_type) path, utxos[m], utxos_enabled[m], k >= unused_index, address_type)
if showprivkey: if showprivkey:
privkey = wallet_service.get_wif_path(path) privkey = wallet_service.get_wif_path(path)
else: else:
@ -536,10 +574,13 @@ def wallet_display(wallet_service, showprivkey, displayall=False,
label = wallet_service.get_address_label(addr) label = wallet_service.get_address_label(addr)
timelock = datetime.utcfromtimestamp(0) + timedelta(seconds=path[-1]) timelock = datetime.utcfromtimestamp(0) + timedelta(seconds=path[-1])
balance = sum([utxodata["value"] for utxo, utxodata in balance = sum([utxodata["value"] for _, utxodata in
utxos[m].items() if path == utxodata["path"]]) utxos[m].items() if path == utxodata["path"]])
status = timelock.strftime("%Y-%m-%d") + " [" + ( status = timelock.strftime("%Y-%m-%d") + " [" + (
"LOCKED" if datetime.now() < timelock else "UNLOCKED") + "]" "LOCKED" if datetime.now() < timelock else "UNLOCKED") + "]"
status += get_utxo_status_string(utxos[m], utxos_enabled[m], path)
privkey = "" privkey = ""
if showprivkey: if showprivkey:
privkey = wallet_service.get_wif_path(path) privkey = wallet_service.get_wif_path(path)

5
scripts/joinmarket-qt.py

@ -1556,9 +1556,8 @@ class JMWalletTab(QWidget):
# if expansion states existed, reinstate them: # if expansion states existed, reinstate them:
if len(previous_expand_states) == max_mixdepth_count: if len(previous_expand_states) == max_mixdepth_count:
m_item.setExpanded(previous_expand_states[mixdepth][0]) m_item.setExpanded(previous_expand_states[mixdepth][0])
# by default, if the mixdepth is 0 or balance of the mixdepth is # we expand at the mixdepth level by default
# greater than 0, expand it else:
elif mixdepth == 0 or float(mdbalance) > 0:
m_item.setExpanded(True) m_item.setExpanded(True)
for address_type in [ for address_type in [

Loading…
Cancel
Save