Browse Source

keyword-only parameters throughout

The MMGen Project 2 weeks ago
parent
commit
89ad0fd29b
101 changed files with 314 additions and 269 deletions
  1. 3 3
      mmgen/addr.py
  2. 4 3
      mmgen/addrfile.py
  3. 1 0
      mmgen/addrlist.py
  4. 2 2
      mmgen/altcoin/params.py
  5. 5 5
      mmgen/amt.py
  6. 9 9
      mmgen/autosign.py
  7. 6 6
      mmgen/baseconv.py
  8. 4 4
      mmgen/bip39.py
  9. 9 7
      mmgen/bip_hd/__init__.py
  10. 3 2
      mmgen/cfg.py
  11. 4 2
      mmgen/crypto.py
  12. 6 4
      mmgen/daemon.py
  13. 1 1
      mmgen/devtools.py
  14. 8 8
      mmgen/filename.py
  15. 10 7
      mmgen/fileutil.py
  16. 1 1
      mmgen/help/help_notes.py
  17. 1 1
      mmgen/help/txsign.py
  18. 2 2
      mmgen/keygen.py
  19. 1 1
      mmgen/led.py
  20. 2 2
      mmgen/main_addrgen.py
  21. 2 2
      mmgen/main_addrimport.py
  22. 2 2
      mmgen/main_passgen.py
  23. 1 1
      mmgen/main_seedjoin.py
  24. 7 4
      mmgen/main_tool.py
  25. 2 2
      mmgen/main_wallet.py
  26. 1 1
      mmgen/mn_entry.py
  27. 1 1
      mmgen/msg.py
  28. 5 5
      mmgen/obj.py
  29. 9 8
      mmgen/objmethods.py
  30. 1 0
      mmgen/passwdlist.py
  31. 2 2
      mmgen/platform/darwin/util.py
  32. 6 6
      mmgen/proto/btc/regtest.py
  33. 4 2
      mmgen/proto/btc/rpc.py
  34. 1 1
      mmgen/proto/btc/tw/ctl.py
  35. 2 2
      mmgen/proto/btc/tx/base.py
  36. 1 1
      mmgen/proto/btc/tx/info.py
  37. 1 1
      mmgen/proto/btc/tx/online.py
  38. 1 1
      mmgen/proto/btc/tx/op_return_data.py
  39. 1 1
      mmgen/proto/eth/contract.py
  40. 3 3
      mmgen/proto/eth/daemon.py
  41. 1 1
      mmgen/proto/eth/misc.py
  42. 5 5
      mmgen/proto/eth/tw/ctl.py
  43. 1 1
      mmgen/proto/eth/tw/json.py
  44. 1 1
      mmgen/proto/eth/tw/unspent.py
  45. 1 1
      mmgen/proto/eth/tx/online.py
  46. 2 2
      mmgen/proto/secp256k1/keygen.py
  47. 1 0
      mmgen/proto/xmr/daemon.py
  48. 5 4
      mmgen/proto/xmr/rpc.py
  49. 3 2
      mmgen/protocol.py
  50. 7 6
      mmgen/rpc.py
  51. 5 5
      mmgen/seedsplit.py
  52. 1 1
      mmgen/sha2.py
  53. 2 2
      mmgen/subseed.py
  54. 8 8
      mmgen/term.py
  55. 1 1
      mmgen/tool/coin.py
  56. 1 1
      mmgen/tool/file.py
  57. 4 4
      mmgen/tool/filecrypt.py
  58. 5 4
      mmgen/tool/fileutil.py
  59. 4 2
      mmgen/tool/mnemonic.py
  60. 7 6
      mmgen/tool/rpc.py
  61. 7 4
      mmgen/tool/util.py
  62. 8 6
      mmgen/tool/wallet.py
  63. 1 1
      mmgen/tw/addresses.py
  64. 8 6
      mmgen/tw/ctl.py
  65. 5 2
      mmgen/tw/json.py
  66. 4 3
      mmgen/tw/view.py
  67. 2 1
      mmgen/tx/base.py
  68. 4 4
      mmgen/tx/file.py
  69. 3 3
      mmgen/tx/info.py
  70. 4 4
      mmgen/tx/new.py
  71. 4 4
      mmgen/tx/sign.py
  72. 3 2
      mmgen/ui.py
  73. 9 8
      mmgen/util.py
  74. 5 4
      mmgen/util2.py
  75. 3 0
      mmgen/wallet/__init__.py
  76. 1 1
      mmgen/wallet/base.py
  77. 2 2
      mmgen/wallet/incog_base.py
  78. 4 4
      mmgen/wallet/mnemonic.py
  79. 1 1
      mmgen/xmrseed.py
  80. 1 1
      mmgen/xmrwallet/file/__init__.py
  81. 3 3
      mmgen/xmrwallet/file/outputs.py
  82. 1 1
      mmgen/xmrwallet/file/tx.py
  83. 1 1
      mmgen/xmrwallet/ops/import.py
  84. 1 1
      mmgen/xmrwallet/ops/relay.py
  85. 1 1
      mmgen/xmrwallet/ops/sign.py
  86. 1 1
      mmgen/xmrwallet/ops/wallet.py
  87. 3 3
      mmgen/xmrwallet/rpc.py
  88. 1 1
      test/cmdtest_d/ct_ethdev.py
  89. 5 5
      test/cmdtest_d/ct_main.py
  90. 2 2
      test/cmdtest_d/ct_regtest.py
  91. 1 1
      test/cmdtest_d/ct_shared.py
  92. 1 1
      test/cmdtest_d/ct_xmr_autosign.py
  93. 2 2
      test/daemontest_d/ut_exec.py
  94. 3 3
      test/daemontest_d/ut_rpc.py
  95. 1 1
      test/daemontest_d/ut_tx.py
  96. 3 3
      test/gentest.py
  97. 1 1
      test/include/common.py
  98. 1 1
      test/modtest_d/ut_bip_hd.py
  99. 1 1
      test/modtest_d/ut_gen.py
  100. 1 1
      test/modtest_d/ut_misc.py
  101. 1 1
      test/modtest_d/ut_seedsplit.py

+ 3 - 3
mmgen/addr.py

@@ -182,14 +182,14 @@ class CoinAddr(HiliteStr, InitErrors, MMGenObject):
 
 
 	# reimplement some HiliteStr methods:
 	# reimplement some HiliteStr methods:
 	@classmethod
 	@classmethod
-	def fmtc(cls, s, width, color=False):
+	def fmtc(cls, s, width, *, color=False):
 		return super().fmtc(s=s[:width-2]+'..' if len(s) > width else s, width=width, color=color)
 		return super().fmtc(s=s[:width-2]+'..' if len(s) > width else s, width=width, color=color)
 
 
-	def fmt(self, view_pref, width, color=False):
+	def fmt(self, view_pref, width, *, color=False):
 		s = self.views[view_pref]
 		s = self.views[view_pref]
 		return super().fmtc(f'{s[:width-2]}..' if len(s) > width else s, width=width, color=color)
 		return super().fmtc(f'{s[:width-2]}..' if len(s) > width else s, width=width, color=color)
 
 
-	def hl(self, view_pref, color=True):
+	def hl(self, view_pref, *, color=True):
 		return getattr(color_mod, self.color)(self.views[view_pref]) if color else self.views[view_pref]
 		return getattr(color_mod, self.color)(self.views[view_pref]) if color else self.views[view_pref]
 
 
 def is_coin_addr(proto, s):
 def is_coin_addr(proto, s):

+ 4 - 3
mmgen/addrfile.py

@@ -66,6 +66,7 @@ class AddrFile(MMGenObject):
 	def write(
 	def write(
 			self,
 			self,
 			fn            = None,
 			fn            = None,
+			*,
 			binary        = False,
 			binary        = False,
 			desc          = None,
 			desc          = None,
 			ask_overwrite = True,
 			ask_overwrite = True,
@@ -92,7 +93,7 @@ class AddrFile(MMGenObject):
 		)
 		)
 		return self.parent.al_id.sid + (' ' if lbl_p2 else '') + lbl_p2
 		return self.parent.al_id.sid + (' ' if lbl_p2 else '') + lbl_p2
 
 
-	def format(self, add_comments=False):
+	def format(self, *, add_comments=False):
 		p = self.parent
 		p = self.parent
 		if p.gen_passwds and p.pw_fmt in ('bip39', 'xmrseed'):
 		if p.gen_passwds and p.pw_fmt in ('bip39', 'xmrseed'):
 			desc_pfx = f'{p.pw_fmt.upper()} '
 			desc_pfx = f'{p.pw_fmt.upper()} '
@@ -200,7 +201,7 @@ class AddrFile(MMGenObject):
 
 
 		return ret
 		return ret
 
 
-	def parse_file(self, fn, buf=[], exit_on_error=True):
+	def parse_file(self, fn, *, buf=[], exit_on_error=True):
 
 
 		def parse_addrfile_label(lbl):
 		def parse_addrfile_label(lbl):
 			"""
 			"""
@@ -249,7 +250,7 @@ class AddrFile(MMGenObject):
 		p = self.parent
 		p = self.parent
 
 
 		from .fileutil import get_lines_from_file
 		from .fileutil import get_lines_from_file
-		lines = get_lines_from_file(p.cfg, fn, p.desc+' data', trim_comments=True)
+		lines = get_lines_from_file(p.cfg, fn, desc=f'{p.desc} data', trim_comments=True)
 
 
 		try:
 		try:
 			assert len(lines) >= 3, f'Too few lines in address file ({len(lines)})'
 			assert len(lines) >= 3, f'Too few lines in address file ({len(lines)})'

+ 1 - 0
mmgen/addrlist.py

@@ -159,6 +159,7 @@ class AddrList(MMGenObject): # Address info for a single seed ID
 			self,
 			self,
 			cfg,
 			cfg,
 			proto,
 			proto,
+			*,
 			infile    = '',
 			infile    = '',
 			al_id     = '',
 			al_id     = '',
 			adata     = [],
 			adata     = [],

+ 2 - 2
mmgen/altcoin/params.py

@@ -267,7 +267,7 @@ class CoinInfo:
 			return None
 			return None
 		return cls.coin_constants[network][idx]
 		return cls.coin_constants[network][idx]
 
 
-def make_proto(e, testnet=False):
+def make_proto(e, *, testnet=False):
 
 
 	proto = ('X_' if e.name[0] in '0123456789' else '') + e.name + ('Testnet' if testnet else '')
 	proto = ('X_' if e.name[0] in '0123456789' else '') + e.name + ('Testnet' if testnet else '')
 
 
@@ -297,7 +297,7 @@ def make_proto(e, testnet=False):
 		)
 		)
 	)
 	)
 
 
-def init_genonly_altcoins(usr_coin=None, testnet=False):
+def init_genonly_altcoins(usr_coin=None, *, testnet=False):
 	"""
 	"""
 	Initialize altcoin protocol class or classes for current network.
 	Initialize altcoin protocol class or classes for current network.
 	If usr_coin is a core coin, initialization is skipped.
 	If usr_coin is a core coin, initialization is skipped.

+ 5 - 5
mmgen/amt.py

@@ -40,7 +40,7 @@ class CoinAmt(Decimal, Hilite, InitErrors): # abstract class
 	max_amt  = None   # coin supply if known, otherwise None
 	max_amt  = None   # coin supply if known, otherwise None
 	units    = ()     # defined unit names, e.g. ('satoshi',...)
 	units    = ()     # defined unit names, e.g. ('satoshi',...)
 
 
-	def __new__(cls, num, from_unit=None, from_decimal=False):
+	def __new__(cls, num, *, from_unit=None, from_decimal=False):
 
 
 		if isinstance(num, CoinAmt):
 		if isinstance(num, CoinAmt):
 			raise TypeError(f'CoinAmt: {num} is instance of {cls.__name__}')
 			raise TypeError(f'CoinAmt: {num} is instance of {cls.__name__}')
@@ -71,7 +71,7 @@ class CoinAmt(Decimal, Hilite, InitErrors): # abstract class
 	def fmtc(cls, *args, **kwargs):
 	def fmtc(cls, *args, **kwargs):
 		cls.method_not_implemented()
 		cls.method_not_implemented()
 
 
-	def fmt(self, color=False, iwidth=1, prec=None): # iwidth: width of the integer part
+	def fmt(self, *, color=False, iwidth=1, prec=None): # iwidth: width of the integer part
 		prec = prec or self.max_prec
 		prec = prec or self.max_prec
 		if '.' in (s := str(self)):
 		if '.' in (s := str(self)):
 			a, b = s.split('.', 1)
 			a, b = s.split('.', 1)
@@ -83,11 +83,11 @@ class CoinAmt(Decimal, Hilite, InitErrors): # abstract class
 				s.rjust(iwidth).ljust(iwidth+prec+1),
 				s.rjust(iwidth).ljust(iwidth+prec+1),
 				color = color)
 				color = color)
 
 
-	def hl(self, color=True):
+	def hl(self, *, color=True):
 		return self.colorize(str(self), color=color)
 		return self.colorize(str(self), color=color)
 
 
 	# fancy highlighting with coin unit, enclosure, formatting
 	# fancy highlighting with coin unit, enclosure, formatting
