whitespace (82 files)
This commit is contained in:
parent
62b360bb7d
commit
09e70c4bf3
82 changed files with 236 additions and 363 deletions
|
|
@ -53,8 +53,8 @@ class MMGenAddrType(HiliteStr, InitErrors, MMGenObject):
|
|||
'X': ati('bech32x', 'std', True, 'p2pkh', 'bech32', 'wif', (), 'Cross-chain Bech32 address'),
|
||||
'E': ati('ethereum', 'std', False,'ethereum','p2pkh', 'privkey', ('wallet_passwd',),'Ethereum address'),
|
||||
'Z': ati('zcash_z','zcash_z',False,'zcash_z', 'zcash_z', 'wif', ('viewkey',), 'Zcash z-address'),
|
||||
'M': ati('monero', 'monero', False,'monero', 'monero', 'spendkey',('viewkey','wallet_passwd'),'Monero address'),
|
||||
}
|
||||
'M': ati('monero', 'monero', False,'monero', 'monero', 'spendkey',('viewkey','wallet_passwd'),'Monero address')}
|
||||
|
||||
def __new__(cls, proto, id_str, *, errmsg=None):
|
||||
if isinstance(id_str, cls):
|
||||
return id_str
|
||||
|
|
|
|||
|
|
@ -103,8 +103,7 @@ class TwAddrData(AddrData, metaclass=AsyncInit):
|
|||
self.cfg,
|
||||
self.proto,
|
||||
al_id = al_id,
|
||||
adata = AddrListData(sorted(out[al_id], key=lambda a: a.idx))
|
||||
))
|
||||
adata = AddrListData(sorted(out[al_id], key=lambda a: a.idx))))
|
||||
|
||||
class TwAddrDataWithStore(TwAddrData):
|
||||
|
||||
|
|
@ -112,8 +111,7 @@ class TwAddrDataWithStore(TwAddrData):
|
|||
'multiple_acct_addrs': """
|
||||
ERROR: More than one address found for account: {acct!r}.
|
||||
Your tracking wallet is corrupted!
|
||||
"""
|
||||
}
|
||||
"""}
|
||||
|
||||
async def get_tw_data(self, *, twctl=None):
|
||||
self.cfg._util.vmsg('Getting address data from tracking wallet')
|
||||
|
|
|
|||
|
|
@ -89,8 +89,7 @@ class AddrFile(MMGenObject):
|
|||
lbl_p2 = ':'.join(
|
||||
([] if coin == 'BTC' or (coin == 'BCH' and not self.cfg.cashaddr) else [coin])
|
||||
+ ([] if mmtype == 'E' or (mmtype == 'L' and not proto.testnet) else [mmtype.name.upper()])
|
||||
+ ([proto.network.upper()] if proto.testnet else [])
|
||||
)
|
||||
+ ([proto.network.upper()] if proto.testnet else []))
|
||||
return self.parent.al_id.sid + (' ' if lbl_p2 else '') + lbl_p2
|
||||
|
||||
def format(self, *, add_comments=False):
|
||||
|
|
@ -162,7 +161,7 @@ class AddrFile(MMGenObject):
|
|||
assert is_addr_idx(idx), f'invalid address index {idx!r}'
|
||||
p.check_format(addr)
|
||||
|
||||
a = le(**{'proto': p.proto, 'idx':int(idx), p.main_attr:addr, 'comment':comment})
|
||||
a = le(**{'proto': p.proto, 'idx': int(idx), p.main_attr: addr, 'comment': comment})
|
||||
|
||||
if p.has_keys: # order: wif, (orig_hex), viewkey, wallet_passwd
|
||||
if type(self) is not ViewKeyAddrFile:
|
||||
|
|
@ -350,7 +349,7 @@ class PasswordFile(AddrFile):
|
|||
ret = lines.pop(0).split(None, p.pw_len + 1)
|
||||
match len(ret) - 1:
|
||||
case p.pw_len:
|
||||
return (ret[0], ' '.join(ret[1:p.pw_len + 1]), '')
|
||||
return (ret[0], ' '.join(ret[1: p.pw_len + 1]), '')
|
||||
case x if x > p.pw_len:
|
||||
raise ValueError(
|
||||
f'extraneous text {ret[p.pw_len + 1]!r} found after password '
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ def check_data(orig_func):
|
|||
def f(self, data):
|
||||
assert data.pubkey_type == self.pubkey_type, 'addrgen.py:check_data() pubkey_type mismatch'
|
||||
assert data.compressed == self.compressed, (
|
||||
f'addrgen.py:check_data() expected compressed={self.compressed} but got compressed={data.compressed}'
|
||||
)
|
||||
f'addrgen.py:check_data() expected compressed={self.compressed} '
|
||||
f'but got compressed={data.compressed}')
|
||||
return orig_func(self, data)
|
||||
return f
|
||||
|
||||
|
|
@ -62,8 +62,7 @@ def AddrGenerator(cfg, proto, addr_type):
|
|||
'bech32x': 'xchain',
|
||||
'monero': 'xmr',
|
||||
'ethereum': 'eth',
|
||||
'zcash_z': 'zec',
|
||||
}
|
||||
'zcash_z': 'zec'}
|
||||
|
||||
from .addr import MMGenAddrType
|
||||
|
||||
|
|
|
|||
|
|
@ -287,15 +287,11 @@ def make_proto(e, *, testnet=False):
|
|||
'base_coin': e.symbol,
|
||||
'addr_ver_info': dict(
|
||||
[(num2hexstr(e.p2pkh_info[0]), 'p2pkh')] +
|
||||
([(num2hexstr(e.p2sh_info[0]), 'p2sh')] if e.p2sh_info else [])
|
||||
),
|
||||
([(num2hexstr(e.p2sh_info[0]), 'p2sh')] if e.p2sh_info else [])),
|
||||
'wif_ver_num': {'std': num2hexstr(e.wif_ver_num)},
|
||||
'mmtypes': ('L', 'C', 'S') if e.has_segwit else ('L', 'C'),
|
||||
'dfl_mmtype': 'L',
|
||||
'mmcaps': (),
|
||||
},
|
||||
)
|
||||
)
|
||||
'mmcaps': ()}))
|
||||
|
||||
def init_genonly_altcoins(usr_coin=None, *, testnet=False):
|
||||
"""
|
||||
|
|
|
|||
12
mmgen/amt.py
12
mmgen/amt.py
|
|
@ -100,8 +100,7 @@ class CoinAmt(Decimal, Hilite, InitErrors): # abstract class
|
|||
(res.rstrip('0').rstrip('.') if '.' in res else res) +
|
||||
(' ' + self.coin if unit else ''),
|
||||
color = color)
|
||||
+ encl[1:]
|
||||
)
|
||||
+ encl[1:])
|
||||
|
||||
def __str__(self): # format simply, with no exponential notation
|
||||
return str(int(self)) if int(self) == self else self.normalize().__format__('f')
|
||||
|
|
@ -135,22 +134,19 @@ class CoinAmt(Decimal, Hilite, InitErrors): # abstract class
|
|||
def __mul__(self, other, *args, **kwargs):
|
||||
return type(self)('{:0.{p}f}'.format(
|
||||
Decimal.__mul__(self, Decimal(other), *args, **kwargs),
|
||||
p = self.max_prec
|
||||
))
|
||||
p = self.max_prec))
|
||||
|
||||
__rmul__ = __mul__
|
||||
|
||||
def __truediv__(self, other, *args, **kwargs):
|
||||
return type(self)('{:0.{p}f}'.format(
|
||||
Decimal.__truediv__(self, Decimal(other), *args, **kwargs),
|
||||
p = self.max_prec
|
||||
))
|
||||
p = self.max_prec))
|
||||
|
||||
def __rtruediv__(self, other, *args, **kwargs):
|
||||
return type(self)('{:0.{p}f}'.format(
|
||||
Decimal.__rtruediv__(self, Decimal(other), *args, **kwargs),
|
||||
p = self.max_prec
|
||||
))
|
||||
p = self.max_prec))
|
||||
|
||||
def __neg__(self, *args, **kwargs):
|
||||
self.method_not_implemented()
|
||||
|
|
|
|||
|
|
@ -188,8 +188,8 @@ class Signable:
|
|||
def print_bad_list(self, bad_files):
|
||||
msg('\n{a}\n{b}'.format(
|
||||
a = red(f'Failed {self.desc}s:'),
|
||||
b = ' {}\n'.format('\n '.join(self.gen_bad_list(sorted(bad_files, key=lambda f: f.name))))
|
||||
))
|
||||
b = ' {}\n'.format('\n '.join(
|
||||
self.gen_bad_list(sorted(bad_files, key=lambda f: f.name))))))
|
||||
|
||||
def die_wrong_num_txs(self, tx_type, *, msg=None, desc=None, show_dir=False):
|
||||
num_txs = len(getattr(self, tx_type))
|
||||
|
|
@ -199,8 +199,7 @@ class Signable:
|
|||
b = desc or tx_type,
|
||||
c = suf(num_txs),
|
||||
d = 'already present' if num_txs else 'present',
|
||||
e = f'in ‘{getattr(self.parent, self.dir_name)}’' if show_dir else 'on removable device',
|
||||
))
|
||||
e = f'in ‘{getattr(self.parent, self.dir_name)}’' if show_dir else 'on removable device'))
|
||||
|
||||
def check_create_ok(self):
|
||||
if len(self.unsigned):
|
||||
|
|
@ -441,20 +440,20 @@ class Autosign:
|
|||
|
||||
mn_fmts = {
|
||||
'mmgen': 'words',
|
||||
'bip39': 'bip39',
|
||||
}
|
||||
'bip39': 'bip39'}
|
||||
|
||||
dfl_mn_fmt = 'mmgen'
|
||||
|
||||
non_xmr_dirs = {
|
||||
'tx_dir': 'tx',
|
||||
'txauto_dir': 'txauto',
|
||||
'msg_dir': 'msg',
|
||||
}
|
||||
'msg_dir': 'msg'}
|
||||
|
||||
xmr_dirs = {
|
||||
'xmr_dir': 'xmr',
|
||||
'xmr_tx_dir': 'xmr/tx',
|
||||
'xmr_outputs_dir': 'xmr/outputs',
|
||||
}
|
||||
'xmr_outputs_dir': 'xmr/outputs'}
|
||||
|
||||
have_xmr = False
|
||||
xmr_only = False
|
||||
|
||||
|
|
@ -802,8 +801,7 @@ class Autosign:
|
|||
'autosign': True,
|
||||
'autosign_mountpoint': str(self.mountpoint),
|
||||
'offline': True,
|
||||
'passwd_file': str(self.keyfile),
|
||||
})
|
||||
'passwd_file': str(self.keyfile)})
|
||||
return self._xmrwallet_cfg
|
||||
|
||||
def xmr_setup(self):
|
||||
|
|
|
|||
|
|
@ -80,10 +80,9 @@ class AttrCtrl(metaclass=AttrCtrlMeta):
|
|||
ref_val = getattr(type(self), name) if self._use_class_attr else getattr(self, name)
|
||||
|
||||
if (
|
||||
(name not in self._skip_type_check)
|
||||
and (ref_val is not None)
|
||||
and not isinstance(value, type(ref_val))
|
||||
):
|
||||
(name not in self._skip_type_check)
|
||||
and (ref_val is not None)
|
||||
and not isinstance(value, type(ref_val))):
|
||||
do_error(name, value, ref_val)
|
||||
|
||||
return object.__setattr__(self, name, value)
|
||||
|
|
|
|||
|
|
@ -43,14 +43,16 @@ class baseconv:
|
|||
constants = {
|
||||
'desc': {
|
||||
'b58': dt('base58', 'base58-encoded data'),
|
||||
'b32': dt('MMGen base32', 'MMGen base32-encoded data created using simple base conversion'),
|
||||
'b32': dt('MMGen base32',
|
||||
'MMGen base32-encoded data created using simple base conversion'),
|
||||
'b16': dt('hexadecimal string', 'base16 (hexadecimal) string data'),
|
||||
'b10': dt('base10 string', 'base10 (decimal) string data'),
|
||||
'b8': dt('base8 string', 'base8 (octal) string data'),
|
||||
'b6d': dt('base6d (die roll)', 'base6 data using the digits from one to six'),
|
||||
'mmgen': dt('MMGen native mnemonic',
|
||||
'MMGen native mnemonic seed phrase created using old Electrum wordlist and simple base conversion'),
|
||||
},
|
||||
'MMGen native mnemonic seed phrase created using old Electrum wordlist '
|
||||
'and simple base conversion')},
|
||||
|
||||
# https://en.wikipedia.org/wiki/Base32#RFC_4648_Base32_alphabet
|
||||
# https://tools.ietf.org/html/rfc4648
|
||||
'digits': {
|
||||
|
|
@ -59,24 +61,22 @@ class baseconv:
|
|||
'b16': tuple('0123456789abcdef'),
|
||||
'b10': tuple('0123456789'),
|
||||
'b8': tuple('01234567'),
|
||||
'b6d': tuple('123456'),
|
||||
},
|
||||
'b6d': tuple('123456')},
|
||||
|
||||
'wl_chksum': {
|
||||
'mmgen': '5ca31424',
|
||||
'mmgen': '5ca31424'},
|
||||
# 'tirosh': '48f05e1f', # tirosh truncated to mn_base
|
||||
# 'tirosh1633': '1a5faeff' # tirosh list is 1633 words long!
|
||||
},
|
||||
|
||||
'seedlen_map': {
|
||||
'b58': {16:22, 24:33, 32:44},
|
||||
'b6d': {16:50, 24:75, 32:100},
|
||||
'mmgen': {16:12, 24:18, 32:24},
|
||||
},
|
||||
'mmgen': {16:12, 24:18, 32:24}},
|
||||
|
||||
'seedlen_map_rev': {
|
||||
'b58': {22:16, 33:24, 44:32},
|
||||
'b6d': {50:16, 75:24, 100:32},
|
||||
'mmgen': {12:16, 18:24, 24:32},
|
||||
}
|
||||
}
|
||||
'mmgen': {12:16, 18:24, 24:32}}}
|
||||
|
||||
def __init__(self, wl_id):
|
||||
|
||||
|
|
|
|||
|
|
@ -44,8 +44,7 @@ class bip39(baseconv):
|
|||
160: bc(5, 15),
|
||||
192: bc(6, 18),
|
||||
224: bc(7, 21),
|
||||
256: bc(8, 24),
|
||||
}
|
||||
256: bc(8, 24)}
|
||||
|
||||
def __init__(self, wl_id='bip39'):
|
||||
assert wl_id == 'bip39', "initialize with 'bip39' for compatibility with baseconv API"
|
||||
|
|
|
|||
|
|
@ -148,8 +148,7 @@ class BipHDConfig(Lockable):
|
|||
'coin': coin,
|
||||
'network': network,
|
||||
'type': addr_type or None,
|
||||
'quiet': True
|
||||
})
|
||||
'quiet': True})
|
||||
|
||||
dfl_type = base_cfg._proto.dfl_mmtype
|
||||
addr_type = MMGenAddrType(
|
||||
|
|
@ -417,8 +416,7 @@ class BipHDNode(Lockable):
|
|||
addr_types = {
|
||||
84: 'bech32',
|
||||
49: 'segwit',
|
||||
44: None
|
||||
}
|
||||
44: None}
|
||||
|
||||
new = bip_hd_nodes[xk.depth]()
|
||||
|
||||
|
|
|
|||
14
mmgen/cfg.py
14
mmgen/cfg.py
|
|
@ -84,8 +84,8 @@ class GlobalConstants(Lockable):
|
|||
'walletchk': _cc(False, False, False, None, [], 'lmw'),
|
||||
'walletconv': _cc(False, False, False, None, [], 'lmw'),
|
||||
'walletgen': _cc(False, False, False, None, [], 'lmw'),
|
||||
'xmrwallet': _cc(True, True, False, '-rx', ['rpc'], 'lmw'),
|
||||
}
|
||||
'xmrwallet': _cc(True, True, False, '-rx', ['rpc'], 'lmw')}
|
||||
|
||||
altcoin_cmds = ('swaptxcreate', 'swaptxdo', 'xmrwallet')
|
||||
|
||||
prog_name = os.path.basename(sys.argv[0])
|
||||
|
|
@ -390,15 +390,14 @@ class Config(Lockable):
|
|||
'fee_estimate_mode': _ov('nocase_pfx', ['conservative', 'economical']),
|
||||
'rpc_backend': _ov('nocase_pfx', ['auto', 'httplib', 'curl', 'aiohttp', 'requests']),
|
||||
'swap_proto': _ov('nocase_pfx', ['thorchain']),
|
||||
'tx_proxy': _ov('nocase_pfx', ['etherscan']) # , 'blockchair'
|
||||
}
|
||||
'tx_proxy': _ov('nocase_pfx', ['etherscan'])} # , 'blockchair'
|
||||
|
||||
_dfl_none_autoset_opts = ('tx_proxy',)
|
||||
|
||||
_auto_typeset_opts = {
|
||||
'seed_len': int,
|
||||
'subseeds': int,
|
||||
'vsize_adj': float,
|
||||
}
|
||||
'vsize_adj': float}
|
||||
|
||||
# test suite:
|
||||
err_disp_timeout = 0.7
|
||||
|
|
@ -962,8 +961,7 @@ def conv_type(name, val, refval, *, src, invert_bool=False):
|
|||
desc = {
|
||||
'cmdline': 'command-line',
|
||||
'cfg': 'Config',
|
||||
'env': 'environment var',
|
||||
}
|
||||
'env': 'environment var'}
|
||||
die(1, '{a!r}: invalid value for {b} option {c!r}{d} (must be of type {e!r})'.format(
|
||||
a = val,
|
||||
b = desc.get(src, 'config file'),
|
||||
|
|
|
|||
|
|
@ -91,8 +91,7 @@ class cfg_file:
|
|||
d = {
|
||||
'usr': CfgFileUsr,
|
||||
'sys': CfgFileSampleSys,
|
||||
'sample': CfgFileSampleUsr,
|
||||
}
|
||||
'sample': CfgFileSampleUsr}
|
||||
return d[id_str]
|
||||
|
||||
class cfg_file_sample(cfg_file):
|
||||
|
|
@ -242,8 +241,7 @@ class CfgFileSampleUsr(cfg_file_sample):
|
|||
if removed or added:
|
||||
return {
|
||||
'removed': [i for i in a_tup if i.name in removed],
|
||||
'added': [i for i in b_tup if i.name in added],
|
||||
}
|
||||
'added': [i for i in b_tup if i.name in added]}
|
||||
else:
|
||||
return None
|
||||
|
||||
|
|
|
|||
|
|
@ -50,8 +50,7 @@ class Crypto:
|
|||
'4': _hp(15, 8, 12),
|
||||
'5': _hp(16, 8, 16),
|
||||
'6': _hp(17, 8, 20),
|
||||
'7': _hp(18, 8, 24),
|
||||
}
|
||||
'7': _hp(18, 8, 24)}
|
||||
|
||||
class pwfile_reuse_warning(oneshot_warning):
|
||||
message = 'Reusing passphrase from file {!r} at user request'
|
||||
|
|
@ -301,7 +300,7 @@ class Crypto:
|
|||
rand_bytes,
|
||||
*,
|
||||
desc,
|
||||
urand = {'data':b'', 'counter':0}):
|
||||
urand = {'data': b'', 'counter': 0}):
|
||||
|
||||
assert type(rand_bytes) is bytes, 'add_user_random_chk1'
|
||||
|
||||
|
|
|
|||
|
|
@ -291,8 +291,7 @@ class CoinDaemon(Daemon):
|
|||
'LTC': _cd(['litecoin_core']),
|
||||
'XMR': _cd(['monero']),
|
||||
'ETH': _cd(['geth', 'reth', 'erigon']), #, 'openethereum'
|
||||
'ETC': _cd(['parity']),
|
||||
}
|
||||
'ETC': _cd(['parity'])}
|
||||
|
||||
@classmethod
|
||||
def all_daemon_ids(cls):
|
||||
|
|
|
|||
|
|
@ -72,8 +72,7 @@ def gen_arg_tuple(cfg, func, text):
|
|||
'proto': proto,
|
||||
'help_notes': help_notes,
|
||||
'help_mod': help_mod,
|
||||
'cfg': cfg,
|
||||
}
|
||||
'cfg': cfg}
|
||||
|
||||
for arg in func.__code__.co_varnames:
|
||||
yield d[arg] if arg in d else text
|
||||
|
|
|
|||
|
|
@ -40,8 +40,7 @@ class HTTPClient:
|
|||
elif cfg.proxy:
|
||||
self.session.proxies.update({
|
||||
'http': f'socks5h://{cfg.proxy}',
|
||||
'https': f'socks5h://{cfg.proxy}'
|
||||
})
|
||||
'https': f'socks5h://{cfg.proxy}'})
|
||||
|
||||
def call(self, name, path, err_fs, timeout, *, data=None):
|
||||
url = self.network_proto + '://' + self.host + path
|
||||
|
|
|
|||
|
|
@ -57,17 +57,13 @@ class keygen_base:
|
|||
backend_data = {
|
||||
'std': {
|
||||
'backends': ('libsecp256k1', 'python-ecdsa'),
|
||||
'package': 'secp256k1',
|
||||
},
|
||||
'package': 'secp256k1'},
|
||||
'monero': {
|
||||
'backends': ('nacl', 'ed25519ll-djbec', 'ed25519'),
|
||||
'package': 'xmr',
|
||||
},
|
||||
'package': 'xmr'},
|
||||
'zcash_z': {
|
||||
'backends': ('nacl',),
|
||||
'package': 'zec',
|
||||
},
|
||||
}
|
||||
'package': 'zec'}}
|
||||
|
||||
def get_backends(pubkey_type):
|
||||
return backend_data[pubkey_type]['backends']
|
||||
|
|
|
|||
|
|
@ -85,8 +85,7 @@ class LEDControl:
|
|||
'dummy': binfo(
|
||||
name = 'Fake Board',
|
||||
control = '/tmp/led_status',
|
||||
trigger = '/tmp/led_trigger'),
|
||||
}
|
||||
trigger = '/tmp/led_trigger')}
|
||||
|
||||
def __init__(self, *, enabled, simulate=False, debug=False):
|
||||
|
||||
|
|
|
|||
|
|
@ -198,8 +198,7 @@ cfg = Config(
|
|||
'out_fmt': 'wallet',
|
||||
'usr_randchars': 0,
|
||||
'hash_preset': '1',
|
||||
'label': 'Autosign Wallet',
|
||||
},
|
||||
'label': 'Autosign Wallet'},
|
||||
caller_post_init = True)
|
||||
|
||||
cmd = cfg._args[0] if len(cfg._args) == 1 else 'sign' if not cfg._args else cfg._usage()
|
||||
|
|
|
|||
|
|
@ -214,10 +214,10 @@ def create_call_sig(cmd, cls, *, as_string=False):
|
|||
else:
|
||||
get_type_from_ann = lambda x: 'str' if ann[x] == 'sstr' else ann[x].__name__
|
||||
return (
|
||||
[(a, get_type_from_ann(a)) for a in args[:nargs]], # c_args
|
||||
{a:dfls[n] for n, a in enumerate(args[nargs:])}, # c_kwargs
|
||||
{a:dfl_types[n] for n, a in enumerate(args[nargs:])}, # c_kwargs_types
|
||||
('STDIN_OK' if nargs and ann[args[0]] == 'sstr' else flag), # flag
|
||||
[(a, get_type_from_ann(a)) for a in args[:nargs]], # c_args
|
||||
{a: dfls[n] for n, a in enumerate(args[nargs:])}, # c_kwargs
|
||||
{a: dfl_types[n] for n, a in enumerate(args[nargs:])}, # c_kwargs_types
|
||||
('STDIN_OK' if nargs and ann[args[0]] == 'sstr' else flag), # flag
|
||||
ann) # ann
|
||||
|
||||
def process_args(cmd, cmd_args, cls):
|
||||
|
|
@ -299,7 +299,7 @@ def process_args(cmd, cmd_args, cls):
|
|||
args = [conv_type(u_args[i], c_args[0][0], c_args[0][1]) for i in range(len(u_args))]
|
||||
else:
|
||||
args = [conv_type(u_args[i], c_args[i][0], c_args[i][1]) for i in range(len(c_args))]
|
||||
kwargs = {k:conv_type(v, k, c_kwargs_types[k].__name__) for k, v in u_kwargs.items()}
|
||||
kwargs = {k: conv_type(v, k, c_kwargs_types[k].__name__) for k, v in u_kwargs.items()}
|
||||
|
||||
return (args, kwargs)
|
||||
|
||||
|
|
|
|||
|
|
@ -223,8 +223,7 @@ class MnemonicEntry:
|
|||
ignored. This feature allows you to guard against acoustic side-channel
|
||||
attacks by padding your keyboard entry with “dead characters”. Pad char-
|
||||
acters may be typed before, after, or in the middle of words.
|
||||
""",
|
||||
}
|
||||
"""}
|
||||
word_prompt = ('Enter word #{}: ', 'Incorrect entry. Repeat word #{}: ')
|
||||
usr_dfl_entry_mode = None
|
||||
_lw = None
|
||||
|
|
@ -373,8 +372,7 @@ class MnemonicEntry:
|
|||
d = {
|
||||
'mmgen': MnemonicEntryMMGen,
|
||||
'bip39': MnemonicEntryBIP39,
|
||||
'xmrseed': MnemonicEntryMonero,
|
||||
}
|
||||
'xmrseed': MnemonicEntryMonero}
|
||||
wl = wl.lower()
|
||||
if wl not in d:
|
||||
raise ValueError(f'wordlist {wl!r} not recognized (valid choices: {fmt_list(list(d))})')
|
||||
|
|
|
|||
39
mmgen/msg.py
39
mmgen/msg.py
|
|
@ -67,7 +67,7 @@ class coin_msg:
|
|||
def chksum(self):
|
||||
return make_chksum_6(
|
||||
json.dumps(
|
||||
{k:self.data[k] for k in self.chksum_keys},
|
||||
{k: self.data[k] for k in self.chksum_keys},
|
||||
sort_keys = True,
|
||||
separators = (',', ':')
|
||||
))
|
||||
|
|
@ -99,9 +99,7 @@ class coin_msg:
|
|||
data = {
|
||||
'id': f'{gc.proj_name} {self.desc}',
|
||||
'metadata': self.data,
|
||||
'signatures': self.sigs,
|
||||
}
|
||||
|
||||
'signatures': self.sigs}
|
||||
write_data_to_file(
|
||||
cfg = self.cfg,
|
||||
outfile = os.path.join(outdir or '', self.filename),
|
||||
|
|
@ -122,8 +120,7 @@ class coin_msg:
|
|||
'network': '{}_{}'.format(self.proto.coin.lower(), self.proto.network),
|
||||
'addrlists': [MMGenIDRange(self.proto, i) for i in addrlists.split()],
|
||||
'message': message,
|
||||
'msghash_type': msghash_type,
|
||||
}
|
||||
'msghash_type': msghash_type}
|
||||
self.sigs = {}
|
||||
|
||||
class completed(base):
|
||||
|
|
@ -150,8 +147,7 @@ class coin_msg:
|
|||
'addr': 'address:',
|
||||
'addr_p2pkh': 'addr_p2pkh:',
|
||||
'pubhash': 'pubkey hash:',
|
||||
'sig': 'signature:',
|
||||
}
|
||||
'sig': 'signature:'}
|
||||
|
||||
def gen_entry(e):
|
||||
for k in labels:
|
||||
|
|
@ -186,8 +182,7 @@ class coin_msg:
|
|||
'network': ('Network:', lambda v: v.replace('_', ' ').upper()),
|
||||
'msghash_type': ('Message Hash Type:', lambda v: v),
|
||||
'addrlists': ('Address Ranges:', lambda v: fmt_list(v, fmt='bare')),
|
||||
'failed_sids': ('Failed Seed IDs:', lambda v: red(fmt_list(v, fmt='bare'))),
|
||||
}
|
||||
'failed_sids': ('Failed Seed IDs:', lambda v: red(fmt_list(v, fmt='bare')))}
|
||||
|
||||
if len(self.msg_cls.msghash_types) == 1:
|
||||
del hdr_data['msghash_type']
|
||||
|
|
@ -235,10 +230,11 @@ class coin_msg:
|
|||
mmid = f'{al_in.sid}:{al_in.mmtype}:{e.idx}'
|
||||
data = {
|
||||
'addr': e.addr,
|
||||
'sig': sig,
|
||||
}
|
||||
'sig': sig}
|
||||
|
||||
if self.msg_cls.include_pubhash:
|
||||
data.update({'pubhash': self.proto.decode_addr(e.addr_p2pkh or e.addr).bytes.hex()})
|
||||
data.update(
|
||||
{'pubhash': self.proto.decode_addr(e.addr_p2pkh or e.addr).bytes.hex()})
|
||||
|
||||
if e.addr_p2pkh:
|
||||
data.update({'addr_p2pkh': e.addr_p2pkh})
|
||||
|
|
@ -295,7 +291,7 @@ class coin_msg:
|
|||
req_addr = (
|
||||
CoinAddr(self.proto, addr) if type(self).__name__ == 'exported_sigs' else
|
||||
MMGenID(self.proto, addr))
|
||||
sigs = {k:v for k, v in self.sigs.items() if k == req_addr}
|
||||
sigs = {k: v for k, v in self.sigs.items() if k == req_addr}
|
||||
else:
|
||||
sigs = self.sigs
|
||||
|
||||
|
|
@ -327,17 +323,14 @@ class coin_msg:
|
|||
sigs = list(self.get_sigs(addr).values())
|
||||
pfx = self.msg_cls.sigdata_pfx
|
||||
if pfx:
|
||||
sigs = [{k:pfx+v for k, v in e.items()} for e in sigs]
|
||||
return json.dumps(
|
||||
{
|
||||
sigs = [{k: pfx+v for k, v in e.items()} for e in sigs]
|
||||
return json.dumps({
|
||||
'message': self.data['message'],
|
||||
'msghash_type': self.data['msghash_type'],
|
||||
'network': self.data['network'].upper(),
|
||||
'signatures': sigs,
|
||||
},
|
||||
'signatures': sigs},
|
||||
sort_keys = True,
|
||||
indent = 4
|
||||
)
|
||||
indent = 4)
|
||||
|
||||
class exported_sigs(signed_online):
|
||||
|
||||
|
|
@ -351,8 +344,8 @@ class coin_msg:
|
|||
)
|
||||
|
||||
pfx = self.msg_cls.sigdata_pfx
|
||||
self.sigs = {sig_data['addr']:sig_data for sig_data in (
|
||||
[{k:v[len(pfx):] for k, v in e.items()} for e in self.data['signatures']]
|
||||
self.sigs = {sig_data['addr']: sig_data for sig_data in (
|
||||
[{k: v[len(pfx):] for k, v in e.items()} for e in self.data['signatures']]
|
||||
if pfx else
|
||||
self.data['signatures']
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -186,8 +186,7 @@ class MMGenListItem(MMGenObject):
|
|||
'pexit',
|
||||
'valid_attrs',
|
||||
'invalid_attrs',
|
||||
'immutable_attr_init_check',
|
||||
}
|
||||
'immutable_attr_init_check'}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
# generate valid_attrs, or use the class valid_attrs if set
|
||||
|
|
|
|||
|
|
@ -58,8 +58,7 @@ class PasswordList(AddrList):
|
|||
'b58': pwinfo(8, 36 , 20, None, 'base58 password', 'baseconv.is_b58_str'),
|
||||
'bip39': pwinfo(12, 24 , 24, [12, 18, 24], 'BIP39 mnemonic', 'bip39.is_bip39_mnemonic'),
|
||||
'xmrseed': pwinfo(25, 25, 25, [25], 'Monero new-style mnemonic', 'xmrseed.is_xmrseed'),
|
||||
'hex': pwinfo(32, 64 , 64, [32, 48, 64], 'hexadecimal password', 'util.is_hex_str'),
|
||||
}
|
||||
'hex': pwinfo(32, 64 , 64, [32, 48, 64], 'hexadecimal password', 'util.is_hex_str')}
|
||||
chksum_rec_f = lambda foo, e: (str(e.idx), e.passwd)
|
||||
|
||||
feature_warn_fs = 'WARNING: {!r} is a potentially dangerous feature. Use at your own risk!'
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ cashaddr_addr_types = {
|
|||
'token_script': 3,
|
||||
'unknown': 15,
|
||||
}
|
||||
addr_types_rev = {v:k for k, v in cashaddr_addr_types.items()}
|
||||
addr_types_rev = {v: k for k, v in cashaddr_addr_types.items()}
|
||||
|
||||
data_sizes = (160, 192, 224, 256, 320, 384, 448, 512)
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,7 @@ class BitcoinTwAddrData(TwAddrData):
|
|||
Your 'wallet.dat' file appears to have been altered by a non-{proj} program.
|
||||
Please restore your tracking wallet from a backup or create a new one and
|
||||
re-import your addresses.
|
||||
"""
|
||||
}
|
||||
"""}
|
||||
|
||||
async def get_tw_data(self, *, twctl=None):
|
||||
self.cfg._util.vmsg('Getting address data from tracking wallet')
|
||||
|
|
|
|||
|
|
@ -30,8 +30,7 @@ class bitcoin_core_daemon(CoinDaemon):
|
|||
datadirs = {
|
||||
'linux': [gc.home_dir, '.bitcoin'],
|
||||
'darwin': [gc.home_dir, 'Library', 'Application Support', 'Bitcoin'],
|
||||
'win32': [os.getenv('APPDATA'), 'Bitcoin']
|
||||
}
|
||||
'win32': [os.getenv('APPDATA'), 'Bitcoin']}
|
||||
avail_opts = ('no_daemonize', 'online', 'bdb_wallet')
|
||||
|
||||
def init_datadir(self):
|
||||
|
|
@ -133,8 +132,7 @@ class bitcoin_cash_node_daemon(bitcoin_core_daemon):
|
|||
datadirs = {
|
||||
'linux': [gc.home_dir, '.bitcoin-bchn'],
|
||||
'darwin': [gc.home_dir, 'Library', 'Application Support', 'Bitcoin-Cash-Node'],
|
||||
'win32': [os.getenv('APPDATA'), 'Bitcoin-Cash-Node']
|
||||
}
|
||||
'win32': [os.getenv('APPDATA'), 'Bitcoin-Cash-Node']}
|
||||
|
||||
def set_comment_args(self, rpc, coinaddr, lbl):
|
||||
# bitcoin-{abc, bchn} 'setlabel' RPC is broken, so use old 'importaddress' method to set label
|
||||
|
|
@ -163,5 +161,4 @@ class litecoin_core_daemon(bitcoin_core_daemon):
|
|||
datadirs = {
|
||||
'linux': [gc.home_dir, '.litecoin'],
|
||||
'darwin': [gc.home_dir, 'Library', 'Application Support', 'Litecoin'],
|
||||
'win32': [os.getenv('APPDATA'), 'Litecoin']
|
||||
}
|
||||
'win32': [os.getenv('APPDATA'), 'Litecoin']}
|
||||
|
|
|
|||
|
|
@ -71,8 +71,7 @@ class MMGenRegtest(MMGenObject):
|
|||
# cTyMdQ2BgfAsjopRVZrj7AoEGp97pKfrC2NkqLuwHr4KHfPNAKwp hdseed=1
|
||||
'btc': 'bcrt1qaq8t3pakcftpk095tnqfv5cmmczysls024atnd',
|
||||
'ltc': 'rltc1qaq8t3pakcftpk095tnqfv5cmmczysls05c8zyn',
|
||||
'bch': 'n2fxhNx27GhHAWQhyuZ5REcBNrJqCJsJ12',
|
||||
}
|
||||
'bch': 'n2fxhNx27GhHAWQhyuZ5REcBNrJqCJsJ12'}
|
||||
|
||||
def __init__(self, cfg, coin, *, bdb_wallet=False):
|
||||
self.cfg = cfg
|
||||
|
|
|
|||
|
|
@ -31,8 +31,7 @@ class BitcoinTwAddresses(BitcoinTwView, TwAddresses, BitcoinTwRPC):
|
|||
'View/Print: pager [v]iew, [w]ide pager view, [p]rint{s}',
|
||||
'Actions: [q]uit menu, r[e]draw, add [l]abel:']
|
||||
prompt_fs_repl = {
|
||||
'BCH': (1, 'Column options: toggle [D]ays/date/confs/block, cas[h]addr')
|
||||
}
|
||||
'BCH': (1, 'Column options: toggle [D]ays/date/confs/block, cas[h]addr')}
|
||||
extra_key_mappings = {
|
||||
'A':'s_age',
|
||||
'D':'d_days',
|
||||
|
|
|
|||
|
|
@ -27,8 +27,7 @@ class BitcoinTwGetBalance(TwGetBalance):
|
|||
conf_cols = {
|
||||
'unconfirmed': 'Unconfirmed',
|
||||
'lt_minconf': '<{minconf} confs',
|
||||
'ge_minconf': '>={minconf} confs',
|
||||
}
|
||||
'ge_minconf': '>={minconf} confs'}
|
||||
|
||||
async def create_data(self):
|
||||
lbl_id = ('account', 'label')['label_api' in self.rpc.caps]
|
||||
|
|
|
|||
|
|
@ -24,8 +24,7 @@ class BitcoinTwAddressesPrune(BitcoinTwAddresses, TwAddressesPrune):
|
|||
'View/Actions: pager [v]iew, [w]ide view, r[e]draw{s}',
|
||||
'Pruning: [q]uit pruning, [p]rune, [u]nprune, [c]lear prune list:']
|
||||
prompt_fs_repl = {
|
||||
'BCH': (1, 'Column options: toggle [D]ays/date/confs/block, cas[h]addr')
|
||||
}
|
||||
'BCH': (1, 'Column options: toggle [D]ays/date/confs/block, cas[h]addr')}
|
||||
key_mappings = {
|
||||
'a':'s_amt',
|
||||
'A':'s_age',
|
||||
|
|
|
|||
|
|
@ -108,12 +108,10 @@ class BitcoinTwTransaction:
|
|||
# 'outputs' refers to wallet-related outputs only
|
||||
self.vouts_info = {
|
||||
'inputs': gen_vouts_info(gen_prevouts_data()),
|
||||
'outputs': gen_vouts_info(gen_wallet_vouts_data())
|
||||
}
|
||||
'outputs': gen_vouts_info(gen_wallet_vouts_data())}
|
||||
self.max_addrlen = {
|
||||
'inputs': max(len(addr) for addr in gen_all_addrs('inputs')),
|
||||
'outputs': max(len(addr) for addr in gen_all_addrs('outputs'))
|
||||
}
|
||||
'outputs': max(len(addr) for addr in gen_all_addrs('outputs'))}
|
||||
self.inputs_total = total(self.vouts_info['inputs'])
|
||||
self.outputs_total = sum(coin_amt(i['value']) for i in self.tx['decoded']['vout'])
|
||||
self.wallet_outputs_total = total(self.vouts_info['outputs'])
|
||||
|
|
@ -255,8 +253,7 @@ class BitcoinTwTxHistory(BitcoinTwView, TwTxHistory, BitcoinTwRPC):
|
|||
'View/Print: pager [v]iew, full pager [V]iew, [p]rint, full [P]rint{s}',
|
||||
'Filters/Actions: show [u]nconfirmed, [q]uit menu, r[e]draw:']
|
||||
prompt_fs_repl = {
|
||||
'BCH': (1, 'Column options: toggle [D]ate/confs, cas[h]addr, tx[i]d, [T]otal amt')
|
||||
}
|
||||
'BCH': (1, 'Column options: toggle [D]ate/confs, cas[h]addr, tx[i]d, [T]otal amt')}
|
||||
key_mappings = {
|
||||
'A':'s_age',
|
||||
'n':'s_blockheight',
|
||||
|
|
@ -351,14 +348,12 @@ class BitcoinTwTxHistory(BitcoinTwView, TwTxHistory, BitcoinTwRPC):
|
|||
do_json_dump((_wallet_txs, 'wallet-txs'),)
|
||||
|
||||
_wip = namedtuple('prevout', ['txid', 'vout'])
|
||||
txdata = [
|
||||
{
|
||||
'tx': tx,
|
||||
'wallet_vouts': sorted({i.vout for i in
|
||||
[_wip(CoinTxID(d['txid']), d['vout']) for d in data]
|
||||
if i.txid == tx['txid']}),
|
||||
'prevouts': [_wip(CoinTxID(vin['txid']), vin['vout']) for vin in tx['decoded']['vin']]
|
||||
}
|
||||
txdata = [{
|
||||
'tx': tx,
|
||||
'wallet_vouts': sorted({i.vout for i in
|
||||
[_wip(CoinTxID(d['txid']), d['vout']) for d in data]
|
||||
if i.txid == tx['txid']}),
|
||||
'prevouts': [_wip(CoinTxID(vin['txid']), vin['vout']) for vin in tx['decoded']['vin']]}
|
||||
for tx in _wallet_txs]
|
||||
|
||||
_prevout_txids = {i.txid for d in txdata for i in d['prevouts']}
|
||||
|
|
|
|||
|
|
@ -59,8 +59,7 @@ class BitcoinTwUnspentOutputs(BitcoinTwView, TwUnspentOutputs):
|
|||
'View options: pager [v]iew, [w]ide pager view{s}',
|
||||
'Actions: [q]uit menu, [p]rint, r[e]draw, add [l]abel:']
|
||||
prompt_fs_repl = {
|
||||
'BCH': (1, 'Column options: toggle [D]ate/confs, cas[h]addr, gr[o]up, show [m]mgen addr')
|
||||
}
|
||||
'BCH': (1, 'Column options: toggle [D]ate/confs, cas[h]addr, gr[o]up, show [m]mgen addr')}
|
||||
extra_key_mappings = {
|
||||
'D':'d_days',
|
||||
'o':'d_group',
|
||||
|
|
|
|||
|
|
@ -25,5 +25,4 @@ class BitcoinTwView:
|
|||
'block': (8, 'Block'),
|
||||
'days': (6, 'Age(d)'),
|
||||
'date': (8, 'Date'),
|
||||
'date_time': (16, 'Date/Time'),
|
||||
}
|
||||
'date_time': (16, 'Date/Time')}
|
||||
|
|
|
|||
|
|
@ -245,8 +245,7 @@ class Base(TxBase):
|
|||
'L': isize_common + sig_size + pubkey_size_uncompressed, # = 180
|
||||
'C': isize_common + sig_size + pubkey_size_compressed, # = 148
|
||||
'S': isize_common + 23, # = 64
|
||||
'B': isize_common + 0 # = 41
|
||||
}
|
||||
'B': isize_common + 0} # = 41
|
||||
ret = sum(input_size[i.mmtype] for i in self.inputs if i.mmtype)
|
||||
|
||||
# We have no way of knowing whether a non-MMGen P2PKH addr is compressed or uncompressed
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class Unsigned(Completed, TxBase.Unsigned):
|
|||
|
||||
sig_data = []
|
||||
for d in self.inputs:
|
||||
e = {k:getattr(d, k) for k in ('txid', 'vout', 'scriptPubKey', 'amt')}
|
||||
e = {k: getattr(d, k) for k in ('txid', 'vout', 'scriptPubKey', 'amt')}
|
||||
e['amount'] = e['amt']
|
||||
del e['amt']
|
||||
if d.mmtype == 'S':
|
||||
|
|
|
|||
|
|
@ -64,8 +64,7 @@ class openethereum_daemon(ethereum_daemon):
|
|||
datadirs = {
|
||||
'linux': [gc.home_dir, '.local', 'share', 'io.parity.ethereum'],
|
||||
'darwin': [gc.home_dir, 'Library', 'Application Support', 'io.parity.ethereum'],
|
||||
'win32': [os.getenv('LOCALAPPDATA'), 'Parity', 'Ethereum']
|
||||
}
|
||||
'win32': [os.getenv('LOCALAPPDATA'), 'Parity', 'Ethereum']}
|
||||
|
||||
def init_subclass(self):
|
||||
|
||||
|
|
@ -107,8 +106,7 @@ class geth_daemon(ethereum_daemon):
|
|||
datadirs = {
|
||||
'linux': [gc.home_dir, '.ethereum', 'geth'],
|
||||
'darwin': [gc.home_dir, 'Library', 'Ethereum', 'geth'],
|
||||
'win32': [os.getenv('LOCALAPPDATA'), 'Geth'] # FIXME
|
||||
}
|
||||
'win32': [os.getenv('LOCALAPPDATA'), 'Geth']} # FIXME
|
||||
|
||||
def init_subclass(self):
|
||||
|
||||
|
|
@ -137,8 +135,7 @@ class reth_daemon(geth_daemon):
|
|||
exec_fn = 'reth'
|
||||
version_info_arg = '--version'
|
||||
datadirs = {
|
||||
'linux': [gc.home_dir, '.local', 'share', 'reth'],
|
||||
}
|
||||
'linux': [gc.home_dir, '.local', 'share', 'reth']}
|
||||
|
||||
# https://github.com/ledgerwatch/erigon
|
||||
class erigon_daemon(geth_daemon):
|
||||
|
|
@ -150,8 +147,7 @@ class erigon_daemon(geth_daemon):
|
|||
version_info_arg = '--version'
|
||||
datadirs = {
|
||||
'linux': [gc.home_dir, '.local', 'share', 'erigon'],
|
||||
'win32': [os.getenv('LOCALAPPDATA'), 'Erigon'] # FIXME
|
||||
}
|
||||
'win32': [os.getenv('LOCALAPPDATA'), 'Erigon']} # FIXME
|
||||
|
||||
def init_subclass(self):
|
||||
|
||||
|
|
|
|||
|
|
@ -54,20 +54,17 @@ class mainnet(CoinProtocol.DummyWIF, CoinProtocol.Secp256k1):
|
|||
17: 'developmentchain', # parity dev chain
|
||||
1337: 'developmentchain', # geth dev chain
|
||||
711: 'ethereum', # geth mainnet (empty chain)
|
||||
17000: 'holesky', # proof-of-stake testnet
|
||||
}
|
||||
17000: 'holesky'} # proof-of-stake testnet
|
||||
|
||||
coin_cfg_opts = (
|
||||
'daemon_id',
|
||||
'ignore_daemon_version',
|
||||
'rpc_host',
|
||||
'rpc_port',
|
||||
'max_tx_fee',
|
||||
)
|
||||
'max_tx_fee')
|
||||
|
||||
proto_cfg_opts = (
|
||||
'chain_names',
|
||||
)
|
||||
'chain_names')
|
||||
|
||||
@property
|
||||
def dcoin(self):
|
||||
|
|
|
|||
|
|
@ -27,8 +27,7 @@ class EthereumTwGetBalance(TwGetBalance):
|
|||
|
||||
start_labels = ('TOTAL', 'Non-MMGen')
|
||||
conf_cols = {
|
||||
'ge_minconf': 'Balance',
|
||||
}
|
||||
'ge_minconf': 'Balance'}
|
||||
|
||||
async def __init__(self, cfg, proto, *, minconf, quiet):
|
||||
self.twctl = await TwCtl(cfg, proto, mode='w')
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@ class EthereumTwCtl(TwCtlWithStore):
|
|||
'coin': self.proto.coin,
|
||||
'network': self.proto.network.upper(),
|
||||
'accounts': {},
|
||||
'tokens': {},
|
||||
}
|
||||
'tokens': {}}
|
||||
|
||||
def upgrade_wallet_maybe(self):
|
||||
|
||||
|
|
@ -182,6 +181,4 @@ class EthereumTokenTwCtl(EthereumTwCtl):
|
|||
self.data['tokens'][tokenaddr] = {
|
||||
'params': {
|
||||
'symbol': await t.get_symbol(),
|
||||
'decimals': await t.get_decimals()
|
||||
}
|
||||
}
|
||||
'decimals': await t.get_decimals()}}
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@ class EthereumTwJSON(TwJSON):
|
|||
|
||||
return self.json_dump({
|
||||
'accounts': list(gen_mappings(self.entries['accounts'])),
|
||||
'tokens': {k:list(gen_mappings(v)) for k, v in self.entries['tokens'].items()}
|
||||
})
|
||||
'tokens': {k: list(gen_mappings(v)) for k, v in self.entries['tokens'].items()}})
|
||||
|
||||
@property
|
||||
def num_entries(self):
|
||||
|
|
@ -82,8 +81,7 @@ class EthereumTwJSON(TwJSON):
|
|||
|
||||
return {
|
||||
'accounts': list(gen_entries(edata['accounts'])),
|
||||
'tokens': dict(list(gen_token_entries()))
|
||||
}
|
||||
'tokens': dict(list(gen_token_entries()))}
|
||||
|
||||
async def do_import(self, batch):
|
||||
|
||||
|
|
@ -103,8 +101,7 @@ class EthereumTwJSON(TwJSON):
|
|||
'coin': self.coin.upper(),
|
||||
'network': self.network.upper(),
|
||||
'accounts': dict(gen_data(self.entries['accounts'])),
|
||||
'tokens': {k:dict(gen_data(v)) for k, v in self.entries['tokens'].items()},
|
||||
}
|
||||
'tokens': {k: dict(gen_data(v)) for k, v in self.entries['tokens'].items()}}
|
||||
self.twctl.write(quiet=False)
|
||||
|
||||
class Export(TwJSON.Export, Base):
|
||||
|
|
@ -134,8 +131,7 @@ class EthereumTwJSON(TwJSON):
|
|||
'accounts': sorted(
|
||||
gen_data(self.twctl.data['accounts']),
|
||||
key = lambda x: x.mmgen_id.sort_key),
|
||||
'tokens': dict(sorted(gen_token_data()))
|
||||
}
|
||||
'tokens': dict(sorted(gen_token_data()))}
|
||||
|
||||
@property
|
||||
async def entries_out(self):
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class Signed(Completed, TxBase.Signed):
|
|||
'gasPrice': self.proto.coin_amt(d['gasprice'], from_unit='wei'),
|
||||
'startGas': d['startgas'],
|
||||
'nonce': ETHNonce(d['nonce']),
|
||||
'data': HexStr(d['data']) }
|
||||
'data': HexStr(d['data'])}
|
||||
if o['data'] and not o['to']: # token- or contract-creating transaction
|
||||
# NB: could be a non-token contract address:
|
||||
o['token_addr'] = ContractAddr(self.proto, etx.creates.hex())
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ class New:
|
|||
o_ok = 0 if self.usr_contract_data else 1
|
||||
assert o_num == o_ok, f'Transaction has {o_num} output{suf(o_num)} (should have {o_ok})'
|
||||
await self.make_txobj()
|
||||
self.serialized = {k:v if v is None else str(v) for k, v in self.txobj.items() if k != 'token_to'}
|
||||
self.serialized = {k: v if v is None else str(v)
|
||||
for k, v in self.txobj.items() if k != 'token_to'}
|
||||
self.update_txid()
|
||||
|
||||
def update_txid(self, data=None):
|
||||
|
|
|
|||
|
|
@ -29,8 +29,7 @@ class monero_daemon(CoinDaemon):
|
|||
datadirs = {
|
||||
'linux': [gc.home_dir, '.bitmonero'],
|
||||
'darwin': [gc.home_dir, '.bitmonero'],
|
||||
'win32': ['/', 'c', 'ProgramData', 'bitmonero']
|
||||
}
|
||||
'win32': ['/', 'c', 'ProgramData', 'bitmonero']}
|
||||
|
||||
def init_datadir(self):
|
||||
self.logdir = super().init_datadir()
|
||||
|
|
|
|||
|
|
@ -47,8 +47,7 @@ class CoinProtocol(MMGenObject):
|
|||
'etc': proto_info('EthereumClassic', 4),
|
||||
'zec': proto_info('Zcash', 2),
|
||||
'xmr': proto_info('Monero', 5),
|
||||
'rune': proto_info('THORChain', 4)
|
||||
}
|
||||
'rune': proto_info('THORChain', 4)}
|
||||
|
||||
class Base(Lockable):
|
||||
base_proto = None
|
||||
|
|
@ -82,14 +81,14 @@ class CoinProtocol(MMGenObject):
|
|||
}[network]
|
||||
|
||||
if hasattr(self, 'wif_ver_num'):
|
||||
self.wif_ver_bytes = {k:bytes.fromhex(v) for k, v in self.wif_ver_num.items()}
|
||||
self.wif_ver_bytes_to_pubkey_type = {v:k for k, v in self.wif_ver_bytes.items()}
|
||||
self.wif_ver_bytes = {k: bytes.fromhex(v) for k, v in self.wif_ver_num.items()}
|
||||
self.wif_ver_bytes_to_pubkey_type = {v: k for k, v in self.wif_ver_bytes.items()}
|
||||
vbs = list(self.wif_ver_bytes.values())
|
||||
self.wif_ver_bytes_len = len(vbs[0]) if len(set(len(b) for b in vbs)) == 1 else None
|
||||
|
||||
if hasattr(self, 'addr_ver_info'):
|
||||
self.addr_ver_bytes = {bytes.fromhex(k):v for k, v in self.addr_ver_info.items()}
|
||||
self.addr_fmt_to_ver_bytes = {v:k for k, v in self.addr_ver_bytes.items()}
|
||||
self.addr_ver_bytes = {bytes.fromhex(k): v for k, v in self.addr_ver_info.items()}
|
||||
self.addr_fmt_to_ver_bytes = {v: k for k, v in self.addr_ver_bytes.items()}
|
||||
self.addr_ver_bytes_len = len(list(self.addr_ver_bytes)[0])
|
||||
|
||||
if gc.cmd_caps:
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@ class requests(base):
|
|||
if self.proxy: # used only by XMR for now: requires pysocks package
|
||||
self.session.proxies.update({
|
||||
'http': f'socks5h://{self.proxy}',
|
||||
'https': f'socks5h://{self.proxy}'
|
||||
})
|
||||
'https': f'socks5h://{self.proxy}'})
|
||||
|
||||
async def run(self, *args, **kwargs):
|
||||
return self.run_noasync(*args, **kwargs)
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ class SeedShareBase(MMGenObject):
|
|||
class SeedShare(SeedShareBase, SubSeed):
|
||||
|
||||
@staticmethod
|
||||
def make_subseed_bin(parent_list, idx:int, nonce:int, length:str):
|
||||
def make_subseed_bin(parent_list, idx: int, nonce: int, length: str):
|
||||
seed = parent_list.parent_seed
|
||||
assert parent_list.have_short is False
|
||||
assert length == 'long'
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ class SubSeed(SeedBase):
|
|||
seed_bin=self.make_subseed_bin(parent_list, idx, nonce, length))
|
||||
|
||||
@staticmethod
|
||||
def make_subseed_bin(parent_list, idx:int, nonce:int, length:str):
|
||||
def make_subseed_bin(parent_list, idx: int, nonce: int, length: str):
|
||||
seed = parent_list.parent_seed
|
||||
short = {'short': True, 'long': False}[length]
|
||||
# field maximums: idx: 4294967295 (1000000), nonce: 65535 (1000), short: 255 (1)
|
||||
|
|
|
|||
|
|
@ -40,8 +40,7 @@ class THORChainSwapAsset(SwapAsset):
|
|||
'ETH.vTHOR': _ad('THORSwap Staking (ETH)', None, 'ETH.vTHOR', None, True),
|
||||
'ETH.WBTC': _ad('Wrapped BTC (ETH)', None, 'ETH.WBTC', None, True),
|
||||
'ETH.XRUNE': _ad('Thorstarter (ETH)', None, 'ETH.XRUNE', None, True),
|
||||
'ETH.YFI': _ad('yearn.finance (ETH)', None, 'ETH.YFI', None, True),
|
||||
}
|
||||
'ETH.YFI': _ad('yearn.finance (ETH)', None, 'ETH.YFI', None, True)}
|
||||
|
||||
evm_contracts = {
|
||||
'ETH.AAVE': '7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9',
|
||||
|
|
@ -60,8 +59,7 @@ class THORChainSwapAsset(SwapAsset):
|
|||
'ETH.vTHOR': '815c23eca83261b6ec689b60cc4a58b54bc24d8d',
|
||||
'ETH.WBTC': '2260fac5e5542a773aa44fbcfedf7c193bc2c599',
|
||||
'ETH.XRUNE': '69fa0fee221ad11012bab0fdb45d444d3d2ce71c',
|
||||
'ETH.YFI': '0bc529c00c6401aef6d220be8c6ea1667f6ad93e',
|
||||
}
|
||||
'ETH.YFI': '0bc529c00c6401aef6d220be8c6ea1667f6ad93e'}
|
||||
|
||||
unsupported = ('DOGE',)
|
||||
|
||||
|
|
|
|||
|
|
@ -24,8 +24,7 @@ class THORChainMemo:
|
|||
function = 'SWAP'
|
||||
|
||||
function_abbrevs = {
|
||||
'SWAP': '=',
|
||||
}
|
||||
'SWAP': '='}
|
||||
|
||||
@classmethod
|
||||
def is_partial_memo(cls, bytes_data):
|
||||
|
|
@ -38,8 +37,7 @@ class THORChainMemo:
|
|||
'pool': (r'POOL(\+|-)',),
|
||||
'trade': (r'TRADE(\+|-)',),
|
||||
'secure': (r'SECURE(\+|-)',),
|
||||
'misc': ('BOND', 'UNBOND', 'LEAVE', 'MIGRATE', 'NOOP', 'DONATE', 'RESERVE'),
|
||||
}
|
||||
'misc': ('BOND', 'UNBOND', 'LEAVE', 'MIGRATE', 'NOOP', 'DONATE', 'RESERVE')}
|
||||
pat = r'^(' + '|'.join('|'.join(pats) for pats in ops.values()) + r'):\S\S+'
|
||||
return bool(re.search(pat.encode(), bytes_data))
|
||||
|
||||
|
|
@ -60,7 +58,7 @@ class THORChainMemo:
|
|||
def get_id(data, item, desc):
|
||||
if item in data:
|
||||
return item
|
||||
rev_data = {v:k for k,v in data.items()}
|
||||
rev_data = {v: k for k,v in data.items()}
|
||||
if item in rev_data:
|
||||
return rev_data[item]
|
||||
die('SwapMemoParseError', f'{item!r}: unrecognized {proto_name} {desc} abbreviation')
|
||||
|
|
|
|||
|
|
@ -74,8 +74,7 @@ class Thornode:
|
|||
self.data = in_data | {
|
||||
'expected_amount_out': out_data['expected_amount_out'],
|
||||
'fees': out_data['fees'],
|
||||
'expiry': min(in_data['expiry'], out_data['expiry'])
|
||||
}
|
||||
'expiry': min(in_data['expiry'], out_data['expiry'])}
|
||||
else:
|
||||
self.data = get_data(
|
||||
self.tx.send_asset.full_name,
|
||||
|
|
|
|||
|
|
@ -47,4 +47,4 @@ class tool_cmd_base(MMGenObject):
|
|||
|
||||
@property
|
||||
def user_commands(self):
|
||||
return {k:v for k, v in type(self).__dict__.items() if callable(v) and not k.startswith('_')}
|
||||
return {k: v for k, v in type(self).__dict__.items() if callable(v) and not k.startswith('_')}
|
||||
|
|
|
|||
|
|
@ -33,9 +33,9 @@ class tool_cmd(tool_cmd_base):
|
|||
super().__init__(cfg=cfg, cmdname=cmdname, proto=proto, mmtype=mmtype)
|
||||
|
||||
def _file_chksum(self, mmgen_addrfile, obj):
|
||||
kwargs = {'skip_chksum_msg':True}
|
||||
kwargs = {'skip_chksum_msg': True}
|
||||
if not obj.__name__ == 'PasswordList':
|
||||
kwargs.update({'key_address_validity_check':False})
|
||||
kwargs.update({'key_address_validity_check': False})
|
||||
ret = obj(self.cfg, self.proto, infile=mmgen_addrfile, **kwargs)
|
||||
if self.cfg.verbose:
|
||||
from ..util import msg, capfirst
|
||||
|
|
@ -85,9 +85,7 @@ class tool_cmd(tool_cmd_base):
|
|||
'pager': 'send output to pager',
|
||||
'terse': 'produce compact tabular output',
|
||||
'sort': 'sort order for transaction inputs and outputs ' + options_annot_str(['addr', 'raw']),
|
||||
'filesort': 'file sort order ' + options_annot_str(['mtime', 'ctime', 'atime']),
|
||||
}
|
||||
},
|
||||
'filesort': 'file sort order ' + options_annot_str(['mtime', 'ctime', 'atime'])}},
|
||||
*infiles,
|
||||
**kwargs):
|
||||
"display specified raw or signed MMGen transaction files in human-readable form"
|
||||
|
|
|
|||
|
|
@ -81,26 +81,26 @@ class tool_cmd(tool_cmd_base):
|
|||
msg(f'Seed: {randbytes.hex()}')
|
||||
return self.hex2mn(randbytes.hex(), fmt=fmt)
|
||||
|
||||
def mn_rand128(self, fmt:mn_opts_disp = dfl_mnemonic_fmt):
|
||||
def mn_rand128(self, fmt: mn_opts_disp = dfl_mnemonic_fmt):
|
||||
"generate a random 128-bit mnemonic seed phrase"
|
||||
return self._do_random_mn(16, fmt)
|
||||
|
||||
def mn_rand192(self, fmt:mn_opts_disp = dfl_mnemonic_fmt):
|
||||
def mn_rand192(self, fmt: mn_opts_disp = dfl_mnemonic_fmt):
|
||||
"generate a random 192-bit mnemonic seed phrase"
|
||||
return self._do_random_mn(24, fmt)
|
||||
|
||||
def mn_rand256(self, fmt:mn_opts_disp = dfl_mnemonic_fmt):
|
||||
def mn_rand256(self, fmt: mn_opts_disp = dfl_mnemonic_fmt):
|
||||
"generate a random 256-bit mnemonic seed phrase"
|
||||
return self._do_random_mn(32, fmt)
|
||||
|
||||
def hex2mn(self, hexstr: 'sstr', fmt:mn_opts_disp = dfl_mnemonic_fmt):
|
||||
def hex2mn(self, hexstr: 'sstr', fmt: mn_opts_disp = dfl_mnemonic_fmt):
|
||||
"convert a 16, 24 or 32-byte hexadecimal string to a mnemonic seed phrase"
|
||||
if fmt == 'xmrseed':
|
||||
hexstr = self._xmr_reduce(bytes.fromhex(hexstr)).hex()
|
||||
f = mnemonic_fmts[fmt]
|
||||
return ' '.join(f.conv_cls(fmt).fromhex(hexstr, pad=f.pad))
|
||||
|
||||
def mn2hex(self, seed_mnemonic: 'sstr', fmt:mn_opts_disp = dfl_mnemonic_fmt):
|
||||
def mn2hex(self, seed_mnemonic: 'sstr', fmt: mn_opts_disp = dfl_mnemonic_fmt):
|
||||
"convert a mnemonic seed phrase to a hexadecimal string"
|
||||
f = mnemonic_fmts[fmt]
|
||||
return f.conv_cls(fmt).tohex(seed_mnemonic.split(), pad=f.pad)
|
||||
|
|
@ -118,7 +118,7 @@ class tool_cmd(tool_cmd_base):
|
|||
msg(mn)
|
||||
return self.mn2hex(seed_mnemonic=mn, fmt=fmt)
|
||||
|
||||
def mn_stats(self, fmt:mn_opts_disp = dfl_mnemonic_fmt):
|
||||
def mn_stats(self, fmt: mn_opts_disp = dfl_mnemonic_fmt):
|
||||
"show stats for a mnemonic wordlist"
|
||||
return mnemonic_fmts[fmt].conv_cls(fmt).check_wordlist(self.cfg)
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class TwAddresses(TwView):
|
|||
filters = ('showempty', 'showused', 'all_labels')
|
||||
showcoinaddrs = True
|
||||
showempty = True
|
||||
showused = 1 # tristate: 0:no, 1:yes, 2:all
|
||||
showused = 1 # tristate: 0: no, 1: yes, 2: all
|
||||
all_labels = False
|
||||
mod_subpath = 'tw.addresses'
|
||||
has_age = False
|
||||
|
|
@ -191,20 +191,16 @@ class TwAddresses(TwView):
|
|||
'date': self.age_w if self.has_age else 0,
|
||||
'block': self.age_col_params['block'][0] if wide and self.has_age else 0,
|
||||
'date_time': self.age_col_params['date_time'][0] if wide and self.has_age else 0,
|
||||
'spc': self.spc_w,
|
||||
},
|
||||
'spc': self.spc_w},
|
||||
maxws = { # expandable cols
|
||||
'addr': max(len(d.addr) for d in data) if self.showcoinaddrs else 0,
|
||||
'comment': max(d.comment.screen_width for d in data),
|
||||
},
|
||||
'comment': max(d.comment.screen_width for d in data)},
|
||||
minws = {
|
||||
'addr': 12 if self.showcoinaddrs else 0,
|
||||
'comment': len('Comment'),
|
||||
},
|
||||
'comment': len('Comment')},
|
||||
maxws_nice = {'addr': 18},
|
||||
wide = wide,
|
||||
interactive = interactive,
|
||||
)
|
||||
interactive = interactive)
|
||||
|
||||
def squeezed_col_hdr(self, cw, fs, color):
|
||||
return fs.format(
|
||||
|
|
@ -273,8 +269,7 @@ class TwAddresses(TwView):
|
|||
sort_disp = {
|
||||
'age': 'AddrListID+Age',
|
||||
'amt': 'AddrListID+Amt',
|
||||
'twmmid': 'MMGenID',
|
||||
}
|
||||
'twmmid': 'MMGenID'}
|
||||
|
||||
sort_funcs = {
|
||||
'age': lambda d: '{}_{}_{}'.format(
|
||||
|
|
@ -283,8 +278,7 @@ class TwAddresses(TwView):
|
|||
('{:>012}'.format(1_000_000_000 - d.confs) if d.confs else '_'),
|
||||
d.twmmid.sort_key),
|
||||
'amt': lambda d: f'{d.al_id}_{d.amt}',
|
||||
'twmmid': lambda d: d.twmmid.sort_key,
|
||||
}
|
||||
'twmmid': lambda d: d.twmmid.sort_key}
|
||||
|
||||
@property
|
||||
def dump_fn_pfx(self):
|
||||
|
|
|
|||
|
|
@ -38,15 +38,14 @@ class TwGetBalance(MMGenObject, metaclass=AsyncInit):
|
|||
'unconfirmed': amt0,
|
||||
'lt_minconf': amt0,
|
||||
'ge_minconf': amt0,
|
||||
'spendable': amt0,
|
||||
}
|
||||
'spendable': amt0}
|
||||
dict.__init__(self, **data)
|
||||
|
||||
self.minconf = NonNegativeInt(minconf)
|
||||
self.balance_info = BalanceInfo
|
||||
self.quiet = quiet
|
||||
self.proto = proto
|
||||
self.data = {k:self.balance_info() for k in self.start_labels}
|
||||
self.data = {k: self.balance_info() for k in self.start_labels}
|
||||
|
||||
if minconf < 2 and 'lt_minconf' in self.conf_cols:
|
||||
del self.conf_cols['lt_minconf']
|
||||
|
|
|
|||
|
|
@ -201,8 +201,8 @@ class TwJSON:
|
|||
'mappings_checksum': self.mappings_chksum,
|
||||
'entries_keys': self.keys,
|
||||
'entries': await self.entries_out,
|
||||
'num_entries': self.num_entries,
|
||||
}
|
||||
'num_entries': self.num_entries}
|
||||
|
||||
if include_amts:
|
||||
data['value'] = await self.total
|
||||
|
||||
|
|
|
|||
|
|
@ -86,22 +86,18 @@ class TwAddressesPrune(TwAddresses):
|
|||
|
||||
from collections import namedtuple
|
||||
md = namedtuple('mdata', ['wmsg', 'prompt'])
|
||||
|
||||
m = {
|
||||
'amt': md(
|
||||
red('Address #{a} ({b}) has a balance of {c}!'.format(
|
||||
a = addrnum,
|
||||
b = e.twmmid.addr,
|
||||
c = e.amt.hl2(color=False, unit=True))),
|
||||
'[p]rune anyway, [P]rune all with balance, [s]kip, [S]kip all with balance: ',
|
||||
),
|
||||
'[p]rune anyway, [P]rune all with balance, [s]kip, [S]kip all with balance: '),
|
||||
'used': md(
|
||||
yellow('Address #{a} ({b}) is used!'.format(
|
||||
a = addrnum,
|
||||
b = e.twmmid.addr)),
|
||||
'[p]rune anyway, [P]rune all used, [s]kip, [S]kip all used: ',
|
||||
),
|
||||
}
|
||||
'[p]rune anyway, [P]rune all used, [s]kip, [S]kip all used: ')}
|
||||
|
||||
from ..term import get_char
|
||||
valid_res = 'pPsS'
|
||||
|
|
|
|||
|
|
@ -97,8 +97,7 @@ class TwCtlWithStore(TwCtl, metaclass=AsyncInit):
|
|||
self.data = {
|
||||
'coin': self.proto.coin,
|
||||
'network': self.proto.network.upper(),
|
||||
'addresses': {},
|
||||
}
|
||||
'addresses': {}}
|
||||
|
||||
def init_from_wallet_file(self):
|
||||
from ..fileutil import check_or_create_dir, get_data_from_file
|
||||
|
|
|
|||
|
|
@ -63,18 +63,19 @@ class TwTxHistory(TwView):
|
|||
if not hasattr(self, 'varcol_maxwidths'):
|
||||
self.varcol_maxwidths = {
|
||||
'inputs': max(len(d.vouts_disp(
|
||||
'inputs', width=None, color=False, addr_view_pref=self.addr_view_pref)) for d in data),
|
||||
'inputs', width=None, color=False, addr_view_pref=self.addr_view_pref))
|
||||
for d in data),
|
||||
'outputs': max(len(d.vouts_disp(
|
||||
'outputs', width=None, color=False, addr_view_pref=self.addr_view_pref)) for d in data),
|
||||
'comment': max(len(d.comment) for d in data),
|
||||
}
|
||||
'outputs', width=None, color=False, addr_view_pref=self.addr_view_pref))
|
||||
for d in data),
|
||||
'comment': max(len(d.comment)
|
||||
for d in data)}
|
||||
|
||||
maxws = self.varcol_maxwidths.copy()
|
||||
minws = {
|
||||
'inputs': 15,
|
||||
'outputs': 15,
|
||||
'comment': len('Comment'),
|
||||
}
|
||||
'comment': len('Comment')}
|
||||
if self.show_txid:
|
||||
maxws['txid'] = self.txid_w
|
||||
minws['txid'] = 8
|
||||
|
|
@ -88,8 +89,7 @@ class TwTxHistory(TwView):
|
|||
'num': max(2, len(str(len(data)))+1),
|
||||
'date': self.age_w,
|
||||
'amt': self.amt_widths['amt'],
|
||||
'spc': 6 + self.show_txid, # 5(6) spaces between cols + 1 leading space in fs
|
||||
}
|
||||
'spc': 6 + self.show_txid} # 5(6) spaces between cols + 1 leading space in fs
|
||||
|
||||
return self.compute_column_widths(
|
||||
widths,
|
||||
|
|
@ -171,16 +171,14 @@ class TwTxHistory(TwView):
|
|||
'blockheight': 'Block Height',
|
||||
'amt': 'Wallet Amt',
|
||||
'total_amt': 'TX Amt',
|
||||
'txid': 'TxID',
|
||||
}
|
||||
'txid': 'TxID'}
|
||||
|
||||
sort_funcs = {
|
||||
'age': lambda i: '{:010}.{:010}'.format(0xffffffff - abs(i.confirmations), i.time_received or 0),
|
||||
'blockheight': lambda i: 0 - abs(i.confirmations), # old/altcoin daemons return no 'blockheight' field
|
||||
'amt': lambda i: i.wallet_outputs_total,
|
||||
'total_amt': lambda i: i.outputs_total,
|
||||
'txid': lambda i: i.txid,
|
||||
}
|
||||
'txid': lambda i: i.txid}
|
||||
|
||||
async def set_dates(self, _):
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -120,11 +120,10 @@ class TwUnspentOutputs(TwView):
|
|||
'twmmid': l.mmid,
|
||||
'comment': l.comment or '',
|
||||
'addr': CoinAddr(self.proto, o['address']),
|
||||
'confs': o['confirmations']
|
||||
})
|
||||
'confs': o['confirmations']})
|
||||
yield self.MMGenTwUnspentOutput(
|
||||
self.proto,
|
||||
**{k:v for k, v in o.items() if k in self.MMGenTwUnspentOutput.valid_attrs})
|
||||
**{k: v for k, v in o.items() if k in self.MMGenTwUnspentOutput.valid_attrs})
|
||||
|
||||
async def get_rpc_data(self):
|
||||
wl = self.twctl.sorted_list
|
||||
|
|
@ -170,8 +169,7 @@ class TwUnspentOutputs(TwView):
|
|||
'block': self.age_col_params['block'][0] if wide else 0,
|
||||
'date_time': self.age_col_params['date_time'][0] if wide else 0,
|
||||
'date': self.age_w,
|
||||
'spc': self.disp_spc + (2 * show_mmid) + self.has_amt2
|
||||
},
|
||||
'spc': self.disp_spc + (2 * show_mmid) + self.has_amt2},
|
||||
maxws = { # expandable cols
|
||||
'addr': max(len(d.addr) for d in data),
|
||||
'comment': max(d.comment.screen_width for d in data) if show_mmid else 0,
|
||||
|
|
|
|||
|
|
@ -121,8 +121,7 @@ class TwView(MMGenObject, metaclass=AsyncInit):
|
|||
'date_time': fp('D', True, True, ' {D:%s}', ' {D:%s}'),
|
||||
'block': fp('b', True, True, ' {b:%s}', ' {b:<%s}'),
|
||||
'inputs': fp('i', True, False, ' {i:%s}', ' {i}'),
|
||||
'outputs': fp('o', True, False, ' {o:%s}', ' {o}'),
|
||||
}
|
||||
'outputs': fp('o', True, False, ' {o:%s}', ' {o}')}
|
||||
|
||||
age_fmts = ('confs', 'block', 'days', 'date', 'date_time')
|
||||
age_fmts_date_dependent = ('days', 'date', 'date_time')
|
||||
|
|
@ -131,12 +130,11 @@ class TwView(MMGenObject, metaclass=AsyncInit):
|
|||
bch_addr_fmts = ('cashaddr', 'legacy')
|
||||
|
||||
age_col_params = {
|
||||
'confs': (0, 'Confs'),
|
||||
'block': (0, 'Block'),
|
||||
'days': (0, 'Age(d)'),
|
||||
'date': (0, 'Date'),
|
||||
'date_time': (0, 'Date/Time'),
|
||||
}
|
||||
'confs': (0, 'Confs'),
|
||||
'block': (0, 'Block'),
|
||||
'days': (0, 'Age(d)'),
|
||||
'date': (0, 'Date'),
|
||||
'date_time': (0, 'Date/Time')}
|
||||
|
||||
date_formatter = {
|
||||
'days': lambda rpc, secs: (rpc.cur_date - secs) // 86400 if secs else 0,
|
||||
|
|
@ -145,8 +143,7 @@ class TwView(MMGenObject, metaclass=AsyncInit):
|
|||
if secs else '- '),
|
||||
'date_time': (
|
||||
lambda rpc, secs: '{}-{:02}-{:02} {:02}:{:02}'.format(*time.gmtime(secs)[:5])
|
||||
if secs else '- '),
|
||||
}
|
||||
if secs else '- ')}
|
||||
|
||||
twidth_diemsg = """
|
||||
--columns or MMGEN_COLUMNS value ({}) is too small to display the {}
|
||||
|
|
@ -163,7 +160,6 @@ class TwView(MMGenObject, metaclass=AsyncInit):
|
|||
|
||||
squeezed_format_line = None
|
||||
detail_format_line = None
|
||||
|
||||
scroll_keys = {
|
||||
'vi': {
|
||||
'k': 'm_cursor_up',
|
||||
|
|
@ -171,25 +167,21 @@ class TwView(MMGenObject, metaclass=AsyncInit):
|
|||
'b': 'm_pg_up',
|
||||
'f': 'm_pg_down',
|
||||
'g': 'm_top',
|
||||
'G': 'm_bot',
|
||||
},
|
||||
'G': 'm_bot'},
|
||||
'linux': {
|
||||
'\x1b[A': 'm_cursor_up',
|
||||
'\x1b[B': 'm_cursor_down',
|
||||
'\x1b[5~': 'm_pg_up',
|
||||
'\x1b[6~': 'm_pg_down',
|
||||
'\x1b[7~': 'm_top',
|
||||
'\x1b[8~': 'm_bot',
|
||||
},
|
||||
'\x1b[8~': 'm_bot'},
|
||||
'win32': {
|
||||
'\xe0H': 'm_cursor_up',
|
||||
'\xe0P': 'm_cursor_down',
|
||||
'\xe0I': 'm_pg_up',
|
||||
'\xe0Q': 'm_pg_down',
|
||||
'\xe0G': 'm_top',
|
||||
'\xe0O': 'm_bot',
|
||||
}
|
||||
}
|
||||
'\xe0O': 'm_bot'}}
|
||||
scroll_keys['darwin'] = scroll_keys['linux']
|
||||
extra_key_mappings = {}
|
||||
|
||||
|
|
@ -248,16 +240,14 @@ class TwView(MMGenObject, metaclass=AsyncInit):
|
|||
'age': 'Age',
|
||||
'amt': 'Amt',
|
||||
'txid': 'TxID',
|
||||
'twmmid': 'MMGenID',
|
||||
}
|
||||
'twmmid': 'MMGenID'}
|
||||
|
||||
sort_funcs = {
|
||||
'addr': lambda i: i.addr,
|
||||
'age': lambda i: 0 - i.confs,
|
||||
'amt': lambda i: i.amt,
|
||||
'txid': lambda i: f'{i.txid} {i.vout:04}',
|
||||
'twmmid': lambda i: i.twmmid.sort_key
|
||||
}
|
||||
'twmmid': lambda i: i.twmmid.sort_key}
|
||||
|
||||
def sort_info(self, *, include_group=True):
|
||||
ret = ([], ['Reverse'])[self.reverse]
|
||||
|
|
@ -327,12 +317,12 @@ class TwView(MMGenObject, metaclass=AsyncInit):
|
|||
def compute_column_widths(self, widths, maxws, minws, maxws_nice, *, wide, interactive):
|
||||
|
||||
def do_ret(freews):
|
||||
widths.update({k:minws[k] + freews.get(k, 0) for k in minws})
|
||||
widths.update({k: minws[k] + freews.get(k, 0) for k in minws})
|
||||
widths.update({ikey: widths[key] - self.disp_prec - 1 for key, ikey in self.amt_keys.items()})
|
||||
return namedtuple('column_widths', widths.keys())(*widths.values())
|
||||
|
||||
def do_ret_max():
|
||||
widths.update({k:max(minws[k], maxws[k]) for k in minws})
|
||||
widths.update({k: max(minws[k], maxws[k]) for k in minws})
|
||||
widths.update({ikey: widths[key] - self.disp_prec - 1 for key, ikey in self.amt_keys.items()})
|
||||
return namedtuple('column_widths', widths.keys())(*widths.values())
|
||||
|
||||
|
|
@ -340,7 +330,7 @@ class TwView(MMGenObject, metaclass=AsyncInit):
|
|||
freew = cols - minw
|
||||
if freew and varw:
|
||||
x = freew / varw
|
||||
freews = {k:int(varws[k] * x) for k in varws}
|
||||
freews = {k: int(varws[k] * x) for k in varws}
|
||||
remainder = freew - sum(freews.values())
|
||||
for k in varws:
|
||||
if not remainder:
|
||||
|
|
@ -352,7 +342,7 @@ class TwView(MMGenObject, metaclass=AsyncInit):
|
|||
else:
|
||||
return {k:0 for k in varws}
|
||||
|
||||
varws = {k:maxws[k] - minws[k] for k in maxws if maxws[k] > minws[k]}
|
||||
varws = {k: maxws[k] - minws[k] for k in maxws if maxws[k] > minws[k]}
|
||||
minw = sum(widths.values()) + sum(minws.values())
|
||||
varw = sum(varws.values())
|
||||
|
||||
|
|
@ -383,7 +373,7 @@ class TwView(MMGenObject, metaclass=AsyncInit):
|
|||
sum(varws_lp.values()),
|
||||
minw + sum(widths_hp.values()))
|
||||
# sum the two for each field:
|
||||
return do_ret({k:widths_hp[k] + widths_lp.get(k, 0) for k in varws})
|
||||
return do_ret({k: widths_hp[k] + widths_lp.get(k, 0) for k in varws})
|
||||
else:
|
||||
return do_ret(get_freews(self.cols, varws, varw, minw))
|
||||
|
||||
|
|
@ -407,8 +397,9 @@ class TwView(MMGenObject, metaclass=AsyncInit):
|
|||
def set_amt_widths(self, data):
|
||||
# width of amts column: min(7, width of integer part) + len('.') + width of fractional part
|
||||
self.amt_widths = {
|
||||
k:min(7, max(len(str(getattr(d, k).to_integral_value())) for d in data)) + 1 + self.disp_prec
|
||||
for k in self.amt_keys}
|
||||
k: min(7, max(len(str(getattr(d, k).to_integral_value()))
|
||||
for d in data)) + 1 + self.disp_prec
|
||||
for k in self.amt_keys}
|
||||
|
||||
async def format(
|
||||
self,
|
||||
|
|
@ -428,7 +419,7 @@ class TwView(MMGenObject, metaclass=AsyncInit):
|
|||
sort_info = ' '.join(self.sort_info())
|
||||
|
||||
def fmt_filter(k):
|
||||
return '{}:{}'.format(k, {0:No, 1:Yes, 2:All}[getattr(self, k)])
|
||||
return '{}:{}'.format(k, {0: No, 1: Yes, 2: All}[getattr(self, k)])
|
||||
|
||||
yield '{} (sort order: {}){}'.format(
|
||||
self.hdr_lbl.upper(),
|
||||
|
|
@ -555,8 +546,7 @@ class TwView(MMGenObject, metaclass=AsyncInit):
|
|||
's_': 'sort_action',
|
||||
'd_': 'display_action',
|
||||
'm_': 'scroll_action',
|
||||
'i_': 'item_action',
|
||||
}
|
||||
'i_': 'item_action'}
|
||||
|
||||
def make_key_mappings(scroll):
|
||||
if scroll:
|
||||
|
|
|
|||
|
|
@ -274,8 +274,8 @@ class MMGenTxFile(MMGenObject):
|
|||
k: getattr(tx, k) for k in self.attrs
|
||||
} | {
|
||||
'inputs': [e._asdict() for e in tx.inputs],
|
||||
'outputs': [{k:v for k,v in e._asdict().items() if not (type(v) is bool and v is False)}
|
||||
for e in tx.outputs]
|
||||
'outputs': [{k: v for k,v in e._asdict().items()
|
||||
if not (type(v) is bool and v is False)} for e in tx.outputs]
|
||||
} | {
|
||||
k: getattr(tx, k) for k in self.extra_attrs if getattr(tx, k)
|
||||
} | ({
|
||||
|
|
|
|||
|
|
@ -47,8 +47,7 @@ def mmaddr2coinaddr(cfg, mmaddr, ad_w, ad_f, proto):
|
|||
No data for {gc.proj_name} address {mmaddr} could be found in the tracking
|
||||
wallet. Please import this address into your tracking wallet or supply an
|
||||
address file for it on the command line.
|
||||
"""
|
||||
}
|
||||
"""}
|
||||
return '\n' + fmt(messages[k], indent=' ')
|
||||
|
||||
# assume mmaddr has already been checked
|
||||
|
|
@ -72,7 +71,7 @@ def mmaddr2coinaddr(cfg, mmaddr, ad_w, ad_f, proto):
|
|||
|
||||
def parse_fee_spec(proto, fee_arg):
|
||||
import re
|
||||
units = {u[0]:u for u in proto.coin_amt.units}
|
||||
units = {u[0]: u for u in proto.coin_amt.units}
|
||||
pat = re.compile(r'((?:[1-9][0-9]*)|(?:[0-9]+\.[0-9]+))({})'.format('|'.join(units)))
|
||||
if m := pat.match(fee_arg):
|
||||
return namedtuple('parsed_fee_spec', ['amt', 'unit'])(m[1], units[m[2]])
|
||||
|
|
@ -370,7 +369,8 @@ class New(Base):
|
|||
for d in tw_unspent_data:
|
||||
i = self.Input(
|
||||
self.proto,
|
||||
**{attr:getattr(d, attr) for attr in d.__dict__ if attr in self.Input.tw_copy_attrs})
|
||||
**{attr: getattr(d, attr) for attr in d.__dict__
|
||||
if attr in self.Input.tw_copy_attrs})
|
||||
if d.twmmid.type == 'mmgen':
|
||||
i.mmid = d.twmmid # twmmid -> mmid
|
||||
yield i
|
||||
|
|
|
|||
|
|
@ -58,8 +58,7 @@ class BlockchairTxProxyClient(TxProxyClient):
|
|||
'eth': 'ethereum',
|
||||
'etc': 'ethereum-classic',
|
||||
'ltc': 'litecoin',
|
||||
'zec': 'zcash',
|
||||
}
|
||||
'zec': 'zcash'}
|
||||
active_assets = () # tried with ETH, doesn’t work
|
||||
|
||||
def create_post_data(self, *, form_text, coin, tx_hex):
|
||||
|
|
|
|||
|
|
@ -268,19 +268,15 @@ def suf(arg, suf_type='s', *, verb='none'):
|
|||
'none': {
|
||||
's': ('s', ''),
|
||||
'es': ('es', ''),
|
||||
'ies': ('ies', 'y'),
|
||||
},
|
||||
'ies': ('ies', 'y')},
|
||||
'is': {
|
||||
's': ('s are', ' is'),
|
||||
'es': ('es are', ' is'),
|
||||
'ies': ('ies are', 'y is'),
|
||||
},
|
||||
'ies': ('ies are', 'y is')},
|
||||
'has': {
|
||||
's': ('s have', ' has'),
|
||||
'es': ('es have', ' has'),
|
||||
'ies': ('ies have', 'y has'),
|
||||
},
|
||||
}
|
||||
'ies': ('ies have', 'y has')}}
|
||||
match arg:
|
||||
case int():
|
||||
return suf_types[verb][suf_type][arg == 1]
|
||||
|
|
|
|||
|
|
@ -116,8 +116,7 @@ class wallet(MMGenObject, metaclass=WalletMeta):
|
|||
'desc': desc or self.desc,
|
||||
'ask_tty': self.ask_tty,
|
||||
'no_tty': self.no_tty,
|
||||
'binary': self.file_mode == 'binary'
|
||||
}
|
||||
'binary': self.file_mode == 'binary'}
|
||||
|
||||
if outdir:
|
||||
# write_data_to_file(): outfile with absolute path overrides self.cfg.outdir
|
||||
|
|
|
|||
|
|
@ -27,8 +27,7 @@ class wallet(wallet):
|
|||
Make a record of the Incog ID but keep it secret. You will use it to
|
||||
identify your incog wallet data in the future.
|
||||
""",
|
||||
'decrypt_params': " {} hash preset"
|
||||
}
|
||||
'decrypt_params': " {} hash preset"}
|
||||
|
||||
def _make_iv_chksum(self, s):
|
||||
from hashlib import sha256
|
||||
|
|
|
|||
|
|
@ -43,8 +43,7 @@ class wallet(wallet):
|
|||
identify the incog wallet data in the future and to locate the offset
|
||||
where the data is hidden in the event you forget it.
|
||||
""",
|
||||
'decrypt_params': ', hash preset, offset {} seed length'
|
||||
}
|
||||
'decrypt_params': ', hash preset, offset {} seed length'}
|
||||
|
||||
def _get_hincog_params(self, wtype):
|
||||
# permit comma in filename:
|
||||
|
|
|
|||
|
|
@ -42,8 +42,7 @@ uarg_info = (
|
|||
'label_spec': e('WALLET:ACCOUNT:ADDRESS,"label text"', r'(\d+):(\d+):(\d+),(.*)'),
|
||||
})(
|
||||
namedtuple('uarg_info_entry', ['annot','pat']),
|
||||
r'(?:[^:]+):(?:\d+)'
|
||||
)
|
||||
r'(?:[^:]+):(?:\d+)')
|
||||
|
||||
# canonical op names mapped to their respective modules:
|
||||
op_names = {
|
||||
|
|
|
|||
|
|
@ -50,10 +50,9 @@ class MoneroMMGenFile:
|
|||
'data': in_data,
|
||||
} if self.full_chksum else {
|
||||
'base_chksum': self.base_chksum,
|
||||
'data': in_data,
|
||||
}
|
||||
'data': in_data}
|
||||
return json.dumps(
|
||||
{ self.data_label: out },
|
||||
{self.data_label: out},
|
||||
cls = json_encoder,
|
||||
indent = 2,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -87,11 +87,10 @@ class MoneroWalletOutputsFile:
|
|||
init_data = dict.fromkeys(self.data_tuple._fields)
|
||||
init_data.update({
|
||||
'seed_id': parent.kal.al_id.sid,
|
||||
'wallet_index': wallet_idx or parent.get_idx_from_fn(wallet_fn),
|
||||
})
|
||||
'wallet_index': wallet_idx or parent.get_idx_from_fn(wallet_fn)})
|
||||
if sign:
|
||||
init_data['sign'] = sign
|
||||
init_data.update({k:v for k, v in data.items() if k in init_data})
|
||||
init_data.update({k: v for k, v in data.items() if k in init_data})
|
||||
self.data = self.data_tuple(**init_data)
|
||||
|
||||
class Completed(New):
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class MoneroMMGenTX:
|
|||
'seed_id',
|
||||
'source',
|
||||
'dest',
|
||||
'amount' }
|
||||
'amount'}
|
||||
full_chksum_fields = {
|
||||
'op',
|
||||
'create_time',
|
||||
|
|
@ -52,7 +52,7 @@ class MoneroMMGenTX:
|
|||
'dest',
|
||||
'amount',
|
||||
'fee',
|
||||
'blob' }
|
||||
'blob'}
|
||||
oneline_fs = '{a:7} {b:8} {c:19} {d:13} {e:9} {f:6} {x:2} {g:6} {h:17} {j}'
|
||||
oneline_fixed_cols_w = 96 # width of all columns except the last (coin address)
|
||||
chksum_nchars = 6
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ class OpRestore(OpCreate):
|
|||
msg(fs.format(acct_idx, addr_idx, addr_data['label']))
|
||||
self.c.call(
|
||||
'label_address',
|
||||
index = { 'major': acct_idx, 'minor': addr_idx },
|
||||
index = {'major': acct_idx, 'minor': addr_idx},
|
||||
label = addr_data['label'],
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -135,9 +135,8 @@ class MoneroWalletRPC:
|
|||
def set_label(self, account, address_idx, label):
|
||||
return self.c.call(
|
||||
'label_address',
|
||||
index = { 'major': account, 'minor': address_idx },
|
||||
label = label
|
||||
)
|
||||
index = {'major': account, 'minor': address_idx},
|
||||
label = label)
|
||||
|
||||
def make_transfer_tx(self, account, addr, amt):
|
||||
res = self.c.call(
|
||||
|
|
@ -145,8 +144,7 @@ class MoneroWalletRPC:
|
|||
account_index = account,
|
||||
destinations = [{
|
||||
'amount': amt.to_unit('atomic'),
|
||||
'address': addr
|
||||
}],
|
||||
'address': addr}],
|
||||
priority = self.cfg.priority or None,
|
||||
do_not_relay = True,
|
||||
get_tx_hex = True,
|
||||
|
|
|
|||
|
|
@ -105,9 +105,9 @@ def main():
|
|||
slip44_data = json.loads(fh.read())
|
||||
|
||||
bip_utils_data = {
|
||||
n:{v.m_coin_idx:(k, v) for k, v in globals()[f'Bip{n}Conf'].__dict__.items() if not k.startswith('_')}
|
||||
for n in (44, 49, 84, 86)
|
||||
}
|
||||
n: {v.m_coin_idx: (k, v)
|
||||
for k, v in globals()[f'Bip{n}Conf'].__dict__.items() if not k.startswith('_')}
|
||||
for n in (44, 49, 84, 86)}
|
||||
|
||||
print('\n'.join(gen()))
|
||||
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ def compile_code(cfg, code):
|
|||
msg(err)
|
||||
if cfg.stdout:
|
||||
o = out.split('\n')
|
||||
return {k:o[i+2] for k in ('SafeMath', 'Owned', 'Token') for i in range(len(o)) if k in o[i]}
|
||||
return {k: o[i+2] for k in ('SafeMath', 'Owned', 'Token') for i in range(len(o)) if k in o[i]}
|
||||
else:
|
||||
cfg._util.vmsg(out)
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ scripts/exec_wrapper.py: wrapper to launch MMGen scripts in a testing environmen
|
|||
def exec_wrapper_get_colors():
|
||||
from collections import namedtuple
|
||||
return namedtuple('colors', ['red', 'green', 'yellow', 'blue', 'purple'])(*[
|
||||
(lambda s:s) if exec_wrapper_os.getenv('MMGEN_DISABLE_COLOR') else
|
||||
(lambda s, n=n:f'\033[{n};1m{s}\033[0m')
|
||||
(lambda s: s) if exec_wrapper_os.getenv('MMGEN_DISABLE_COLOR') else
|
||||
(lambda s, n=n: f'\033[{n};1m{s}\033[0m')
|
||||
for n in (31, 32, 33, 34, 35)])
|
||||
|
||||
def exec_wrapper_init():
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ def cleanup_file(fn):
|
|||
|
||||
def gen_text():
|
||||
for line in data.split('\n'): # do not use splitlines()
|
||||
line = line.translate({ord(a):b for a, b in translate.items()})
|
||||
line = line.translate({ord(a): b for a, b in translate.items()})
|
||||
line = re.sub(r'\s+$', '', line) # trailing whitespace
|
||||
yield line
|
||||
|
||||
|
|
|
|||
|
|
@ -83,17 +83,13 @@ sample_text = 'The Times 03/Jan/2009 Chancellor on brink of second bailout for b
|
|||
sample_mn = {
|
||||
'mmgen': { # 'able': 0, 'youth': 1625, 'after' == 'afternoon'[:5]
|
||||
'mn': 'able cast forgive master funny gaze after afternoon million paint moral youth',
|
||||
'hex': '0005685ab4e94cbe3b228cf92112bc5f',
|
||||
},
|
||||
'hex': '0005685ab4e94cbe3b228cf92112bc5f'},
|
||||
'bip39': { # len('sun') < uniq_ss_len
|
||||
'mn': 'vessel ladder alter error federal sibling chat ability sun glass valve picture',
|
||||
'hex': 'f30f8c1da665478f49b001d94c5fc452',
|
||||
},
|
||||
'hex': 'f30f8c1da665478f49b001d94c5fc452'},
|
||||
'xmrseed': {
|
||||
'mn': 'viewpoint donuts ardent template unveil agile meant unafraid urgent athlete rustled mime azure jaded hawk baby jagged haystack baby jagged haystack ramped oncoming point template',
|
||||
'hex': 'e8164dda6d42bd1e261a3406b2038dcbddadbeefdeadbeefdeadbeefdeadbe0f',
|
||||
},
|
||||
}
|
||||
'hex': 'e8164dda6d42bd1e261a3406b2038dcbddadbeefdeadbeefdeadbeefdeadbe0f'}}
|
||||
|
||||
ref_kafile_pass = 'kafile password'
|
||||
ref_kafile_hash_preset = '1'
|
||||
|
|
@ -168,7 +164,7 @@ def mk_tmpdir(d):
|
|||
def clean(cfgs, tmpdir_ids=None, extra_dirs=[]):
|
||||
|
||||
def clean_tmpdirs():
|
||||
cfg_tmpdirs = {k:cfgs[k]['tmpdir'] for k in cfgs}
|
||||
cfg_tmpdirs = {k: cfgs[k]['tmpdir'] for k in cfgs}
|
||||
for d in map(str, sorted(map(int, (tmpdir_ids or cfg_tmpdirs)))):
|
||||
if d in cfg_tmpdirs:
|
||||
if cleandir(cfg_tmpdirs[d]):
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@ if overlay_fake_os.getenv('MMGEN_TEST_SUITE_DETERMINISTIC'):
|
|||
'date': lambda rpc, secs: '{}-{:02}-{:02}'.format(
|
||||
*time.gmtime(next(overlay_fake_data.time_iter))[:3])[2:],
|
||||
'date_time': lambda rpc, secs: '{}-{:02}-{:02} {:02}:{:02}'.format(
|
||||
*time.gmtime(next(overlay_fake_data.time_iter))[:5]),
|
||||
}
|
||||
*time.gmtime(next(overlay_fake_data.time_iter))[:5])}
|
||||
|
||||
if overlay_fake_os.getenv('MMGEN_BOGUS_UNSPENT_DATA'):
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue