Compare commits
11 Commits
v0.2.3
...
ef0ab56de4
| Author | SHA1 | Date | |
|---|---|---|---|
|
ef0ab56de4
|
|||
|
c5ad5a61bb
|
|||
|
f7bd09df91
|
|||
|
2a4eab81fd
|
|||
|
d86b941fcb
|
|||
|
1836cdd892
|
|||
|
2416d0ce8d
|
|||
|
8e4e401d1b
|
|||
|
b8859ee5c1
|
|||
|
faeff1ff3c
|
|||
|
437105477d
|
21
bal.py
21
bal.py
@@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
# import random
|
# import random
|
||||||
# import zipfile as zipfile_lib
|
# import zipfile as zipfile_lib
|
||||||
|
|
||||||
@@ -18,7 +19,6 @@ json_db.register_dict("will", dict, None)
|
|||||||
json_db.register_dict("will_settings", lambda x: x, None)
|
json_db.register_dict("will_settings", lambda x: x, None)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_will(x):
|
def get_will(x):
|
||||||
try:
|
try:
|
||||||
x["tx"] = tx_from_any(x["tx"])
|
x["tx"] = tx_from_any(x["tx"])
|
||||||
@@ -68,15 +68,9 @@ class BalPlugin(BasePlugin):
|
|||||||
self.base_dir = os.path.join(config.electrum_path(), "bal")
|
self.base_dir = os.path.join(config.electrum_path(), "bal")
|
||||||
self.plugin_dir = os.path.split(os.path.realpath(__file__))[0]
|
self.plugin_dir = os.path.split(os.path.realpath(__file__))[0]
|
||||||
zipfile = "/".join(self.plugin_dir.split("/")[:-1])
|
zipfile = "/".join(self.plugin_dir.split("/")[:-1])
|
||||||
# print("real path",os.path.realpath(__file__))
|
|
||||||
# self.logger.info(self.base_dir)
|
|
||||||
# print("base_dir:", self.base_dir)
|
|
||||||
# print("suca:",zipfile)
|
|
||||||
# print("plugin_dir:", self.plugin_dir)
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
sys.path.insert(0, zipfile)
|
sys.path.insert(0, zipfile)
|
||||||
# print("sono state listate?")
|
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.config = config
|
self.config = config
|
||||||
self.name = name
|
self.name = name
|
||||||
@@ -96,10 +90,10 @@ class BalPlugin(BasePlugin):
|
|||||||
self.PREVIEW = BalConfig(config, "bal_preview", True)
|
self.PREVIEW = BalConfig(config, "bal_preview", True)
|
||||||
self.SAVE_TXS = BalConfig(config, "bal_save_txs", True)
|
self.SAVE_TXS = BalConfig(config, "bal_save_txs", True)
|
||||||
self.WILLEXECUTORS = BalConfig(config, "bal_willexecutors", True)
|
self.WILLEXECUTORS = BalConfig(config, "bal_willexecutors", True)
|
||||||
self.PING_WILLEXECUTORS = BalConfig(config, "bal_ping_willexecutors", True)
|
# self.PING_WILLEXECUTORS = BalConfig(config, "bal_ping_willexecutors", True)
|
||||||
self.ASK_PING_WILLEXECUTORS = BalConfig(
|
# self.ASK_PING_WILLEXECUTORS = BalConfig(
|
||||||
config, "bal_ask_ping_willexecutors", True
|
# config, "bal_ask_ping_willexecutors", True
|
||||||
)
|
# )
|
||||||
self.NO_WILLEXECUTOR = BalConfig(config, "bal_no_willexecutor", True)
|
self.NO_WILLEXECUTOR = BalConfig(config, "bal_no_willexecutor", True)
|
||||||
self.HIDE_REPLACED = BalConfig(config, "bal_hide_replaced", True)
|
self.HIDE_REPLACED = BalConfig(config, "bal_hide_replaced", True)
|
||||||
self.HIDE_INVALIDATED = BalConfig(config, "bal_hide_invalidated", True)
|
self.HIDE_INVALIDATED = BalConfig(config, "bal_hide_invalidated", True)
|
||||||
@@ -145,16 +139,13 @@ class BalPlugin(BasePlugin):
|
|||||||
self.HIDE_REPLACED.set(self._hide_replaced)
|
self.HIDE_REPLACED.set(self._hide_replaced)
|
||||||
|
|
||||||
def validate_will_settings(self, will_settings):
|
def validate_will_settings(self, will_settings):
|
||||||
# print(type(will_settings))
|
|
||||||
# print(will_settings.get('baltx_fees',1),1)
|
|
||||||
if int(will_settings.get("baltx_fees", 1)) < 1:
|
if int(will_settings.get("baltx_fees", 1)) < 1:
|
||||||
will_settings["baltx_fees"] = 1
|
will_settings["baltx_fees"] = 1
|
||||||
if not will_settings.get("threshold"):
|
if not will_settings.get("threshold"):
|
||||||
will_settings["threshold"] = "180d"
|
will_settings["threshold"] = "180d"
|
||||||
if not will_settings.get("locktime") == "":
|
if not will_settings.get("locktime"):
|
||||||
will_settings["locktime"] = "1y"
|
will_settings["locktime"] = "1y"
|
||||||
return will_settings
|
return will_settings
|
||||||
|
|
||||||
def default_will_settings(self):
|
def default_will_settings(self):
|
||||||
return {"baltx_fees": 100, "threshold": "180d", "locktime": "1y"}
|
return {"baltx_fees": 100, "threshold": "180d", "locktime": "1y"}
|
||||||
|
|
||||||
|
|||||||
103
heirs.py
103
heirs.py
@@ -29,6 +29,8 @@ from electrum.util import (
|
|||||||
|
|
||||||
from .util import Util
|
from .util import Util
|
||||||
from .willexecutors import Willexecutors
|
from .willexecutors import Willexecutors
|
||||||
|
from electrum.util import BitcoinException
|
||||||
|
from electrum import constants
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .simple_config import SimpleConfig
|
from .simple_config import SimpleConfig
|
||||||
@@ -41,6 +43,7 @@ HEIR_ADDRESS = 0
|
|||||||
HEIR_AMOUNT = 1
|
HEIR_AMOUNT = 1
|
||||||
HEIR_LOCKTIME = 2
|
HEIR_LOCKTIME = 2
|
||||||
HEIR_REAL_AMOUNT = 3
|
HEIR_REAL_AMOUNT = 3
|
||||||
|
HEIR_DUST_AMOUNT = 4
|
||||||
TRANSACTION_LABEL = "inheritance transaction"
|
TRANSACTION_LABEL = "inheritance transaction"
|
||||||
|
|
||||||
|
|
||||||
@@ -88,35 +91,41 @@ def prepare_transactions(locktimes, available_utxos, fees, wallet):
|
|||||||
txsout = {}
|
txsout = {}
|
||||||
locktime, _ = Util.get_lowest_locktimes(locktimes)
|
locktime, _ = Util.get_lowest_locktimes(locktimes)
|
||||||
if not locktime:
|
if not locktime:
|
||||||
|
_logger.info("prepare transactions, no locktime")
|
||||||
return
|
return
|
||||||
locktime = locktime[0]
|
locktime = locktime[0]
|
||||||
|
|
||||||
heirs = locktimes[locktime]
|
heirs = locktimes[locktime]
|
||||||
vero = True
|
true = True
|
||||||
while vero:
|
while true:
|
||||||
vero = False
|
true = False
|
||||||
fee = fees.get(locktime, 0)
|
fee = fees.get(locktime, 0)
|
||||||
out_amount = fee
|
out_amount = fee
|
||||||
description = ""
|
description = ""
|
||||||
outputs = []
|
outputs = []
|
||||||
paid_heirs = {}
|
paid_heirs = {}
|
||||||
for name, heir in heirs.items():
|
for name, heir in heirs.items():
|
||||||
|
if len(heir) > HEIR_REAL_AMOUNT and not "DUST" in str(
|
||||||
|
heir[HEIR_REAL_AMOUNT]
|
||||||
|
):
|
||||||
try:
|
try:
|
||||||
if len(heir) > HEIR_REAL_AMOUNT:
|
|
||||||
real_amount = heir[HEIR_REAL_AMOUNT]
|
real_amount = heir[HEIR_REAL_AMOUNT]
|
||||||
out_amount += real_amount
|
|
||||||
description += f"{name}\n"
|
|
||||||
paid_heirs[name] = heir
|
|
||||||
outputs.append(
|
outputs.append(
|
||||||
PartialTxOutput.from_address_and_value(
|
PartialTxOutput.from_address_and_value(
|
||||||
heir[HEIR_ADDRESS], real_amount
|
heir[HEIR_ADDRESS], real_amount
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
out_amount += real_amount
|
||||||
pass
|
description += f"{name}\n"
|
||||||
|
except BitcoinException as e:
|
||||||
|
_logger.info("exception decoding output {} - {}".format(type(e), e))
|
||||||
|
heir[HEIR_REAL_AMOUNT] = e
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
heir[HEIR_REAL_AMOUNT] = e
|
||||||
|
_logger.error(f"error preparing transactions: {e}")
|
||||||
pass
|
pass
|
||||||
|
paid_heirs[name] = heir
|
||||||
|
|
||||||
in_amount = 0.0
|
in_amount = 0.0
|
||||||
used_utxos = []
|
used_utxos = []
|
||||||
@@ -125,13 +134,19 @@ def prepare_transactions(locktimes, available_utxos, fees, wallet):
|
|||||||
value = utxo.value_sats()
|
value = utxo.value_sats()
|
||||||
in_amount += value
|
in_amount += value
|
||||||
used_utxos.append(utxo)
|
used_utxos.append(utxo)
|
||||||
if in_amount > out_amount:
|
if in_amount >= out_amount:
|
||||||
break
|
break
|
||||||
|
|
||||||
except IndexError as e:
|
except IndexError as e:
|
||||||
|
_logger.error(
|
||||||
|
f"error preparing transactions index error {e} {in_amount}, {out_amount}"
|
||||||
|
)
|
||||||
pass
|
pass
|
||||||
if int(in_amount) < int(out_amount):
|
if int(in_amount) < int(out_amount):
|
||||||
break
|
_logger.error(
|
||||||
|
"error preparing transactions in_amount < out_amount ({} < {}) "
|
||||||
|
)
|
||||||
|
continue
|
||||||
heirsvalue = out_amount
|
heirsvalue = out_amount
|
||||||
change = get_change_output(wallet, in_amount, out_amount, fee)
|
change = get_change_output(wallet, in_amount, out_amount, fee)
|
||||||
if change:
|
if change:
|
||||||
@@ -263,9 +278,10 @@ def get_change_output(wallet, in_amount, out_amount, fee):
|
|||||||
|
|
||||||
class Heirs(dict, Logger):
|
class Heirs(dict, Logger):
|
||||||
|
|
||||||
def __init__(self, db: "WalletDB"):
|
def __init__(self, wallet):
|
||||||
Logger.__init__(self)
|
Logger.__init__(self)
|
||||||
self.db = db
|
self.db = wallet.db
|
||||||
|
self.wallet = wallet
|
||||||
d = self.db.get("heirs", {})
|
d = self.db.get("heirs", {})
|
||||||
try:
|
try:
|
||||||
self.update(d)
|
self.update(d)
|
||||||
@@ -303,7 +319,7 @@ class Heirs(dict, Logger):
|
|||||||
locktime = Util.parse_locktime_string(self[key][HEIR_LOCKTIME])
|
locktime = Util.parse_locktime_string(self[key][HEIR_LOCKTIME])
|
||||||
if locktime > from_locktime and not a or locktime <= from_locktime and a:
|
if locktime > from_locktime and not a or locktime <= from_locktime and a:
|
||||||
locktimes[int(locktime)] = None
|
locktimes[int(locktime)] = None
|
||||||
return locktimes.keys()
|
return list(locktimes.keys())
|
||||||
|
|
||||||
def check_locktime(self):
|
def check_locktime(self):
|
||||||
return False
|
return False
|
||||||
@@ -317,6 +333,8 @@ class Heirs(dict, Logger):
|
|||||||
column = HEIR_AMOUNT
|
column = HEIR_AMOUNT
|
||||||
if real:
|
if real:
|
||||||
column = HEIR_REAL_AMOUNT
|
column = HEIR_REAL_AMOUNT
|
||||||
|
if "DUST" in str(v[column]):
|
||||||
|
column = HEIR_DUST_AMOUNT
|
||||||
value = int(
|
value = int(
|
||||||
math.floor(
|
math.floor(
|
||||||
total_balance
|
total_balance
|
||||||
@@ -327,6 +345,10 @@ class Heirs(dict, Logger):
|
|||||||
if value > wallet.dust_threshold():
|
if value > wallet.dust_threshold():
|
||||||
heir_list[key].insert(HEIR_REAL_AMOUNT, value)
|
heir_list[key].insert(HEIR_REAL_AMOUNT, value)
|
||||||
amount += value
|
amount += value
|
||||||
|
else:
|
||||||
|
heir_list[key].insert(HEIR_REAL_AMOUNT, f"DUST: {value}")
|
||||||
|
heir_list[key].insert(HEIR_DUST_AMOUNT, value)
|
||||||
|
_logger.info(f"{key}, {value} is dust will be ignored")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise e
|
raise e
|
||||||
@@ -346,27 +368,32 @@ class Heirs(dict, Logger):
|
|||||||
fixed_amount = 0.0
|
fixed_amount = 0.0
|
||||||
percent_heirs = {}
|
percent_heirs = {}
|
||||||
percent_amount = 0.0
|
percent_amount = 0.0
|
||||||
|
fixed_amount_with_dust =0.0
|
||||||
for key in self.keys():
|
for key in self.keys():
|
||||||
try:
|
try:
|
||||||
cmp = (
|
cmp = (
|
||||||
Util.parse_locktime_string(self[key][HEIR_LOCKTIME]) - from_locktime
|
Util.parse_locktime_string(self[key][HEIR_LOCKTIME]) - from_locktime
|
||||||
)
|
)
|
||||||
if cmp <= 0:
|
if cmp <= 0:
|
||||||
|
_logger.debug("cmp < 0 {} {} {} ".format(cmp, key, self[key][HEIR_LOCKTIME], from_locktime))
|
||||||
continue
|
continue
|
||||||
if Util.is_perc(self[key][HEIR_AMOUNT]):
|
if Util.is_perc(self[key][HEIR_AMOUNT]):
|
||||||
percent_amount += float(self[key][HEIR_AMOUNT][:-1])
|
percent_amount += float(self[key][HEIR_AMOUNT][:-1])
|
||||||
percent_heirs[key] = list(self[key])
|
percent_heirs[key] = list(self[key])
|
||||||
else:
|
else:
|
||||||
heir_amount = int(math.floor(float(self[key][HEIR_AMOUNT])))
|
heir_amount = int(math.floor(float(self[key][HEIR_AMOUNT])))
|
||||||
|
fixed_amount_with_dust += heir_amount
|
||||||
|
fixed_heirs[key] = list(self[key])
|
||||||
if heir_amount > dust_threshold:
|
if heir_amount > dust_threshold:
|
||||||
fixed_amount += heir_amount
|
fixed_amount += heir_amount
|
||||||
fixed_heirs[key] = list(self[key])
|
|
||||||
fixed_heirs[key].insert(HEIR_REAL_AMOUNT, heir_amount)
|
fixed_heirs[key].insert(HEIR_REAL_AMOUNT, heir_amount)
|
||||||
else:
|
else:
|
||||||
pass
|
fixed_heirs[key] = list(self[key])
|
||||||
|
fixed_heirs[key].insert(HEIR_REAL_AMOUNT, f"DUST: {heir_amount}")
|
||||||
|
fixed_heirs[key].insert(HEIR_DUST_AMOUNT, heir_amount)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
_logger.error(e)
|
_logger.error(e)
|
||||||
return fixed_heirs, fixed_amount, percent_heirs, percent_amount
|
return fixed_heirs, fixed_amount, percent_heirs, percent_amount, fixed_amount_with_dust
|
||||||
|
|
||||||
def prepare_lists(
|
def prepare_lists(
|
||||||
self, balance, total_fees, wallet, willexecutor=False, from_locktime=0
|
self, balance, total_fees, wallet, willexecutor=False, from_locktime=0
|
||||||
@@ -399,9 +426,13 @@ class Heirs(dict, Logger):
|
|||||||
),
|
),
|
||||||
heir_list.update(willexecutors)
|
heir_list.update(willexecutors)
|
||||||
newbalance -= willexecutors_amount
|
newbalance -= willexecutors_amount
|
||||||
fixed_heirs, fixed_amount, percent_heirs, percent_amount = (
|
if newbalance<0:
|
||||||
|
raise WillExecutorFeeException(willexecutor)
|
||||||
|
a=list(self.fixed_percent_lists_amount(from_locktime, wallet.dust_threshold()))
|
||||||
|
fixed_heirs, fixed_amount, percent_heirs, percent_amount,fixed_amount_with_dust = (
|
||||||
self.fixed_percent_lists_amount(from_locktime, wallet.dust_threshold())
|
self.fixed_percent_lists_amount(from_locktime, wallet.dust_threshold())
|
||||||
)
|
)
|
||||||
|
|
||||||
if fixed_amount > newbalance:
|
if fixed_amount > newbalance:
|
||||||
fixed_amount = self.normalize_perc(
|
fixed_amount = self.normalize_perc(
|
||||||
fixed_heirs, newbalance, fixed_amount, wallet
|
fixed_heirs, newbalance, fixed_amount, wallet
|
||||||
@@ -422,7 +453,7 @@ class Heirs(dict, Logger):
|
|||||||
if newbalance > 0:
|
if newbalance > 0:
|
||||||
newbalance += fixed_amount
|
newbalance += fixed_amount
|
||||||
fixed_amount = self.normalize_perc(
|
fixed_amount = self.normalize_perc(
|
||||||
fixed_heirs, newbalance, fixed_amount, wallet, real=True
|
fixed_heirs, newbalance, fixed_amount_with_dust, wallet, real=True
|
||||||
)
|
)
|
||||||
newbalance -= fixed_amount
|
newbalance -= fixed_amount
|
||||||
heir_list.update(fixed_heirs)
|
heir_list.update(fixed_heirs)
|
||||||
@@ -449,6 +480,7 @@ class Heirs(dict, Logger):
|
|||||||
):
|
):
|
||||||
Heirs._validate(self)
|
Heirs._validate(self)
|
||||||
if len(self) <= 0:
|
if len(self) <= 0:
|
||||||
|
_logger.info("while building transactions there was no heirs")
|
||||||
return
|
return
|
||||||
balance = 0.0
|
balance = 0.0
|
||||||
len_utxo_set = 0
|
len_utxo_set = 0
|
||||||
@@ -464,6 +496,7 @@ class Heirs(dict, Logger):
|
|||||||
len_utxo_set += 1
|
len_utxo_set += 1
|
||||||
available_utxos.append(utxo)
|
available_utxos.append(utxo)
|
||||||
if len_utxo_set == 0:
|
if len_utxo_set == 0:
|
||||||
|
_logger.info("no usable utxos")
|
||||||
return
|
return
|
||||||
j = -2
|
j = -2
|
||||||
willexecutorsitems = list(willexecutors.items())
|
willexecutorsitems = list(willexecutors.items())
|
||||||
@@ -487,7 +520,7 @@ class Heirs(dict, Logger):
|
|||||||
break
|
break
|
||||||
fees = {}
|
fees = {}
|
||||||
i = 0
|
i = 0
|
||||||
while True:
|
while i<10:
|
||||||
txs = {}
|
txs = {}
|
||||||
redo = False
|
redo = False
|
||||||
i += 1
|
i += 1
|
||||||
@@ -495,9 +528,14 @@ class Heirs(dict, Logger):
|
|||||||
for fee in fees:
|
for fee in fees:
|
||||||
total_fees += int(fees[fee])
|
total_fees += int(fees[fee])
|
||||||
newbalance = balance
|
newbalance = balance
|
||||||
|
try:
|
||||||
locktimes, onlyfixed = self.prepare_lists(
|
locktimes, onlyfixed = self.prepare_lists(
|
||||||
balance, total_fees, wallet, willexecutor, from_locktime
|
balance, total_fees, wallet, willexecutor, from_locktime
|
||||||
)
|
)
|
||||||
|
except WillExecutorFeeException as e:
|
||||||
|
i=10
|
||||||
|
continue
|
||||||
|
if locktimes:
|
||||||
try:
|
try:
|
||||||
txs = prepare_transactions(
|
txs = prepare_transactions(
|
||||||
locktimes, available_utxos[:], fees, wallet
|
locktimes, available_utxos[:], fees, wallet
|
||||||
@@ -505,6 +543,7 @@ class Heirs(dict, Logger):
|
|||||||
if not txs:
|
if not txs:
|
||||||
return {}
|
return {}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
_logger.error(f"build transactions: error preparing transactions: {e}")
|
||||||
try:
|
try:
|
||||||
if "w!ll3x3c" in e.heirname:
|
if "w!ll3x3c" in e.heirname:
|
||||||
Willexecutors.is_selected(willexecutors[w], False)
|
Willexecutors.is_selected(willexecutors[w], False)
|
||||||
@@ -533,6 +572,9 @@ class Heirs(dict, Logger):
|
|||||||
break
|
break
|
||||||
if i >= 10:
|
if i >= 10:
|
||||||
break
|
break
|
||||||
|
else:
|
||||||
|
_logger.info(f"no locktimes for willexecutor {willexecutor} skipped")
|
||||||
|
break
|
||||||
alltxs.update(txs)
|
alltxs.update(txs)
|
||||||
|
|
||||||
return alltxs
|
return alltxs
|
||||||
@@ -632,7 +674,7 @@ class Heirs(dict, Logger):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def validate_address(address):
|
def validate_address(address):
|
||||||
if not bitcoin.is_address(address):
|
if not bitcoin.is_address(address, net=constants.net):
|
||||||
raise NotAnAddress(f"not an address,{address}")
|
raise NotAnAddress(f"not an address,{address}")
|
||||||
return address
|
return address
|
||||||
|
|
||||||
@@ -661,12 +703,14 @@ class Heirs(dict, Logger):
|
|||||||
return (address, amount, locktime)
|
return (address, amount, locktime)
|
||||||
|
|
||||||
def _validate(data, timestamp_to_check=False):
|
def _validate(data, timestamp_to_check=False):
|
||||||
|
|
||||||
for k, v in list(data.items()):
|
for k, v in list(data.items()):
|
||||||
if k == "heirs":
|
if k == "heirs":
|
||||||
return Heirs._validate(v)
|
return Heirs._validate(v, timestamp_to_check)
|
||||||
try:
|
try:
|
||||||
Heirs.validate_heir(k, v)
|
Heirs.validate_heir(k, v, timestamp_to_check)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
_logger.info(f"exception heir removed {e}")
|
||||||
data.pop(k)
|
data.pop(k)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
@@ -685,3 +729,14 @@ class LocktimeNotValid(ValueError):
|
|||||||
|
|
||||||
class HeirExpiredException(LocktimeNotValid):
|
class HeirExpiredException(LocktimeNotValid):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class HeirAmountIsDustException(Exception):
|
||||||
|
pass
|
||||||
|
class NoHeirsException(Exception):
|
||||||
|
pass
|
||||||
|
class WillExecutorFeeException(Exception):
|
||||||
|
def __init__(self,willexecutor):
|
||||||
|
self.willexecutor=willexecutor
|
||||||
|
def __str__(self):
|
||||||
|
return "WillExecutorFeeException: {} fee:{}".format(self.willexecutor['url'],self.willexecutor['base_fee'])
|
||||||
|
|||||||
BIN
icons/confirmed.png
Normal file
BIN
icons/confirmed.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 53 KiB |
BIN
icons/status_connected.png
Normal file
BIN
icons/status_connected.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 69 KiB |
BIN
icons/unconfirmed.png
Normal file
BIN
icons/unconfirmed.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.4 KiB |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "BAL",
|
"name": "BAL",
|
||||||
"fullname": "Bitcoin After Life",
|
"fullname": "Bitcoin After Life",
|
||||||
"description": "Provides free and decentralized inheritance support<br> Version: 0.2.3",
|
"description": "Provides free and decentralized inheritance support<br> Version: 0.2.4",
|
||||||
"author":"Svatantrya",
|
"author":"Svatantrya",
|
||||||
"available_for": ["qt"],
|
"available_for": ["qt"],
|
||||||
"icon":"icons/bal32x32.png"
|
"icon":"icons/bal32x32.png"
|
||||||
|
|||||||
296
qt.py
296
qt.py
@@ -145,7 +145,7 @@ from electrum.util import (
|
|||||||
|
|
||||||
from .bal import BalPlugin
|
from .bal import BalPlugin
|
||||||
from .bal_resources import DEFAULT_ICON, icon_path
|
from .bal_resources import DEFAULT_ICON, icon_path
|
||||||
from .heirs import Heirs
|
from .heirs import Heirs, HEIR_REAL_AMOUNT, HEIR_DUST_AMOUNT
|
||||||
from .util import Util
|
from .util import Util
|
||||||
from .will import (
|
from .will import (
|
||||||
AmountException,
|
AmountException,
|
||||||
@@ -295,8 +295,8 @@ class Plugin(BalPlugin, Logger):
|
|||||||
lbl_logo = QLabel()
|
lbl_logo = QLabel()
|
||||||
lbl_logo.setPixmap(qicon)
|
lbl_logo.setPixmap(qicon)
|
||||||
|
|
||||||
heir_ping_willexecutors = bal_checkbox(self.PING_WILLEXECUTORS)
|
# heir_ping_willexecutors = bal_checkbox(self.PING_WILLEXECUTORS)
|
||||||
heir_ask_ping_willexecutors = bal_checkbox(self.ASK_PING_WILLEXECUTORS)
|
# heir_ask_ping_willexecutors = bal_checkbox(self.ASK_PING_WILLEXECUTORS)
|
||||||
heir_no_willexecutor = bal_checkbox(self.NO_WILLEXECUTOR)
|
heir_no_willexecutor = bal_checkbox(self.NO_WILLEXECUTOR)
|
||||||
|
|
||||||
def on_multiverse_change():
|
def on_multiverse_change():
|
||||||
@@ -327,27 +327,27 @@ class Plugin(BalPlugin, Logger):
|
|||||||
2,
|
2,
|
||||||
"Hide invalidated transactions from will detail and list",
|
"Hide invalidated transactions from will detail and list",
|
||||||
)
|
)
|
||||||
add_widget(
|
# add_widget(
|
||||||
grid,
|
# grid,
|
||||||
"Ping Willexecutors",
|
# "Ping Willexecutors",
|
||||||
heir_ping_willexecutors,
|
# heir_ping_willexecutors,
|
||||||
3,
|
# 3,
|
||||||
"Ping willexecutors to get payment info before compiling will",
|
# "Ping willexecutors to get payment info before compiling will",
|
||||||
)
|
# )
|
||||||
add_widget(
|
# add_widget(
|
||||||
grid,
|
# grid,
|
||||||
" - Ask before",
|
# " - Ask before",
|
||||||
heir_ask_ping_willexecutors,
|
# heir_ask_ping_willexecutors,
|
||||||
4,
|
# 4,
|
||||||
"Ask before to ping willexecutor",
|
# "Ask before to ping willexecutor",
|
||||||
)
|
# )
|
||||||
add_widget(
|
# add_widget(
|
||||||
grid,
|
# grid,
|
||||||
"Backup Transaction",
|
# "Backup Transaction",
|
||||||
heir_no_willexecutor,
|
# heir_no_willexecutor,
|
||||||
5,
|
# 5,
|
||||||
"Add transactions without willexecutor",
|
# "Add transactions without willexecutor",
|
||||||
)
|
# )
|
||||||
# add_widget(grid,"Enable Multiverse(EXPERIMENTAL/BROKEN)",heir_enable_multiverse,6,"enable multiple locktimes, will import.... ")
|
# add_widget(grid,"Enable Multiverse(EXPERIMENTAL/BROKEN)",heir_enable_multiverse,6,"enable multiple locktimes, will import.... ")
|
||||||
grid.addWidget(heir_repush, 7, 0)
|
grid.addWidget(heir_repush, 7, 0)
|
||||||
grid.addWidget(
|
grid.addWidget(
|
||||||
@@ -401,13 +401,13 @@ class BalWindow(Logger):
|
|||||||
self.willitems = {}
|
self.willitems = {}
|
||||||
self.willexecutors = {}
|
self.willexecutors = {}
|
||||||
self.will_settings = None
|
self.will_settings = None
|
||||||
self.heirs_tab = self.create_heirs_tab()
|
|
||||||
self.will_tab = self.create_will_tab()
|
|
||||||
self.ok = False
|
self.ok = False
|
||||||
self.disable_plugin = True
|
self.disable_plugin = True
|
||||||
self.bal_plugin.get_decimal_point = self.window.get_decimal_point
|
self.bal_plugin.get_decimal_point = self.window.get_decimal_point
|
||||||
|
|
||||||
if self.window.wallet:
|
if self.window.wallet:
|
||||||
|
self.heirs_tab = self.create_heirs_tab()
|
||||||
|
self.will_tab = self.create_will_tab()
|
||||||
self.wallet = self.window.wallet
|
self.wallet = self.window.wallet
|
||||||
self.heirs_tab.wallet = self.wallet
|
self.heirs_tab.wallet = self.wallet
|
||||||
self.will_tab.wallet = self.wallet
|
self.will_tab.wallet = self.wallet
|
||||||
@@ -419,7 +419,7 @@ class BalWindow(Logger):
|
|||||||
tab.tab_icon = icon
|
tab.tab_icon = icon
|
||||||
tab.tab_description = description
|
tab.tab_description = description
|
||||||
tab.tab_pos = len(tabs)
|
tab.tab_pos = len(tabs)
|
||||||
if tab.is_shown_cv:
|
if tab.is_shown_cv.get():
|
||||||
tabs.addTab(tab, icon, description.replace("&", ""))
|
tabs.addTab(tab, icon, description.replace("&", ""))
|
||||||
|
|
||||||
def add_toggle_action(tab):
|
def add_toggle_action(tab):
|
||||||
@@ -473,7 +473,7 @@ class BalWindow(Logger):
|
|||||||
self.bal_plugin, update=False, bal_window=self
|
self.bal_plugin, update=False, bal_window=self
|
||||||
)
|
)
|
||||||
if not self.heirs:
|
if not self.heirs:
|
||||||
self.heirs = Heirs._validate(Heirs(self.wallet.db))
|
self.heirs = Heirs._validate(Heirs(self.wallet))
|
||||||
if not self.will:
|
if not self.will:
|
||||||
self.will = self.wallet.db.get_dict("will")
|
self.will = self.wallet.db.get_dict("will")
|
||||||
Util.fix_will_tx_fees(self.will)
|
Util.fix_will_tx_fees(self.will)
|
||||||
@@ -498,9 +498,9 @@ class BalWindow(Logger):
|
|||||||
if not self.will_settings:
|
if not self.will_settings:
|
||||||
Util.copy(self.will_settings, self.bal_plugin.default_will_settings())
|
Util.copy(self.will_settings, self.bal_plugin.default_will_settings())
|
||||||
self.logger.debug("not_will_settings {}".format(self.will_settings))
|
self.logger.debug("not_will_settings {}".format(self.will_settings))
|
||||||
|
|
||||||
self.bal_plugin.validate_will_settings(self.will_settings)
|
self.bal_plugin.validate_will_settings(self.will_settings)
|
||||||
self.heir_list.update_will_settings()
|
self.heir_list.update_will_settings()
|
||||||
|
self.heir_list.update()
|
||||||
|
|
||||||
def init_wizard(self):
|
def init_wizard(self):
|
||||||
wizard_dialog = BalWizardDialog(self)
|
wizard_dialog = BalWizardDialog(self)
|
||||||
@@ -514,7 +514,7 @@ class BalWindow(Logger):
|
|||||||
self.heir_list = l = HeirList(self, self.window)
|
self.heir_list = l = HeirList(self, self.window)
|
||||||
|
|
||||||
tab = self.window.create_list_tab(l)
|
tab = self.window.create_list_tab(l)
|
||||||
tab.is_shown_cv = shown_cv(True)
|
tab.is_shown_cv = shown_cv(False)
|
||||||
return tab
|
return tab
|
||||||
|
|
||||||
def create_will_tab(self):
|
def create_will_tab(self):
|
||||||
@@ -625,7 +625,11 @@ class BalWindow(Logger):
|
|||||||
|
|
||||||
def delete_heirs(self, heirs):
|
def delete_heirs(self, heirs):
|
||||||
for heir in heirs:
|
for heir in heirs:
|
||||||
|
try:
|
||||||
del self.heirs[heir]
|
del self.heirs[heir]
|
||||||
|
except Exception as e:
|
||||||
|
_logger.debug(f"error deleting heir: {heir} {e}")
|
||||||
|
pass
|
||||||
self.heirs.save()
|
self.heirs.save()
|
||||||
self.heir_list.update()
|
self.heir_list.update()
|
||||||
return True
|
return True
|
||||||
@@ -655,7 +659,7 @@ class BalWindow(Logger):
|
|||||||
Will.normalize_will(self.willitems, self.wallet)
|
Will.normalize_will(self.willitems, self.wallet)
|
||||||
|
|
||||||
def build_will(self, ignore_duplicate=True, keep_original=True):
|
def build_will(self, ignore_duplicate=True, keep_original=True):
|
||||||
|
_logger.debug("building will...")
|
||||||
will = {}
|
will = {}
|
||||||
willtodelete = []
|
willtodelete = []
|
||||||
willtoappend = {}
|
willtoappend = {}
|
||||||
@@ -664,7 +668,6 @@ class BalWindow(Logger):
|
|||||||
self.willexecutors = Willexecutors.get_willexecutors(
|
self.willexecutors = Willexecutors.get_willexecutors(
|
||||||
self.bal_plugin, update=False, bal_window=self
|
self.bal_plugin, update=False, bal_window=self
|
||||||
)
|
)
|
||||||
|
|
||||||
if not self.no_willexecutor:
|
if not self.no_willexecutor:
|
||||||
|
|
||||||
f = False
|
f = False
|
||||||
@@ -672,6 +675,7 @@ class BalWindow(Logger):
|
|||||||
if Willexecutors.is_selected(w):
|
if Willexecutors.is_selected(w):
|
||||||
f = True
|
f = True
|
||||||
if not f:
|
if not f:
|
||||||
|
_logger.error("No Will-Executor or backup transaction selected")
|
||||||
raise NoWillExecutorNotPresent(
|
raise NoWillExecutorNotPresent(
|
||||||
"No Will-Executor or backup transaction selected"
|
"No Will-Executor or backup transaction selected"
|
||||||
)
|
)
|
||||||
@@ -682,7 +686,8 @@ class BalWindow(Logger):
|
|||||||
None,
|
None,
|
||||||
self.date_to_check,
|
self.date_to_check,
|
||||||
)
|
)
|
||||||
self.logger.info(txs)
|
|
||||||
|
self.logger.info(f"txs built: {txs}")
|
||||||
creation_time = time.time()
|
creation_time = time.time()
|
||||||
if txs:
|
if txs:
|
||||||
for txid in txs:
|
for txid in txs:
|
||||||
@@ -701,7 +706,14 @@ class BalWindow(Logger):
|
|||||||
tx["txchildren"] = []
|
tx["txchildren"] = []
|
||||||
will[txid] = WillItem(tx, _id=txid, wallet=self.wallet)
|
will[txid] = WillItem(tx, _id=txid, wallet=self.wallet)
|
||||||
self.update_will(will)
|
self.update_will(will)
|
||||||
|
else:
|
||||||
|
self.logger.info("No transactions was built")
|
||||||
|
self.logger.info(f"will-settings: {self.will_settings}")
|
||||||
|
self.logger.info(f"date_to_check:{self.date_to_check}")
|
||||||
|
self.logger.info(f"heirs: {self.heirs}")
|
||||||
|
return {}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
self.logger.info(f"Exception build_will: {e}")
|
||||||
raise e
|
raise e
|
||||||
pass
|
pass
|
||||||
return self.willitems
|
return self.willitems
|
||||||
@@ -1577,7 +1589,7 @@ class BalWizardDialog(BalDialog):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def on_next_we(self):
|
def on_next_we(self):
|
||||||
close_window = BalBuildWillDialog(self.bal_window, self)
|
close_window = BalBuildWillDialog(self.bal_window)
|
||||||
close_window.build_will_task()
|
close_window.build_will_task()
|
||||||
self.close()
|
self.close()
|
||||||
# self.next_widget(BalWizardLocktimeAndFeeWidget(self.bal_window,self,self.on_next_locktimeandfee,self.on_next_wedonwload,self.on_next_wedonwload.on_cancel_heir))
|
# self.next_widget(BalWizardLocktimeAndFeeWidget(self.bal_window,self,self.on_next_locktimeandfee,self.on_next_wedonwload,self.on_next_wedonwload.on_cancel_heir))
|
||||||
@@ -1681,13 +1693,13 @@ class BalWizardHeirsWidget(BalWizardWidget):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def get_content(self):
|
def get_content(self):
|
||||||
self.heirs_list = HeirList(self.bal_window, self.parent)
|
self.heirs_list = HeirList(self.bal_window, self)
|
||||||
button_add = QPushButton(_("Add"))
|
button_add = QPushButton(_("Add"))
|
||||||
button_add.clicked.connect(self.add_heir)
|
button_add.clicked.connect(self.add_heir)
|
||||||
button_import = QPushButton(_("Import"))
|
button_import = QPushButton(_("Import"))
|
||||||
button_import.clicked.connect(self.import_from_file)
|
button_import.clicked.connect(self.import_from_file)
|
||||||
button_export = QPushButton(_("Export"))
|
button_export = QPushButton(_("Export"))
|
||||||
button_import.clicked.connect(self.export_to_file)
|
button_export.clicked.connect(self.export_to_file)
|
||||||
widget = QWidget()
|
widget = QWidget()
|
||||||
vbox = QVBoxLayout(widget)
|
vbox = QVBoxLayout(widget)
|
||||||
vbox.addWidget(self.heirs_list)
|
vbox.addWidget(self.heirs_list)
|
||||||
@@ -1759,7 +1771,9 @@ class BalWizardWEDownloadWidget(BalWizardWidget):
|
|||||||
|
|
||||||
def on_success(willexecutors):
|
def on_success(willexecutors):
|
||||||
self.bal_window.willexecutors.update(willexecutors)
|
self.bal_window.willexecutors.update(willexecutors)
|
||||||
self.bal_window.ping_willexecutors(self.bal_window.willexecutors)
|
self.bal_window.ping_willexecutors(
|
||||||
|
self.bal_window.willexecutors, False
|
||||||
|
)
|
||||||
if index < 1:
|
if index < 1:
|
||||||
for we in self.bal_window.willexecutors:
|
for we in self.bal_window.willexecutors:
|
||||||
if self.bal_window.willexecutors[we]["status"] == 200:
|
if self.bal_window.willexecutors[we]["status"] == 200:
|
||||||
@@ -1820,6 +1834,7 @@ class BalWizardLocktimeAndFeeWidget(BalWizardWidget):
|
|||||||
widget = QWidget()
|
widget = QWidget()
|
||||||
self.heir_locktime = HeirsLockTimeEdit(widget, 0)
|
self.heir_locktime = HeirsLockTimeEdit(widget, 0)
|
||||||
will_settings = self.bal_window.bal_plugin.WILL_SETTINGS.get()
|
will_settings = self.bal_window.bal_plugin.WILL_SETTINGS.get()
|
||||||
|
will_settings = self.bal_window.will_settings
|
||||||
self.heir_locktime.set_locktime(will_settings["locktime"])
|
self.heir_locktime.set_locktime(will_settings["locktime"])
|
||||||
|
|
||||||
def on_heir_locktime():
|
def on_heir_locktime():
|
||||||
@@ -2023,11 +2038,15 @@ class bal_checkbox(QCheckBox):
|
|||||||
|
|
||||||
class BalBuildWillDialog(BalDialog):
|
class BalBuildWillDialog(BalDialog):
|
||||||
updatemessage = pyqtSignal()
|
updatemessage = pyqtSignal()
|
||||||
|
COLOR_WARNING='#cfa808'
|
||||||
|
COLOR_ERROR='#ff0000'
|
||||||
|
COLOR_OK='#05ad05'
|
||||||
|
|
||||||
def __init__(self, bal_window, parent=None):
|
def __init__(self, bal_window, parent=None):
|
||||||
if not parent:
|
if not parent:
|
||||||
parent = bal_window.window
|
parent = bal_window.window
|
||||||
BalDialog.__init__(self, parent, bal_window.bal_plugin, "Building Will")
|
BalDialog.__init__(self, parent, bal_window.bal_plugin, "Building Will")
|
||||||
|
self.parent = parent
|
||||||
self.updatemessage.connect(self.update)
|
self.updatemessage.connect(self.update)
|
||||||
self.bal_window = bal_window
|
self.bal_window = bal_window
|
||||||
self.message_label = QLabel("Building Will:")
|
self.message_label = QLabel("Building Will:")
|
||||||
@@ -2078,25 +2097,24 @@ class BalBuildWillDialog(BalDialog):
|
|||||||
self.bal_window.window.wallet.dust_threshold(),
|
self.bal_window.window.wallet.dust_threshold(),
|
||||||
)
|
)
|
||||||
_logger.debug("variables ok")
|
_logger.debug("variables ok")
|
||||||
self.msg_set_status("checking variables:", varrow,"Ok")
|
self.msg_set_status("checking variables:", varrow, "Ok",self.COLOR_OK)
|
||||||
except AmountException:
|
except AmountException:
|
||||||
self.msg_set_status(
|
self.msg_set_status(
|
||||||
"checking variables",
|
"checking variables",
|
||||||
varrow,
|
varrow,
|
||||||
'<font color="#ff0000">'
|
_(
|
||||||
+ _(
|
|
||||||
"In the inheritance process, "
|
"In the inheritance process, "
|
||||||
+ "the entire wallet will always be fully emptied. \n"
|
+ "the entire wallet will always be fully emptied. \n"
|
||||||
+ "Your settings require an adjustment of the amounts"
|
+ "Your settings require an adjustment of the amounts"
|
||||||
)
|
),
|
||||||
+ "</font>",
|
self.COLOR_WARNING
|
||||||
)
|
)
|
||||||
|
|
||||||
self.msg_set_checking()
|
self.msg_set_checking()
|
||||||
have_to_build = False
|
have_to_build = False
|
||||||
try:
|
try:
|
||||||
self.bal_window.check_will()
|
self.bal_window.check_will()
|
||||||
self.msg_set_checking("Ok")
|
self.msg_set_checking(self.msg_ok())
|
||||||
except WillExpiredException:
|
except WillExpiredException:
|
||||||
_logger.debug("expired")
|
_logger.debug("expired")
|
||||||
self.msg_set_checking("Expired")
|
self.msg_set_checking("Expired")
|
||||||
@@ -2108,7 +2126,7 @@ class BalBuildWillDialog(BalDialog):
|
|||||||
_logger.debug("no heirs")
|
_logger.debug("no heirs")
|
||||||
self.msg_set_checking("No Heirs")
|
self.msg_set_checking("No Heirs")
|
||||||
except NotCompleteWillException as e:
|
except NotCompleteWillException as e:
|
||||||
_logger.debug("not complete", e)
|
_logger.debug(f"not complete {e} true")
|
||||||
message = False
|
message = False
|
||||||
have_to_build = True
|
have_to_build = True
|
||||||
if isinstance(e, HeirChangeException):
|
if isinstance(e, HeirChangeException):
|
||||||
@@ -2122,7 +2140,7 @@ class BalBuildWillDialog(BalDialog):
|
|||||||
elif isinstance(e, HeirNotFoundException):
|
elif isinstance(e, HeirNotFoundException):
|
||||||
message = "Heir not found"
|
message = "Heir not found"
|
||||||
if message:
|
if message:
|
||||||
_logger.debug("message")
|
_logger.debug(f"message: {message}")
|
||||||
self.msg_set_checking(message)
|
self.msg_set_checking(message)
|
||||||
else:
|
else:
|
||||||
self.msg_set_checking("New")
|
self.msg_set_checking("New")
|
||||||
@@ -2130,14 +2148,39 @@ class BalBuildWillDialog(BalDialog):
|
|||||||
if have_to_build:
|
if have_to_build:
|
||||||
self.msg_set_building()
|
self.msg_set_building()
|
||||||
try:
|
try:
|
||||||
self.bal_window.build_will()
|
if not self.bal_window.build_will():
|
||||||
|
self.msg_set_status(
|
||||||
|
_("Balance is too low. No transaction was built"),None,_("Skipped"),self.COLOR_ERROR
|
||||||
|
)
|
||||||
|
|
||||||
self.bal_window.check_will()
|
self.bal_window.check_will()
|
||||||
for wid in Will.only_valid(self.bal_window.willitems):
|
for wid in Will.only_valid(self.bal_window.willitems):
|
||||||
self.bal_window.wallet.set_label(wid, "BAL Transaction")
|
self.bal_window.wallet.set_label(wid, "BAL Transaction")
|
||||||
self.msg_set_building("Ok")
|
self.msg_set_building(self.msg_ok())
|
||||||
|
except WillExecutorNotPresent as e:
|
||||||
|
self.msg_set_status(
|
||||||
|
_("Will-Executor excluded"),
|
||||||
|
None,
|
||||||
|
_("Skipped"),
|
||||||
|
self.COLOR_ERROR
|
||||||
|
)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.msg_set_building(self.msg_error(e))
|
self.msg_set_building(self.msg_error(e))
|
||||||
return False, None
|
return False, None
|
||||||
|
|
||||||
|
excluded_heirs = []
|
||||||
|
for wid in Will.only_valid(self.bal_window.willitems):
|
||||||
|
heirs = self.bal_window.willitems[wid].heirs
|
||||||
|
for hid, heir in heirs.items():
|
||||||
|
if "DUST" in str(heir[HEIR_REAL_AMOUNT]):
|
||||||
|
self.msg_set_status(
|
||||||
|
f'{hid},{heir[HEIR_DUST_AMOUNT]} is DUST',
|
||||||
|
None,
|
||||||
|
f"Excluded from will {wid}",
|
||||||
|
self.COLOR_WARNING
|
||||||
|
)
|
||||||
|
|
||||||
have_to_sign = False
|
have_to_sign = False
|
||||||
for wid in Will.only_valid(self.bal_window.willitems):
|
for wid in Will.only_valid(self.bal_window.willitems):
|
||||||
if not self.bal_window.willitems[wid].get_status("COMPLETE"):
|
if not self.bal_window.willitems[wid].get_status("COMPLETE"):
|
||||||
@@ -2171,7 +2214,7 @@ class BalBuildWillDialog(BalDialog):
|
|||||||
txid = self.network.run_from_another_thread(
|
txid = self.network.run_from_another_thread(
|
||||||
self.network.broadcast_transaction(tx, timeout=120), timeout=120
|
self.network.broadcast_transaction(tx, timeout=120), timeout=120
|
||||||
)
|
)
|
||||||
self.msg_set_invalidating("Ok")
|
self.msg_set_invalidating(self.msg_ok())
|
||||||
if not txid:
|
if not txid:
|
||||||
_logger.debug(f"should not be none txid: {txid}")
|
_logger.debug(f"should not be none txid: {txid}")
|
||||||
|
|
||||||
@@ -2267,6 +2310,7 @@ class BalBuildWillDialog(BalDialog):
|
|||||||
def on_error(self, error):
|
def on_error(self, error):
|
||||||
_logger.error(error)
|
_logger.error(error)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def on_success_phase1(self, result):
|
def on_success_phase1(self, result):
|
||||||
self.have_to_sign, tx = list(result)
|
self.have_to_sign, tx = list(result)
|
||||||
_logger.debug("have to sign {}".format(self.have_to_sign))
|
_logger.debug("have to sign {}".format(self.have_to_sign))
|
||||||
@@ -2327,7 +2371,7 @@ class BalBuildWillDialog(BalDialog):
|
|||||||
for txid, tx in txs.items():
|
for txid, tx in txs.items():
|
||||||
self.bal_window.willitems[txid].tx = copy.deepcopy(tx)
|
self.bal_window.willitems[txid].tx = copy.deepcopy(tx)
|
||||||
self.bal_window.save_willitems()
|
self.bal_window.save_willitems()
|
||||||
self.msg_set_signing("Ok")
|
self.msg_set_signing(self.msg_ok())
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.msg_set_signing(self.msg_error(e))
|
self.msg_set_signing(self.msg_error(e))
|
||||||
|
|
||||||
@@ -2342,11 +2386,11 @@ class BalBuildWillDialog(BalDialog):
|
|||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
self.loop_push()
|
self.loop_push()
|
||||||
self.msg_set_pushing("Ok")
|
self.msg_set_pushing(self.msg_ok())
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.msg_set_pushing(self.msg_error(e))
|
self.msg_set_pushing(self.msg_error(e))
|
||||||
self.msg_edit_row("Ok")
|
self.msg_edit_row(self.msg_ok())
|
||||||
self.wait(5)
|
self.wait(5)
|
||||||
|
|
||||||
def on_error_phase1(self, error):
|
def on_error_phase1(self, error):
|
||||||
@@ -2386,19 +2430,24 @@ class BalBuildWillDialog(BalDialog):
|
|||||||
self.wait_row = self.msg_edit_row(f"Please wait {status}secs", self.wait_row)
|
self.wait_row = self.msg_edit_row(f"Please wait {status}secs", self.wait_row)
|
||||||
|
|
||||||
def msg_error(self, e):
|
def msg_error(self, e):
|
||||||
return "Error: {}".format(e)
|
return "<font color='{}'>{}</font>".format(self.COLOR_ERROR,e)
|
||||||
|
|
||||||
def msg_set_status(self, msg, row=None, status=None):
|
def msg_ok(self, e="Ok"):
|
||||||
|
return "<font color='{}'>{}</font>".format(self.COLOR_OK,e)
|
||||||
|
|
||||||
|
def msg_warning(self, e):
|
||||||
|
return "<font color='{}'>{}</font".format(self.COLOR_WARNING,e)
|
||||||
|
|
||||||
|
def msg_set_status(self, msg, row=None, status=None,color="#000000"):
|
||||||
status = "Wait" if status is None else status
|
status = "Wait" if status is None else status
|
||||||
line = "{}:\t{}".format(_(msg), status)
|
line = "<font color={}>{}:\t{}</font>".format(color,_(msg), status)
|
||||||
return self.msg_edit_row(line, row)
|
return self.msg_edit_row(line, row)
|
||||||
|
|
||||||
|
|
||||||
def ask_password(self, msg=None):
|
def ask_password(self, msg=None):
|
||||||
self.password = self.bal_window.get_wallet_password(msg, parent=self)
|
self.password = self.bal_window.get_wallet_password(msg, parent=self)
|
||||||
|
|
||||||
def msg_edit_row(self, line, row=None):
|
def msg_edit_row(self, line, row=None):
|
||||||
_logger.debug(f"{row},{line}")
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.labels[row] = line
|
self.labels[row] = line
|
||||||
except Exception:
|
except Exception:
|
||||||
@@ -2511,6 +2560,10 @@ class HeirList(MyTreeView, MessageBoxMixin):
|
|||||||
except Exception:
|
except Exception:
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
|
def delete_heirs(self,selected_keys):
|
||||||
|
self.bal_window.delete_heirs(selected_keys)
|
||||||
|
self.update()
|
||||||
|
|
||||||
def create_menu(self, position):
|
def create_menu(self, position):
|
||||||
menu = QMenu()
|
menu = QMenu()
|
||||||
idx = self.indexAt(position)
|
idx = self.indexAt(position)
|
||||||
@@ -2539,7 +2592,7 @@ class HeirList(MyTreeView, MessageBoxMixin):
|
|||||||
lambda p=persistent: self.edit(QModelIndex(p)),
|
lambda p=persistent: self.edit(QModelIndex(p)),
|
||||||
)
|
)
|
||||||
menu.addAction(
|
menu.addAction(
|
||||||
_("Delete"), lambda: self.bal_window.delete_heirs(selected_keys)
|
_("Delete"), lambda: self.delete_heirs(selected_keys)
|
||||||
)
|
)
|
||||||
menu.exec(self.viewport().mapToGlobal(position))
|
menu.exec(self.viewport().mapToGlobal(position))
|
||||||
|
|
||||||
@@ -2550,8 +2603,6 @@ class HeirList(MyTreeView, MessageBoxMixin):
|
|||||||
# selected_keys.append(sel_key)
|
# selected_keys.append(sel_key)
|
||||||
# return selected_keys
|
# return selected_keys
|
||||||
def update(self):
|
def update(self):
|
||||||
if self.maybe_defer_update():
|
|
||||||
return
|
|
||||||
current_key = self.get_role_data_for_current_item(
|
current_key = self.get_role_data_for_current_item(
|
||||||
col=self.Columns.NAME, role=self.ROLE_HEIR_KEY
|
col=self.Columns.NAME, role=self.ROLE_HEIR_KEY
|
||||||
)
|
)
|
||||||
@@ -2571,9 +2622,15 @@ class HeirList(MyTreeView, MessageBoxMixin):
|
|||||||
items[self.Columns.NAME].setEditable(True)
|
items[self.Columns.NAME].setEditable(True)
|
||||||
items[self.Columns.ADDRESS].setEditable(True)
|
items[self.Columns.ADDRESS].setEditable(True)
|
||||||
items[self.Columns.AMOUNT].setEditable(True)
|
items[self.Columns.AMOUNT].setEditable(True)
|
||||||
items[self.Columns.NAME].setData(key, self.ROLE_HEIR_KEY + 1)
|
items[self.Columns.NAME].setData(
|
||||||
items[self.Columns.ADDRESS].setData(key, self.ROLE_HEIR_KEY + 2)
|
key, self.ROLE_HEIR_KEY + self.Columns.NAME
|
||||||
items[self.Columns.AMOUNT].setData(key, self.ROLE_HEIR_KEY + 3)
|
)
|
||||||
|
items[self.Columns.ADDRESS].setData(
|
||||||
|
key, self.ROLE_HEIR_KEY + self.Columns.ADDRESS
|
||||||
|
)
|
||||||
|
items[self.Columns.AMOUNT].setData(
|
||||||
|
key, self.ROLE_HEIR_KEY + self.Columns.AMOUNT
|
||||||
|
)
|
||||||
|
|
||||||
row_count = self.model().rowCount()
|
row_count = self.model().rowCount()
|
||||||
self.model().insertRow(row_count, items)
|
self.model().insertRow(row_count, items)
|
||||||
@@ -2592,9 +2649,8 @@ class HeirList(MyTreeView, MessageBoxMixin):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def get_edit_key_from_coordinate(self, row, col):
|
def get_edit_key_from_coordinate(self, row, col):
|
||||||
return self.get_role_data_from_coordinate(
|
a = self.get_role_data_from_coordinate(row, col, role=self.ROLE_HEIR_KEY + col)
|
||||||
row, col, role=self.ROLE_HEIR_KEY + col + 1
|
return a
|
||||||
)
|
|
||||||
|
|
||||||
def create_toolbar(self, config):
|
def create_toolbar(self, config):
|
||||||
toolbar, menu = self.create_toolbar_with_menu("")
|
toolbar, menu = self.create_toolbar_with_menu("")
|
||||||
@@ -2691,8 +2747,8 @@ class HeirList(MyTreeView, MessageBoxMixin):
|
|||||||
def update_will_settings(self):
|
def update_will_settings(self):
|
||||||
try:
|
try:
|
||||||
self.heir_locktime.set_locktime(self.bal_window.will_settings["locktime"])
|
self.heir_locktime.set_locktime(self.bal_window.will_settings["locktime"])
|
||||||
self.heir_tx_fees.setValue(int(self.bal_window.will_settings["baltx_fees"]))
|
|
||||||
self.heir_threshold.set_locktime(self.bal_window.will_settings["threshold"])
|
self.heir_threshold.set_locktime(self.bal_window.will_settings["threshold"])
|
||||||
|
self.heir_tx_fees.setValue(int(self.bal_window.will_settings["baltx_fees"]))
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
_logger.debug(f"Exception update_will_settings {e}")
|
_logger.debug(f"Exception update_will_settings {e}")
|
||||||
@@ -2737,6 +2793,7 @@ class PreviewList(MyTreeView):
|
|||||||
|
|
||||||
self.wallet = bal_window.window.wallet
|
self.wallet = bal_window.window.wallet
|
||||||
self.setModel(QStandardItemModel(self))
|
self.setModel(QStandardItemModel(self))
|
||||||
|
self.sortByColumn(self.Columns.LOCKTIME, Qt.SortOrder.AscendingOrder)
|
||||||
self.setSortingEnabled(True)
|
self.setSortingEnabled(True)
|
||||||
self.std_model = self.model()
|
self.std_model = self.model()
|
||||||
self.config = bal_window.bal_plugin.config
|
self.config = bal_window.bal_plugin.config
|
||||||
@@ -2895,6 +2952,8 @@ class PreviewList(MyTreeView):
|
|||||||
tmp = self.replace(set_current, current_key, txid, bal_tx)
|
tmp = self.replace(set_current, current_key, txid, bal_tx)
|
||||||
if tmp:
|
if tmp:
|
||||||
set_current = tmp
|
set_current = tmp
|
||||||
|
self.sortByColumn(self.Columns.LOCKTIME, Qt.SortOrder.AscendingOrder)
|
||||||
|
self.setSortingEnabled(True)
|
||||||
|
|
||||||
def create_toolbar(self, config):
|
def create_toolbar(self, config):
|
||||||
toolbar, menu = self.create_toolbar_with_menu("")
|
toolbar, menu = self.create_toolbar_with_menu("")
|
||||||
@@ -2913,6 +2972,9 @@ class PreviewList(MyTreeView):
|
|||||||
display = QPushButton(_("Display"))
|
display = QPushButton(_("Display"))
|
||||||
display.clicked.connect(self.bal_window.preview_modal_dialog)
|
display.clicked.connect(self.bal_window.preview_modal_dialog)
|
||||||
|
|
||||||
|
display = QPushButton(_("Refresh"))
|
||||||
|
display.clicked.connect(self.check)
|
||||||
|
|
||||||
widget = QWidget()
|
widget = QWidget()
|
||||||
hlayout = QHBoxLayout(widget)
|
hlayout = QHBoxLayout(widget)
|
||||||
hlayout.addWidget(wizard)
|
hlayout.addWidget(wizard)
|
||||||
@@ -2954,10 +3016,25 @@ class PreviewList(MyTreeView):
|
|||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def check(self):
|
def check(self):
|
||||||
|
Will.add_willtree(self.bal_window.willitems)
|
||||||
|
all_utxos = self.bal_window.wallet.get_utxos()
|
||||||
|
utxos_list = Will.utxos_strs(all_utxos)
|
||||||
|
Will.check_invalidated(
|
||||||
|
self.bal_window.willitems, utxos_list, self.bal_window.wallet
|
||||||
|
)
|
||||||
|
|
||||||
|
close_window = BalBuildWillDialog(self.bal_window)
|
||||||
|
close_window.build_will_task()
|
||||||
|
|
||||||
will = {}
|
will = {}
|
||||||
for wid, w in self.bal_window.willitems.items():
|
for wid, w in self.bal_window.willitems.items():
|
||||||
if w.get_status("VALID"):
|
if (
|
||||||
|
w.get_status("VALID")
|
||||||
|
and w.get_status("PUSHED")
|
||||||
|
and not w.get_status("CHECKED")
|
||||||
|
):
|
||||||
will[wid] = w
|
will[wid] = w
|
||||||
|
if will:
|
||||||
self.bal_window.check_transactions(will)
|
self.bal_window.check_transactions(will)
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
@@ -2991,6 +3068,10 @@ class PreviewDialog(BalDialog, MessageBoxMixin):
|
|||||||
self.setMinimumSize(1000, 200)
|
self.setMinimumSize(1000, 200)
|
||||||
self.size_label = QLabel()
|
self.size_label = QLabel()
|
||||||
self.transactions_list = PreviewList(self.bal_window, self.will)
|
self.transactions_list = PreviewList(self.bal_window, self.will)
|
||||||
|
|
||||||
|
self.bal_window.init_class_variables()
|
||||||
|
self.check_will()
|
||||||
|
|
||||||
vbox = QVBoxLayout(self)
|
vbox = QVBoxLayout(self)
|
||||||
vbox.addWidget(self.size_label)
|
vbox.addWidget(self.size_label)
|
||||||
vbox.addWidget(self.transactions_list)
|
vbox.addWidget(self.transactions_list)
|
||||||
@@ -3041,14 +3122,6 @@ class PreviewDialog(BalDialog, MessageBoxMixin):
|
|||||||
event.accept()
|
event.accept()
|
||||||
|
|
||||||
|
|
||||||
def read_bal_QIcon(icon_basename: str = DEFAULT_ICON) -> QIcon:
|
|
||||||
return QIcon(icon_path(icon_basename))
|
|
||||||
|
|
||||||
|
|
||||||
def read_bal_QPixmap(icon_basename: str = DEFAULT_ICON) -> QPixmap:
|
|
||||||
return QPixmap(icon_path(icon_basename))
|
|
||||||
|
|
||||||
|
|
||||||
class WillDetailDialog(BalDialog):
|
class WillDetailDialog(BalDialog):
|
||||||
def __init__(self, bal_window):
|
def __init__(self, bal_window):
|
||||||
|
|
||||||
@@ -3246,24 +3319,27 @@ class WillExecutorList(MyTreeView):
|
|||||||
class Columns(MyTreeView.BaseColumnsEnum):
|
class Columns(MyTreeView.BaseColumnsEnum):
|
||||||
SELECTED = enum.auto()
|
SELECTED = enum.auto()
|
||||||
URL = enum.auto()
|
URL = enum.auto()
|
||||||
|
STATUS = enum.auto()
|
||||||
BASE_FEE = enum.auto()
|
BASE_FEE = enum.auto()
|
||||||
INFO = enum.auto()
|
INFO = enum.auto()
|
||||||
ADDRESS = enum.auto()
|
ADDRESS = enum.auto()
|
||||||
STATUS = enum.auto()
|
|
||||||
|
|
||||||
headers = {
|
headers = {
|
||||||
Columns.SELECTED: _(""),
|
Columns.SELECTED: _(""),
|
||||||
Columns.URL: _("Url"),
|
Columns.URL: _("Url"),
|
||||||
|
Columns.STATUS: _("S"),
|
||||||
Columns.BASE_FEE: _("Base fee"),
|
Columns.BASE_FEE: _("Base fee"),
|
||||||
Columns.INFO: _("Info"),
|
Columns.INFO: _("Info"),
|
||||||
Columns.ADDRESS: _("Default Address"),
|
Columns.ADDRESS: _("Default Address"),
|
||||||
Columns.STATUS: _("S"),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ROLE_HEIR_KEY = Qt.ItemDataRole.UserRole + 2000
|
filter_columns = [Columns.URL]
|
||||||
|
|
||||||
|
ROLE_SORT_ORDER = Qt.ItemDataRole.UserRole + 3000
|
||||||
|
ROLE_HEIR_KEY = Qt.ItemDataRole.UserRole + 3001
|
||||||
key_role = ROLE_HEIR_KEY
|
key_role = ROLE_HEIR_KEY
|
||||||
|
|
||||||
def __init__(self, parent: "WillExecutorDialog"):
|
def __init__(self, parent: "WillExecutorWidget"):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
parent=parent,
|
parent=parent,
|
||||||
stretch_column=self.Columns.ADDRESS,
|
stretch_column=self.Columns.ADDRESS,
|
||||||
@@ -3275,7 +3351,12 @@ class WillExecutorList(MyTreeView):
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
|
try:
|
||||||
self.setModel(QStandardItemModel(self))
|
self.setModel(QStandardItemModel(self))
|
||||||
|
self.sortByColumn(self.Columns.SELECTED, Qt.SortOrder.AscendingOrder)
|
||||||
|
self.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
self.setSortingEnabled(True)
|
self.setSortingEnabled(True)
|
||||||
self.std_model = self.model()
|
self.std_model = self.model()
|
||||||
self.config = parent.bal_plugin.config
|
self.config = parent.bal_plugin.config
|
||||||
@@ -3335,7 +3416,8 @@ class WillExecutorList(MyTreeView):
|
|||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def get_edit_key_from_coordinate(self, row, col):
|
def get_edit_key_from_coordinate(self, row, col):
|
||||||
a = self.get_role_data_from_coordinate(row, col, role=self.ROLE_HEIR_KEY + col)
|
role = self.ROLE_HEIR_KEY + col
|
||||||
|
a = self.get_role_data_from_coordinate(row, col, role=role)
|
||||||
return a
|
return a
|
||||||
|
|
||||||
def delete(self, selected_keys):
|
def delete(self, selected_keys):
|
||||||
@@ -3394,16 +3476,33 @@ class WillExecutorList(MyTreeView):
|
|||||||
labels[self.Columns.URL] = url
|
labels[self.Columns.URL] = url
|
||||||
if Willexecutors.is_selected(value):
|
if Willexecutors.is_selected(value):
|
||||||
|
|
||||||
labels[self.Columns.SELECTED] = [read_QIcon_from_bytes(self.parent.bal_plugin.read_file("icons/confirmed.png")),""]
|
labels[self.Columns.SELECTED] = [
|
||||||
|
read_QIcon_from_bytes(
|
||||||
|
self.parent.bal_plugin.read_file("icons/confirmed.png")
|
||||||
|
),
|
||||||
|
"",
|
||||||
|
]
|
||||||
else:
|
else:
|
||||||
labels[self.Columns.SELECTED] = ""
|
labels[self.Columns.SELECTED] = ""
|
||||||
labels[self.Columns.BASE_FEE] = Util.decode_amount(
|
labels[self.Columns.BASE_FEE] = Util.decode_amount(
|
||||||
value.get("base_fee", 0), self.get_decimal_point()
|
value.get("base_fee", 0), self.get_decimal_point()
|
||||||
)
|
)
|
||||||
if str(value.get("status", 0)) == "200":
|
if str(value.get("status", 0)) == "200":
|
||||||
labels[self.Columns.STATUS] = [read_QIcon_from_bytes(self.parent.bal_plugin.read_file("icons/status_connected.png")),""]
|
labels[self.Columns.STATUS] = [
|
||||||
|
read_QIcon_from_bytes(
|
||||||
|
self.parent.bal_plugin.read_file(
|
||||||
|
"icons/status_connected.png"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"",
|
||||||
|
]
|
||||||
else:
|
else:
|
||||||
labels[self.Columns.STATUS] = [read_QIcon_from_bytes(self.parent.bal_plugin.read_file("icons/unconfirmed.png")),""]
|
labels[self.Columns.STATUS] = [
|
||||||
|
read_QIcon_from_bytes(
|
||||||
|
self.parent.bal_plugin.read_file("icons/unconfirmed.png")
|
||||||
|
),
|
||||||
|
"",
|
||||||
|
]
|
||||||
labels[self.Columns.ADDRESS] = str(value.get("address", ""))
|
labels[self.Columns.ADDRESS] = str(value.get("address", ""))
|
||||||
labels[self.Columns.INFO] = str(value.get("info", ""))
|
labels[self.Columns.INFO] = str(value.get("info", ""))
|
||||||
|
|
||||||
@@ -3423,17 +3522,25 @@ class WillExecutorList(MyTreeView):
|
|||||||
items[self.Columns.BASE_FEE].setEditable(True)
|
items[self.Columns.BASE_FEE].setEditable(True)
|
||||||
items[self.Columns.STATUS].setEditable(False)
|
items[self.Columns.STATUS].setEditable(False)
|
||||||
|
|
||||||
items[self.Columns.URL].setData(url, self.ROLE_HEIR_KEY + 1)
|
items[self.Columns.URL].setData(
|
||||||
items[self.Columns.BASE_FEE].setData(url, self.ROLE_HEIR_KEY + 2)
|
url, self.ROLE_HEIR_KEY + self.Columns.URL
|
||||||
items[self.Columns.INFO].setData(url, self.ROLE_HEIR_KEY + 3)
|
)
|
||||||
items[self.Columns.ADDRESS].setData(url, self.ROLE_HEIR_KEY + 4)
|
items[self.Columns.BASE_FEE].setData(
|
||||||
|
url, self.ROLE_HEIR_KEY + self.Columns.BASE_FEE
|
||||||
|
)
|
||||||
|
items[self.Columns.INFO].setData(
|
||||||
|
url, self.ROLE_HEIR_KEY + self.Columns.INFO
|
||||||
|
)
|
||||||
|
items[self.Columns.ADDRESS].setData(
|
||||||
|
url, self.ROLE_HEIR_KEY + self.Columns.ADDRESS
|
||||||
|
)
|
||||||
row_count = self.model().rowCount()
|
row_count = self.model().rowCount()
|
||||||
self.model().insertRow(row_count, items)
|
self.model().insertRow(row_count, items)
|
||||||
if url == current_key:
|
if url == current_key:
|
||||||
idx = self.model().index(row_count, self.Columns.NAME)
|
idx = self.model().index(row_count, self.Columns.URL)
|
||||||
set_current = QPersistentModelIndex(idx)
|
set_current = QPersistentModelIndex(idx)
|
||||||
self.set_current_idx(set_current)
|
self.set_current_idx(set_current)
|
||||||
|
self.filter()
|
||||||
self.parent.save_willexecutors()
|
self.parent.save_willexecutors()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -3494,7 +3601,7 @@ class WillExecutorWidget(QWidget, MessageBoxMixin):
|
|||||||
buttonbox.addWidget(b)
|
buttonbox.addWidget(b)
|
||||||
|
|
||||||
vbox.addLayout(buttonbox)
|
vbox.addLayout(buttonbox)
|
||||||
self.willexecutor_list.update()
|
# self.willexecutor_list.update()
|
||||||
|
|
||||||
def add(self):
|
def add(self):
|
||||||
self.willexecutors_list["http://localhost:8080"] = {
|
self.willexecutors_list["http://localhost:8080"] = {
|
||||||
@@ -3526,14 +3633,7 @@ class WillExecutorWidget(QWidget, MessageBoxMixin):
|
|||||||
|
|
||||||
def update_willexecutors(self, wes=None):
|
def update_willexecutors(self, wes=None):
|
||||||
if not wes:
|
if not wes:
|
||||||
self.willexecutors_list = Willexecutors.get_willexecutors(
|
wes = self.willexecutors_list
|
||||||
self.bal_plugin,
|
|
||||||
update=True,
|
|
||||||
bal_window=self.bal_window,
|
|
||||||
force=True,
|
|
||||||
task=self,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
self.bal_window.ping_willexecutors(wes, self.parent)
|
self.bal_window.ping_willexecutors(wes, self.parent)
|
||||||
self.willexecutors_list.update(wes)
|
self.willexecutors_list.update(wes)
|
||||||
self.willexecutor_list.update()
|
self.willexecutor_list.update()
|
||||||
|
|||||||
8
util.py
8
util.py
@@ -84,9 +84,11 @@ class Util:
|
|||||||
if Util.is_perc(amount):
|
if Util.is_perc(amount):
|
||||||
return amount
|
return amount
|
||||||
else:
|
else:
|
||||||
num = 8 - decimal_point
|
basestr = "{{:0.{}f}}".format(decimal_point)
|
||||||
basestr = "{{:0{}.{}f}}".format(num, num)
|
try:
|
||||||
return "{:08.8f}".format(float(amount) / pow(10, decimal_point))
|
return basestr.format(float(amount) / pow(10, decimal_point))
|
||||||
|
except:
|
||||||
|
return str(amount)
|
||||||
|
|
||||||
def is_perc(value):
|
def is_perc(value):
|
||||||
try:
|
try:
|
||||||
|
|||||||
49
will.py
49
will.py
@@ -28,7 +28,6 @@ _logger = get_logger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class Will:
|
class Will:
|
||||||
# return an array with the list of children
|
|
||||||
def get_children(will, willid):
|
def get_children(will, willid):
|
||||||
out = []
|
out = []
|
||||||
for _id in will:
|
for _id in will:
|
||||||
@@ -82,8 +81,6 @@ class Will:
|
|||||||
for txin in will[wid].tx.inputs():
|
for txin in will[wid].tx.inputs():
|
||||||
txid = txin.prevout.txid.hex()
|
txid = txin.prevout.txid.hex()
|
||||||
if txid in will:
|
if txid in will:
|
||||||
# print(will[txid].tx.outputs())
|
|
||||||
# print(txin.prevout.out_idx)
|
|
||||||
change = will[txid].tx.outputs()[txin.prevout.out_idx]
|
change = will[txid].tx.outputs()[txin.prevout.out_idx]
|
||||||
txin._trusted_value_sats = change.value
|
txin._trusted_value_sats = change.value
|
||||||
try:
|
try:
|
||||||
@@ -155,6 +152,16 @@ class Will:
|
|||||||
inp._TxInput__value_sats = change.value
|
inp._TxInput__value_sats = change.value
|
||||||
return inp
|
return inp
|
||||||
|
|
||||||
|
"""
|
||||||
|
in questa situazione sono presenti due transazioni con id differente(quindi transazioni differenti)
|
||||||
|
per prima cosa controllo il locktime
|
||||||
|
se il locktime della nuova transazione e' maggiore del locktime della vecchia transazione, allora
|
||||||
|
confronto gli eredi, per locktime se corrispondono controllo i willexecutor
|
||||||
|
se hanno la stessa url ma le fee vecchie sono superiori alle fee nuove, allora anticipare.
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
def check_anticipate(ow: "WillItem", nw: "WillItem"):
|
def check_anticipate(ow: "WillItem", nw: "WillItem"):
|
||||||
anticipate = Util.anticipate_locktime(ow.tx.locktime, days=1)
|
anticipate = Util.anticipate_locktime(ow.tx.locktime, days=1)
|
||||||
if int(nw.tx.locktime) >= int(anticipate):
|
if int(nw.tx.locktime) >= int(anticipate):
|
||||||
@@ -258,7 +265,7 @@ class Will:
|
|||||||
to_append = {}
|
to_append = {}
|
||||||
new_inputs = Will.get_all_inputs(will, only_valid=True)
|
new_inputs = Will.get_all_inputs(will, only_valid=True)
|
||||||
for nid, nwi in will.items():
|
for nid, nwi in will.items():
|
||||||
if nwi.search_anticipate(new_inputs) or nwi.search_anticipate(old_inputs):
|
if nwi.search_anticipate(new_inputs):
|
||||||
if nid != nwi.tx.txid():
|
if nid != nwi.tx.txid():
|
||||||
redo = True
|
redo = True
|
||||||
to_delete.append(nid)
|
to_delete.append(nid)
|
||||||
@@ -268,6 +275,17 @@ class Will:
|
|||||||
Will.change_input(
|
Will.change_input(
|
||||||
will, nid, i, outputs[i], new_inputs, to_delete, to_append
|
will, nid, i, outputs[i], new_inputs, to_delete, to_append
|
||||||
)
|
)
|
||||||
|
if nwi.search_anticipate(old_inputs):
|
||||||
|
if nid != nwi.tx.txid():
|
||||||
|
redo = True
|
||||||
|
|
||||||
|
to_delete.append(nid)
|
||||||
|
to_append[nwi.tx.txid()] = nwi
|
||||||
|
outputs = nwi.tx.outputs()
|
||||||
|
for i in range(0, len(outputs)):
|
||||||
|
Will.change_input(
|
||||||
|
will, nid, i, outputs[i], new_inputs, to_delete, to_append
|
||||||
|
)
|
||||||
|
|
||||||
for w in to_delete:
|
for w in to_delete:
|
||||||
try:
|
try:
|
||||||
@@ -277,6 +295,7 @@ class Will:
|
|||||||
for k, w in to_append.items():
|
for k, w in to_append.items():
|
||||||
will[k] = w
|
will[k] = w
|
||||||
if redo:
|
if redo:
|
||||||
|
|
||||||
Will.search_anticipate_rec(will, old_inputs)
|
Will.search_anticipate_rec(will, old_inputs)
|
||||||
|
|
||||||
def update_will(old_will, new_will):
|
def update_will(old_will, new_will):
|
||||||
@@ -286,7 +305,6 @@ class Will:
|
|||||||
# check if the new input is already spent by other transaction
|
# check if the new input is already spent by other transaction
|
||||||
# if it is use the same locktime, or anticipate.
|
# if it is use the same locktime, or anticipate.
|
||||||
Will.search_anticipate_rec(new_will, all_old_inputs)
|
Will.search_anticipate_rec(new_will, all_old_inputs)
|
||||||
|
|
||||||
other_inputs = Will.get_all_inputs(old_will, {})
|
other_inputs = Will.get_all_inputs(old_will, {})
|
||||||
try:
|
try:
|
||||||
Will.normalize_will(new_will, others_inputs=other_inputs)
|
Will.normalize_will(new_will, others_inputs=other_inputs)
|
||||||
@@ -421,7 +439,11 @@ class Will:
|
|||||||
# check if transactions are stil valid tecnically valid
|
# check if transactions are stil valid tecnically valid
|
||||||
def check_invalidated(willtree, utxos_list, wallet):
|
def check_invalidated(willtree, utxos_list, wallet):
|
||||||
for wid, w in willtree.items():
|
for wid, w in willtree.items():
|
||||||
if not w.father:
|
if (
|
||||||
|
not w.father
|
||||||
|
or willtree[w.father].get_status("CONFIRMED")
|
||||||
|
or willtree[w.father].get_status("PENDING")
|
||||||
|
):
|
||||||
for inp in w.tx.inputs():
|
for inp in w.tx.inputs():
|
||||||
inp_str = Util.utxo_to_str(inp)
|
inp_str = Util.utxo_to_str(inp)
|
||||||
if not inp_str in utxos_list:
|
if not inp_str in utxos_list:
|
||||||
@@ -448,7 +470,7 @@ class Will:
|
|||||||
Will.reflect_to_children(wc)
|
Will.reflect_to_children(wc)
|
||||||
|
|
||||||
def check_amounts(heirs, willexecutors, all_utxos, timestamp_to_check, dust):
|
def check_amounts(heirs, willexecutors, all_utxos, timestamp_to_check, dust):
|
||||||
fixed_heirs, fixed_amount, perc_heirs, perc_amount = (
|
fixed_heirs, fixed_amount, perc_heirs, perc_amount,fixed_amount_with_dust = (
|
||||||
heirs.fixed_percent_lists_amount(timestamp_to_check, dust, reverse=True)
|
heirs.fixed_percent_lists_amount(timestamp_to_check, dust, reverse=True)
|
||||||
)
|
)
|
||||||
wallet_balance = 0
|
wallet_balance = 0
|
||||||
@@ -598,9 +620,9 @@ class Will:
|
|||||||
heirs_found[wheir] = count + 1
|
heirs_found[wheir] = count + 1
|
||||||
else:
|
else:
|
||||||
_logger.debug(
|
_logger.debug(
|
||||||
"heir not present transaction is not valid:", wid, w
|
f"heir not present transaction is not valid:{wheir} {wid}, {w}"
|
||||||
)
|
)
|
||||||
continue
|
|
||||||
if willexecutor := w.we:
|
if willexecutor := w.we:
|
||||||
count = willexecutors_found.get(willexecutor["url"], 0)
|
count = willexecutors_found.get(willexecutor["url"], 0)
|
||||||
if Util.cmp_willexecutor(
|
if Util.cmp_willexecutor(
|
||||||
@@ -612,6 +634,7 @@ class Will:
|
|||||||
no_willexecutor += 1
|
no_willexecutor += 1
|
||||||
count_heirs = 0
|
count_heirs = 0
|
||||||
for h in heirs:
|
for h in heirs:
|
||||||
|
|
||||||
if Util.parse_locktime_string(heirs[h][2]) >= check_date:
|
if Util.parse_locktime_string(heirs[h][2]) >= check_date:
|
||||||
count_heirs += 1
|
count_heirs += 1
|
||||||
if not h in heirs_found:
|
if not h in heirs_found:
|
||||||
@@ -621,7 +644,6 @@ class Will:
|
|||||||
raise NoHeirsException("there are not valid heirs")
|
raise NoHeirsException("there are not valid heirs")
|
||||||
if self_willexecutor and no_willexecutor == 0:
|
if self_willexecutor and no_willexecutor == 0:
|
||||||
raise NoWillExecutorNotPresent("Backup tx")
|
raise NoWillExecutorNotPresent("Backup tx")
|
||||||
|
|
||||||
for url, we in willexecutors.items():
|
for url, we in willexecutors.items():
|
||||||
if Willexecutors.is_selected(we):
|
if Willexecutors.is_selected(we):
|
||||||
if not url in willexecutors_found:
|
if not url in willexecutors_found:
|
||||||
@@ -632,7 +654,6 @@ class Will:
|
|||||||
|
|
||||||
|
|
||||||
class WillItem(Logger):
|
class WillItem(Logger):
|
||||||
|
|
||||||
STATUS_DEFAULT = {
|
STATUS_DEFAULT = {
|
||||||
"ANTICIPATED": ["Anticipated", False],
|
"ANTICIPATED": ["Anticipated", False],
|
||||||
"BROADCASTED": ["Broadcasted", False],
|
"BROADCASTED": ["Broadcasted", False],
|
||||||
@@ -662,7 +683,7 @@ class WillItem(Logger):
|
|||||||
if self.STATUS[status][1] == bool(value):
|
if self.STATUS[status][1] == bool(value):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
self.status += "." + ("NOT " if not value else "" + _(self.STATUS[status][0]))
|
self.status += "." + (("NOT " if not value else "") + _(self.STATUS[status][0]))
|
||||||
self.STATUS[status][1] = bool(value)
|
self.STATUS[status][1] = bool(value)
|
||||||
if value:
|
if value:
|
||||||
if status in ["INVALIDATED", "REPLACED", "CONFIRMED", "PENDING"]:
|
if status in ["INVALIDATED", "REPLACED", "CONFIRMED", "PENDING"]:
|
||||||
@@ -867,3 +888,7 @@ class PercAmountException(AmountException):
|
|||||||
|
|
||||||
class FixedAmountException(AmountException):
|
class FixedAmountException(AmountException):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def test_check_invalidated():
|
||||||
|
Will.check_invalidated(will, utxos_list, wallet)
|
||||||
|
|||||||
@@ -35,34 +35,36 @@ class Willexecutors:
|
|||||||
continue
|
continue
|
||||||
Willexecutors.initialize_willexecutor(willexecutors[w], w)
|
Willexecutors.initialize_willexecutor(willexecutors[w], w)
|
||||||
for w in to_del:
|
for w in to_del:
|
||||||
_logger.error("error Willexecutor to delete type:{} ", type(willexecutor[w]),w)
|
_logger.error(
|
||||||
|
"error Willexecutor to delete type:{} ", type(willexecutor[w]), w
|
||||||
|
)
|
||||||
del willexecutors[w]
|
del willexecutors[w]
|
||||||
bal = bal_plugin.WILLEXECUTORS.default.get(constants.net.NET_NAME, {})
|
bal = bal_plugin.WILLEXECUTORS.default.get(constants.net.NET_NAME, {})
|
||||||
for bal_url, bal_executor in bal.items():
|
for bal_url, bal_executor in bal.items():
|
||||||
if not bal_url in willexecutors:
|
if not bal_url in willexecutors:
|
||||||
_logger.debug(f"force add {bal_url} willexecutor")
|
_logger.debug(f"force add {bal_url} willexecutor")
|
||||||
willexecutors[bal_url] = bal_executor
|
willexecutors[bal_url] = bal_executor
|
||||||
if update:
|
# if update:
|
||||||
found = False
|
# found = False
|
||||||
for url, we in willexecutors.items():
|
# for url, we in willexecutors.items():
|
||||||
if Willexecutors.is_selected(we):
|
# if Willexecutors.is_selected(we):
|
||||||
found = True
|
# found = True
|
||||||
if found or force:
|
# if found or force:
|
||||||
if bal_plugin.PING_WILLEXECUTORS.get() or force:
|
# if bal_plugin.PING_WILLEXECUTORS.get() or force:
|
||||||
ping_willexecutors = True
|
# ping_willexecutors = True
|
||||||
if bal_plugin.ASK_PING_WILLEXECUTORS.get() and not force:
|
# if bal_plugin.ASK_PING_WILLEXECUTORS.get() and not force:
|
||||||
if bal_window:
|
# if bal_window:
|
||||||
ping_willexecutors = bal_window.window.question(
|
# ping_willexecutors = bal_window.window.question(
|
||||||
_(
|
# _(
|
||||||
"Contact willexecutors servers to update payment informations?"
|
# "Contact willexecutors servers to update payment informations?"
|
||||||
)
|
# )
|
||||||
)
|
# )
|
||||||
|
|
||||||
if ping_willexecutors:
|
# if ping_willexecutors:
|
||||||
if task:
|
# if task:
|
||||||
bal_window.ping_willexecutors(willexecutors, task)
|
# bal_window.ping_willexecutors(willexecutors, task)
|
||||||
else:
|
# else:
|
||||||
bal_window.ping_willexecutors_task(willexecutors)
|
# bal_window.ping_willexecutors_task(willexecutors)
|
||||||
w_sorted = dict(
|
w_sorted = dict(
|
||||||
sorted(
|
sorted(
|
||||||
willexecutors.items(), key=lambda w: w[1].get("sort", 0), reverse=True
|
willexecutors.items(), key=lambda w: w[1].get("sort", 0), reverse=True
|
||||||
@@ -119,7 +121,7 @@ class Willexecutors:
|
|||||||
def send_request(method, url, data=None, *, timeout=10):
|
def send_request(method, url, data=None, *, timeout=10):
|
||||||
network = Network.get_instance()
|
network = Network.get_instance()
|
||||||
if not network:
|
if not network:
|
||||||
raise ErrorConnectingServer("You are offline.")
|
raise Exception("You are offline.")
|
||||||
_logger.debug(f"<-- {method} {url} {data}")
|
_logger.debug(f"<-- {method} {url} {data}")
|
||||||
headers = {}
|
headers = {}
|
||||||
headers["user-agent"] = f"BalPlugin v:{BalPlugin.version()}"
|
headers["user-agent"] = f"BalPlugin v:{BalPlugin.version()}"
|
||||||
@@ -170,8 +172,7 @@ class Willexecutors:
|
|||||||
def push_transactions_to_willexecutor(willexecutor):
|
def push_transactions_to_willexecutor(willexecutor):
|
||||||
out = True
|
out = True
|
||||||
try:
|
try:
|
||||||
|
_logger.debug(f"{willexecutor['url']}: {willexecutor['txs']}")
|
||||||
_logger.debug(f"willexecutor['txs']")
|
|
||||||
if w := Willexecutors.send_request(
|
if w := Willexecutors.send_request(
|
||||||
"post",
|
"post",
|
||||||
willexecutor["url"] + "/" + constants.net.NET_NAME + "/pushtxs",
|
willexecutor["url"] + "/" + constants.net.NET_NAME + "/pushtxs",
|
||||||
|
|||||||
Reference in New Issue
Block a user