-	def hl2(self, color=True, unit=False, fs='{}', encl=''):
+	def hl2(self, *, color=True, unit=False, fs='{}', encl=''):
 		res = fs.format(self)
 		res = fs.format(self)
 		return (
 		return (
 			encl[:-1]
 			encl[:-1]
@@ -156,7 +156,7 @@ class CoinAmt(Decimal, Hilite, InitErrors): # abstract class
 	def __mod__(self, *args, **kwargs):
 	def __mod__(self, *args, **kwargs):
 		self.method_not_implemented()
 		self.method_not_implemented()
 
 
-def is_coin_amt(proto, num, from_unit=None, from_decimal=False):
+def is_coin_amt(proto, num, *, from_unit=None, from_decimal=False):
 	assert proto.coin_amt, 'proto.coin_amt is None!  Did you call init_proto() with ‘need_amt’?'
 	assert proto.coin_amt, 'proto.coin_amt is None!  Did you call init_proto() with ‘need_amt’?'
 	return get_obj(proto.coin_amt, num=num, from_unit=from_unit, from_decimal=from_decimal, silent=True, return_bool=True)
 	return get_obj(proto.coin_amt, num=num, from_unit=from_unit, from_decimal=from_decimal, silent=True, return_bool=True)
 
 

+ 9 - 9
mmgen/autosign.py

@@ -33,12 +33,12 @@ def SwapMgr(*args, **kwargs):
 
 
 class SwapMgrBase:
 class SwapMgrBase:
 
 
-	def __init__(self, cfg, ignore_zram=False):
+	def __init__(self, cfg, *, ignore_zram=False):
 		self.cfg = cfg
 		self.cfg = cfg
 		self.ignore_zram = ignore_zram
 		self.ignore_zram = ignore_zram
 		self.desc = 'disk swap' if ignore_zram else 'swap'
 		self.desc = 'disk swap' if ignore_zram else 'swap'
 
 
-	def enable(self, quiet=False):
+	def enable(self, *, quiet=False):
 		ret = self.do_enable()
 		ret = self.do_enable()
 		if not quiet:
 		if not quiet:
 			self.cfg._util.qmsg(
 			self.cfg._util.qmsg(
@@ -47,7 +47,7 @@ class SwapMgrBase:
 				f'Could not enable {self.desc}')
 				f'Could not enable {self.desc}')
 		return ret
 		return ret
 
 
-	def disable(self, quiet=False):
+	def disable(self, *, quiet=False):
 		self.cfg._util.qmsg_r(f'Attempting to disable {self.desc}...')
 		self.cfg._util.qmsg_r(f'Attempting to disable {self.desc}...')
 		ret = self.do_disable()
 		ret = self.do_disable()
 		self.cfg._util.qmsg('success')
 		self.cfg._util.qmsg('success')
@@ -189,7 +189,7 @@ class Signable:
 				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):
+		def die_wrong_num_txs(self, tx_type, *, msg=None, desc=None, show_dir=False):
 			num_txs = len(getattr(self, tx_type))
 			num_txs = len(getattr(self, tx_type))
 			die('AutosignTXError', "{m}{a} {b} transaction{c} {d} {e}!".format(
 			die('AutosignTXError', "{m}{a} {b} transaction{c} {d} {e}!".format(
 				m = msg + '\n' if msg else '',
 				m = msg + '\n' if msg else '',
@@ -581,7 +581,7 @@ class Autosign:
 
 
 		return self._wallet_files
 		return self._wallet_files
 
 
-	def do_mount(self, silent=False, verbose=False):
+	def do_mount(self, *, silent=False, verbose=False):
 
 
 		def check_or_create(dirname):
 		def check_or_create(dirname):
 			path = getattr(self, dirname)
 			path = getattr(self, dirname)
@@ -615,7 +615,7 @@ class Autosign:
 		for dirname in self.dirs:
 		for dirname in self.dirs:
 			check_or_create(dirname)
 			check_or_create(dirname)
 
 
-	def do_umount(self, silent=False, verbose=False):
+	def do_umount(self, *, silent=False, verbose=False):
 		if self.mountpoint.is_mount():
 		if self.mountpoint.is_mount():
 			run(['sync'], check=True)
 			run(['sync'], check=True)
 			if not silent:
 			if not silent:
@@ -630,7 +630,7 @@ class Autosign:
 		fails = 0
 		fails = 0
 		for wf in self.wallet_files:
 		for wf in self.wallet_files:
 			try:
 			try:
-				Wallet(self.cfg, wf, ignore_in_fmt=True, passwd_file=str(self.keyfile))
+				Wallet(self.cfg, fn=wf, ignore_in_fmt=True, passwd_file=str(self.keyfile))
 			except SystemExit as e:
 			except SystemExit as e:
 				if e.code != 0:
 				if e.code != 0:
 					fails += 1
 					fails += 1
@@ -710,7 +710,7 @@ class Autosign:
 			die(2, 'Unable to write ' + desc)
 			die(2, 'Unable to write ' + desc)
 		msg('Wrote ' + desc)
 		msg('Wrote ' + desc)
 
 
-	def gen_key(self, no_unmount=False):
+	def gen_key(self, *, no_unmount=False):
 		if not self.device_inserted:
 		if not self.device_inserted:
 			die(1, 'Removable device not present!')
 			die(1, 'Removable device not present!')
 		self.do_mount()
 		self.do_mount()
@@ -776,7 +776,7 @@ class Autosign:
 				cfg         = self.cfg,
 				cfg         = self.cfg,
 				prompt      = f"Default wallet '{wf}' found.\nUse default wallet for autosigning?",
 				prompt      = f"Default wallet '{wf}' found.\nUse default wallet for autosigning?",
 				default_yes = True):
 				default_yes = True):
-			ss_in = Wallet(Config(), wf)
+			ss_in = Wallet(Config(), fn=wf)
 		else:
 		else:
 			ss_in = Wallet(self.cfg, in_fmt=self.mn_fmts[self.cfg.mnemonic_fmt or self.dfl_mn_fmt])
 			ss_in = Wallet(self.cfg, in_fmt=self.mn_fmts[self.cfg.mnemonic_fmt or self.dfl_mn_fmt])
 		ss_out = Wallet(self.cfg, ss=ss_in, passwd_file=str(self.keyfile))
 		ss_out = Wallet(self.cfg, ss=ss_in, passwd_file=str(self.keyfile))

+ 6 - 6
mmgen/baseconv.py

@@ -129,11 +129,11 @@ class baseconv:
 		else:
 		else:
 			die('BaseConversionPadError', f"{pad!r}: illegal value for 'pad' (must be None, 'seed' or int)")
 			die('BaseConversionPadError', f"{pad!r}: illegal value for 'pad' (must be None, 'seed' or int)")
 
 
-	def tohex(self, words_arg, pad=None):
+	def tohex(self, words_arg, *, pad=None):
 		"convert string or list data of instance base to a hexadecimal string"
 		"convert string or list data of instance base to a hexadecimal string"
-		return self.tobytes(words_arg, pad//2 if type(pad) is int else pad).hex()
+		return self.tobytes(words_arg, pad=pad//2 if type(pad) is int else pad).hex()
 
 
-	def tobytes(self, words_arg, pad=None):
+	def tobytes(self, words_arg, *, pad=None):
 		"convert string or list data of instance base to byte string"
 		"convert string or list data of instance base to byte string"
 
 
 		words = words_arg if isinstance(words_arg, (list, tuple)) else tuple(words_arg.strip())
 		words = words_arg if isinstance(words_arg, (list, tuple)) else tuple(words_arg.strip())
@@ -163,7 +163,7 @@ class baseconv:
 		bl = ret.bit_length()
 		bl = ret.bit_length()
 		return ret.to_bytes(max(pad_val, bl//8+bool(bl%8)), 'big')
 		return ret.to_bytes(max(pad_val, bl//8+bool(bl%8)), 'big')
 
 
-	def fromhex(self, hexstr, pad=None, tostr=False):
+	def fromhex(self, hexstr, *, pad=None, tostr=False):
 		"convert a hexadecimal string to a list or string data of instance base"
 		"convert a hexadecimal string to a list or string data of instance base"
 
 
 		from .util import is_hex_str
 		from .util import is_hex_str
@@ -172,9 +172,9 @@ class baseconv:
 				('seed data' if pad == 'seed' else f'{hexstr!r}:') +
 				('seed data' if pad == 'seed' else f'{hexstr!r}:') +
 				' not a hexadecimal string')
 				' not a hexadecimal string')
 
 
-		return self.frombytes(bytes.fromhex(hexstr), pad, tostr)
+		return self.frombytes(bytes.fromhex(hexstr), pad=pad, tostr=tostr)
 
 
-	def frombytes(self, bytestr, pad=None, tostr=False):
+	def frombytes(self, bytestr, *, pad=None, tostr=False):
 		"convert byte string to list or string data of instance base"
 		"convert byte string to list or string data of instance base"
 
 
 		if not bytestr:
 		if not bytestr:

+ 4 - 4
mmgen/bip39.py

@@ -54,14 +54,14 @@ class bip39(baseconv):
 		self.wl_id = 'bip39'
 		self.wl_id = 'bip39'
 
 
 	@classmethod
 	@classmethod
-	def nwords2seedlen(cls, nwords, in_bytes=False, in_hex=False):
+	def nwords2seedlen(cls, nwords, *, in_bytes=False, in_hex=False):
 		for k, v in cls.constants.items():
 		for k, v in cls.constants.items():
 			if v.mn_len == nwords:
 			if v.mn_len == nwords:
 				return k//8 if in_bytes else k//4 if in_hex else k
 				return k//8 if in_bytes else k//4 if in_hex else k
 		die('MnemonicError', f'{nwords!r}: invalid word length for BIP39 mnemonic')
 		die('MnemonicError', f'{nwords!r}: invalid word length for BIP39 mnemonic')
 
 
 	@classmethod
 	@classmethod
-	def seedlen2nwords(cls, seed_len, in_bytes=False, in_hex=False):
+	def seedlen2nwords(cls, seed_len, *, in_bytes=False, in_hex=False):
 		seed_bits = seed_len * 8 if in_bytes else seed_len * 4 if in_hex else seed_len
 		seed_bits = seed_len * 8 if in_bytes else seed_len * 4 if in_hex else seed_len
 		try:
 		try:
 			return cls.constants[seed_bits].mn_len
 			return cls.constants[seed_bits].mn_len
@@ -105,11 +105,11 @@ class bip39(baseconv):
 
 
 		return seed_bytes
 		return seed_bytes
 
 
-	def fromhex(self, hexstr, pad=None, tostr=False):
+	def fromhex(self, hexstr, *, pad=None, tostr=False):
 		assert is_hex_str(hexstr), 'seed data not a hexadecimal string'
 		assert is_hex_str(hexstr), 'seed data not a hexadecimal string'
 		return self.frombytes(bytes.fromhex(hexstr), pad=pad, tostr=tostr)
 		return self.frombytes(bytes.fromhex(hexstr), pad=pad, tostr=tostr)
 
 
-	def frombytes(self, seed_bytes, pad=None, tostr=False):
+	def frombytes(self, seed_bytes, *, pad=None, tostr=False):
 		assert tostr is False, "'tostr' must be False for 'bip39'"
 		assert tostr is False, "'tostr' must be False for 'bip39'"
 		assert pad in (None, 'seed'), f"{pad}: invalid 'pad' argument (must be None or 'seed')"
 		assert pad in (None, 'seed'), f"{pad}: invalid 'pad' argument (must be None or 'seed')"
 
 

+ 9 - 7
mmgen/bip_hd/__init__.py

@@ -185,6 +185,7 @@ class MasterNode(Lockable):
 	def init_cfg(
 	def init_cfg(
 			self,
 			self,
 			coin           = None,
 			coin           = None,
+			*,
 			network        = None,
 			network        = None,
 			addr_type      = None,
 			addr_type      = None,
 			from_path      = False,
 			from_path      = False,
@@ -204,11 +205,11 @@ class MasterNode(Lockable):
 		new._lock()
 		new._lock()
 		return new
 		return new
 
 
-	def to_coin_type(self, coin=None, network=None, addr_type=None):
-		return self.init_cfg(coin, network, addr_type).to_coin_type()
+	def to_coin_type(self, *, coin=None, network=None, addr_type=None):
+		return self.init_cfg(coin, network=network, addr_type=addr_type).to_coin_type()
 
 
-	def to_chain(self, idx, coin=None, network=None, addr_type=None, hardened=False, public=False):
-		return self.init_cfg(coin, network, addr_type).to_chain(
+	def to_chain(self, idx, *, coin=None, network=None, addr_type=None, hardened=False, public=False):
+		return self.init_cfg(coin, network=network, addr_type=addr_type).to_chain(
 			idx      = idx,
 			idx      = idx,
 			hardened = hardened,
 			hardened = hardened,
 			public   = public)
 			public   = public)
@@ -294,7 +295,7 @@ class BipHDNode(Lockable):
 	def xprv(self):
 	def xprv(self):
 		return self.key_extended(public=False, as_str=True)
 		return self.key_extended(public=False, as_str=True)
 
 
-	def key_extended(self, public, as_str=False):
+	def key_extended(self, public, *, as_str=False):
 		if self.public and not public:
 		if self.public and not public:
 			raise ValueError('cannot create extended private key for public node!')
 			raise ValueError('cannot create extended private key for public node!')
 		ret = b58chk_encode(
 		ret = b58chk_encode(
@@ -363,6 +364,7 @@ class BipHDNode(Lockable):
 			base_cfg,
 			base_cfg,
 			seed,
 			seed,
 			path_str,
 			path_str,
+			*,
 			coin           = None,
 			coin           = None,
 			addr_type      = None,
 			addr_type      = None,
 			no_path_checks = False):
 			no_path_checks = False):
@@ -441,7 +443,7 @@ class BipHDNodeMaster(BipHDNode):
 		#           purpose          coin_type
 		#           purpose          coin_type
 		return self.derive_private().derive_private()
 		return self.derive_private().derive_private()
 
 
-	def to_chain(self, idx, hardened=False, public=False):
+	def to_chain(self, idx, *, hardened=False, public=False):
 		#           purpose          coin_type        account #0            chain
 		#           purpose          coin_type        account #0            chain
 		return self.derive_private().derive_private().derive_private(idx=0).derive(
 		return self.derive_private().derive_private().derive_private(idx=0).derive(
 			idx      = idx,
 			idx      = idx,
@@ -475,7 +477,7 @@ class BipHDNodeCoinType(BipHDNode):
 				f'chain index {chain_idx} for coin {cfg.base_cfg.coin!r}')
 				f'chain index {chain_idx} for coin {cfg.base_cfg.coin!r}')
 		return (chain_idx, type(self).hardened)
 		return (chain_idx, type(self).hardened)
 
 
-	def to_chain(self, idx, hardened=False, public=False):
+	def to_chain(self, idx, *, hardened=False, public=False):
 		#           account #0            chain
 		#           account #0            chain
 		return self.derive_private(idx=0).derive(
 		return self.derive_private(idx=0).derive(
 			idx      = idx,
 			idx      = idx,

+ 3 - 2
mmgen/cfg.py

@@ -438,6 +438,7 @@ class Config(Lockable):
 	def __init__(
 	def __init__(
 			self,
 			self,
 			cfg          = None,
 			cfg          = None,
+			*,
 			opts_data    = None,
 			opts_data    = None,
 			init_opts    = None,
 			init_opts    = None,
 			parse_only   = False,
 			parse_only   = False,
@@ -845,7 +846,7 @@ def check_opts(cfg): # Raises exception if any check fails
 			if hasattr(cfg, key2):
 			if hasattr(cfg, key2):
 				val2 = getattr(cfg, key2)
 				val2 = getattr(cfg, key2)
 				from .wallet import get_wallet_data
 				from .wallet import get_wallet_data
-				wd = get_wallet_data('incog_hidden')
+				wd = get_wallet_data(wtype='incog_hidden')
 				if val2 and val2 not in wd.fmt_codes:
 				if val2 and val2 not in wd.fmt_codes:
 					die('UserOptError', f'Option conflict:\n  {fmt_opt(name)}, with\n  {fmt_opt(key2)}={val2}')
 					die('UserOptError', f'Option conflict:\n  {fmt_opt(name)}, with\n  {fmt_opt(key2)}={val2}')
 
 
@@ -929,7 +930,7 @@ def opt_postproc_debug(cfg):
 	Msg('        {}\n'.format('\n        '.join(none_opts)))
 	Msg('        {}\n'.format('\n        '.join(none_opts)))
 	Msg('\n=== end opts.py debug ===\n')
 	Msg('\n=== end opts.py debug ===\n')
 
 
-def conv_type(name, val, refval, src, invert_bool=False):
+def conv_type(name, val, refval, *, src, invert_bool=False):
 
 
 	def do_fail():
 	def do_fail():
 		desc = {
 		desc = {

+ 4 - 2
mmgen/crypto.py

@@ -90,7 +90,7 @@ class Crypto:
 		return self.sha256_rounds(step1)
 		return self.sha256_rounds(step1)
 
 
 	def encrypt_seed(self, data, key, desc='seed'):
 	def encrypt_seed(self, data, key, desc='seed'):
-		return self.encrypt_data(data, key, desc=desc)
+		return self.encrypt_data(data, key=key, desc=desc)
 
 
 	def decrypt_seed(self, enc_seed, key, seed_id, key_id):
 	def decrypt_seed(self, enc_seed, key, seed_id, key_id):
 		self.util.vmsg_r('Checking key...')
 		self.util.vmsg_r('Checking key...')
@@ -121,6 +121,7 @@ class Crypto:
 	def encrypt_data(
 	def encrypt_data(
 			self,
 			self,
 			data,
 			data,
+			*,
 			key,
 			key,
 			iv     = aesctr_dfl_iv,
 			iv     = aesctr_dfl_iv,
 			desc   = 'data',
 			desc   = 'data',
@@ -214,6 +215,7 @@ class Crypto:
 			passwd,
 			passwd,
 			salt,
 			salt,
 			hash_preset,
 			hash_preset,
+			*,
 			desc      = 'encryption key',
 			desc      = 'encryption key',
 			from_what = 'passphrase',
 			from_what = 'passphrase',
 			verbose   = False):
 			verbose   = False):
@@ -407,7 +409,7 @@ class Crypto:
 			passwd_file = self.cfg.passwd_file)
 			passwd_file = self.cfg.passwd_file)
 		key    = self.make_key(passwd, salt, hp)
 		key    = self.make_key(passwd, salt, hp)
 		from hashlib import sha256
 		from hashlib import sha256
-		enc_d  = self.encrypt_data(sha256(nonce+data).digest() + nonce + data, key, iv, desc=desc)
+		enc_d  = self.encrypt_data(sha256(nonce+data).digest() + nonce + data, key=key, iv=iv, desc=desc)
 		return salt+iv+enc_d
 		return salt+iv+enc_d
 
 
 	def mmgen_decrypt(self, data, desc='data', hash_preset=None):
 	def mmgen_decrypt(self, data, desc='data', hash_preset=None):

+ 6 - 4
mmgen/daemon.py

@@ -91,7 +91,7 @@ class Daemon(Lockable):
 			print(cp)
 			print(cp)
 		return cp
 		return cp
 
 
-	def run_cmd(self, cmd, silent=False, is_daemon=False, check_retcode=False):
+	def run_cmd(self, cmd, *, silent=False, is_daemon=False, check_retcode=False):
 
 
 		if self.debug:
 		if self.debug:
 			msg('\n\n')
 			msg('\n\n')
@@ -181,7 +181,7 @@ class Daemon(Lockable):
 	def pre_start(self):
 	def pre_start(self):
 		pass
 		pass
 
 
-	def start(self, quiet=False, silent=False):
+	def start(self, *, quiet=False, silent=False):
 		if self.state == 'ready':
 		if self.state == 'ready':
 			if not (quiet or silent):
 			if not (quiet or silent):
 				msg(self.state_msg(extra_text='already'))
 				msg(self.state_msg(extra_text='already'))
@@ -200,7 +200,7 @@ class Daemon(Lockable):
 
 
 		return ret
 		return ret
 
 
-	def stop(self, quiet=False, silent=False):
+	def stop(self, *, quiet=False, silent=False):
 		if self.state == 'ready':
 		if self.state == 'ready':
 			if not silent:
 			if not silent:
 				msg(f'Stopping {self.desc} on port {self.bind_port}')
 				msg(f'Stopping {self.desc} on port {self.bind_port}')
@@ -221,7 +221,7 @@ class Daemon(Lockable):
 				msg(f'{self.desc} on port {self.bind_port} not running')
 				msg(f'{self.desc} on port {self.bind_port} not running')
 			return True
 			return True
 
 
-	def restart(self, silent=False):
+	def restart(self, *, silent=False):
 		self.stop(silent=silent)
 		self.stop(silent=silent)
 		return self.start(silent=silent)
 		return self.start(silent=silent)
 
 
@@ -339,6 +339,7 @@ class CoinDaemon(Daemon):
 
 
 	def __new__(cls,
 	def __new__(cls,
 			cfg,
 			cfg,
+			*,
 			network_id = None,
 			network_id = None,
 			proto      = None,
 			proto      = None,
 			opts       = None,
 			opts       = None,
@@ -384,6 +385,7 @@ class CoinDaemon(Daemon):
 
 
 	def __init__(self,
 	def __init__(self,
 			cfg,
 			cfg,
+			*,
 			network_id = None,
 			network_id = None,
 			proto      = None,
 			proto      = None,
 			opts       = None,
 			opts       = None,

+ 1 - 1
mmgen/devtools.py

@@ -131,7 +131,7 @@ class MMGenObjectMethods: # mixin class for MMGenObject
 		def isScalar(obj):
 		def isScalar(obj):
 			return isinstance(obj, scalars)
 			return isinstance(obj, scalars)
 
 
-		def do_list(out, e, lvl=0, is_dict=False):
+		def do_list(out, e, *, lvl=0, is_dict=False):
 			out.append('\n')
 			out.append('\n')
 			for i in e:
 			for i in e:
 				el = i if not is_dict else e[i]
 				el = i if not is_dict else e[i]

+ 8 - 8
mmgen/filename.py

@@ -25,7 +25,7 @@ from .util import die, get_extension
 
 
 class File:
 class File:
 
 
-	def __init__(self, fn, write=False):
+	def __init__(self, fn, *, write=False):
 
 
 		self.name     = fn
 		self.name     = fn
 		self.dirname  = os.path.dirname(fn)
 		self.dirname  = os.path.dirname(fn)
@@ -66,21 +66,21 @@ class File:
 
 
 class FileList(list):
 class FileList(list):
 
 
-	def __init__(self, fns, write=False):
+	def __init__(self, fns, *, write=False):
 		list.__init__(
 		list.__init__(
 			self,
 			self,
-			[File(fn, write) for fn in fns])
+			[File(fn, write=write) for fn in fns])
 
 
 	def names(self):
 	def names(self):
 		return [f.name for f in self]
 		return [f.name for f in self]
 
 
-	def sort_by_age(self, key='mtime', reverse=False):
+	def sort_by_age(self, *, key='mtime', reverse=False):
 		assert key in ('atime', 'ctime', 'mtime'), f'{key!r}: invalid sort key'
 		assert key in ('atime', 'ctime', 'mtime'), f'{key!r}: invalid sort key'
 		self.sort(key=lambda a: getattr(a, key), reverse=reverse)
 		self.sort(key=lambda a: getattr(a, key), reverse=reverse)
 
 
 class MMGenFile(File):
 class MMGenFile(File):
 
 
-	def __init__(self, fn, base_class=None, subclass=None, proto=None, write=False):
+	def __init__(self, fn, *, base_class=None, subclass=None, proto=None, write=False):
 		"""
 		"""
 		'base_class' - a base class with an 'ext_to_cls' method
 		'base_class' - a base class with an 'ext_to_cls' method
 		'subclass'   - a subclass with an 'ext' attribute
 		'subclass'   - a subclass with an 'ext' attribute
@@ -91,7 +91,7 @@ class MMGenFile(File):
 		attribute to True.
 		attribute to True.
 		"""
 		"""
 
 
-		super().__init__(fn, write)
+		super().__init__(fn, write=write)
 
 
 		assert (subclass or base_class) and not (subclass and base_class), 'MMGenFile chk1'
 		assert (subclass or base_class) and not (subclass and base_class), 'MMGenFile chk1'
 
 
@@ -107,12 +107,12 @@ class MMGenFile(File):
 
 
 class MMGenFileList(FileList):
 class MMGenFileList(FileList):
 
 
-	def __init__(self, fns, base_class, proto=None, write=False):
+	def __init__(self, fns, base_class, *, proto=None, write=False):
 		list.__init__(
 		list.__init__(
 			self,
 			self,
 			[MMGenFile(fn, base_class=base_class, proto=proto, write=write) for fn in fns])
 			[MMGenFile(fn, base_class=base_class, proto=proto, write=write) for fn in fns])
 
 
-def find_files_in_dir(subclass, fdir, no_dups=False):
+def find_files_in_dir(subclass, fdir, *, no_dups=False):
 
 
 	assert isinstance(subclass, type), f'{subclass}: not a class'
 	assert isinstance(subclass, type), f'{subclass}: not a class'
 
 

+ 10 - 7
mmgen/fileutil.py

@@ -57,7 +57,7 @@ def check_binary(args):
 		die(2, f'{args[0]!r} binary missing, not in path, or not executable')
 		die(2, f'{args[0]!r} binary missing, not in path, or not executable')
 	set_vt100()
 	set_vt100()
 
 
-def shred_file(fn, verbose=False):
+def shred_file(fn, *, verbose=False):
 	check_binary(['shred', '--version'])
 	check_binary(['shred', '--version'])
 	from subprocess import run
 	from subprocess import run
 	run(
 	run(
@@ -67,7 +67,7 @@ def shred_file(fn, verbose=False):
 		check=True)
 		check=True)
 	set_vt100()
 	set_vt100()
 
 
-def _check_file_type_and_access(fname, ftype, blkdev_ok=False):
+def _check_file_type_and_access(fname, ftype, *, blkdev_ok=False):
 
 
 	import stat
 	import stat
 
 
@@ -103,16 +103,16 @@ def _check_file_type_and_access(fname, ftype, blkdev_ok=False):
 
 
 	return True
 	return True
 
 
-def check_infile(f, blkdev_ok=False):
+def check_infile(f, *, blkdev_ok=False):
 	return _check_file_type_and_access(f, 'input file', blkdev_ok=blkdev_ok)
 	return _check_file_type_and_access(f, 'input file', blkdev_ok=blkdev_ok)
 
 
-def check_outfile(f, blkdev_ok=False):
+def check_outfile(f, *, blkdev_ok=False):
 	return _check_file_type_and_access(f, 'output file', blkdev_ok=blkdev_ok)
 	return _check_file_type_and_access(f, 'output file', blkdev_ok=blkdev_ok)
 
 
 def check_outdir(f):
 def check_outdir(f):
 	return _check_file_type_and_access(f, 'output directory')
 	return _check_file_type_and_access(f, 'output directory')
 
 
-def get_seed_file(cfg, nargs, wallets=None, invoked_as=None):
+def get_seed_file(cfg, *, nargs, wallets=None, invoked_as=None):
 
 
 	wallets = wallets or cfg._args
 	wallets = wallets or cfg._args
 
 
@@ -137,7 +137,7 @@ def get_seed_file(cfg, nargs, wallets=None, invoked_as=None):
 
 
 	return str(wallets[0]) if wallets else (wf, None)[wd_from_opt] # could be a Path instance
 	return str(wallets[0]) if wallets else (wf, None)[wd_from_opt] # could be a Path instance
 
 
-def _open_or_die(filename, mode, silent=False):
+def _open_or_die(filename, mode, *, silent=False):
 	try:
 	try:
 		return open(filename, mode)
 		return open(filename, mode)
 	except:
 	except:
@@ -152,6 +152,7 @@ def write_data_to_file(
 		cfg,
 		cfg,
 		outfile,
 		outfile,
 		data,
 		data,
+		*,
 		desc                  = 'data',
 		desc                  = 'data',
 		ask_write             = False,
 		ask_write             = False,
 		ask_write_prompt      = '',
 		ask_write_prompt      = '',
@@ -279,7 +280,7 @@ def write_data_to_file(
 	else:
 	else:
 		do_file(outfile, ask_write_prompt)
 		do_file(outfile, ask_write_prompt)
 
 
-def get_words_from_file(cfg, infile, desc, quiet=False):
+def get_words_from_file(cfg, infile, *, desc, quiet=False):
 
 
 	if not quiet:
 	if not quiet:
 		cfg._util.qmsg(f'Getting {desc} from file ‘{infile}’')
 		cfg._util.qmsg(f'Getting {desc} from file ‘{infile}’')
@@ -299,6 +300,7 @@ def get_words_from_file(cfg, infile, desc, quiet=False):
 def get_data_from_file(
 def get_data_from_file(
 		cfg,
 		cfg,
 		infile,
 		infile,
+		*,
 		desc   = 'data',
 		desc   = 'data',
 		dash   = False,
 		dash   = False,
 		silent = False,
 		silent = False,
@@ -326,6 +328,7 @@ def get_data_from_file(
 def get_lines_from_file(
 def get_lines_from_file(
 		cfg,
 		cfg,
 		fn,
 		fn,
+		*,
 		desc          = 'data',
 		desc          = 'data',
 		trim_comments = False,
 		trim_comments = False,
 		quiet         = False,
 		quiet         = False,

+ 1 - 1
mmgen/help/help_notes.py

@@ -30,7 +30,7 @@ class help_notes:
 	def account_info_desc(self):
 	def account_info_desc(self):
 		return 'unspent outputs' if self.proto.base_proto == 'Bitcoin' else 'account info'
 		return 'unspent outputs' if self.proto.base_proto == 'Bitcoin' else 'account info'
 
 
-	def fee_spec_letters(self, use_quotes=False):
+	def fee_spec_letters(self, *, use_quotes=False):
 		cu = self.proto.coin_amt.units
 		cu = self.proto.coin_amt.units
 		sep, conj = ((',', ' or '), ("','", "' or '"))[use_quotes]
 		sep, conj = ((',', ' or '), ("','", "' or '"))[use_quotes]
 		return sep.join(u[0] for u in cu[:-1]) + ('', conj)[len(cu)>1] + cu[-1][0]
 		return sep.join(u[0] for u in cu[:-1]) + ('', conj)[len(cu)>1] + cu[-1][0]

+ 1 - 1
mmgen/help/txsign.py

@@ -19,7 +19,7 @@ from ..daemon import CoinDaemon
 def help(proto, cfg):
 def help(proto, cfg):
 
 
 	def coind_exec():
 	def coind_exec():
-		return CoinDaemon(cfg, proto.coin).exec_fn if proto.coin in CoinDaemon.coins else 'bitcoind'
+		return CoinDaemon(cfg, network_id=proto.coin).exec_fn if proto.coin in CoinDaemon.coins else 'bitcoind'
 
 
 	return """
 	return """
 Transactions may contain both {pnm} or non-{pnm} input addresses.
 Transactions may contain both {pnm} or non-{pnm} input addresses.

+ 2 - 2
mmgen/keygen.py

@@ -51,7 +51,7 @@ class keygen_base:
 		return None
 		return None
 
 
 	@classmethod
 	@classmethod
-	def get_clsname(cls, cfg, silent=False):
+	def get_clsname(cls, cfg, *, silent=False):
 		return cls.__name__
 		return cls.__name__
 
 
 backend_data = {
 backend_data = {
@@ -104,7 +104,7 @@ def check_backend(cfg, proto, backend, addr_type):
 
 
 	return  _check_backend(cfg, backend, pubkey_type, desc='--keygen-backend parameter')
 	return  _check_backend(cfg, backend, pubkey_type, desc='--keygen-backend parameter')
 
 
-def KeyGenerator(cfg, proto, pubkey_type, backend=None, silent=False):
+def KeyGenerator(cfg, proto, pubkey_type, *, backend=None, silent=False):
 	"""
 	"""
 	factory function returning a key generator backend for the specified pubkey type
 	factory function returning a key generator backend for the specified pubkey type
 	"""
 	"""

+ 1 - 1
mmgen/led.py

@@ -71,7 +71,7 @@ class LEDControl:
 			trigger = '/tmp/led_trigger'),
 			trigger = '/tmp/led_trigger'),
 	}
 	}
 
 
-	def __init__(self, enabled, simulate=False, debug=False):
+	def __init__(self, *, enabled, simulate=False, debug=False):
 
 
 		self.enabled = enabled
 		self.enabled = enabled
 		self.debug = debug or simulate
 		self.debug = debug or simulate

+ 2 - 2
mmgen/main_addrgen.py

@@ -141,12 +141,12 @@ if cfg.keygen_backend:
 idxs = addrlist.AddrIdxList(fmt_str=cfg._args.pop())
 idxs = addrlist.AddrIdxList(fmt_str=cfg._args.pop())
 
 
 from .fileutil import get_seed_file
 from .fileutil import get_seed_file
-sf = get_seed_file(cfg, 1)
+sf = get_seed_file(cfg, nargs=1)
 
 
 from .ui import do_license_msg
 from .ui import do_license_msg
 do_license_msg(cfg)
 do_license_msg(cfg)
 
 
-ss = Wallet(cfg, sf)
+ss = Wallet(cfg, fn=sf)
 
 
 ss_seed = ss.seed if cfg.subwallet is None else ss.seed.subseed(cfg.subwallet, print_msg=True)
 ss_seed = ss.seed if cfg.subwallet is None else ss.seed.subseed(cfg.subwallet, print_msg=True)
 
 

+ 2 - 2
mmgen/main_addrimport.py

@@ -84,7 +84,7 @@ addrimport_msgs = {
 def parse_cmd_args(rpc, cmd_args):
 def parse_cmd_args(rpc, cmd_args):
 
 
 	def import_mmgen_list(infile):
 	def import_mmgen_list(infile):
-		return (AddrList, KeyAddrList)[bool(cfg.keyaddr_file)](cfg, proto, infile)
+		return (AddrList, KeyAddrList)[bool(cfg.keyaddr_file)](cfg, proto, infile=infile)
 
 
 	if len(cmd_args) == 1:
 	if len(cmd_args) == 1:
 		infile = cmd_args[0]
 		infile = cmd_args[0]
@@ -97,7 +97,7 @@ def parse_cmd_args(rpc, cmd_args):
 				addrlist = get_lines_from_file(
 				addrlist = get_lines_from_file(
 					cfg,
 					cfg,
 					infile,
 					infile,
-					f'non-{gc.proj_name} addresses',
+					desc = f'non-{gc.proj_name} addresses',
 					trim_comments = True))
 					trim_comments = True))
 		else:
 		else:
 			al = import_mmgen_list(infile)
 			al = import_mmgen_list(infile)

+ 2 - 2
mmgen/main_passgen.py

@@ -146,7 +146,7 @@ pw_idxs = AddrIdxList(fmt_str=cfg._args.pop())
 pw_id_str = cfg._args.pop()
 pw_id_str = cfg._args.pop()
 
 
 from .fileutil import get_seed_file
 from .fileutil import get_seed_file
-sf = get_seed_file(cfg, 1)
+sf = get_seed_file(cfg, nargs=1)
 
 
 pw_fmt = cfg.passwd_fmt or PasswordList.dfl_pw_fmt
 pw_fmt = cfg.passwd_fmt or PasswordList.dfl_pw_fmt
 pw_len = pwi[pw_fmt].dfl_len // 2 if cfg.passwd_len in ('h', 'H') else cfg.passwd_len
 pw_len = pwi[pw_fmt].dfl_len // 2 if cfg.passwd_len in ('h', 'H') else cfg.passwd_len
@@ -165,7 +165,7 @@ PasswordList(
 from .ui import do_license_msg
 from .ui import do_license_msg
 do_license_msg(cfg)
 do_license_msg(cfg)
 
 
-ss = Wallet(cfg, sf)
+ss = Wallet(cfg, fn=sf)
 
 
 al = PasswordList(
 al = PasswordList(
 	cfg       = cfg,
 	cfg       = cfg,

+ 1 - 1
mmgen/main_seedjoin.py

@@ -131,7 +131,7 @@ do_license_msg(cfg)
 cfg._util.qmsg('Input files:\n  {}\n'.format('\n  '.join(cfg._args)))
 cfg._util.qmsg('Input files:\n  {}\n'.format('\n  '.join(cfg._args)))
 
 
 shares = [Wallet(cfg).seed] if cfg.hidden_incog_input_params else []
 shares = [Wallet(cfg).seed] if cfg.hidden_incog_input_params else []
-shares += [Wallet(cfg,fn).seed for fn in cfg._args]
+shares += [Wallet(cfg, fn=fn).seed for fn in cfg._args]
 
 
 if cfg.master_share:
 if cfg.master_share:
 	share1 = SeedShareMasterJoining(cfg, master_idx, shares[0], id_str, len(shares)).derived_seed
 	share1 = SeedShareMasterJoining(cfg, master_idx, shares[0], id_str, len(shares)).derived_seed

+ 7 - 4
mmgen/main_tool.py

@@ -179,7 +179,7 @@ mods = {
 def get_cmds():
 def get_cmds():
 	return [cmd for mod, cmds in mods.items() if mod != 'help' for cmd in cmds]
 	return [cmd for mod, cmds in mods.items() if mod != 'help' for cmd in cmds]
 
 
-def create_call_sig(cmd, cls, as_string=False):
+def create_call_sig(cmd, cls, *, as_string=False):
 
 
 	m = getattr(cls, cmd)
 	m = getattr(cls, cmd)
 
 
@@ -189,8 +189,11 @@ def create_call_sig(cmd, cls, as_string=False):
 		args, dfls, ann = va['args'], va['dfls'], va['annots']
 		args, dfls, ann = va['args'], va['dfls'], va['annots']
 	else:
 	else:
 		flag = None
 		flag = None
-		args = m.__code__.co_varnames[1:m.__code__.co_argcount]
-		dfls = m.__defaults__ or ()
+		c = m.__code__
+		args = c.co_varnames[1:c.co_argcount + c.co_posonlyargcount + c.co_kwonlyargcount]
+		dfls = (
+			(m.__defaults__ or ()) +
+			tuple(m.__kwdefaults__[k] for k in args if k in (m.__kwdefaults__ or ())))
 		ann  = m.__annotations__
 		ann  = m.__annotations__
 
 
 	nargs = len(args) - len(dfls)
 	nargs = len(args) - len(dfls)
@@ -295,7 +298,7 @@ def process_args(cmd, cmd_args, cls):
 
 
 	return (args, kwargs)
 	return (args, kwargs)
 
 
-def process_result(ret, pager=False, print_result=False):
+def process_result(ret, *, pager=False, print_result=False):
 	"""
 	"""
 	Convert result to something suitable for output to screen and return it.
 	Convert result to something suitable for output to screen and return it.
 	If result is bytes and not convertible to utf8, output as binary using os.write().
 	If result is bytes and not convertible to utf8, output as binary using os.write().

+ 2 - 2
mmgen/main_wallet.py

@@ -179,7 +179,7 @@ if cmd_args:
 		cfg._usage()
 		cfg._usage()
 	check_infile(cmd_args[0])
 	check_infile(cmd_args[0])
 
 
-sf = get_seed_file(cfg, nargs, invoked_as=invoked_as)
+sf = get_seed_file(cfg, nargs=nargs, invoked_as=invoked_as)
 
 
 if invoked_as != 'chk':
 if invoked_as != 'chk':
 	from .ui import do_license_msg
 	from .ui import do_license_msg
@@ -212,7 +212,7 @@ if invoked_as == 'subgen':
 		cfg      = cfg,
 		cfg      = cfg,
 		seed_bin = ss_in.seed.subseed(ss_idx, print_msg=True).data)
 		seed_bin = ss_in.seed.subseed(ss_idx, print_msg=True).data)
 elif invoked_as == 'seedsplit':
 elif invoked_as == 'seedsplit':
-	shares = ss_in.seed.split(sss.count, sss.id, master_share)
+	shares = ss_in.seed.split(sss.count, id_str=sss.id, master_idx=master_share)
 	seed_out = shares.get_share_by_idx(sss.idx, base_seed=True)
 	seed_out = shares.get_share_by_idx(sss.idx, base_seed=True)
 	msg(seed_out.get_desc(ui=True))
 	msg(seed_out.get_desc(ui=True))
 	ss_out = Wallet(
 	ss_out = Wallet(

+ 1 - 1
mmgen/mn_entry.py

@@ -323,7 +323,7 @@ class MnemonicEntry:
 				time.sleep(self.cfg.err_disp_timeout)
 				time.sleep(self.cfg.err_disp_timeout)
 				msg_r(erase)
 				msg_r(erase)
 
 
-	def get_mnemonic_from_user(self, mn_len, validate=True):
+	def get_mnemonic_from_user(self, mn_len, *, validate=True):
 		mll = list(self.bconv.seedlen_map_rev)
 		mll = list(self.bconv.seedlen_map_rev)
 		assert mn_len in mll, f'{mn_len}: invalid mnemonic length (must be one of {mll})'
 		assert mn_len in mll, f'{mn_len}: invalid mnemonic length (must be one of {mll})'
 
 

+ 1 - 1
mmgen/msg.py

@@ -91,7 +91,7 @@ class coin_msg:
 			coin, network = network_id.split('_')
 			coin, network = network_id.split('_')
 			return init_proto(cfg=cfg, coin=coin, network=network)
 			return init_proto(cfg=cfg, coin=coin, network=network)
 
 
-		def write_to_file(self, outdir=None, ask_overwrite=False):
+		def write_to_file(self, *, outdir=None, ask_overwrite=False):
 			data = {
 			data = {
 				'id': f'{gc.proj_name} {self.desc}',
 				'id': f'{gc.proj_name} {self.desc}',
 				'metadata': self.data,
 				'metadata': self.data,

+ 5 - 5
mmgen/obj.py

@@ -102,7 +102,7 @@ class ImmutableAttr: # Descriptor
 	"""
 	"""
 	ok_dtypes = (type, type(None), type(lambda:0))
 	ok_dtypes = (type, type(None), type(lambda:0))
 
 
-	def __init__(self, dtype, typeconv=True, set_none_ok=False, include_proto=False):
+	def __init__(self, dtype, *, typeconv=True, set_none_ok=False, include_proto=False):
 		self.set_none_ok = set_none_ok
 		self.set_none_ok = set_none_ok
 		self.typeconv = typeconv
 		self.typeconv = typeconv
 
 
@@ -154,7 +154,7 @@ class ListItemAttr(ImmutableAttr):
 	For attributes that might not be present in the data instance
 	For attributes that might not be present in the data instance
 	Reassignment or deletion allowed if specified
 	Reassignment or deletion allowed if specified
 	"""
 	"""
-	def __init__(self, dtype, typeconv=True, include_proto=False, reassign_ok=False, delete_ok=False):
+	def __init__(self, dtype, *, typeconv=True, include_proto=False, reassign_ok=False, delete_ok=False):
 		self.reassign_ok = reassign_ok
 		self.reassign_ok = reassign_ok
 		self.delete_ok = delete_ok
 		self.delete_ok = delete_ok
 		ImmutableAttr.__init__(self, dtype, typeconv=typeconv, include_proto=include_proto)
 		ImmutableAttr.__init__(self, dtype, typeconv=typeconv, include_proto=include_proto)
@@ -280,10 +280,10 @@ class Int(int, Hilite, InitErrors):
 			return cls.init_fail(e, n)
 			return cls.init_fail(e, n)
 
 
 	@classmethod
 	@classmethod
-	def fmtc(cls, s, width, color=False):
+	def fmtc(cls, s, width, *, color=False):
 		return super().fmtc(str(s), width=width, color=color)
 		return super().fmtc(str(s), width=width, color=color)
 
 
-	def fmt(self, width, color=False):
+	def fmt(self, width, *, color=False):
 		return super().fmtc(str(self), width=width, color=color)
 		return super().fmtc(str(self), width=width, color=color)
 
 
 	def hl(self, **kwargs):
 	def hl(self, **kwargs):
@@ -324,7 +324,7 @@ class HexStr(HiliteStr, InitErrors):
 		except Exception as e:
 		except Exception as e:
 			return cls.init_fail(e, s)
 			return cls.init_fail(e, s)
 
 
-	def truncate(self, width, color=True):
+	def truncate(self, width, *, color=True):
 		return self.colorize(
 		return self.colorize(
 			self if width >= self.width else self[:width-2] + '..',
 			self if width >= self.width else self[:width-2] + '..',
 			color = color)
 			color = color)

+ 9 - 8
mmgen/objmethods.py

@@ -49,7 +49,7 @@ class Hilite:
 
 
 	# class method equivalent of fmt()
 	# class method equivalent of fmt()
 	@classmethod
 	@classmethod
-	def fmtc(cls, s, width, color=False):
+	def fmtc(cls, s, width, *, color=False):
 		if len(s) > width:
 		if len(s) > width:
 			assert cls.trunc_ok, "If 'trunc_ok' is false, 'width' must be >= width of string"
 			assert cls.trunc_ok, "If 'trunc_ok' is false, 'width' must be >= width of string"
 			return cls.colorize(s[:width].ljust(width), color=color)
 			return cls.colorize(s[:width].ljust(width), color=color)
@@ -57,21 +57,21 @@ class Hilite:
 			return cls.colorize(s.ljust(width), color=color)
 			return cls.colorize(s.ljust(width), color=color)
 
 
 	@classmethod
 	@classmethod
-	def hlc(cls, s, color=True):
+	def hlc(cls, s, *, color=True):
 		return getattr(color_mod, cls.color)(s) if color else s
 		return getattr(color_mod, cls.color)(s) if color else s
 
 
 	@classmethod
 	@classmethod
-	def colorize(cls, s, color=True):
+	def colorize(cls, s, *, color=True):
 		return getattr(color_mod, cls.color)(s) if color else s
 		return getattr(color_mod, cls.color)(s) if color else s
 
 
 	@classmethod
 	@classmethod
-	def colorize2(cls, s, color=True, color_override=''):
+	def colorize2(cls, s, *, color=True, color_override=''):
 		return getattr(color_mod, color_override or cls.color)(s) if color else s
 		return getattr(color_mod, color_override or cls.color)(s) if color else s
 
 
 class HiliteStr(str, Hilite):
 class HiliteStr(str, Hilite):
 
 
 	# supports single-width characters only
 	# supports single-width characters only
-	def fmt(self, width, color=False):
+	def fmt(self, width, *, color=False):
 		if len(self) > width:
 		if len(self) > width:
 			assert self.trunc_ok, "If 'trunc_ok' is false, 'width' must be >= width of string"
 			assert self.trunc_ok, "If 'trunc_ok' is false, 'width' must be >= width of string"
 			return self.colorize(self[:width].ljust(width), color=color)
 			return self.colorize(self[:width].ljust(width), color=color)
@@ -82,6 +82,7 @@ class HiliteStr(str, Hilite):
 	def fmt2(
 	def fmt2(
 			self,
 			self,
 			width,                  # screen width - must be at least 2 (one wide char)
 			width,                  # screen width - must be at least 2 (one wide char)
+			*,
 			color          = False,
 			color          = False,
 			encl           = '',    # if set, must be exactly 2 single-width chars
 			encl           = '',    # if set, must be exactly 2 single-width chars
 			nullrepl       = '',
 			nullrepl       = '',
@@ -112,12 +113,12 @@ class HiliteStr(str, Hilite):
 		else:
 		else:
 			return self.colorize2(s.ljust(width-s_wide_count), color=color, color_override=color_override)
 			return self.colorize2(s.ljust(width-s_wide_count), color=color, color_override=color_override)
 
 
-	def hl(self, color=True):
+	def hl(self, *, color=True):
 		return getattr(color_mod, self.color)(self) if color else self
 		return getattr(color_mod, self.color)(self) if color else self
 
 
 	# an alternative to hl(), with enclosure and color override
 	# an alternative to hl(), with enclosure and color override
 	# can be called as an unbound method with class as first argument
 	# can be called as an unbound method with class as first argument
-	def hl2(self, s=None, color=True, encl='', color_override=''):
+	def hl2(self, s=None, *, color=True, encl='', color_override=''):
 		if encl:
 		if encl:
 			return self.colorize2(encl[0]+(s or self)+encl[1], color=color, color_override=color_override)
 			return self.colorize2(encl[0]+(s or self)+encl[1], color=color, color_override=color_override)
 		else:
 		else:
@@ -126,7 +127,7 @@ class HiliteStr(str, Hilite):
 class InitErrors:
 class InitErrors:
 
 
 	@classmethod
 	@classmethod
-	def init_fail(cls, e, m, e2=None, m2=None, objname=None, preformat=False):
+	def init_fail(cls, e, m, *, e2=None, m2=None, objname=None, preformat=False):
 
 
 		def get_errmsg():
 		def get_errmsg():
 			ret = m if preformat else (
 			ret = m if preformat else (

+ 1 - 0
mmgen/passwdlist.py

@@ -69,6 +69,7 @@ class PasswordList(AddrList):
 			self,
 			self,
 			cfg,
 			cfg,
 			proto,
 			proto,
+			*,
 			infile          = None,
 			infile          = None,
 			seed            = None,
 			seed            = None,
 			pw_idxs         = None,
 			pw_idxs         = None,

+ 2 - 2
mmgen/platform/darwin/util.py

@@ -59,7 +59,7 @@ class MacOSRamDisk:
 	def get_diskutil_size(self):
 	def get_diskutil_size(self):
 		return get_device_size(self.label) // (2**20)
 		return get_device_size(self.label) // (2**20)
 
 
-	def create(self, quiet=False):
+	def create(self, *, quiet=False):
 		redir = DEVNULL if quiet else None
 		redir = DEVNULL if quiet else None
 		if self.exists():
 		if self.exists():
 			diskutil_size = self.get_diskutil_size()
 			diskutil_size = self.get_diskutil_size()
@@ -81,7 +81,7 @@ class MacOSRamDisk:
 			self.path.mkdir(parents=True, exist_ok=True)
 			self.path.mkdir(parents=True, exist_ok=True)
 			run(['diskutil', 'mount', '-mountPoint', str(self.path.absolute()), self.label], stdout=redir, check=True)
 			run(['diskutil', 'mount', '-mountPoint', str(self.path.absolute()), self.label], stdout=redir, check=True)
 
 
-	def destroy(self, quiet=False):
+	def destroy(self, *, quiet=False):
 		if not self.exists():
 		if not self.exists():
 			self.cfg._util.qmsg(f'{self.desc.capitalize()} {self.label.hl()} at path {self.path} not found')
 			self.cfg._util.qmsg(f'{self.desc.capitalize()} {self.label.hl()} at path {self.path} not found')
 			return
 			return

+ 6 - 6
mmgen/proto/btc/regtest.py

@@ -73,7 +73,7 @@ class MMGenRegtest(MMGenObject):
 		'bch': 'n2fxhNx27GhHAWQhyuZ5REcBNrJqCJsJ12',
 		'bch': 'n2fxhNx27GhHAWQhyuZ5REcBNrJqCJsJ12',
 	}
 	}
 
 
-	def __init__(self, cfg, coin, bdb_wallet=False):
+	def __init__(self, cfg, coin, *, bdb_wallet=False):
 		self.cfg = cfg
 		self.cfg = cfg
 		self.coin = coin.lower()
 		self.coin = coin.lower()
 		self.bdb_wallet = bdb_wallet
 		self.bdb_wallet = bdb_wallet
@@ -83,7 +83,7 @@ class MMGenRegtest(MMGenObject):
 		self.proto = init_proto(cfg, self.coin, regtest=True, need_amt=True)
 		self.proto = init_proto(cfg, self.coin, regtest=True, need_amt=True)
 		self.d = CoinDaemon(
 		self.d = CoinDaemon(
 			cfg,
 			cfg,
-			self.coin + '_rt',
+			network_id = self.coin + '_rt',
 			test_suite = cfg.test_suite,
 			test_suite = cfg.test_suite,
 			opts       = ['bdb_wallet'] if bdb_wallet else None)
 			opts       = ['bdb_wallet'] if bdb_wallet else None)
 
 
@@ -116,7 +116,7 @@ class MMGenRegtest(MMGenObject):
 		t.addrtype = 'compressed' if self.proto.coin == 'BCH' else 'bech32'
 		t.addrtype = 'compressed' if self.proto.coin == 'BCH' else 'bech32'
 		return t.hex2wif(self.bdb_hdseed)
 		return t.hex2wif(self.bdb_hdseed)
 
 
-	async def generate(self, blocks=1, silent=False):
+	async def generate(self, blocks=1, *, silent=False):
 
 
 		blocks = int(blocks)
 		blocks = int(blocks)
 
 
@@ -194,11 +194,11 @@ class MMGenRegtest(MMGenObject):
 			msg('Stopping regtest daemon')
 			msg('Stopping regtest daemon')
 			await self.rpc_call('stop')
 			await self.rpc_call('stop')
 
 
-	def init_daemon(self, reindex=False):
+	def init_daemon(self, *, reindex=False):
 		if reindex:
 		if reindex:
 			self.d.usr_coind_args.append('--reindex')
 			self.d.usr_coind_args.append('--reindex')
 
 
-	async def start_daemon(self, reindex=False, silent=True):
+	async def start_daemon(self, *, reindex=False, silent=True):
 		self.init_daemon(reindex=reindex)
 		self.init_daemon(reindex=reindex)
 		self.d.start(silent=silent)
 		self.d.start(silent=silent)
 		for user in ('miner', 'bob', 'alice'):
 		for user in ('miner', 'bob', 'alice'):
@@ -260,7 +260,7 @@ class MMGenRegtest(MMGenObject):
 
 
 	async def fork(self, coin): # currently disabled
 	async def fork(self, coin): # currently disabled
 
 
-		proto = init_proto(self.cfg, coin, False)
+		proto = init_proto(self.cfg, coin, testnet=False)
 		if not [f for f in proto.forks if f[2] == proto.coin.lower() and f[3] is True]:
 		if not [f for f in proto.forks if f[2] == proto.coin.lower() and f[3] is True]:
 			die(1, f'Coin {proto.coin} is not a replayable fork of coin {coin}')
 			die(1, f'Coin {proto.coin} is not a replayable fork of coin {coin}')
 
 

+ 4 - 2
mmgen/proto/btc/rpc.py

@@ -54,6 +54,7 @@ class CallSigs:
 		def createwallet(
 		def createwallet(
 				self,
 				self,
 				wallet_name,
 				wallet_name,
+				*,
 				no_keys         = True,
 				no_keys         = True,
 				blank           = True,
 				blank           = True,
 				passphrase      = '',
 				passphrase      = '',
@@ -86,6 +87,7 @@ class CallSigs:
 		def createwallet(
 		def createwallet(
 				self,
 				self,
 				wallet_name,
 				wallet_name,
+				*,
 				no_keys         = True,
 				no_keys         = True,
 				blank           = True,
 				blank           = True,
 				passphrase      = '',
 				passphrase      = '',
@@ -269,7 +271,7 @@ class BitcoinRPCClient(RPCClient, metaclass=AsyncInit):
 		fn = self.get_daemon_cfg_fn()
 		fn = self.get_daemon_cfg_fn()
 		try:
 		try:
 			lines = get_lines_from_file(
 			lines = get_lines_from_file(
-				self.cfg, fn, 'daemon config file', silent=not self.cfg.verbose)
+				self.cfg, fn, desc='daemon config file', silent=not self.cfg.verbose)
 		except:
 		except:
 			self.cfg._util.vmsg(f'Warning: {fn!r} does not exist or is unreadable')
 			self.cfg._util.vmsg(f'Warning: {fn!r} does not exist or is unreadable')
 			return dict((k, None) for k in req_keys)
 			return dict((k, None) for k in req_keys)
@@ -289,7 +291,7 @@ class BitcoinRPCClient(RPCClient, metaclass=AsyncInit):
 	def get_daemon_auth_cookie(self):
 	def get_daemon_auth_cookie(self):
 		fn = self.daemon.auth_cookie_fn
 		fn = self.daemon.auth_cookie_fn
 		return get_lines_from_file(
 		return get_lines_from_file(
-			self.cfg, fn, 'cookie', quiet=True)[0] if os.access(fn, os.R_OK) else ''
+			self.cfg, fn, desc='cookie', quiet=True)[0] if os.access(fn, os.R_OK) else ''
 
 
 	def info(self, info_id):
 	def info(self, info_id):
 
 

+ 1 - 1
mmgen/proto/btc/tw/ctl.py

@@ -27,7 +27,7 @@ class BitcoinTwCtl(TwCtl):
 		raise NotImplementedError('not implemented')
 		raise NotImplementedError('not implemented')
 
 
 	@write_mode
 	@write_mode
-	async def import_address(self, addr, label, rescan=False):
+	async def import_address(self, addr, *, label, rescan=False):
 		if (await self.rpc.walletinfo).get('descriptors'):
 		if (await self.rpc.walletinfo).get('descriptors'):
 			return await self.batch_import_address([(addr, label, rescan)])
 			return await self.batch_import_address([(addr, label, rescan)])
 		else:
 		else:

+ 2 - 2
mmgen/proto/btc/tx/base.py

@@ -75,7 +75,7 @@ def DeserializeTX(proto, txhex):
 	def bytes2coin_amt(bytes_le):
 	def bytes2coin_amt(bytes_le):
 		return proto.coin_amt(bytes2int(bytes_le), from_unit='satoshi')
 		return proto.coin_amt(bytes2int(bytes_le), from_unit='satoshi')
 
 
-	def bshift(n, skip=False, sub_null=False):
+	def bshift(n, *, skip=False, sub_null=False):
 		nonlocal idx, raw_tx
 		nonlocal idx, raw_tx
 		ret = tx[idx:idx+n]
 		ret = tx[idx:idx+n]
 		idx += n
 		idx += n
@@ -87,7 +87,7 @@ def DeserializeTX(proto, txhex):
 
 
 	# https://bitcoin.org/en/developer-reference#compactsize-unsigned-integers
 	# https://bitcoin.org/en/developer-reference#compactsize-unsigned-integers
 	# For example, the number 515 is encoded as 0xfd0302.
 	# For example, the number 515 is encoded as 0xfd0302.
-	def readVInt(skip=False):
+	def readVInt(*, skip=False):
 		nonlocal idx, raw_tx
 		nonlocal idx, raw_tx
 		s = tx[idx]
 		s = tx[idx]
 		idx += 1
 		idx += 1

+ 1 - 1
mmgen/proto/btc/tx/info.py

@@ -145,7 +145,7 @@ class TxInfo(TxInfo):
 			+ ''.join(format_io('inputs'))
 			+ ''.join(format_io('inputs'))
 			+ ''.join(format_io('outputs')))
 			+ ''.join(format_io('outputs')))
 
 
-	def strfmt_locktime(self, locktime=None, terse=False):
+	def strfmt_locktime(self, locktime=None, *, terse=False):
 		# Locktime itself is an unsigned 4-byte integer which can be parsed two ways:
 		# Locktime itself is an unsigned 4-byte integer which can be parsed two ways:
 		#
 		#
 		# If less than 500 million, locktime is parsed as a block height. The transaction can be
 		# If less than 500 million, locktime is parsed as a block height. The transaction can be

+ 1 - 1
mmgen/proto/btc/tx/online.py

@@ -19,7 +19,7 @@ from .signed import Signed
 
 
 class OnlineSigned(Signed, TxBase.OnlineSigned):
 class OnlineSigned(Signed, TxBase.OnlineSigned):
 
 
-	async def send(self, prompt_user=True):
+	async def send(self, *, prompt_user=True):
 
 
 		self.check_correct_chain()
 		self.check_correct_chain()
 
 

+ 1 - 1
mmgen/proto/btc/tx/op_return_data.py

@@ -61,7 +61,7 @@ class OpReturnData(bytes, InitErrors):
 			self.display_hex = False
 			self.display_hex = False
 			return ret
 			return ret
 
 
-	def hl(self, add_label=False):
+	def hl(self, *, add_label=False):
 		'colorize and optionally label the result of str()'
 		'colorize and optionally label the result of str()'
 		from ....color import blue, pink
 		from ....color import blue, pink
 		ret = str(self)
 		ret = str(self)

+ 1 - 1
mmgen/proto/eth/contract.py

@@ -45,7 +45,7 @@ class TokenCommon(MMGenObject):
 			int(parse_abi(data)[-1], 16) * self.base_unit,
 			int(parse_abi(data)[-1], 16) * self.base_unit,
 			from_decimal = True)
 			from_decimal = True)
 
 
-	async def do_call(self, method_sig, method_args='', toUnit=False):
+	async def do_call(self, method_sig, method_args='', *, toUnit=False):
 		data = self.create_method_id(method_sig) + method_args
 		data = self.create_method_id(method_sig) + method_args
 		if self.cfg.debug:
 		if self.cfg.debug:
 			msg('ETH_CALL {}:  {}'.format(
 			msg('ETH_CALL {}:  {}'.format(

+ 3 - 3
mmgen/proto/eth/daemon.py

@@ -174,12 +174,12 @@ class erigon_daemon(geth_daemon):
 			test_suite   = self.test_suite,
 			test_suite   = self.test_suite,
 			datadir      = self.datadir)
 			datadir      = self.datadir)
 
 
-	def start(self, quiet=False, silent=False):
+	def start(self, *, quiet=False, silent=False):
 		super().start(quiet=quiet, silent=silent)
 		super().start(quiet=quiet, silent=silent)
 		self.rpc_d.debug = self.debug
 		self.rpc_d.debug = self.debug
 		return self.rpc_d.start(quiet=quiet, silent=silent)
 		return self.rpc_d.start(quiet=quiet, silent=silent)
 
 
-	def stop(self, quiet=False, silent=False):
+	def stop(self, *, quiet=False, silent=False):
 		self.rpc_d.debug = self.debug
 		self.rpc_d.debug = self.debug
 		self.rpc_d.stop(quiet=quiet, silent=silent)
 		self.rpc_d.stop(quiet=quiet, silent=silent)
 		return super().stop(quiet=quiet, silent=silent)
 		return super().stop(quiet=quiet, silent=silent)
@@ -196,7 +196,7 @@ class erigon_rpcdaemon(RPCDaemon):
 	use_pidfile = False
 	use_pidfile = False
 	use_threads = True
 	use_threads = True
 
 
-	def __init__(self, cfg, proto, rpc_port, private_port, test_suite, datadir):
+	def __init__(self, cfg, proto, *, rpc_port, private_port, test_suite, datadir):
 
 
 		self.proto = proto
 		self.proto = proto
 		self.test_suite = test_suite
 		self.test_suite = test_suite

+ 1 - 1
mmgen/proto/eth/misc.py

@@ -14,7 +14,7 @@ proto.eth.misc: miscellaneous utilities for Ethereum base protocol
 
 
 from ...util2 import get_keccak
 from ...util2 import get_keccak
 
 
-def decrypt_geth_keystore(cfg, wallet_fn, passwd, check_addr=True):
+def decrypt_geth_keystore(cfg, wallet_fn, passwd, *, check_addr=True):
 	"""
 	"""
 	Decrypt the encrypted private key in a Geth keystore wallet, returning the decrypted key
 	Decrypt the encrypted private key in a Geth keystore wallet, returning the decrypted key
 	"""
 	"""

+ 5 - 5
mmgen/proto/eth/tw/ctl.py

@@ -88,13 +88,13 @@ class EthereumTwCtl(TwCtl):
 
 
 	@write_mode
 	@write_mode
 	async def batch_import_address(self, args_list):
 	async def batch_import_address(self, args_list):
-		return [await self.import_address(*a) for a in args_list]
+		return [await self.import_address(a, label=b, rescan=c) for a, b, c in args_list]
 
 
 	async def rescan_addresses(self, coin_addrs):
 	async def rescan_addresses(self, coin_addrs):
 		pass
 		pass
 
 
 	@write_mode
 	@write_mode
-	async def import_address(self, addr, label, rescan=False):
+	async def import_address(self, addr, *, label, rescan=False):
 		r = self.data_root
 		r = self.data_root
 		if addr in r:
 		if addr in r:
 			if not r[addr]['mmid'] and label.mmid:
 			if not r[addr]['mmid'] and label.mmid:
@@ -174,7 +174,7 @@ class EthereumTokenTwCtl(EthereumTwCtl):
 	symbol = None
 	symbol = None
 	cur_eth_balances = {}
 	cur_eth_balances = {}
 
 
-	async def __init__(self, cfg, proto, mode='r', token_addr=None, no_rpc=False):
+	async def __init__(self, cfg, proto, *, mode='r', token_addr=None, no_rpc=False):
 
 
 		await super().__init__(cfg, proto, mode=mode, no_rpc=no_rpc)
 		await super().__init__(cfg, proto, mode=mode, no_rpc=no_rpc)
 
 
@@ -215,13 +215,13 @@ class EthereumTokenTwCtl(EthereumTwCtl):
 	async def rpc_get_balance(self, addr):
 	async def rpc_get_balance(self, addr):
 		return await Token(self.cfg, self.proto, self.token, self.decimals, self.rpc).get_balance(addr)
 		return await Token(self.cfg, self.proto, self.token, self.decimals, self.rpc).get_balance(addr)
 
 
-	async def get_eth_balance(self, addr, force_rpc=False):
+	async def get_eth_balance(self, addr, *, force_rpc=False):
 		cache = self.cur_eth_balances
 		cache = self.cur_eth_balances
 		r = self.data['accounts']
 		r = self.data['accounts']
 		ret = None if force_rpc else self.get_cached_balance(addr, cache, r)
 		ret = None if force_rpc else self.get_cached_balance(addr, cache, r)
 		if ret is None:
 		if ret is None:
 			ret = await super().rpc_get_balance(addr)
 			ret = await super().rpc_get_balance(addr)
-			self.cache_balance(addr, ret, cache, r)
+			self.cache_balance(addr, ret, session_cache=cache, data_root=r)
 		return ret
 		return ret
 
 
 	def get_param(self, param):
 	def get_param(self, param):

+ 1 - 1
mmgen/proto/eth/tw/json.py

@@ -109,7 +109,7 @@ class EthereumTwJSON(TwJSON):
 
 
 	class Export(TwJSON.Export, Base):
 	class Export(TwJSON.Export, Base):
 
 
-		async def get_entries(self, include_amts=True):
+		async def get_entries(self, *, include_amts=True):
 
 
 			def gen_data(data):
 			def gen_data(data):
 				for k, v in data.items():
 				for k, v in data.items():

+ 1 - 1
mmgen/proto/eth/tw/unspent.py

@@ -95,7 +95,7 @@ class EthereumTwUnspentOutputs(EthereumTwView, TwUnspentOutputs):
 			interactive = interactive,
 			interactive = interactive,
 		)
 		)
 
 
-	def do_sort(self, key=None, reverse=False):
+	def do_sort(self, key=None, *, reverse=False):
 		if key == 'txid':
 		if key == 'txid':
 			return
 			return
 		super().do_sort(key=key, reverse=reverse)
 		super().do_sort(key=key, reverse=reverse)

+ 1 - 1
mmgen/proto/eth/tx/online.py

@@ -20,7 +20,7 @@ from .signed import Signed, TokenSigned
 
 
 class OnlineSigned(Signed, TxBase.OnlineSigned):
 class OnlineSigned(Signed, TxBase.OnlineSigned):
 
 
-	async def send(self, prompt_user=True):
+	async def send(self, *, prompt_user=True):
 
 
 		self.check_correct_chain()
 		self.check_correct_chain()
 
 

+ 2 - 2
mmgen/proto/secp256k1/keygen.py

@@ -37,7 +37,7 @@ class backend:
 				compressed = privkey.compressed)
 				compressed = privkey.compressed)
 
 
 		@classmethod
 		@classmethod
-		def get_clsname(cls, cfg, silent=False):
+		def get_clsname(cls, cfg, *, silent=False):
 			try:
 			try:
 				from .secp256k1 import pubkey_gen
 				from .secp256k1 import pubkey_gen
 				if not pubkey_gen(bytes.fromhex('deadbeef'*8), 1):
 				if not pubkey_gen(bytes.fromhex('deadbeef'*8), 1):
@@ -67,7 +67,7 @@ class backend:
 			Uncompressed public keys start with 0x04; compressed public keys begin with 0x03 or
 			Uncompressed public keys start with 0x04; compressed public keys begin with 0x03 or
 			0x02 depending on whether they're greater or less than the midpoint of the curve.
 			0x02 depending on whether they're greater or less than the midpoint of the curve.
 			"""
 			"""
-			def privnum2pubkey(numpriv, compressed=False):
+			def privnum2pubkey(numpriv, *, compressed=False):
 				pk = self.ecdsa.SigningKey.from_secret_exponent(numpriv, curve=self.ecdsa.SECP256k1)
 				pk = self.ecdsa.SigningKey.from_secret_exponent(numpriv, curve=self.ecdsa.SECP256k1)
 				# vk_bytes = x (32 bytes) + y (32 bytes) (unsigned big-endian)
 				# vk_bytes = x (32 bytes) + y (32 bytes) (unsigned big-endian)
 				return pubkey_format(pk.verifying_key.to_string(), compressed)
 				return pubkey_format(pk.verifying_key.to_string(), compressed)

+ 1 - 0
mmgen/proto/xmr/daemon.py

@@ -104,6 +104,7 @@ class MoneroWalletDaemon(RPCDaemon):
 			self,
 			self,
 			cfg,
 			cfg,
 			proto,
 			proto,
+			*,
 			wallet_dir  = None,
 			wallet_dir  = None,
 			test_suite  = False,
 			test_suite  = False,
 			user        = None,
 			user        = None,

+ 5 - 4
mmgen/proto/xmr/rpc.py

@@ -25,6 +25,7 @@ class MoneroRPCClient(RPCClient):
 			self,
 			self,
 			cfg,
 			cfg,
 			proto,
 			proto,
+			*,
 			host,
 			host,
 			port,
 			port,
 			user,
 			user,
@@ -42,7 +43,7 @@ class MoneroRPCClient(RPCClient):
 			if host.endswith('.onion'):
 			if host.endswith('.onion'):
 				self.network_proto = 'http'
 				self.network_proto = 'http'
 
 
-		super().__init__(cfg, host, port, test_connection)
+		super().__init__(cfg, host, port, test_connection=test_connection)
 
 
 		if self.auth_type:
 		if self.auth_type:
 			self.auth = auth_data(user, passwd)
 			self.auth = auth_data(user, passwd)
@@ -90,7 +91,7 @@ class MoneroRPCClient(RPCClient):
 			host_path = f'/{method}'
 			host_path = f'/{method}'
 		), json_rpc=False)
 		), json_rpc=False)
 
 
-	async def do_stop_daemon(self, silent=False):
+	async def do_stop_daemon(self, *, silent=False):
 		return self.call_raw('stop_daemon') # unreliable on macOS (daemon stops, but closes connection)
 		return self.call_raw('stop_daemon') # unreliable on macOS (daemon stops, but closes connection)
 
 
 	rpcmethods = ('get_info',)
 	rpcmethods = ('get_info',)
@@ -100,7 +101,7 @@ class MoneroWalletRPCClient(MoneroRPCClient):
 
 
 	auth_type = 'digest'
 	auth_type = 'digest'
 
 
-	def __init__(self, cfg, daemon, test_connection=True):
+	def __init__(self, cfg, daemon, *, test_connection=True):
 
 
 		RPCClient.__init__(
 		RPCClient.__init__(
 			self            = self,
 			self            = self,
@@ -128,7 +129,7 @@ class MoneroWalletRPCClient(MoneroRPCClient):
 	def call_raw(self, *args, **kwargs):
 	def call_raw(self, *args, **kwargs):
 		raise NotImplementedError('call_raw() not implemented for class MoneroWalletRPCClient')
 		raise NotImplementedError('call_raw() not implemented for class MoneroWalletRPCClient')
 
 
-	async def do_stop_daemon(self, silent=False):
+	async def do_stop_daemon(self, *, silent=False):
 		"""
 		"""
 		NB: the 'stop_wallet' RPC call closes the open wallet before shutting down the daemon,
 		NB: the 'stop_wallet' RPC call closes the open wallet before shutting down the daemon,
 		returning an error if no wallet is open
 		returning an error if no wallet is open

+ 3 - 2
mmgen/protocol.py

@@ -59,7 +59,7 @@ class CoinProtocol(MMGenObject):
 		decimal_prec = 28
 		decimal_prec = 28
 		_set_ok = ('tokensym',)
 		_set_ok = ('tokensym',)
 
 
-		def __init__(self, cfg, coin, name, network, tokensym=None, need_amt=False):
+		def __init__(self, cfg, coin, *, name, network, tokensym=None, need_amt=False):
 			self.cfg        = cfg
 			self.cfg        = cfg
 			self.coin       = coin.upper()
 			self.coin       = coin.upper()
 			self.coin_id    = self.coin
 			self.coin_id    = self.coin
@@ -180,7 +180,7 @@ class CoinProtocol(MMGenObject):
 		def viewkey(self, viewkey_str):
 		def viewkey(self, viewkey_str):
 			raise NotImplementedError(f'{self.name} protocol does not support view keys')
 			raise NotImplementedError(f'{self.name} protocol does not support view keys')
 
 
-		def base_proto_subclass(self, cls, modname, sub_clsname=None, is_token=False):
+		def base_proto_subclass(self, cls, modname, *, sub_clsname=None, is_token=False):
 			"""
 			"""
 			magic module loading and class selection
 			magic module loading and class selection
 			"""
 			"""
@@ -281,6 +281,7 @@ class CoinProtocol(MMGenObject):
 def init_proto(
 def init_proto(
 		cfg,
 		cfg,
 		coin       = None,
 		coin       = None,
+		*,
 		testnet    = False,
 		testnet    = False,
 		regtest    = False,
 		regtest    = False,
 		network    = None,
 		network    = None,

+ 7 - 6
mmgen/rpc.py

@@ -30,7 +30,7 @@ from .objmethods import HiliteStr, InitErrors, MMGenObject
 
 
 auth_data = namedtuple('rpc_auth_data', ['user', 'passwd'])
 auth_data = namedtuple('rpc_auth_data', ['user', 'passwd'])
 
 
-def dmsg_rpc(fs, data=None, is_json=False):
+def dmsg_rpc(fs, data=None, *, is_json=False):
 	msg(
 	msg(
 		fs if data is None else
 		fs if data is None else
 		fs.format(pp_fmt(json.loads(data) if is_json else data))
 		fs.format(pp_fmt(json.loads(data) if is_json else data))
@@ -255,7 +255,7 @@ class RPCClient(MMGenObject):
 	network_proto = 'http'
 	network_proto = 'http'
 	proxy = None
 	proxy = None
 
 
-	def __init__(self, cfg, host, port, test_connection=True):
+	def __init__(self, cfg, host, port, *, test_connection=True):
 
 
 		self.cfg = cfg
 		self.cfg = cfg
 		self.name = type(self).__name__
 		self.name = type(self).__name__
@@ -376,7 +376,7 @@ class RPCClient(MMGenObject):
 			timeout = timeout,
 			timeout = timeout,
 			wallet = wallet)
 			wallet = wallet)
 
 
-	def process_http_resp(self, run_ret, batch=False, json_rpc=True):
+	def process_http_resp(self, run_ret, *, batch=False, json_rpc=True):
 
 
 		def float_parser(n):
 		def float_parser(n):
 			return n
 			return n
@@ -424,7 +424,7 @@ class RPCClient(MMGenObject):
 						m = text
 						m = text
 			die('RPCFailure', f'{s.value} {s.name}: {m}')
 			die('RPCFailure', f'{s.value} {s.name}: {m}')
 
 
-	async def stop_daemon(self, quiet=False, silent=False):
+	async def stop_daemon(self, *, quiet=False, silent=False):
 		if self.daemon.state == 'ready':
 		if self.daemon.state == 'ready':
 			if not (quiet or silent):
 			if not (quiet or silent):
 				msg(f'Stopping {self.daemon.desc} on port {self.daemon.bind_port}')
 				msg(f'Stopping {self.daemon.desc} on port {self.daemon.bind_port}')
@@ -437,10 +437,10 @@ class RPCClient(MMGenObject):
 				msg(f'{self.daemon.desc} on port {self.daemon.bind_port} not running')
 				msg(f'{self.daemon.desc} on port {self.daemon.bind_port} not running')
 			return True
 			return True
 
 
-	def start_daemon(self, silent=False):
+	def start_daemon(self, *, silent=False):
 		return self.daemon.start(silent=silent)
 		return self.daemon.start(silent=silent)
 
 
-	async def restart_daemon(self, quiet=False, silent=False):
+	async def restart_daemon(self, *, quiet=False, silent=False):
 		await self.stop_daemon(quiet=quiet, silent=silent)
 		await self.stop_daemon(quiet=quiet, silent=silent)
 		return self.daemon.start(silent=silent)
 		return self.daemon.start(silent=silent)
 
 
@@ -467,6 +467,7 @@ class RPCClient(MMGenObject):
 async def rpc_init(
 async def rpc_init(
 		cfg,
 		cfg,
 		proto                 = None,
 		proto                 = None,
+		*,
 		backend               = None,
 		backend               = None,
 		daemon                = None,
 		daemon                = None,
 		ignore_daemon_version = False,
 		ignore_daemon_version = False,

+ 5 - 5
mmgen/seedsplit.py

@@ -68,7 +68,7 @@ class SeedShareList(SubSeedList):
 	count  = ImmutableAttr(SeedShareCount)
 	count  = ImmutableAttr(SeedShareCount)
 	id_str = ImmutableAttr(SeedSplitIDString)
 	id_str = ImmutableAttr(SeedSplitIDString)
 
 
-	def __init__(self, parent_seed, count, id_str=None, master_idx=None, debug_last_share=False):
+	def __init__(self, parent_seed, count, *, id_str=None, master_idx=None, debug_last_share=False):
 		self.member_type = SeedShare
 		self.member_type = SeedShare
 		self.parent_seed = parent_seed
 		self.parent_seed = parent_seed
 		self.id_str = id_str or 'default'
 		self.id_str = id_str or 'default'
@@ -118,7 +118,7 @@ class SeedShareList(SubSeedList):
 			B = self.join().data
 			B = self.join().data
 			assert A == B, f'Data mismatch!\noriginal seed: {A!r}\nrejoined seed: {B!r}'
 			assert A == B, f'Data mismatch!\noriginal seed: {A!r}\nrejoined seed: {B!r}'
 
 
-	def get_share_by_idx(self, idx, base_seed=False):
+	def get_share_by_idx(self, idx, *, base_seed=False):
 		if idx < 1 or idx > self.count:
 		if idx < 1 or idx > self.count:
 			die('RangeError', f'{idx}: share index out of range')
 			die('RangeError', f'{idx}: share index out of range')
 		elif idx == self.count:
 		elif idx == self.count:
@@ -129,7 +129,7 @@ class SeedShareList(SubSeedList):
 			ss_idx = SubSeedIdx(str(idx) + 'L')
 			ss_idx = SubSeedIdx(str(idx) + 'L')
 			return self.get_subseed_by_ss_idx(ss_idx)
 			return self.get_subseed_by_ss_idx(ss_idx)
 
 
-	def get_share_by_seed_id(self, sid, base_seed=False):
+	def get_share_by_seed_id(self, sid, *, base_seed=False):
 		if sid == self.data['long'].key(self.count-1):
 		if sid == self.data['long'].key(self.count-1):
 			return self.last_share
 			return self.last_share
 		elif self.master_share and sid == self.data['long'].key(0):
 		elif self.master_share and sid == self.data['long'].key(0):
@@ -181,7 +181,7 @@ class SeedShareBase(MMGenObject):
 	def desc(self):
 	def desc(self):
 		return self.get_desc()
 		return self.get_desc()
 
 
-	def get_desc(self, ui=False):
+	def get_desc(self, *, ui=False):
 		pl = self.parent_list
 		pl = self.parent_list
 		mss = f', with master share #{pl.master_share.idx}' if pl.master_share else ''
 		mss = f', with master share #{pl.master_share.idx}' if pl.master_share else ''
 		if ui:
 		if ui:
@@ -274,7 +274,7 @@ class SeedShareMaster(SeedBase, SeedShareBase):
 		scramble_key = id_str.encode() + b':' + count.to_bytes(2, 'big')
 		scramble_key = id_str.encode() + b':' + count.to_bytes(2, 'big')
 		return Crypto(self.cfg).scramble_seed(self.data, scramble_key)[:self.byte_len]
 		return Crypto(self.cfg).scramble_seed(self.data, scramble_key)[:self.byte_len]
 
 
-	def get_desc(self, ui=False):
+	def get_desc(self, *, ui=False):
 		psid = self.parent_list.parent_seed.sid
 		psid = self.parent_list.parent_seed.sid
 		mss = f'master share #{self.idx} of '
 		mss = f'master share #{self.idx} of '
 		return yellow('(' + mss) + psid.hl() + yellow(')') if ui else mss + psid
 		return yellow('(' + mss) + psid.hl() + yellow(')') if ui else mss + psid

+ 1 - 1
mmgen/sha2.py

@@ -68,7 +68,7 @@ class Sha2:
 		# First wordBits bits of the fractional parts of the cube roots of the first nRounds primes
 		# First wordBits bits of the fractional parts of the cube roots of the first nRounds primes
 		cls.K = tuple(getFractionalBits(cbrt(n)) for n in primes)
 		cls.K = tuple(getFractionalBits(cbrt(n)) for n in primes)
 
 
-	def __init__(self, message, preprocess=True):
+	def __init__(self, message, *, preprocess=True):
 		'Use preprocess=False for Sha256Compress'
 		'Use preprocess=False for Sha256Compress'
 		assert isinstance(message, (bytes, bytearray, list)), 'message must be of type bytes, bytearray or list'
 		assert isinstance(message, (bytes, bytearray, list)), 'message must be of type bytes, bytearray or list'
 		if not self.K:
 		if not self.K:

+ 2 - 2
mmgen/subseed.py

@@ -95,7 +95,7 @@ class SubSeedList(MMGenObject):
 	def __len__(self):
 	def __len__(self):
 		return len(self.data['long'])
 		return len(self.data['long'])
 
 
-	def get_subseed_by_ss_idx(self, ss_idx_in, print_msg=False):
+	def get_subseed_by_ss_idx(self, ss_idx_in, *, print_msg=False):
 		ss_idx = SubSeedIdx(ss_idx_in)
 		ss_idx = SubSeedIdx(ss_idx_in)
 		if print_msg:
 		if print_msg:
 			msg_r('{} {} of {}...'.format(
 			msg_r('{} {} of {}...'.format(
@@ -122,7 +122,7 @@ class SubSeedList(MMGenObject):
 		assert seed.sid == sid, f'{seed.sid} != {sid}: Seed ID mismatch!'
 		assert seed.sid == sid, f'{seed.sid} != {sid}: Seed ID mismatch!'
 		return seed
 		return seed
 
 
-	def get_subseed_by_seed_id(self, sid, last_idx=None, print_msg=False):
+	def get_subseed_by_seed_id(self, sid, *, last_idx=None, print_msg=False):
 
 
 		def get_existing_subseed_by_seed_id(sid):
 		def get_existing_subseed_by_seed_id(sid):
 			for k in ('long', 'short') if self.have_short else ('long',):
 			for k in ('long', 'short') if self.have_short else ('long',):

+ 8 - 8
mmgen/term.py

@@ -50,7 +50,7 @@ class MMGenTerm:
 		pass
 		pass
 
 
 	@classmethod
 	@classmethod
-	def init(cls, noecho=False):
+	def init(cls, *, noecho=False):
 		pass
 		pass
 
 
 	@classmethod
 	@classmethod
@@ -93,7 +93,7 @@ class MMGenTermLinux(MMGenTerm):
 		cls.cur_term = termios.tcgetattr(cls.stdin_fd)
 		cls.cur_term = termios.tcgetattr(cls.stdin_fd)
 
 
 	@classmethod
 	@classmethod
-	def init(cls, noecho=False):
+	def init(cls, *, noecho=False):
 		cls.stdin_fd = sys.stdin.fileno()
 		cls.stdin_fd = sys.stdin.fileno()
 		cls.cur_term = termios.tcgetattr(cls.stdin_fd)
 		cls.cur_term = termios.tcgetattr(cls.stdin_fd)
 		if not hasattr(cls, 'orig_term'):
 		if not hasattr(cls, 'orig_term'):
@@ -128,7 +128,7 @@ class MMGenTermLinux(MMGenTerm):
 				break
 				break
 
 
 	@classmethod
 	@classmethod
-	def get_char(cls, prompt='', immed_chars='', prehold_protect=True, num_bytes=5):
+	def get_char(cls, prompt='', *, immed_chars='', prehold_protect=True, num_bytes=5):
 		"""
 		"""
 		Use os.read(), not file.read(), to get a variable number of bytes without blocking.
 		Use os.read(), not file.read(), to get a variable number of bytes without blocking.
 		Request 5 bytes to cover escape sequences generated by F1, F2, .. Fn keys (5 bytes)
 		Request 5 bytes to cover escape sequences generated by F1, F2, .. Fn keys (5 bytes)
@@ -169,7 +169,7 @@ class MMGenTermLinuxStub(MMGenTermLinux):
 		pass
 		pass
 
 
 	@classmethod
 	@classmethod
-	def init(cls, noecho=False):
+	def init(cls, *, noecho=False):
 		cls.stdin_fd = sys.stdin.fileno()
 		cls.stdin_fd = sys.stdin.fileno()
 
 
 	@classmethod
 	@classmethod
@@ -181,7 +181,7 @@ class MMGenTermLinuxStub(MMGenTermLinux):
 		pass
 		pass
 
 
 	@classmethod
 	@classmethod
-	def get_char(cls, prompt='', immed_chars='', prehold_protect=None, num_bytes=5):
+	def get_char(cls, prompt='', *, immed_chars='', prehold_protect=None, num_bytes=5):
 		msg_r(prompt)
 		msg_r(prompt)
 		return os.read(0, num_bytes).decode()
 		return os.read(0, num_bytes).decode()
 
 
@@ -230,7 +230,7 @@ class MMGenTermMSWin(MMGenTerm):
 					return
 					return
 
 
 	@classmethod
 	@classmethod
-	def get_char(cls, prompt='', immed_chars='', prehold_protect=True, num_bytes=None):
+	def get_char(cls, prompt='', *, immed_chars='', prehold_protect=True, num_bytes=None):
 		"""
 		"""
 		always return a single character, ignore num_bytes
 		always return a single character, ignore num_bytes
 		first character of 2-character sequence returned by F1-F12 keys is discarded
 		first character of 2-character sequence returned by F1-F12 keys is discarded
@@ -268,7 +268,7 @@ class MMGenTermMSWin(MMGenTerm):
 class MMGenTermMSWinStub(MMGenTermMSWin):
 class MMGenTermMSWinStub(MMGenTermMSWin):
 
 
 	@classmethod
 	@classmethod
-	def get_char(cls, prompt='', immed_chars='', prehold_protect=None, num_bytes=None):
+	def get_char(cls, prompt='', *, immed_chars='', prehold_protect=None, num_bytes=None):
 		"""
 		"""
 		Use stdin to allow UTF-8 and emulate the one-character behavior of MMGenTermMSWin
 		Use stdin to allow UTF-8 and emulate the one-character behavior of MMGenTermMSWin
 		"""
 		"""
@@ -289,7 +289,7 @@ def get_term():
 		'win32': (MMGenTermMSWin if sys.stdin.isatty() else MMGenTermMSWinStub),
 		'win32': (MMGenTermMSWin if sys.stdin.isatty() else MMGenTermMSWinStub),
 	}[sys.platform]
 	}[sys.platform]
 
 
-def init_term(cfg, noecho=False):
+def init_term(cfg, *, noecho=False):
 
 
 	term = get_term()
 	term = get_term()
 
 

+ 1 - 1
mmgen/tool/coin.py

@@ -113,7 +113,7 @@ class tool_cmd(tool_cmd_base):
 			gd.ag.to_segwit_redeem_script(data),
 			gd.ag.to_segwit_redeem_script(data),
 			gd.ag.to_addr(data))
 			gd.ag.to_addr(data))
 
 
-	def _privhex2out(self, privhex: 'sstr', output_pubhex=False):
+	def _privhex2out(self, privhex: 'sstr', *, output_pubhex=False):
 		gd = self._init_generators()
 		gd = self._init_generators()
 		pk = PrivKey(
 		pk = PrivKey(
 			self.proto,
 			self.proto,

+ 1 - 1
mmgen/tool/file.py

@@ -36,7 +36,7 @@ class tool_cmd(tool_cmd_base):
 		kwargs = {'skip_chksum_msg':True}
 		kwargs = {'skip_chksum_msg':True}
 		if not obj.__name__ == 'PasswordList':
 		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, mmgen_addrfile, **kwargs)
+		ret = obj(self.cfg, self.proto, infile=mmgen_addrfile, **kwargs)
 		if self.cfg.verbose:
 		if self.cfg.verbose:
 			from ..util import msg, capfirst
 			from ..util import msg, capfirst
 			if ret.al_id.mmtype.name == 'password':
 			if ret.al_id.mmtype.name == 'password':

+ 4 - 4
mmgen/tool/filecrypt.py

@@ -37,16 +37,16 @@ class tool_cmd(tool_cmd_base):
 	"""
 	"""
 	def encrypt(self, infile: str, outfile='', hash_preset=''):
 	def encrypt(self, infile: str, outfile='', hash_preset=''):
 		"encrypt a file"
 		"encrypt a file"
-		data = get_data_from_file(self.cfg, infile, 'data for encryption', binary=True)
+		data = get_data_from_file(self.cfg, infile, desc='data for encryption', binary=True)
 		enc_d = Crypto(self.cfg).mmgen_encrypt(data, 'data', hash_preset)
 		enc_d = Crypto(self.cfg).mmgen_encrypt(data, 'data', hash_preset)
 		if not outfile:
 		if not outfile:
 			outfile = f'{os.path.basename(infile)}.{Crypto.mmenc_ext}'
 			outfile = f'{os.path.basename(infile)}.{Crypto.mmenc_ext}'
-		write_data_to_file(self.cfg, outfile, enc_d, 'encrypted data', binary=True)
+		write_data_to_file(self.cfg, outfile, enc_d, desc='encrypted data', binary=True)
 		return True
 		return True
 
 
 	def decrypt(self, infile: str, outfile='', hash_preset=''):
 	def decrypt(self, infile: str, outfile='', hash_preset=''):
 		"decrypt a file"
 		"decrypt a file"
-		enc_d = get_data_from_file(self.cfg, infile, 'encrypted data', binary=True)
+		enc_d = get_data_from_file(self.cfg, infile, desc='encrypted data', binary=True)
 		while True:
 		while True:
 			dec_d = Crypto(self.cfg).mmgen_decrypt(enc_d, 'data', hash_preset)
 			dec_d = Crypto(self.cfg).mmgen_decrypt(enc_d, 'data', hash_preset)
 			if dec_d:
 			if dec_d:
@@ -59,5 +59,5 @@ class tool_cmd(tool_cmd_base):
 			outfile = remove_extension(o, Crypto.mmenc_ext)
 			outfile = remove_extension(o, Crypto.mmenc_ext)
 			if outfile == o:
 			if outfile == o:
 				outfile += '.dec'
 				outfile += '.dec'
-		write_data_to_file(self.cfg, outfile, dec_d, 'decrypted data', binary=True)
+		write_data_to_file(self.cfg, outfile, dec_d, desc='decrypted data', binary=True)
 		return True
 		return True

+ 5 - 4
mmgen/tool/fileutil.py

@@ -32,6 +32,7 @@ class tool_cmd(tool_cmd_base):
 	def find_incog_data(self,
 	def find_incog_data(self,
 			filename: str,
 			filename: str,
 			incog_id: str,
 			incog_id: str,
+			*,
 			keep_searching: 'continue search after finding data (ID collisions can yield false positives)' = False):
 			keep_searching: 'continue search after finding data (ID collisions can yield false positives)' = False):
 		"Use an Incog ID to find hidden incognito wallet data"
 		"Use an Incog ID to find hidden incognito wallet data"
 
 
@@ -65,7 +66,7 @@ class tool_cmd(tool_cmd_base):
 		os.close(f)
 		os.close(f)
 		return True
 		return True
 
 
-	def rand2file(self, outfile: str, nbytes: str, threads=4, silent=False):
+	def rand2file(self, outfile: str, nbytes: str, *, threads=4, silent=False):
 		"""
 		"""
 		write ‘nbytes’ bytes of random data to specified file (dd-style byte specifiers supported)
 		write ‘nbytes’ bytes of random data to specified file (dd-style byte specifiers supported)
 
 
@@ -148,7 +149,7 @@ class tool_cmd(tool_cmd_base):
 
 
 		return True
 		return True
 
 
-	def decrypt_keystore(self, wallet_file: str, output_hex=False):
+	def decrypt_keystore(self, wallet_file: str, *, output_hex=False):
 		"decrypt the data in a keystore wallet, returning the decrypted data in binary format"
 		"decrypt the data in a keystore wallet, returning the decrypted data in binary format"
 		from ..ui import line_input
 		from ..ui import line_input
 		passwd = line_input(self.cfg, 'Enter passphrase: ', echo=self.cfg.echo_passphrase).strip().encode()
 		passwd = line_input(self.cfg, 'Enter passphrase: ', echo=self.cfg.echo_passphrase).strip().encode()
@@ -159,9 +160,9 @@ class tool_cmd(tool_cmd_base):
 		ret = decrypt_keystore(data[0]['keystore'], passwd)
 		ret = decrypt_keystore(data[0]['keystore'], passwd)
 		return ret.hex() if output_hex else ret
 		return ret.hex() if output_hex else ret
 
 
-	def decrypt_geth_keystore(self, wallet_file: str, check_addr=True):
+	def decrypt_geth_keystore(self, wallet_file: str, *, check_addr=True):
 		"decrypt the private key in a Geth keystore wallet, returning the decrypted key in hex format"
 		"decrypt the private key in a Geth keystore wallet, returning the decrypted key in hex format"
 		from ..ui import line_input
 		from ..ui import line_input
 		passwd = line_input(self.cfg, 'Enter passphrase: ', echo=self.cfg.echo_passphrase).strip().encode()
 		passwd = line_input(self.cfg, 'Enter passphrase: ', echo=self.cfg.echo_passphrase).strip().encode()
 		from ..proto.eth.misc import decrypt_geth_keystore
 		from ..proto.eth.misc import decrypt_geth_keystore
-		return decrypt_geth_keystore(self.cfg, wallet_file, passwd, check_addr).hex()
+		return decrypt_geth_keystore(self.cfg, wallet_file, passwd, check_addr=check_addr).hex()

+ 4 - 2
mmgen/tool/mnemonic.py

@@ -98,14 +98,15 @@ class tool_cmd(tool_cmd_base):
 		if fmt == 'xmrseed':
 		if fmt == 'xmrseed':
 			hexstr = self._xmr_reduce(bytes.fromhex(hexstr)).hex()
 			hexstr = self._xmr_reduce(bytes.fromhex(hexstr)).hex()
 		f = mnemonic_fmts[fmt]
 		f = mnemonic_fmts[fmt]
-		return ' '.join(f.conv_cls(fmt).fromhex(hexstr, f.pad))
+		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"
 		"convert a mnemonic seed phrase to a hexadecimal string"
 		f = mnemonic_fmts[fmt]
 		f = mnemonic_fmts[fmt]
-		return f.conv_cls(fmt).tohex(seed_mnemonic.split(), f.pad)
+		return f.conv_cls(fmt).tohex(seed_mnemonic.split(), pad=f.pad)
 
 
 	def mn2hex_interactive(self,
 	def mn2hex_interactive(self,
+			*,
 			fmt: mn_opts_disp = dfl_mnemonic_fmt,
 			fmt: mn_opts_disp = dfl_mnemonic_fmt,
 			mn_len: 'length of seed phrase in words' = 24,
 			mn_len: 'length of seed phrase in words' = 24,
 			print_mn: 'print the seed phrase after entry' = False):
 			print_mn: 'print the seed phrase after entry' = False):
@@ -122,6 +123,7 @@ class tool_cmd(tool_cmd_base):
 		return mnemonic_fmts[fmt].conv_cls(fmt).check_wordlist(self.cfg)
 		return mnemonic_fmts[fmt].conv_cls(fmt).check_wordlist(self.cfg)
 
 
 	def mn_printlist(self,
 	def mn_printlist(self,
+			*,
 			fmt: mn_opts_disp = dfl_mnemonic_fmt,
 			fmt: mn_opts_disp = dfl_mnemonic_fmt,
 			enum: 'enumerate the list' = False,
 			enum: 'enumerate the list' = False,
 			pager: 'send output to pager' = False):
 			pager: 'send output to pager' = False):

+ 7 - 6
mmgen/tool/rpc.py

@@ -50,7 +50,7 @@ class tool_cmd(tool_cmd_base):
 			r = await rpc_init(self.cfg, self.proto, ignore_daemon_version=True, ignore_wallet=True)
 			r = await rpc_init(self.cfg, self.proto, ignore_daemon_version=True, ignore_wallet=True)
 		return f'{d.coind_name} version {r.daemon_version} ({r.daemon_version_str})'
 		return f'{d.coind_name} version {r.daemon_version} ({r.daemon_version_str})'
 
 
-	async def getbalance(self,
+	async def getbalance(self, *,
 			minconf: 'minimum number of confirmations' = 1,
 			minconf: 'minimum number of confirmations' = 1,
 			quiet:   'produce quieter output' = False,
 			quiet:   'produce quieter output' = False,
 			pager:   'send output to pager' = False):
 			pager:   'send output to pager' = False):
@@ -81,7 +81,7 @@ class tool_cmd(tool_cmd_base):
 
 
 		return ret
 		return ret
 
 
-	async def twview(self,
+	async def twview(self, *,
 			pager:       'send output to pager' = False,
 			pager:       'send output to pager' = False,
 			reverse:     'reverse order of unspent outputs' = False,
 			reverse:     'reverse order of unspent outputs' = False,
 			wide:        'display data in wide tabular format' = False,
 			wide:        'display data in wide tabular format' = False,
@@ -98,7 +98,7 @@ class tool_cmd(tool_cmd_base):
 			obj, pager, reverse, wide, sort, age_fmt, interactive,
 			obj, pager, reverse, wide, sort, age_fmt, interactive,
 			show_mmid = show_mmid)
 			show_mmid = show_mmid)
 
 
-	async def txhist(self,
+	async def txhist(self, *,
 			pager:       'send output to pager' = False,
 			pager:       'send output to pager' = False,
 			reverse:     'reverse order of transactions' = False,
 			reverse:     'reverse order of transactions' = False,
 			detail:      'produce detailed, non-tabular output' = False,
 			detail:      'produce detailed, non-tabular output' = False,
@@ -114,6 +114,7 @@ class tool_cmd(tool_cmd_base):
 
 
 	async def listaddress(self,
 	async def listaddress(self,
 			mmgen_addr: str,
 			mmgen_addr: str,
+			*,
 			wide:         'display data in wide tabular format' = False,
 			wide:         'display data in wide tabular format' = False,
 			minconf:      'minimum number of confirmations' = 1,
 			minconf:      'minimum number of confirmations' = 1,
 			showcoinaddr: 'display coin address in addition to MMGen ID' = True,
 			showcoinaddr: 'display coin address in addition to MMGen ID' = True,
@@ -127,7 +128,7 @@ class tool_cmd(tool_cmd_base):
 			showcoinaddrs = showcoinaddr,
 			showcoinaddrs = showcoinaddr,
 			age_fmt       = age_fmt)
 			age_fmt       = age_fmt)
 
 
-	async def listaddresses(self,
+	async def listaddresses(self, *,
 			pager:        'send output to pager' = False,
 			pager:        'send output to pager' = False,
 			reverse:      'reverse order of unspent outputs' = False,
 			reverse:      'reverse order of unspent outputs' = False,
 			wide:         'display data in wide tabular format' = False,
 			wide:         'display data in wide tabular format' = False,
@@ -204,7 +205,7 @@ class tool_cmd(tool_cmd_base):
 		await (await TwCtl(self.cfg, self.proto, mode='w')).rescan_blockchain(start_block, stop_block)
 		await (await TwCtl(self.cfg, self.proto, mode='w')).rescan_blockchain(start_block, stop_block)
 		return True
 		return True
 
 
-	async def twexport(self,
+	async def twexport(self, *,
 			include_amts = True,
 			include_amts = True,
 			pretty       = False,
 			pretty       = False,
 			prune        = False,
 			prune        = False,
@@ -242,7 +243,7 @@ class tool_cmd(tool_cmd_base):
 			force_overwrite = force)
 			force_overwrite = force)
 		return True
 		return True
 
 
-	async def twimport(self, filename: str, ignore_checksum=False, batch=False):
+	async def twimport(self, filename: str, *, ignore_checksum=False, batch=False):
 		"""
 		"""
 		restore a tracking wallet from a JSON dump created by ‘twexport’
 		restore a tracking wallet from a JSON dump created by ‘twexport’
 
 

+ 7 - 4
mmgen/tool/util.py

@@ -57,6 +57,7 @@ class tool_cmd(tool_cmd_base):
 	def to_bytespec(self,
 	def to_bytespec(self,
 			n: int,
 			n: int,
 			dd_style_byte_specifier: str,
 			dd_style_byte_specifier: str,
+			*,
 			fmt:       'width and precision of output' = '0.2',
 			fmt:       'width and precision of output' = '0.2',
 			print_sym: 'print the specifier after the numerical value' = True,
 			print_sym: 'print the specifier after the numerical value' = True,
 			strip:     'strip trailing zeroes' = False,
 			strip:     'strip trailing zeroes' = False,
@@ -139,6 +140,7 @@ class tool_cmd(tool_cmd_base):
 	# TODO: handle stdin
 	# TODO: handle stdin
 	def hash256(self,
 	def hash256(self,
 			data: str,
 			data: str,
+			*,
 			file_input: 'first arg is the name of a file containing the data' = False,
 			file_input: 'first arg is the name of a file containing the data' = False,
 			hex_input:  'first arg is a hexadecimal string' = False):
 			hex_input:  'first arg is a hexadecimal string' = False):
 		"compute sha256(sha256(data)) (double sha256)"
 		"compute sha256(sha256(data)) (double sha256)"
@@ -215,25 +217,26 @@ class tool_cmd(tool_cmd_base):
 	def hextob32(self, hexstr: 'sstr', pad: 'pad output to this width' = 0):
 	def hextob32(self, hexstr: 'sstr', pad: 'pad output to this width' = 0):
 		"convert a hexadecimal string to an MMGen-flavor base 32 string"
 		"convert a hexadecimal string to an MMGen-flavor base 32 string"
 		from ..baseconv import baseconv
 		from ..baseconv import baseconv
-		return baseconv('b32').fromhex(hexstr, pad, tostr=True)
+		return baseconv('b32').fromhex(hexstr, pad=pad, tostr=True)
 
 
 	def b32tohex(self, b32_str: 'sstr', pad: 'pad output to this width' = 0):
 	def b32tohex(self, b32_str: 'sstr', pad: 'pad output to this width' = 0):
 		"convert an MMGen-flavor base 32 string to hexadecimal"
 		"convert an MMGen-flavor base 32 string to hexadecimal"
 		from ..baseconv import baseconv
 		from ..baseconv import baseconv
-		return baseconv('b32').tohex(b32_str.upper(), pad)
+		return baseconv('b32').tohex(b32_str.upper(), pad=pad)
 
 
 	def hextob6d(self,
 	def hextob6d(self,
 			hexstr: 'sstr',
 			hexstr: 'sstr',
+			*,
 			pad: 'pad output to this width' = 0,
 			pad: 'pad output to this width' = 0,
 			add_spaces: 'add a space after every 5th character' = True):
 			add_spaces: 'add a space after every 5th character' = True):
 		"convert a hexadecimal string to die roll base6 (base6d)"
 		"convert a hexadecimal string to die roll base6 (base6d)"
 		from ..baseconv import baseconv
 		from ..baseconv import baseconv
 		from ..util2 import block_format
 		from ..util2 import block_format
-		ret = baseconv('b6d').fromhex(hexstr, pad, tostr=True)
+		ret = baseconv('b6d').fromhex(hexstr, pad=pad, tostr=True)
 		return block_format(ret, gw=5, cols=None).strip() if add_spaces else ret
 		return block_format(ret, gw=5, cols=None).strip() if add_spaces else ret
 
 
 	def b6dtohex(self, b6d_str: 'sstr', pad: 'pad output to this width' = 0):
 	def b6dtohex(self, b6d_str: 'sstr', pad: 'pad output to this width' = 0):
 		"convert a die roll base6 (base6d) string to hexadecimal"
 		"convert a die roll base6 (base6d) string to hexadecimal"
 		from ..baseconv import baseconv
 		from ..baseconv import baseconv
 		from ..util import remove_whitespace
 		from ..util import remove_whitespace
-		return baseconv('b6d').tohex(remove_whitespace(b6d_str), pad)
+		return baseconv('b6d').tohex(remove_whitespace(b6d_str), pad=pad)

+ 8 - 6
mmgen/tool/wallet.py

@@ -43,19 +43,21 @@ class tool_cmd(tool_cmd_base):
 	def get_subseed(self, subseed_idx: str, wallet=''):
 	def get_subseed(self, subseed_idx: str, wallet=''):
 		"get the Seed ID of a single subseed by Subseed Index for default or specified wallet"
 		"get the Seed ID of a single subseed by Subseed Index for default or specified wallet"
 		self.cfg._set_quiet(True)
 		self.cfg._set_quiet(True)
-		return Wallet(self.cfg, self._get_seed_file(wallet)).seed.subseed(subseed_idx).sid
+		return Wallet(self.cfg, fn=self._get_seed_file(wallet)).seed.subseed(subseed_idx).sid
 
 
 	def get_subseed_by_seed_id(self, seed_id: str, wallet='', last_idx=SubSeedList.dfl_len):
 	def get_subseed_by_seed_id(self, seed_id: str, wallet='', last_idx=SubSeedList.dfl_len):
 		"get the Subseed Index of a single subseed by Seed ID for default or specified wallet"
 		"get the Subseed Index of a single subseed by Seed ID for default or specified wallet"
 		self.cfg._set_quiet(True)
 		self.cfg._set_quiet(True)
-		ret = Wallet(self.cfg, self._get_seed_file(wallet)).seed.subseed_by_seed_id(seed_id, last_idx)
+		ret = Wallet(
+			self.cfg,
+			fn = self._get_seed_file(wallet)).seed.subseed_by_seed_id(seed_id, last_idx=last_idx)
 		return ret.ss_idx if ret else None
 		return ret.ss_idx if ret else None
 
 
 	def list_subseeds(self, subseed_idx_range: str, wallet=''):
 	def list_subseeds(self, subseed_idx_range: str, wallet=''):
 		"list a range of subseed Seed IDs for default or specified wallet"
 		"list a range of subseed Seed IDs for default or specified wallet"
 		self.cfg._set_quiet(True)
 		self.cfg._set_quiet(True)
 		from ..subseed import SubSeedIdxRange
 		from ..subseed import SubSeedIdxRange
-		return Wallet(self.cfg, self._get_seed_file(wallet)).seed.subseeds.format(
+		return Wallet(self.cfg, fn=self._get_seed_file(wallet)).seed.subseeds.format(
 			*SubSeedIdxRange(subseed_idx_range))
 			*SubSeedIdxRange(subseed_idx_range))
 
 
 	def list_shares(self,
 	def list_shares(self,
@@ -65,8 +67,8 @@ class tool_cmd(tool_cmd_base):
 			wallet = ''):
 			wallet = ''):
 		"list the Seed IDs of the shares resulting from a split of default or specified wallet"
 		"list the Seed IDs of the shares resulting from a split of default or specified wallet"
 		self.cfg._set_quiet(True)
 		self.cfg._set_quiet(True)
-		return Wallet(self.cfg, self._get_seed_file(wallet)).seed.split(
-			share_count, id_str, master_share).format()
+		return Wallet(self.cfg, fn=self._get_seed_file(wallet)).seed.split(
+			share_count, id_str=id_str, master_idx=master_share).format()
 
 
 	def gen_key(self, mmgen_addr: str, wallet=''):
 	def gen_key(self, mmgen_addr: str, wallet=''):
 		"generate a single WIF key for specified MMGen address from default or specified wallet"
 		"generate a single WIF key for specified MMGen address from default or specified wallet"
@@ -82,7 +84,7 @@ class tool_cmd(tool_cmd_base):
 
 
 		addr = MMGenID(self.proto, mmgen_addr)
 		addr = MMGenID(self.proto, mmgen_addr)
 		self.cfg._set_quiet(True)
 		self.cfg._set_quiet(True)
-		ss = Wallet(self.cfg, self._get_seed_file(wallet))
+		ss = Wallet(self.cfg, fn=self._get_seed_file(wallet))
 
 
 		if ss.seed.sid != addr.sid:
 		if ss.seed.sid != addr.sid:
 			from ..util import die
 			from ..util import die

+ 1 - 1
mmgen/tw/addresses.py

@@ -68,7 +68,7 @@ class TwAddresses(TwView):
 	def coinaddr_list(self):
 	def coinaddr_list(self):
 		return [d.addr for d in self.data]
 		return [d.addr for d in self.data]
 
 
-	async def __init__(self, cfg, proto, minconf=1, mmgen_addrs='', get_data=False):
+	async def __init__(self, cfg, proto, *, minconf=1, mmgen_addrs='', get_data=False):
 
 
 		await super().__init__(cfg, proto)
 		await super().__init__(cfg, proto)
 
 

+ 8 - 6
mmgen/tw/ctl.py

@@ -63,6 +63,7 @@ class TwCtl(MMGenObject, metaclass=AsyncInit):
 			self,
 			self,
 			cfg,
 			cfg,
 			proto,
 			proto,
+			*,
 			mode              = 'r',
 			mode              = 'r',
 			token_addr        = None,
 			token_addr        = None,
 			no_rpc            = False,
 			no_rpc            = False,
@@ -167,7 +168,7 @@ class TwCtl(MMGenObject, metaclass=AsyncInit):
 	def data_root_desc(self):
 	def data_root_desc(self):
 		return self.data_key
 		return self.data_key
 
 
-	def cache_balance(self, addr, bal, session_cache, data_root, force=False):
+	def cache_balance(self, addr, bal, *, session_cache, data_root, force=False):
 		if force or addr not in session_cache:
 		if force or addr not in session_cache:
 			session_cache[addr] = str(bal)
 			session_cache[addr] = str(bal)
 			if addr in data_root:
 			if addr in data_root:
@@ -183,11 +184,11 @@ class TwCtl(MMGenObject, metaclass=AsyncInit):
 		if addr in data_root and 'balance' in data_root[addr]:
 		if addr in data_root and 'balance' in data_root[addr]:
 			return self.proto.coin_amt(data_root[addr]['balance'])
 			return self.proto.coin_amt(data_root[addr]['balance'])
 
 
-	async def get_balance(self, addr, force_rpc=False):
+	async def get_balance(self, addr, *, force_rpc=False):
 		ret = None if force_rpc else self.get_cached_balance(addr, self.cur_balances, self.data_root)
 		ret = None if force_rpc else self.get_cached_balance(addr, self.cur_balances, self.data_root)
 		if ret is None:
 		if ret is None:
 			ret = await self.rpc_get_balance(addr)
 			ret = await self.rpc_get_balance(addr)
-			self.cache_balance(addr, ret, self.cur_balances, self.data_root)
+			self.cache_balance(addr, ret, session_cache=self.cur_balances, data_root=self.data_root)
 		return ret
 		return ret
 
 
 	def force_write(self):
 	def force_write(self):
@@ -212,7 +213,7 @@ class TwCtl(MMGenObject, metaclass=AsyncInit):
 
 
 		self.orig_data = data
 		self.orig_data = data
 
 
-	def write(self, quiet=True):
+	def write(self, *, quiet=True):
 		if not self.use_tw_file:
 		if not self.use_tw_file:
 			self.cfg._util.dmsg("'use_tw_file' is False, doing nothing")
 			self.cfg._util.dmsg("'use_tw_file' is False, doing nothing")
 			return
 			return
@@ -256,6 +257,7 @@ class TwCtl(MMGenObject, metaclass=AsyncInit):
 			self,
 			self,
 			addrspec,
 			addrspec,
 			comment      = '',
 			comment      = '',
+			*,
 			trusted_pair = None,
 			trusted_pair = None,
 			silent       = False):
 			silent       = False):
 
 
@@ -296,11 +298,11 @@ class TwCtl(MMGenObject, metaclass=AsyncInit):
 	async def remove_comment(self, mmaddr):
 	async def remove_comment(self, mmaddr):
 		await self.set_comment(mmaddr, '')
 		await self.set_comment(mmaddr, '')
 
 
-	async def import_address_common(self, data, batch=False, gather=False):
+	async def import_address_common(self, data, *, batch=False, gather=False):
 
 
 		async def do_import(address, comment, message):
 		async def do_import(address, comment, message):
 			try:
 			try:
-				res = await self.import_address(address, comment)
+				res = await self.import_address(address, label=comment)
 				self.cfg._util.qmsg(message)
 				self.cfg._util.qmsg(message)
 				return res
 				return res
 			except Exception as e:
 			except Exception as e:

+ 5 - 2
mmgen/tw/json.py

@@ -30,7 +30,8 @@ class TwJSON:
 		fn_pfx = 'mmgen-tracking-wallet-dump'
 		fn_pfx = 'mmgen-tracking-wallet-dump'
 
 
 		def __new__(cls, cfg, proto, *args, **kwargs):
 		def __new__(cls, cfg, proto, *args, **kwargs):
-			return MMGenObject.__new__(proto.base_proto_subclass(TwJSON, 'tw.json', cls.__name__))
+			return MMGenObject.__new__(
+				proto.base_proto_subclass(TwJSON, 'tw.json', sub_clsname=cls.__name__))
 
 
 		def __init__(self, cfg, proto):
 		def __init__(self, cfg, proto):
 			self.cfg = cfg
 			self.cfg = cfg
@@ -62,7 +63,7 @@ class TwJSON:
 
 
 			return fn
 			return fn
 
 
-		def json_dump(self, data, pretty=False):
+		def json_dump(self, data, *, pretty=False):
 			return json.dumps(
 			return json.dumps(
 				data,
 				data,
 				cls        = json_encoder,
 				cls        = json_encoder,
@@ -90,6 +91,7 @@ class TwJSON:
 				cfg,
 				cfg,
 				proto,
 				proto,
 				filename,
 				filename,
+				*,
 				ignore_checksum = False,
 				ignore_checksum = False,
 				batch           = False):
 				batch           = False):
 
 
@@ -163,6 +165,7 @@ class TwJSON:
 				self,
 				self,
 				cfg,
 				cfg,
 				proto,
 				proto,
+				*,
 				include_amts    = True,
 				include_amts    = True,
 				pretty          = False,
 				pretty          = False,
 				prune           = False,
 				prune           = False,

+ 4 - 3
mmgen/tw/view.py

@@ -250,14 +250,14 @@ class TwView(MMGenObject, metaclass=AsyncInit):
 		'twmmid': lambda i: '{} {:010} {:024.12f}'.format(i.twmmid.sort_key, 0xffffffff - abs(i.confs), i.amt)
 		'twmmid': lambda i: '{} {:010} {:024.12f}'.format(i.twmmid.sort_key, 0xffffffff - abs(i.confs), i.amt)
 	}
 	}
 
 
-	def sort_info(self, include_group=True):
+	def sort_info(self, *, include_group=True):
 		ret = ([], ['Reverse'])[self.reverse]
 		ret = ([], ['Reverse'])[self.reverse]
 		ret.append(self.sort_disp[self.sort_key])
 		ret.append(self.sort_disp[self.sort_key])
 		if include_group and self.group and (self.sort_key in ('addr', 'txid', 'twmmid')):
 		if include_group and self.group and (self.sort_key in ('addr', 'txid', 'twmmid')):
 			ret.append('Grouped')
 			ret.append('Grouped')
 		return ret
 		return ret
 
 
-	def do_sort(self, key=None, reverse=False):
+	def do_sort(self, key=None, *, reverse=False):
 		key = key or self.sort_key
 		key = key or self.sort_key
 		if key not in self.sort_funcs:
 		if key not in self.sort_funcs:
 			die(1, f'{key!r}: invalid sort key.  Valid options: {" ".join(self.sort_funcs)}')
 			die(1, f'{key!r}: invalid sort key.  Valid options: {" ".join(self.sort_funcs)}')
@@ -268,7 +268,7 @@ class TwView(MMGenObject, metaclass=AsyncInit):
 		if self.data != save:
 		if self.data != save:
 			self.pos = 0
 			self.pos = 0
 
 
-	async def get_data(self, sort_key=None, reverse_sort=False):
+	async def get_data(self, *, sort_key=None, reverse_sort=False):
 
 
 		rpc_data = await self.get_rpc_data()
 		rpc_data = await self.get_rpc_data()
 
 
@@ -390,6 +390,7 @@ class TwView(MMGenObject, metaclass=AsyncInit):
 	async def format(
 	async def format(
 			self,
 			self,
 			display_type,
 			display_type,
+			*,
 			color           = True,
 			color           = True,
 			interactive     = False,
 			interactive     = False,
 			line_processing = None,
 			line_processing = None,

+ 2 - 1
mmgen/tx/base.py

@@ -181,7 +181,8 @@ class Base(MMGenObject):
 	def add_comment(self, infile=None):
 	def add_comment(self, infile=None):
 		if infile:
 		if infile:
 			from ..fileutil import get_data_from_file
 			from ..fileutil import get_data_from_file
-			self.comment = MMGenTxComment(get_data_from_file(self.cfg, infile, 'transaction comment'))
+			self.comment = MMGenTxComment(
+				get_data_from_file(self.cfg, infile, desc='transaction comment'))
 		else:
 		else:
 			from ..ui import keypress_confirm, line_input
 			from ..ui import keypress_confirm, line_input
 			if keypress_confirm(
 			if keypress_confirm(

+ 4 - 4
mmgen/tx/file.py

@@ -80,10 +80,10 @@ class MMGenTxFile(MMGenObject):
 		self.fmt_data = None
 		self.fmt_data = None
 		self.filename = None
 		self.filename = None
 
 
-	def parse(self, infile, metadata_only=False, quiet_open=False):
+	def parse(self, infile, *, metadata_only=False, quiet_open=False):
 		tx = self.tx
 		tx = self.tx
 		from ..fileutil import get_data_from_file
 		from ..fileutil import get_data_from_file
-		data = get_data_from_file(tx.cfg, infile, f'{tx.desc} data', quiet=quiet_open)
+		data = get_data_from_file(tx.cfg, infile, desc=f'{tx.desc} data', quiet=quiet_open)
 		if len(data) > tx.cfg.max_tx_file_size:
 		if len(data) > tx.cfg.max_tx_file_size:
 			die('MaxFileSizeExceeded',
 			die('MaxFileSizeExceeded',
 				f'Transaction file size exceeds limit ({tx.cfg.max_tx_file_size} bytes)')
 				f'Transaction file size exceeds limit ({tx.cfg.max_tx_file_size} bytes)')
@@ -286,7 +286,7 @@ class MMGenTxFile(MMGenObject):
 
 
 		return fmt_data
 		return fmt_data
 
 
-	def write(self,
+	def write(self, *,
 		add_desc              = '',
 		add_desc              = '',
 		outdir                = None,
 		outdir                = None,
 		ask_write             = True,
 		ask_write             = True,
@@ -316,7 +316,7 @@ class MMGenTxFile(MMGenObject):
 			ignore_opt_outdir     = outdir)
 			ignore_opt_outdir     = outdir)
 
 
 	@classmethod
 	@classmethod
-	def get_proto(cls, cfg, filename, quiet_open=False):
+	def get_proto(cls, cfg, filename, *, quiet_open=False):
 		from . import BaseTX
 		from . import BaseTX
 		tmp_tx = BaseTX(cfg=cfg)
 		tmp_tx = BaseTX(cfg=cfg)
 		cls(tmp_tx).parse(filename, metadata_only=True, quiet_open=quiet_open)
 		cls(tmp_tx).parse(filename, metadata_only=True, quiet_open=quiet_open)

+ 3 - 3
mmgen/tx/info.py

@@ -25,7 +25,7 @@ class TxInfo:
 		self.cfg = cfg
 		self.cfg = cfg
 		self.tx = tx
 		self.tx = tx
 
 
-	def format(self, terse=False, sort='addr'):
+	def format(self, *, terse=False, sort='addr'):
 
 
 		tx = self.tx
 		tx = self.tx
 
 
@@ -115,7 +115,7 @@ class TxInfo:
 
 
 		return ''.join(gen_view())
 		return ''.join(gen_view())
 
 
-	def view_with_prompt(self, prompt, pause=True):
+	def view_with_prompt(self, prompt, *, pause=True):
 		prompt += ' (y)es, (N)o, pager (v)iew, (t)erse view: '
 		prompt += ' (y)es, (N)o, pager (v)iew, (t)erse view: '
 		from ..term import get_char
 		from ..term import get_char
 		while True:
 		while True:
@@ -131,7 +131,7 @@ class TxInfo:
 				break
 				break
 			msg('Invalid reply')
 			msg('Invalid reply')
 
 
-	def view(self, pager=False, pause=True, terse=False):
+	def view(self, *, pager=False, pause=True, terse=False):
 		o = self.format(terse=terse)
 		o = self.format(terse=terse)
 		if pager:
 		if pager:
 			from ..ui import do_pager
 			from ..ui import do_pager

+ 4 - 4
mmgen/tx/new.py

@@ -164,7 +164,7 @@ class New(Base):
 			return False
 			return False
 		return True
 		return True
 
 
-	def add_output(self, coinaddr, amt, is_chg=False, is_vault=False, data=None):
+	def add_output(self, coinaddr, amt, *, is_chg=False, is_vault=False, data=None):
 		self.outputs.append(
 		self.outputs.append(
 			self.Output(self.proto, addr=coinaddr, amt=amt, is_chg=is_chg, is_vault=is_vault, data=data))
 			self.Output(self.proto, addr=coinaddr, amt=amt, is_chg=is_chg, is_vault=is_vault, data=data))
 
 
@@ -197,7 +197,7 @@ class New(Base):
 
 
 		return _pa(arg, mmid, coin_addr, amt, None, is_vault)
 		return _pa(arg, mmid, coin_addr, amt, None, is_vault)
 
 
-	async def get_autochg_addr(self, proto, arg, exclude, desc, all_addrtypes=False):
+	async def get_autochg_addr(self, proto, arg, *, exclude, desc, all_addrtypes=False):
 		from ..tw.addresses import TwAddresses
 		from ..tw.addresses import TwAddresses
 		al = await TwAddresses(self.cfg, proto, get_data=True)
 		al = await TwAddresses(self.cfg, proto, get_data=True)
 
 
@@ -287,7 +287,7 @@ class New(Base):
 		for addrfile in addrfiles:
 		for addrfile in addrfiles:
 			check_infile(addrfile)
 			check_infile(addrfile)
 			try:
 			try:
-				ad_f.add(AddrList(self.cfg, proto, addrfile))
+				ad_f.add(AddrList(self.cfg, proto, infile=addrfile))
 			except Exception as e:
 			except Exception as e:
 				msg(f'{type(e).__name__}: {e}')
 				msg(f'{type(e).__name__}: {e}')
 		return ad_f
 		return ad_f
@@ -419,7 +419,7 @@ class New(Base):
 		else:
 		else:
 			self.warn_insufficient_funds(funds.amt, self.coin)
 			self.warn_insufficient_funds(funds.amt, self.coin)
 
 
-	async def create(self, cmd_args, locktime=None, do_info=False, caller='txcreate'):
+	async def create(self, cmd_args, *, locktime=None, do_info=False, caller='txcreate'):
 
 
 		assert isinstance(locktime, (int, type(None))), 'locktime must be of type int'
 		assert isinstance(locktime, (int, type(None))), 'locktime must be of type int'
 
 

+ 4 - 4
mmgen/tx/sign.py

@@ -37,7 +37,7 @@ def get_seed_for_seed_id(sid, infiles, saved_seeds):
 	subseeds_checked = False
 	subseeds_checked = False
 	while True:
 	while True:
 		if infiles:
 		if infiles:
-			seed = Wallet(cfg, infiles.pop(0), ignore_in_fmt=True, passwd_file=global_passwd_file).seed
+			seed = Wallet(cfg, fn=infiles.pop(0), ignore_in_fmt=True, passwd_file=global_passwd_file).seed
 		elif subseeds_checked is False:
 		elif subseeds_checked is False:
 			seed = saved_seeds[list(saved_seeds)[0]].subseed_by_seed_id(sid, print_msg=True)
 			seed = saved_seeds[list(saved_seeds)[0]].subseed_by_seed_id(sid, print_msg=True)
 			subseeds_checked = True
 			subseeds_checked = True
@@ -128,7 +128,7 @@ def get_tx_files(cfg, args):
 		die(1, 'You must specify a raw transaction file!')
 		die(1, 'You must specify a raw transaction file!')
 	return ret
 	return ret
 
 
-def get_seed_files(cfg, args, ignore_dfl_wallet=False, empty_ok=False):
+def get_seed_files(cfg, args, *, ignore_dfl_wallet=False, empty_ok=False):
 	# favor unencrypted seed sources first, as they don't require passwords
 	# favor unencrypted seed sources first, as they don't require passwords
 	ret = _pop_matching_fns(args, get_wallet_extensions('unenc'))
 	ret = _pop_matching_fns(args, get_wallet_extensions('unenc'))
 	from ..filename import find_file_in_dir
 	from ..filename import find_file_in_dir
@@ -142,13 +142,13 @@ def get_seed_files(cfg, args, ignore_dfl_wallet=False, empty_ok=False):
 
 
 def get_keyaddrlist(cfg, proto):
 def get_keyaddrlist(cfg, proto):
 	if cfg.mmgen_keys_from_file:
 	if cfg.mmgen_keys_from_file:
-		return KeyAddrList(cfg, proto, cfg.mmgen_keys_from_file)
+		return KeyAddrList(cfg, proto, infile=cfg.mmgen_keys_from_file)
 	return None
 	return None
 
 
 def get_keylist(cfg):
 def get_keylist(cfg):
 	if cfg.keys_from_file:
 	if cfg.keys_from_file:
 		from ..fileutil import get_lines_from_file
 		from ..fileutil import get_lines_from_file
-		return get_lines_from_file(cfg, cfg.keys_from_file, 'key-address data', trim_comments=True)
+		return get_lines_from_file(cfg, cfg.keys_from_file, desc='key-address data', trim_comments=True)
 	return None
 	return None
 
 
 async def txsign(cfg_parm, tx, seed_files, kl, kal, tx_num_str='', passwd_file=None):
 async def txsign(cfg_parm, tx, seed_files, kl, kal, tx_num_str='', passwd_file=None):

+ 3 - 2
mmgen/ui.py

@@ -38,7 +38,7 @@ def get_data_from_user(cfg, desc='data'): # user input MUST be UTF-8
 		msg(f'User input: [{data}]')
 		msg(f'User input: [{data}]')
 	return data
 	return data
 
 
-def line_input(cfg, prompt, echo=True, insert_txt='', hold_protect=True):
+def line_input(cfg, prompt, *, echo=True, insert_txt='', hold_protect=True):
 	"""
 	"""
 	multi-line prompts OK
 	multi-line prompts OK
 	one-line prompts must begin at beginning of line
 	one-line prompts must begin at beginning of line
@@ -83,6 +83,7 @@ def line_input(cfg, prompt, echo=True, insert_txt='', hold_protect=True):
 def keypress_confirm(
 def keypress_confirm(
 		cfg,
 		cfg,
 		prompt,
 		prompt,
+		*,
 		default_yes     = False,
 		default_yes     = False,
 		verbose         = False,
 		verbose         = False,
 		no_nl           = False,
 		no_nl           = False,
@@ -133,7 +134,7 @@ def do_pager(text):
 		Msg(text+end_msg)
 		Msg(text+end_msg)
 	set_vt100()
 	set_vt100()
 
 
-def do_license_msg(cfg, immed=False):
+def do_license_msg(cfg, *, immed=False):
 
 
 	if cfg.quiet or cfg.no_license or cfg.yes or not cfg.stdin_tty:
 	if cfg.quiet or cfg.no_license or cfg.yes or not cfg.stdin_tty:
 		return
 		return

+ 9 - 8
mmgen/util.py

@@ -69,6 +69,7 @@ class Util:
 			desc1,
 			desc1,
 			chk2,
 			chk2,
 			desc2,
 			desc2,
+			*,
 			hdr         = '',
 			hdr         = '',
 			die_on_fail = False,
 			die_on_fail = False,
 			verbose     = False):
 			verbose     = False):
@@ -156,7 +157,7 @@ def mdie(*args):
 	mmsg(*args)
 	mmsg(*args)
 	sys.exit(0)
 	sys.exit(0)
 
 
-def die(ev, s='', stdout=False):
+def die(ev, s='', *, stdout=False):
 	if isinstance(ev, int):
 	if isinstance(ev, int):
 		from .exception import MMGenSystemExit, MMGenError
 		from .exception import MMGenSystemExit, MMGenError
 		if ev <= 2:
 		if ev <= 2:
@@ -242,7 +243,7 @@ def list_gen(*data):
 					yield d[idx]
 					yield d[idx]
 	return list(gen())
 	return list(gen())
 
 
-def remove_dups(iterable, edesc='element', desc='list', quiet=False, hide=False):
+def remove_dups(iterable, *, edesc='element', desc='list', quiet=False, hide=False):
 	"""
 	"""
 	Remove duplicate occurrences of iterable elements, preserving first occurrence
 	Remove duplicate occurrences of iterable elements, preserving first occurrence
 	If iterable is a generator, return a list, else type(iterable)
 	If iterable is a generator, return a list, else type(iterable)
@@ -292,7 +293,7 @@ def remove_extension(fn, ext):
 	a, b = os.path.splitext(fn)
 	a, b = os.path.splitext(fn)
 	return a if b[1:] == ext else fn
 	return a if b[1:] == ext else fn
 
 
-def make_chksum_N(s, nchars, sep=False, rounds=2, upper=True):
+def make_chksum_N(s, nchars, *, sep=False, rounds=2, upper=True):
 	if isinstance(s, str):
 	if isinstance(s, str):
 		s = s.encode()
 		s = s.encode()
 	from hashlib import sha256
 	from hashlib import sha256
@@ -306,7 +307,7 @@ def make_chksum_N(s, nchars, sep=False, rounds=2, upper=True):
 		assert 4 <= nchars <= 64, 'illegal ‘nchars’ value'
 		assert 4 <= nchars <= 64, 'illegal ‘nchars’ value'
 	return ret.upper() if upper else ret
 	return ret.upper() if upper else ret
 
 
-def make_chksum_8(s, sep=False):
+def make_chksum_8(s, *, sep=False):
 	from .obj import HexStr
 	from .obj import HexStr
 	from hashlib import sha256
 	from hashlib import sha256
 	s = HexStr(sha256(sha256(s).digest()).hexdigest()[:8].upper(), case='upper')
 	s = HexStr(sha256(sha256(s).digest()).hexdigest()[:8].upper(), case='upper')
@@ -396,7 +397,7 @@ class oneshot_warning:
 
 
 	color = 'nocolor'
 	color = 'nocolor'
 
 
-	def __init__(self, div=None, fmt_args=[], reverse=False):
+	def __init__(self, *, div=None, fmt_args=[], reverse=False):
 		self.do(type(self), div, fmt_args, reverse)
 		self.do(type(self), div, fmt_args, reverse)
 
 
 	def do(self, wcls, div, fmt_args, reverse):
 	def do(self, wcls, div, fmt_args, reverse):
@@ -422,10 +423,10 @@ class oneshot_warning:
 
 
 class oneshot_warning_group(oneshot_warning):
 class oneshot_warning_group(oneshot_warning):
 
 
-	def __init__(self, wcls, div=None, fmt_args=[], reverse=False):
+	def __init__(self, wcls, *, div=None, fmt_args=[], reverse=False):
 		self.do(getattr(self, wcls), div, fmt_args, reverse)
 		self.do(getattr(self, wcls), div, fmt_args, reverse)
 
 
-def get_subclasses(cls, names=False):
+def get_subclasses(cls, *, names=False):
 	def gen(cls):
 	def gen(cls):
 		for i in cls.__subclasses__():
 		for i in cls.__subclasses__():
 			yield i
 			yield i
@@ -456,7 +457,7 @@ def exit_if_mswin(feature):
 	if sys.platform == 'win32':
 	if sys.platform == 'win32':
 		die(2, capfirst(feature) + ' not supported on the MSWin / MSYS2 platform')
 		die(2, capfirst(feature) + ' not supported on the MSWin / MSYS2 platform')
 
 
-def have_sudo(silent=False):
+def have_sudo(*, silent=False):
 	from subprocess import run, DEVNULL
 	from subprocess import run, DEVNULL
 	redir = DEVNULL if silent else None
 	redir = DEVNULL if silent else None
 	try:
 	try:

+ 5 - 4
mmgen/util2.py

@@ -33,7 +33,7 @@ def die_pause(ev=0, s=''):
 def cffi_override_fixup():
 def cffi_override_fixup():
 	from cffi import FFI
 	from cffi import FFI
 	class FFI_override:
 	class FFI_override:
-		def cdef(self, csource, override=False, packed=False, pack=None):
+		def cdef(self, csource, *, override=False, packed=False, pack=None):
 			self._cdef(csource, override=True, packed=packed, pack=pack)
 			self._cdef(csource, override=True, packed=packed, pack=pack)
 	FFI.cdef = FFI_override.cdef
 	FFI.cdef = FFI_override.cdef
 
 
@@ -92,7 +92,7 @@ bytespec_map = (
 	('E',  1152921504606846976),
 	('E',  1152921504606846976),
 )
 )
 
 
-def int2bytespec(n, spec, fmt, print_sym=True, strip=False, add_space=False):
+def int2bytespec(n, spec, fmt, *, print_sym=True, strip=False, add_space=False):
 
 
 	def spec2int(spec):
 	def spec2int(spec):
 		for k, v in bytespec_map:
 		for k, v in bytespec_map:
@@ -137,6 +137,7 @@ def format_elapsed_days_hr(t, now=None, cached={}):
 
 
 def format_elapsed_hr(
 def format_elapsed_hr(
 		t,
 		t,
+		*,
 		now        = None,
 		now        = None,
 		cached     = {},
 		cached     = {},
 		rel_now    = True,
 		rel_now    = True,
@@ -177,7 +178,7 @@ def pretty_format(s, width=80, pfx=''):
 		s = s[i+1:]
 		s = s[i+1:]
 	return pfx + ('\n'+pfx).join(out)
 	return pfx + ('\n'+pfx).join(out)
 
 
-def block_format(data, gw=2, cols=8, line_nums=None, data_is_hex=False):
+def block_format(data, *, gw=2, cols=8, line_nums=None, data_is_hex=False):
 	assert line_nums in (None, 'hex', 'dec'), "'line_nums' must be one of None, 'hex' or 'dec'"
 	assert line_nums in (None, 'hex', 'dec'), "'line_nums' must be one of None, 'hex' or 'dec'"
 	ln_fs = '{:06x}: ' if line_nums == 'hex' else '{:06}: '
 	ln_fs = '{:06x}: ' if line_nums == 'hex' else '{:06}: '
 	bytes_per_chunk = gw
 	bytes_per_chunk = gw
@@ -192,7 +193,7 @@ def block_format(data, gw=2, cols=8, line_nums=None, data_is_hex=False):
 	).rstrip() + '\n'
 	).rstrip() + '\n'
 
 
 def pretty_hexdump(data, gw=2, cols=8, line_nums=None):
 def pretty_hexdump(data, gw=2, cols=8, line_nums=None):
-	return block_format(data.hex(), gw, cols, line_nums, data_is_hex=True)
+	return block_format(data.hex(), gw=gw, cols=cols, line_nums=line_nums, data_is_hex=True)
 
 
 def decode_pretty_hexdump(data):
 def decode_pretty_hexdump(data):
 	pat = re.compile(fr'^[{hexdigits}]+:\s+')
 	pat = re.compile(fr'^[{hexdigits}]+:\s+')

+ 3 - 0
mmgen/wallet/__init__.py

@@ -47,6 +47,7 @@ _wd('words',        'MMGenMnemonic',     'mmwords', 'mnemonic',   False, ('mmwor
 }
 }
 
 
 def get_wallet_data(
 def get_wallet_data(
+		*,
 		wtype       = None,
 		wtype       = None,
 		fmt_code    = None,
 		fmt_code    = None,
 		ext         = None,
 		ext         = None,
@@ -73,6 +74,7 @@ def get_wallet_data(
 
 
 def get_wallet_cls(
 def get_wallet_cls(
 		wtype       = None,
 		wtype       = None,
+		*,
 		fmt_code    = None,
 		fmt_code    = None,
 		ext         = None,
 		ext         = None,
 		die_on_fail = False):
 		die_on_fail = False):
@@ -111,6 +113,7 @@ def _get_me(modname):
 
 
 def Wallet(
 def Wallet(
 	cfg,
 	cfg,
+	*,
 	fn            = None,
 	fn            = None,
 	ss            = None,
 	ss            = None,
 	seed_bin      = None,
 	seed_bin      = None,

+ 1 - 1
mmgen/wallet/base.py

@@ -79,7 +79,7 @@ class wallet(MMGenObject, metaclass=WalletMeta):
 			self.fmt_data = get_data_from_file(
 			self.fmt_data = get_data_from_file(
 				self.cfg,
 				self.cfg,
 				self.infile.name,
 				self.infile.name,
-				self.desc,
+				desc   = self.desc,
 				binary = self.file_mode=='binary')
 				binary = self.file_mode=='binary')
 		elif self.in_data:
 		elif self.in_data:
 			self.fmt_data = self.in_data
 			self.fmt_data = self.in_data

+ 2 - 2
mmgen/wallet/incog_base.py

@@ -142,9 +142,9 @@ class wallet(wallet):
 			return False
 			return False
 
 
 	def _verify_seed_oldfmt(self, seed):
 	def _verify_seed_oldfmt(self, seed):
-		m = f'Seed ID: {make_chksum_8(seed)}.  Is the Seed ID correct?'
+		prompt = f'Seed ID: {make_chksum_8(seed)}.  Is the Seed ID correct?'
 		from ..ui import keypress_confirm
 		from ..ui import keypress_confirm
-		if keypress_confirm(self.cfg, m, True):
+		if keypress_confirm(self.cfg, prompt, default_yes=True):
 			return seed
 			return seed
 		else:
 		else:
 			return False
 			return False

+ 4 - 4
mmgen/wallet/mnemonic.py

@@ -53,8 +53,8 @@ class wallet(wallet):
 		seed = self.seed.data
 		seed = self.seed.data
 
 
 		bc = self.conv_cls(self.wl_id)
 		bc = self.conv_cls(self.wl_id)
-		mn  = bc.frombytes(seed, 'seed')
-		rev = bc.tobytes(mn, 'seed')
+		mn  = bc.frombytes(seed, pad='seed')
+		rev = bc.tobytes(mn, pad='seed')
 
 
 		# Internal error, so just die on fail
 		# Internal error, so just die on fail
 		self.cfg._util.compare_or_die(rev, 'recomputed seed', seed, 'original seed', e='Internal error')
 		self.cfg._util.compare_or_die(rev, 'recomputed seed', seed, 'original seed', e='Internal error')
@@ -78,8 +78,8 @@ class wallet(wallet):
 				msg(f'Invalid mnemonic: word #{n} is not in the {self.wl_id.upper()} wordlist')
 				msg(f'Invalid mnemonic: word #{n} is not in the {self.wl_id.upper()} wordlist')
 				return False
 				return False
 
 
-		seed = bc.tobytes(mn, 'seed')
-		rev  = bc.frombytes(seed, 'seed')
+		seed = bc.tobytes(mn, pad='seed')
+		rev  = bc.frombytes(seed, pad='seed')
 
 
 		if len(seed) * 8 not in Seed.lens:
 		if len(seed) * 8 not in Seed.lens:
 			msg('Invalid mnemonic (produces too large a number)')
 			msg('Invalid mnemonic (produces too large a number)')

+ 1 - 1
mmgen/xmrseed.py

@@ -77,7 +77,7 @@ class xmrseed(baseconv):
 
 
 		return b''.join(gen())
 		return b''.join(gen())
 
 
-	def frombytes(self, bytestr, pad=None, tostr=False):
+	def frombytes(self, bytestr, *, pad=None, tostr=False):
 		assert pad is None, f"{pad}: invalid 'pad' argument (must be None)"
 		assert pad is None, f"{pad}: invalid 'pad' argument (must be None)"
 
 
 		desc = self.desc.short
 		desc = self.desc.short

+ 1 - 1
mmgen/xmrwallet/file/__init__.py

@@ -60,5 +60,5 @@ class MoneroMMGenFile:
 
 
 	def extract_data_from_file(self, cfg, fn):
 	def extract_data_from_file(self, cfg, fn):
 		return json.loads(
 		return json.loads(
-			get_data_from_file(cfg, str(fn), self.desc, silent=self.silent_load)
+			get_data_from_file(cfg, str(fn), desc=self.desc, silent=self.silent_load)
 		)[self.data_label]
 		)[self.data_label]

+ 3 - 3
mmgen/xmrwallet/file/outputs.py

@@ -45,7 +45,7 @@ class MoneroWalletOutputsFile:
 			self.name = type(self).__name__
 			self.name = type(self).__name__
 			self.cfg = cfg
 			self.cfg = cfg
 
 
-		def write(self, add_suf='', quiet=False):
+		def write(self, *, add_suf='', quiet=False):
 			from ...fileutil import write_data_to_file
 			from ...fileutil import write_data_to_file
 			write_data_to_file(
 			write_data_to_file(
 				cfg               = self.cfg,
 				cfg               = self.cfg,
@@ -81,7 +81,7 @@ class MoneroWalletOutputsFile:
 	class New(Base):
 	class New(Base):
 		ext = 'raw'
 		ext = 'raw'
 
 
-		def __init__(self, parent, wallet_fn, data, wallet_idx=None, sign=False):
+		def __init__(self, parent, wallet_fn, data, *, wallet_idx=None, sign=False):
 			super().__init__(parent.cfg)
 			super().__init__(parent.cfg)
 			self.wallet_fn = wallet_fn
 			self.wallet_fn = wallet_fn
 			init_data = dict.fromkeys(self.data_tuple._fields)
 			init_data = dict.fromkeys(self.data_tuple._fields)
@@ -115,7 +115,7 @@ class MoneroWalletOutputsFile:
 			self.check_checksums(d_wrap)
 			self.check_checksums(d_wrap)
 
 
 		@classmethod
 		@classmethod
-		def find_fn_from_wallet_fn(cls, cfg, wallet_fn, ret_on_no_match=False):
+		def find_fn_from_wallet_fn(cls, cfg, wallet_fn, *, ret_on_no_match=False):
 			path = get_autosign_obj(cfg).xmr_outputs_dir or Path()
 			path = get_autosign_obj(cfg).xmr_outputs_dir or Path()
 			pat = cls.fn_fs.format(
 			pat = cls.fn_fs.format(
 				a = wallet_fn.name,
 				a = wallet_fn.name,

+ 1 - 1
mmgen/xmrwallet/file/tx.py

@@ -153,7 +153,7 @@ class MoneroMMGenTX:
 		def file_id(self):
 		def file_id(self):
 			return (self.base_chksum + ('-' + self.full_chksum if self.full_chksum else '')).upper()
 			return (self.base_chksum + ('-' + self.full_chksum if self.full_chksum else '')).upper()
 
 
-		def write(self, delete_metadata=False, ask_write=True, ask_overwrite=True):
+		def write(self, *, delete_metadata=False, ask_write=True, ask_overwrite=True):
 			dict_data = self.data._asdict()
 			dict_data = self.data._asdict()
 			if delete_metadata:
 			if delete_metadata:
 				dict_data['metadata'] = None
 				dict_data['metadata'] = None

+ 1 - 1
mmgen/xmrwallet/ops/import.py

@@ -23,7 +23,7 @@ class OpImportOutputs(OpWallet):
 	action = 'importing wallet outputs into'
 	action = 'importing wallet outputs into'
 	start_daemon = False
 	start_daemon = False
 
 
-	async def main(self, fn, wallet_idx, restart_daemon=True):
+	async def main(self, fn, wallet_idx, *, restart_daemon=True):
 		if restart_daemon:
 		if restart_daemon:
 			await self.restart_wallet_daemon()
 			await self.restart_wallet_daemon()
 		h = MoneroWalletRPC(self, self.addr_data[0])
 		h = MoneroWalletRPC(self, self.addr_data[0])

+ 1 - 1
mmgen/xmrwallet/ops/relay.py

@@ -41,7 +41,7 @@ class OpRelay(OpBase):
 			md = None
 			md = None
 		else:
 		else:
 			from ...daemon import CoinDaemon
 			from ...daemon import CoinDaemon
-			md = CoinDaemon(self.cfg, 'xmr', test_suite=self.cfg.test_suite)
+			md = CoinDaemon(self.cfg, network_id='xmr', test_suite=self.cfg.test_suite)
 			host, port = ('localhost', md.rpc_port)
 			host, port = ('localhost', md.rpc_port)
 			proxy = None
 			proxy = None
 
 

+ 1 - 1
mmgen/xmrwallet/ops/sign.py

@@ -21,7 +21,7 @@ class OpSign(OpWallet):
 	action = 'signing transaction with'
 	action = 'signing transaction with'
 	start_daemon = False
 	start_daemon = False
 
 
-	async def main(self, fn, restart_daemon=True):
+	async def main(self, fn, *, restart_daemon=True):
 		if restart_daemon:
 		if restart_daemon:
 			await self.restart_wallet_daemon()
 			await self.restart_wallet_daemon()
 		tx = MoneroMMGenTX.Unsigned(self.cfg, fn)
 		tx = MoneroMMGenTX.Unsigned(self.cfg, fn)

+ 1 - 1
mmgen/xmrwallet/ops/wallet.py

@@ -140,7 +140,7 @@ class OpWallet(OpBase):
 		return MoneroRPCClient(
 		return MoneroRPCClient(
 			cfg    = self.cfg,
 			cfg    = self.cfg,
 			proto  = self.proto,
 			proto  = self.proto,
-			daemon = CoinDaemon(self.cfg, 'xmr'),
+			daemon = CoinDaemon(self.cfg, network_id='xmr'),
 			host   = host,
 			host   = host,
 			port   = int(port),
 			port   = int(port),
 			user   = None,
 			user   = None,

+ 3 - 3
mmgen/xmrwallet/rpc.py

@@ -62,7 +62,7 @@ class MoneroWalletRPC:
 		await self.c.stop_daemon(quiet=True) # closes wallet
 		await self.c.stop_daemon(quiet=True) # closes wallet
 		gmsg_r('done')
 		gmsg_r('done')
 
 
-	def gen_accts_info(self, accts_data, addrs_data, indent='    ', skip_empty_ok=False):
+	def gen_accts_info(self, accts_data, addrs_data, *, indent='    ', skip_empty_ok=False):
 		from .ops import addr_width
 		from .ops import addr_width
 		fs = indent + '  {I:<3} {A} {N} {B} {L}'
 		fs = indent + '  {I:<3} {A} {N} {B} {L}'
 		yield indent + f'Accounts of wallet {self.fn.name}:'
 		yield indent + f'Accounts of wallet {self.fn.name}:'
@@ -84,7 +84,7 @@ class MoneroWalletRPC:
 				B = fmt_amt(e['unlocked_balance']),
 				B = fmt_amt(e['unlocked_balance']),
 				L = pink(e['label']))
 				L = pink(e['label']))
 
 
-	def get_wallet_data(self, print=True, skip_empty_ok=False):
+	def get_wallet_data(self, *, print=True, skip_empty_ok=False):
 		accts_data = self.c.call('get_accounts')
 		accts_data = self.c.call('get_accounts')
 		addrs_data = [
 		addrs_data = [
 			self.c.call('get_address', account_index=i)
 			self.c.call('get_address', account_index=i)
@@ -123,7 +123,7 @@ class MoneroWalletRPC:
 		msg(cyan(ret['address']))
 		msg(cyan(ret['address']))
 		return ret['address']
 		return ret['address']
 
 
-	def get_last_addr(self, account, wallet_data, display=True):
+	def get_last_addr(self, account, wallet_data, *, display=True):
 		if display:
 		if display:
 			msg('\n    Getting last address:')
 			msg('\n    Getting last address:')
 		acct_addrs = wallet_data.addrs_data[account]['addresses']
 		acct_addrs = wallet_data.addrs_data[account]['addresses']

+ 1 - 1
test/cmdtest_d/ct_ethdev.py

@@ -426,7 +426,7 @@ class CmdTestEthdev(CmdTestBase, CmdTestShared):
 		self.proto = init_proto( cfg, cfg.coin, network='regtest', need_amt=True)
 		self.proto = init_proto( cfg, cfg.coin, network='regtest', need_amt=True)
 
 
 		from mmgen.daemon import CoinDaemon
 		from mmgen.daemon import CoinDaemon
-		self.daemon = CoinDaemon( cfg, self.proto.coin+'_rt', test_suite=True)
+		self.daemon = CoinDaemon( cfg, network_id=self.proto.coin+'_rt', test_suite=True)
 
 
 		if self.daemon.id == 'reth':
 		if self.daemon.id == 'reth':
 			global dfl_devkey, dfl_devaddr
 			global dfl_devkey, dfl_devaddr

+ 5 - 5
test/cmdtest_d/ct_main.py

@@ -68,7 +68,7 @@ def make_brainwallet_file(fn):
 	d = ''.join(rand_pairs).rstrip() + '\n'
 	d = ''.join(rand_pairs).rstrip() + '\n'
 	if cfg.verbose:
 	if cfg.verbose:
 		msg_r(f'Brainwallet password:\n{cyan(d)}')
 		msg_r(f'Brainwallet password:\n{cyan(d)}')
-	write_data_to_file(cfg, fn, d, 'brainwallet password', quiet=True, ignore_opt_outdir=True)
+	write_data_to_file(cfg, fn, d, desc='brainwallet password', quiet=True, ignore_opt_outdir=True)
 
 
 def verify_checksum_or_exit(checksum, chk):
 def verify_checksum_or_exit(checksum, chk):
 	chk = strip_ansi_escapes(chk)
 	chk = strip_ansi_escapes(chk)
@@ -397,7 +397,7 @@ class CmdTestMain(CmdTestBase, CmdTestShared):
 		addrfile = self.get_file_with_ext('addrs')
 		addrfile = self.get_file_with_ext('addrs')
 		from mmgen.addrlist import AddrList
 		from mmgen.addrlist import AddrList
 		silence()
 		silence()
-		chk = AddrList(cfg, self.proto, addrfile).chksum
+		chk = AddrList(cfg, self.proto, infile=addrfile).chksum
 		end_silence()
 		end_silence()
 		if cfg.verbose and display:
 		if cfg.verbose and display:
 			msg(f'Checksum: {cyan(chk)}')
 			msg(f'Checksum: {cyan(chk)}')
@@ -537,7 +537,7 @@ class CmdTestMain(CmdTestBase, CmdTestShared):
 				cfg,
 				cfg,
 				self.unspent_data_file,
 				self.unspent_data_file,
 				d,
 				d,
-				'Unspent outputs',
+				desc              = 'Unspent outputs',
 				quiet             = True,
 				quiet             = True,
 				ignore_opt_outdir = True)
 				ignore_opt_outdir = True)
 		if cfg.verbose or cfg.exact_output:
 		if cfg.verbose or cfg.exact_output:
@@ -633,7 +633,7 @@ class CmdTestMain(CmdTestBase, CmdTestShared):
 		tx_data, ad = {}, AddrData(self.proto)
 		tx_data, ad = {}, AddrData(self.proto)
 		for s in sources:
 		for s in sources:
 			addrfile = get_file_with_ext(self.cfgs[s]['tmpdir'], 'addrs')
 			addrfile = get_file_with_ext(self.cfgs[s]['tmpdir'], 'addrs')
-			al = AddrList(cfg, self.proto, addrfile)
+			al = AddrList(cfg, self.proto, infile=addrfile)
 			ad.add(al)
 			ad.add(al)
 			aix = AddrIdxList(fmt_str=self.cfgs[s]['addr_idx_list'])
 			aix = AddrIdxList(fmt_str=self.cfgs[s]['addr_idx_list'])
 			if len(aix) != addrs_per_wallet:
 			if len(aix) != addrs_per_wallet:
@@ -849,7 +849,7 @@ class CmdTestMain(CmdTestBase, CmdTestShared):
 		wcls = get_wallet_cls(fmt_code=out_fmt)
 		wcls = get_wallet_cls(fmt_code=out_fmt)
 		msg('==> {}: {}'.format(
 		msg('==> {}: {}'.format(
 			wcls.desc,
 			wcls.desc,
-			cyan(get_data_from_file(cfg, f, wcls.desc))
+			cyan(get_data_from_file(cfg, f, desc=wcls.desc))
 		))
 		))
 		end_silence()
 		end_silence()
 		return t
 		return t

+ 2 - 2
test/cmdtest_d/ct_regtest.py

@@ -498,7 +498,7 @@ class CmdTestRegtest(CmdTestBase, CmdTestShared):
 	def _add_comments_to_addr_file(self, proto, addrfile, outfile, use_comments=False):
 	def _add_comments_to_addr_file(self, proto, addrfile, outfile, use_comments=False):
 		silence()
 		silence()
 		gmsg(f'Adding comments to address file {addrfile!r}')
 		gmsg(f'Adding comments to address file {addrfile!r}')
-		a = AddrList(cfg, proto, addrfile)
+		a = AddrList(cfg, proto, infile=addrfile)
 		for n, idx in enumerate(a.idxs(), 1):
 		for n, idx in enumerate(a.idxs(), 1):
 			if use_comments:
 			if use_comments:
 				a.set_comment(idx, get_comment())
 				a.set_comment(idx, get_comment())
@@ -1110,7 +1110,7 @@ class CmdTestRegtest(CmdTestBase, CmdTestShared):
 			sid, self.get_altcoin_pfx(proto.coin), id_str, addr_range, x='-α' if cfg.debug_utf8 else '')
 			sid, self.get_altcoin_pfx(proto.coin), id_str, addr_range, x='-α' if cfg.debug_utf8 else '')
 		addrfile = get_file_with_ext(self._user_dir(user), ext, no_dot=True)
 		addrfile = get_file_with_ext(self._user_dir(user), ext, no_dot=True)
 		silence()
 		silence()
-		addr = AddrList(cfg, proto, addrfile).data[idx].addr
+		addr = AddrList(cfg, proto, infile=addrfile).data[idx].addr
 		end_silence()
 		end_silence()
 		return addr
 		return addr
 
 

+ 1 - 1
test/cmdtest_d/ct_shared.py

@@ -295,7 +295,7 @@ class CmdTestShared:
 			fn = t.written_to_file('Password list' if passgen else 'Addresses')
 			fn = t.written_to_file('Password list' if passgen else 'Addresses')
 			cls = PasswordList if passgen else AddrList
 			cls = PasswordList if passgen else AddrList
 			silence()
 			silence()
-			al = cls(cfg, self.proto, fn, skip_chksum_msg=True) # read back the file we’ve written
+			al = cls(cfg, self.proto, infile=fn, skip_chksum_msg=True) # read back the file we’ve written
 			end_silence()
 			end_silence()
 			cmp_or_die(al.chksum, chksum, desc=f'{ftype}list data checksum from file')
 			cmp_or_die(al.chksum, chksum, desc=f'{ftype}list data checksum from file')
 		return t
 		return t

+ 1 - 1
test/cmdtest_d/ct_xmr_autosign.py

@@ -133,7 +133,7 @@ class CmdTestXMRAutosign(CmdTestXMRWallet, CmdTestAutosignThreaded):
 			cfg       = self.cfg,
 			cfg       = self.cfg,
 			proto     = self.proto,
 			proto     = self.proto,
 			addr_idxs = '1-2',
 			addr_idxs = '1-2',
-			seed      = Wallet(cfg, data.mmwords).seed,
+			seed      = Wallet(cfg, fn=data.mmwords).seed,
 			skip_chksum_msg = True,
 			skip_chksum_msg = True,
 			key_address_validity_check = False)
 			key_address_validity_check = False)
 		kal.file.write(ask_overwrite=False)
 		kal.file.write(ask_overwrite=False)

+ 2 - 2
test/daemontest_d/ut_exec.py

@@ -14,7 +14,7 @@ from mmgen.daemon import CoinDaemon
 from ..include.common import cfg, qmsg, qmsg_r, vmsg, msg
 from ..include.common import cfg, qmsg, qmsg_r, vmsg, msg
 
 
 def test_flags(coin):
 def test_flags(coin):
-	d = CoinDaemon(cfg, coin)
+	d = CoinDaemon(cfg, network_id=coin)
 	vmsg(f'Available opts:  {fmt_list(d.avail_opts, fmt="bare")}')
 	vmsg(f'Available opts:  {fmt_list(d.avail_opts, fmt="bare")}')
 	vmsg(f'Available flags: {fmt_list(d.avail_flags, fmt="bare")}')
 	vmsg(f'Available flags: {fmt_list(d.avail_flags, fmt="bare")}')
 	vals = namedtuple('vals', ['online', 'no_daemonize', 'keep_cfg_file'])
 	vals = namedtuple('vals', ['online', 'no_daemonize', 'keep_cfg_file'])
@@ -26,7 +26,7 @@ def test_flags(coin):
 				(['online'],                 ['keep_cfg_file'], vals(True, False, True)),
 				(['online'],                 ['keep_cfg_file'], vals(True, False, True)),
 				(['online', 'no_daemonize'], ['keep_cfg_file'], vals(True, True, True)),
 				(['online', 'no_daemonize'], ['keep_cfg_file'], vals(True, True, True)),
 			):
 			):
-			d = CoinDaemon(cfg, coin, opts=opts, flags=flags)
+			d = CoinDaemon(cfg, network_id=coin, opts=opts, flags=flags)
 			assert d.flag.keep_cfg_file == val.keep_cfg_file
 			assert d.flag.keep_cfg_file == val.keep_cfg_file
 			assert d.opt.online == val.online
 			assert d.opt.online == val.online
 			assert d.opt.no_daemonize == val.no_daemonize
 			assert d.opt.no_daemonize == val.no_daemonize

+ 3 - 3
test/daemontest_d/ut_rpc.py

@@ -91,7 +91,7 @@ class init_test:
 
 
 	@staticmethod
 	@staticmethod
 	async def btc(cfg, daemon, backend, cfg_override):
 	async def btc(cfg, daemon, backend, cfg_override):
-		rpc = await rpc_init(cfg, daemon.proto, backend, daemon)
+		rpc = await rpc_init(cfg, daemon.proto, backend=backend, daemon=daemon)
 		do_msg(rpc, backend)
 		do_msg(rpc, backend)
 
 
 		wi = await rpc.walletinfo
 		wi = await rpc.walletinfo
@@ -106,7 +106,7 @@ class init_test:
 
 
 	@staticmethod
 	@staticmethod
 	async def bch(cfg, daemon, backend, cfg_override):
 	async def bch(cfg, daemon, backend, cfg_override):
-		rpc = await rpc_init(cfg, daemon.proto, backend, daemon)
+		rpc = await rpc_init(cfg, daemon.proto, backend=backend, daemon=daemon)
 		do_msg(rpc, backend)
 		do_msg(rpc, backend)
 		return rpc
 		return rpc
 
 
@@ -114,7 +114,7 @@ class init_test:
 
 
 	@staticmethod
 	@staticmethod
 	async def eth(cfg, daemon, backend, cfg_override):
 	async def eth(cfg, daemon, backend, cfg_override):
-		rpc = await rpc_init(cfg, daemon.proto, backend, daemon)
+		rpc = await rpc_init(cfg, daemon.proto, backend=backend, daemon=daemon)
 		do_msg(rpc, backend)
 		do_msg(rpc, backend)
 		await rpc.call('eth_blockNumber', timeout=300)
 		await rpc.call('eth_blockNumber', timeout=300)
 		if rpc.proto.network == 'testnet':
 		if rpc.proto.network == 'testnet':

+ 1 - 1
test/daemontest_d/ut_tx.py

@@ -110,7 +110,7 @@ class unit_tests:
 
 
 	async def newtx(self, name, ut):
 	async def newtx(self, name, ut):
 		qmsg('  Testing NewTX initializer')
 		qmsg('  Testing NewTX initializer')
-		d = CoinDaemon(cfg, 'btc', test_suite=True)
+		d = CoinDaemon(cfg, network_id='btc', test_suite=True)
 		d.start()
 		d.start()
 
 
 		proto = init_proto(cfg, 'btc', need_amt=True)
 		proto = init_proto(cfg, 'btc', need_amt=True)

+ 3 - 3
test/gentest.py

@@ -322,7 +322,7 @@ def do_ab_test(proto, scfg, addr_type, gen1, kg2, ag, tool, cache_data):
 			for _ in range(scfg.rounds):
 			for _ in range(scfg.rounds):
 				yield getrand(32)
 				yield getrand(32)
 
 
-	kg1 = KeyGenerator(cfg, proto, addr_type.pubkey_type, gen1)
+	kg1 = KeyGenerator(cfg, proto, addr_type.pubkey_type, backend=gen1)
 	if type(kg1) == type(kg2):
 	if type(kg1) == type(kg2):
 		die(4, 'Key generators are the same!')
 		die(4, 'Key generators are the same!')
 
 
@@ -378,7 +378,7 @@ def ab_test(proto, scfg):
 
 
 	if scfg.gen2:
 	if scfg.gen2:
 		assert scfg.gen1 != 'all', "'all' must be used only with external tool"
 		assert scfg.gen1 != 'all', "'all' must be used only with external tool"
-		kg2 = KeyGenerator(cfg, proto, addr_type.pubkey_type, scfg.gen2)
+		kg2 = KeyGenerator(cfg, proto, addr_type.pubkey_type, backend=scfg.gen2)
 		tool = None
 		tool = None
 	else:
 	else:
 		toolname = find_or_check_tool(proto, addr_type, scfg.tool)
 		toolname = find_or_check_tool(proto, addr_type, scfg.tool)
@@ -541,7 +541,7 @@ def main():
 		for p in protos:
 		for p in protos:
 			ab_test(p, scfg)
 			ab_test(p, scfg)
 	else:
 	else:
-		kg = KeyGenerator(cfg, proto, addr_type.pubkey_type, scfg.gen1)
+		kg = KeyGenerator(cfg, proto, addr_type.pubkey_type, backend=scfg.gen1)
 		ag = AddrGenerator(cfg, proto, addr_type)
 		ag = AddrGenerator(cfg, proto, addr_type)
 		if scfg.test == 'speed':
 		if scfg.test == 'speed':
 			speed_test(proto, kg, ag, scfg.rounds)
 			speed_test(proto, kg, ag, scfg.rounds)

+ 1 - 1
test/include/common.py

@@ -307,7 +307,7 @@ def test_daemons_ops(*network_ids, op, remove_datadir=False):
 		silent = not (cfg.verbose or cfg.exact_output)
 		silent = not (cfg.verbose or cfg.exact_output)
 		ret = False
 		ret = False
 		for network_id in network_ids:
 		for network_id in network_ids:
-			d = CoinDaemon(cfg, network_id, test_suite=True)
+			d = CoinDaemon(cfg, network_id=network_id, test_suite=True)
 			if remove_datadir:
 			if remove_datadir:
 				d.wait = True
 				d.wait = True
 				d.stop(silent=True)
 				d.stop(silent=True)

+ 1 - 1
test/modtest_d/ut_bip_hd.py

@@ -197,7 +197,7 @@ class unit_tests:
 
 
 		coin_type1 = purpose.derive_private()
 		coin_type1 = purpose.derive_private()
 
 
-		coin_type2 = m.to_coin_type('btc', addr_type='bech32')
+		coin_type2 = m.to_coin_type(coin='btc', addr_type='bech32')
 		assert coin_type1.address == coin_type2.address
 		assert coin_type1.address == coin_type2.address
 		vmsg(f'  {coin_type1.address=}')
 		vmsg(f'  {coin_type1.address=}')
 
 

+ 1 - 1
test/modtest_d/ut_gen.py

@@ -62,7 +62,7 @@ def do_test(proto, wif, addr_chk, addr_type, internal_keccak):
 
 
 	for n, backend in enumerate(get_backends(at.pubkey_type)):
 	for n, backend in enumerate(get_backends(at.pubkey_type)):
 
 
-		kg = KeyGenerator( cfg, proto, at.pubkey_type, n+1)
+		kg = KeyGenerator(cfg, proto, at.pubkey_type, silent=n+1)
 		qmsg(blue(f'  Testing backend {backend!r} for addr type {addr_type!r}{add_msg}'))
 		qmsg(blue(f'  Testing backend {backend!r} for addr type {addr_type!r}{add_msg}'))
 
 
 		data = kg.gen_data(privkey)
 		data = kg.gen_data(privkey)

+ 1 - 1
test/modtest_d/ut_misc.py

@@ -50,7 +50,7 @@ class unit_tests:
 		vmsg(brown('  vectors:'))
 		vmsg(brown('  vectors:'))
 		vmsg(fs.format('REL_NOW', 'SHOW_SECS', 'ELAPSED', 'OUTPUT'))
 		vmsg(fs.format('REL_NOW', 'SHOW_SECS', 'ELAPSED', 'OUTPUT'))
 		for (t, now, rel_now, show_secs, out_chk) in vectors:
 		for (t, now, rel_now, show_secs, out_chk) in vectors:
-			out = format_elapsed_hr(t, now, rel_now=rel_now, show_secs=show_secs)
+			out = format_elapsed_hr(t, now=now, rel_now=rel_now, show_secs=show_secs)
 			assert out == out_chk, f'{out} != {out_chk}'
 			assert out == out_chk, f'{out} != {out_chk}'
 			vmsg(fs.format(repr(rel_now), repr(show_secs), now-t, out))
 			vmsg(fs.format(repr(rel_now), repr(show_secs), now-t, out))
 
 

+ 1 - 1
test/modtest_d/ut_seedsplit.py

@@ -73,7 +73,7 @@ class unit_test:
 							(2, c, c, d, i),
 							(2, c, c, d, i),
 							(5, e, f, h, p)):
 							(5, e, f, h, p)):
 
 
-						shares = seed.split(share_count, id_str, master_idx)
+						shares = seed.split(share_count, id_str=id_str, master_idx=master_idx)
 						A = len(shares)
 						A = len(shares)
 						assert A == share_count, A
 						assert A == share_count, A