Browse Source

help: minor cleanups, move help texts to individual modules

The MMGen Project 2 weeks ago
parent
commit
b3bda1b62b

+ 5 - 174
mmgen/help/help_notes.py

@@ -12,22 +12,21 @@
 help: help notes functions for MMGen suite commands
 """
 
-from ..cfg import gc
-
 class help_notes:
 
 	def __init__(self, proto, cfg):
 		self.proto = proto
 		self.cfg = cfg
 
-	def txcreate_args(self, target):
+	def txcreate_args(self):
 		return (
-			'COIN1 [AMT CHG_ADDR] COIN2 [ADDR]'
-				if target == 'swaptx' else
 			'[ADDR,AMT ... | DATA_SPEC] ADDR'
 				if self.proto.base_proto == 'Bitcoin' else
 			'ADDR,AMT')
 
+	def swaptxcreate_args(self):
+		return 'COIN1 [AMT CHG_ADDR] COIN2 [ADDR]'
+
 	def account_info_desc(self):
 		return 'unspent outputs' if self.proto.base_proto == 'Bitcoin' else 'account info'
 
@@ -40,11 +39,6 @@ class help_notes:
 		cu = self.proto.coin_amt.units
 		return ', '.join(cu[:-1]) + ('', ' and ')[len(cu)>1] + cu[-1] + ('', ',\nrespectively')[len(cu)>1]
 
-	def coind_exec(self):
-		from ..daemon import CoinDaemon
-		return (
-			CoinDaemon(self.cfg, self.proto.coin).exec_fn if self.proto.coin in CoinDaemon.coins else 'bitcoind')
-
 	def dfl_twname(self):
 		from ..proto.btc.rpc import BitcoinRPCClient
 		return BitcoinRPCClient.dfl_twname
@@ -128,7 +122,7 @@ as {r}, using an integer followed by '{l}', for {u}.
 	c = self.proto.coin,
 	r = BaseTX(cfg=self.cfg, proto=self.proto).rel_fee_desc,
 	l = self.fee_spec_letters(use_quotes=True),
-	u = self.fee_spec_names() )
+	u = self.fee_spec_names())
 
 	def passwd(self):
 		return """
@@ -146,167 +140,4 @@ BRAINWALLET NOTE:
 To thwart dictionary attacks, it’s recommended to use a strong hash preset
 with brainwallets.  For a brainwallet passphrase to generate the correct
 seed, the same seed length and hash preset parameters must always be used.
-""".strip()
-
-	def txcreate_examples(self):
-
-		mmtype = 'B' if 'B' in self.proto.mmtypes else self.proto.mmtypes[0]
-		from ..tool.coin import tool_cmd
-		t = tool_cmd(self.cfg, mmtype=mmtype)
-		addr = t.privhex2addr('bead' * 16)
-		sample_addr = addr.views[addr.view_pref]
-
-		return f"""
-EXAMPLES:
-
-  Send 0.123 {self.proto.coin} to an external {self.proto.name} address, returning the change to a
-  specific MMGen address in the tracking wallet:
-
-    $ {gc.prog_name} {sample_addr},0.123 01ABCDEF:{mmtype}:7
-
-  Same as above, but select the change address automatically:
-
-    $ {gc.prog_name} {sample_addr},0.123 01ABCDEF:{mmtype}
-
-  Same as above, but select the change address automatically by address type:
-
-    $ {gc.prog_name} {sample_addr},0.123 {mmtype}
-
-  Same as above, but reduce verbosity and specify fee of 20 satoshis
-  per byte:
-
-    $ {gc.prog_name} -q -f 20s {sample_addr},0.123 {mmtype}
-
-  Send entire balance of selected inputs minus fee to an external {self.proto.name}
-  address:
-
-    $ {gc.prog_name} {sample_addr}
-
-  Send entire balance of selected inputs minus fee to first unused wallet
-  address of specified type:
-
-    $ {gc.prog_name} {mmtype}
-""" if self.proto.base_proto == 'Bitcoin' else f"""
-EXAMPLES:
-
-  Send 0.123 {self.proto.coin} to an external {self.proto.name} address:
-
-    $ {gc.prog_name} {sample_addr},0.123
-
-  Send 0.123 {self.proto.coin} to another account in wallet 01ABCDEF:
-
-    $ {gc.prog_name} 01ABCDEF:{mmtype}:7,0.123
-"""
-
-	def txcreate(self):
-		outputs_info = (
-			"""
-Outputs are specified in the form ADDRESS,AMOUNT or ADDRESS.  The first form
-creates an output sending the given amount to the given address.  The bare
-address form designates the given address as either the change output or the
-sole output of the transaction (excluding any data output).  Exactly one bare
-address argument is required.
-
-For convenience, the bare address argument may be given as ADDRTYPE_CODE or
-SEED_ID:ADDRTYPE_CODE (see ADDRESS TYPES below). In the first form, the first
-unused address of type ADDRTYPE_CODE for each Seed ID in the tracking wallet
-will be displayed in a menu, with the user prompted to select one.  In the
-second form, the user specifies the Seed ID as well, allowing the script to
-select the transaction’s change output or single output without prompting.
-See EXAMPLES below.
-
-A single DATA_SPEC argument may also be given on the command line to create
-an OP_RETURN data output with a zero spend amount.  This is the preferred way
-to embed data in the blockchain.  DATA_SPEC may be of the form "data":DATA
-or "hexdata":DATA. In the first form, DATA is a string in your system’s native
-encoding, typically UTF-8.  In the second, DATA is a hexadecimal string (with
-the leading ‘0x’ omitted) encoding the binary data to be embedded.  In both
-cases, the resulting byte string must not exceed {bl} bytes in length.
-""".format(bl=self.proto.max_op_return_data_len)
-		if self.proto.base_proto == 'Bitcoin' else """
-The transaction output is specified in the form ADDRESS,AMOUNT.
-""")
-
-		return """
-The transaction’s outputs are listed on the command line, while its inputs
-are chosen from a list of the wallet’s unspent outputs via an interactive
-menu.  Alternatively, inputs may be specified using the --inputs option.
-
-Addresses on the command line can be either native coin addresses or MMGen
-IDs in the form SEED_ID:ADDRTYPE_CODE:INDEX.
-{oinfo}
-If the transaction fee is not specified on the command line (see FEE
-SPECIFICATION below), it will be calculated dynamically using network fee
-estimation for the default (or user-specified) number of confirmations.
-If network fee estimation fails, the user will be prompted for a fee.
-
-Network-estimated fees will be multiplied by the value of --fee-adjust, if
-specified.
-""".format(oinfo=outputs_info)
-
-	def txsign(self):
-		from ..proto.btc.params import mainnet
-		return """
-Transactions may contain both {pnm} or non-{pnm} input addresses.
-
-To sign non-{pnm} inputs, a {wd}flat key list is used
-as the key source (--keys-from-file option).
-
-To sign {pnm} inputs, key data is generated from a seed as with the
-{pnl}-addrgen and {pnl}-keygen commands.  Alternatively, a key-address file
-may be used (--mmgen-keys-from-file option).
-
-Multiple wallets or other seed files can be listed on the command line in
-any order.  If the seeds required to sign the transaction’s inputs are not
-found in these files (or in the default wallet), the user will be prompted
-for seed data interactively.
-
-To prevent an attacker from crafting transactions with bogus {pnm}-to-{pnu}
-address mappings, all outputs to {pnm} addresses are verified with a seed
-source.  Therefore, seed files or a key-address file for all {pnm} outputs
-must also be supplied on the command line if the data can’t be found in the
-default wallet.
-""".format(
-	wd  = f'{self.coind_exec()} wallet dump or ' if isinstance(self.proto, mainnet) else '',
-	pnm = gc.proj_name,
-	pnu = self.proto.name,
-	pnl = gc.proj_name.lower())
-
-	def subwallet(self):
-		from ..subseed import SubSeedIdxRange
-		return f"""
-SUBWALLETS:
-
-Subwallets (subseeds) are specified by a ‘Subseed Index’ consisting of:
-
-  a) an integer in the range 1-{SubSeedIdxRange.max_idx}, plus
-  b) an optional single letter, ‘L’ or ‘S’
-
-The letter designates the length of the subseed.  If omitted, ‘L’ is assumed.
-
-Long (‘L’) subseeds are the same length as their parent wallet’s seed
-(typically 256 bits), while short (‘S’) subseeds are always 128-bit.
-The long and short subseeds for a given index are derived independently,
-so both may be used.
-
-MMGen Wallet has no notion of ‘depth’, and to an outside observer subwallets
-are identical to ordinary wallets.  This is a feature rather than a bug, as
-it denies an attacker any way of knowing whether a given wallet has a parent.
-
-Since subwallets are just wallets, they may be used to generate other
-subwallets, leading to hierarchies of arbitrary depth.  However, this is
-inadvisable in practice for two reasons:  Firstly, it creates accounting
-complexity, requiring the user to independently keep track of a derivation
-tree.  More importantly, however, it leads to the danger of Seed ID
-collisions between subseeds at different levels of the hierarchy, as
-MMGen checks and avoids ID collisions only among sibling subseeds.
-
-An exception to this caveat would be a multi-user setup where sibling
-subwallets are distributed to different users as their default wallets.
-Since the subseeds derived from these subwallets are private to each user,
-Seed ID collisions among them doesn’t present a problem.
-
-A safe rule of thumb, therefore, is for *each user* to derive all of his/her
-subwallets from a single parent.  This leaves each user with a total of two
-million subwallets, which should be enough for most practical purposes.
 """.strip()

+ 52 - 0
mmgen/help/subwallet.py

@@ -0,0 +1,52 @@
+#!/usr/bin/env python3
+#
+# MMGen Wallet, a terminal-based cryptocurrency wallet
+# Copyright (C)2013-2025 The MMGen Project <mmgen@tuta.io>
+# Licensed under the GNU General Public License, Version 3:
+#   https://www.gnu.org/licenses
+# Public project repositories:
+#   https://github.com/mmgen/mmgen-wallet
+#   https://gitlab.com/mmgen/mmgen-wallet
+
+"""
+help.subwallet: subwallet help notes for the MMGen Wallet suite
+"""
+
+def help(proto, cfg):
+	from ..subseed import SubSeedIdxRange
+	return f"""
+SUBWALLETS:
+
+Subwallets (subseeds) are specified by a ‘Subseed Index’ consisting of:
+
+  a) an integer in the range 1-{SubSeedIdxRange.max_idx}, plus
+  b) an optional single letter, ‘L’ or ‘S’
+
+The letter designates the length of the subseed.  If omitted, ‘L’ is assumed.
+
+Long (‘L’) subseeds are the same length as their parent wallet’s seed
+(typically 256 bits), while short (‘S’) subseeds are always 128-bit.
+The long and short subseeds for a given index are derived independently,
+so both may be used.
+
+MMGen Wallet has no notion of ‘depth’, and to an outside observer subwallets
+are identical to ordinary wallets.  This is a feature rather than a bug, as
+it denies an attacker any way of knowing whether a given wallet has a parent.
+
+Since subwallets are just wallets, they may be used to generate other
+subwallets, leading to hierarchies of arbitrary depth.  However, this is
+inadvisable in practice for two reasons:  Firstly, it creates accounting
+complexity, requiring the user to independently keep track of a derivation
+tree.  More importantly, however, it leads to the danger of Seed ID
+collisions between subseeds at different levels of the hierarchy, as
+MMGen checks and avoids ID collisions only among sibling subseeds.
+
+An exception to this caveat would be a multi-user setup where sibling
+subwallets are distributed to different users as their default wallets.
+Since the subseeds derived from these subwallets are private to each user,
+Seed ID collisions among them doesn’t present a problem.
+
+A safe rule of thumb, therefore, is for *each user* to derive all of his/her
+subwallets from a single parent.  This leaves each user with a total of two
+million subwallets, which should be enough for most practical purposes.
+""".strip()

+ 59 - 0
mmgen/help/txcreate.py

@@ -0,0 +1,59 @@
+#!/usr/bin/env python3
+#
+# MMGen Wallet, a terminal-based cryptocurrency wallet
+# Copyright (C)2013-2025 The MMGen Project <mmgen@tuta.io>
+# Licensed under the GNU General Public License, Version 3:
+#   https://www.gnu.org/licenses
+# Public project repositories:
+#   https://github.com/mmgen/mmgen-wallet
+#   https://gitlab.com/mmgen/mmgen-wallet
+
+"""
+help.txcreate: txcreate and txdo help notes for the MMGen Wallet suite
+"""
+
+def help(proto, cfg):
+	outputs_info = (
+	"""
+Outputs are specified in the form ADDRESS,AMOUNT or ADDRESS.  The first form
+creates an output sending the given amount to the given address.  The bare
+address form designates the given address as either the change output or the
+sole output of the transaction (excluding any data output).  Exactly one bare
+address argument is required.
+
+For convenience, the bare address argument may be given as ADDRTYPE_CODE or
+SEED_ID:ADDRTYPE_CODE (see ADDRESS TYPES below). In the first form, the first
+unused address of type ADDRTYPE_CODE for each Seed ID in the tracking wallet
+will be displayed in a menu, with the user prompted to select one.  In the
+second form, the user specifies the Seed ID as well, allowing the script to
+select the transaction’s change output or single output without prompting.
+See EXAMPLES below.
+
+A single DATA_SPEC argument may also be given on the command line to create
+an OP_RETURN data output with a zero spend amount.  This is the preferred way
+to embed data in the blockchain.  DATA_SPEC may be of the form "data":DATA
+or "hexdata":DATA. In the first form, DATA is a string in your system’s native
+encoding, typically UTF-8.  In the second, DATA is a hexadecimal string (with
+the leading ‘0x’ omitted) encoding the binary data to be embedded.  In both
+cases, the resulting byte string must not exceed {bl} bytes in length.
+""".format(bl=proto.max_op_return_data_len)
+	if proto.base_proto == 'Bitcoin' else """
+The transaction output is specified in the form ADDRESS,AMOUNT.
+""")
+
+	return f"""
+The transaction’s outputs are listed on the command line, while its inputs
+are chosen from a list of the wallet’s unspent outputs via an interactive
+menu.  Alternatively, inputs may be specified using the --inputs option.
+
+Addresses on the command line can be either native coin addresses or MMGen
+IDs in the form SEED_ID:ADDRTYPE_CODE:INDEX.
+{outputs_info}
+If the transaction fee is not specified on the command line (see FEE
+SPECIFICATION below), it will be calculated dynamically using network fee
+estimation for the default (or user-specified) number of confirmations.
+If network fee estimation fails, the user will be prompted for a fee.
+
+Network-estimated fees will be multiplied by the value of --fee-adjust, if
+specified.
+"""

+ 65 - 0
mmgen/help/txcreate_examples.py

@@ -0,0 +1,65 @@
+#!/usr/bin/env python3
+#
+# MMGen Wallet, a terminal-based cryptocurrency wallet
+# Copyright (C)2013-2025 The MMGen Project <mmgen@tuta.io>
+# Licensed under the GNU General Public License, Version 3:
+#   https://www.gnu.org/licenses
+# Public project repositories:
+#   https://github.com/mmgen/mmgen-wallet
+#   https://gitlab.com/mmgen/mmgen-wallet
+
+"""
+help.txcreate_examples: txcreate and txdo help examples for the MMGen Wallet suite
+"""
+
+from ..cfg import gc
+
+def help(proto, cfg):
+
+	mmtype = 'B' if 'B' in proto.mmtypes else proto.mmtypes[0]
+	from ..tool.coin import tool_cmd
+	t = tool_cmd(cfg, mmtype=mmtype)
+	addr = t.privhex2addr('bead' * 16)
+	sample_addr = addr.views[addr.view_pref]
+
+	return f"""
+EXAMPLES:
+
+  Send 0.123 {proto.coin} to an external {proto.name} address, returning the change to a
+  specific MMGen address in the tracking wallet:
+
+    $ {gc.prog_name} {sample_addr},0.123 01ABCDEF:{mmtype}:7
+
+  Same as above, but select the change address automatically:
+
+    $ {gc.prog_name} {sample_addr},0.123 01ABCDEF:{mmtype}
+
+  Same as above, but select the change address automatically by address type:
+
+    $ {gc.prog_name} {sample_addr},0.123 {mmtype}
+
+  Same as above, but reduce verbosity and specify fee of 20 satoshis
+  per byte:
+
+    $ {gc.prog_name} -q -f 20s {sample_addr},0.123 {mmtype}
+
+  Send entire balance of selected inputs minus fee to an external {proto.name}
+  address:
+
+    $ {gc.prog_name} {sample_addr}
+
+  Send entire balance of selected inputs minus fee to first unused wallet
+  address of specified type:
+
+    $ {gc.prog_name} {mmtype}
+""" if proto.base_proto == 'Bitcoin' else f"""
+EXAMPLES:
+
+  Send 0.123 {proto.coin} to an external {proto.name} address:
+
+    $ {gc.prog_name} {sample_addr},0.123
+
+  Send 0.123 {proto.coin} to another account in wallet 01ABCDEF:
+
+    $ {gc.prog_name} 01ABCDEF:{mmtype}:7,0.123
+"""

+ 48 - 0
mmgen/help/txsign.py

@@ -0,0 +1,48 @@
+#!/usr/bin/env python3
+#
+# MMGen Wallet, a terminal-based cryptocurrency wallet
+# Copyright (C)2013-2025 The MMGen Project <mmgen@tuta.io>
+# Licensed under the GNU General Public License, Version 3:
+#   https://www.gnu.org/licenses
+# Public project repositories:
+#   https://github.com/mmgen/mmgen-wallet
+#   https://gitlab.com/mmgen/mmgen-wallet
+
+"""
+help.txsign: txsign help notes for the MMGen Wallet suite
+"""
+
+from ..cfg import gc
+from ..proto.btc.params import mainnet
+from ..daemon import CoinDaemon
+
+def help(proto, cfg):
+
+	def coind_exec():
+		return CoinDaemon(cfg, proto.coin).exec_fn if proto.coin in CoinDaemon.coins else 'bitcoind'
+
+	return """
+Transactions may contain both {pnm} or non-{pnm} input addresses.
+
+To sign non-{pnm} inputs, a {wd}flat key list is used
+as the key source (--keys-from-file option).
+
+To sign {pnm} inputs, key data is generated from a seed as with the
+{pnl}-addrgen and {pnl}-keygen commands.  Alternatively, a key-address file
+may be used (--mmgen-keys-from-file option).
+
+Multiple wallets or other seed files can be listed on the command line in
+any order.  If the seeds required to sign the transaction’s inputs are not
+found in these files (or in the default wallet), the user will be prompted
+for seed data interactively.
+
+To prevent an attacker from crafting transactions with bogus {pnm}-to-{pnu}
+address mappings, all outputs to {pnm} addresses are verified with a seed
+source.  Therefore, seed files or a key-address file for all {pnm} outputs
+must also be supplied on the command line if the data can’t be found in the
+default wallet.
+""".format(
+	wd  = f'{coind_exec()} wallet dump or ' if isinstance(proto, mainnet) else '',
+	pnm = gc.proj_name,
+	pnu = proto.name,
+	pnl = gc.proj_name.lower())

+ 1 - 1
mmgen/help/xmrwallet.py

@@ -9,7 +9,7 @@
 #   https://gitlab.com/mmgen/mmgen-wallet
 
 """
-help.xmrwallet: xmrwallet help notes for MMGen suite
+help.xmrwallet: xmrwallet help notes for the MMGen Wallet suite
 """
 
 def help(proto, cfg):

+ 2 - 2
mmgen/main_addrgen.py

@@ -111,9 +111,9 @@ range(s).
 			cfg       = cfg,
 			gc        = gc,
 		),
-		'notes': lambda help_notes, s: s.format(
+		'notes': lambda help_mod, help_notes, s: s.format(
 			n_addrkey = note_addrkey,
-			n_sw      = help_notes('subwallet')+'\n\n',
+			n_sw      = help_mod('subwallet')+'\n\n',
 			n_pw      = help_notes('passwd')+'\n\n',
 			n_bw      = help_notes('brainwallet'),
 			n_fmt     = help_notes('fmt_codes'),

+ 5 - 4
mmgen/main_txbump.py

@@ -95,7 +95,8 @@ identical to that of ‘mmgen-txcreate’.
 The user should take care to select a fee sufficient to ensure the original
 transaction is replaced in the mempool.
 
-{e}{s}
+{e}
+{s}
 Seed source files must have the canonical extensions listed in the 'FileExt'
 column below:
 
@@ -104,7 +105,7 @@ column below:
 	},
 	'code': {
 		'usage': lambda cfg, proto, help_notes, s: s.format(
-			u_args = help_notes('txcreate_args', 'tx')),
+			u_args = help_notes('txcreate_args')),
 		'options': lambda cfg, help_notes, proto, s: s.format(
 			cfg     = cfg,
 			gc      = gc,
@@ -116,9 +117,9 @@ column below:
 			coin_id = help_notes('coin_id'),
 			dsl     = help_notes('dfl_seed_len'),
 			cu      = proto.coin),
-		'notes': lambda help_notes, s: s.format(
+		'notes': lambda help_mod, help_notes, s: s.format(
 			e       = help_notes('fee'),
-			s       = help_notes('txsign'),
+			s       = help_mod('txsign'),
 			f       = help_notes('fmt_codes')),
 	}
 }

+ 6 - 6
mmgen/main_txcreate.py

@@ -35,7 +35,7 @@ opts_data = {
 	'text': {
 		'desc': {
 			'tx':     f'Create a transaction with outputs to specified coin or {gc.proj_name} addresses',
-			'swaptx': f'Create a DEX swap transaction with {gc.proj_name} inputs and outputs',
+			'swaptx': f'Create a DEX swap transaction from one {gc.proj_name} tracking wallet to another',
 		}[target],
 		'usage':   '[opts] {u_args} [addr file ...]',
 		'options': """
@@ -80,7 +80,7 @@ opts_data = {
 	},
 	'code': {
 		'usage': lambda cfg, proto, help_notes, s: s.format(
-			u_args = help_notes('txcreate_args', target)),
+			u_args = help_notes('txcreate_args')),
 		'options': lambda cfg, proto, help_notes, s: s.format(
 			cfg    = cfg,
 			cu     = proto.coin,
@@ -91,11 +91,11 @@ opts_data = {
 			fe_dfl = cfg._autoset_opts['fee_estimate_mode'].choices[0],
 			x_all = fmt_list(cfg._autoset_opts['swap_proto'].choices, fmt='no_spc'),
 			x_dfl = cfg._autoset_opts['swap_proto'].choices[0]),
-		'notes': lambda cfg, help_notes, s: s.format(
-			c      = help_notes('txcreate'),
+		'notes': lambda cfg, help_mod, help_notes, s: s.format(
+			c      = help_mod('txcreate'),
 			F      = help_notes('fee'),
-			x      = help_notes('txcreate_examples'),
-			n_at   = help_notes('address_types'))
+			n_at   = help_notes('address_types'),
+			x      = help_mod('txcreate_examples'))
 	}
 }
 

+ 11 - 10
mmgen/main_txdo.py

@@ -17,7 +17,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 """
-mmgen-txdo: Create, sign and broadcast an online MMGen transaction
+mmgen-txdo: Create, sign and send an online MMGen transaction
 """
 
 from .cfg import gc, Config
@@ -35,7 +35,7 @@ opts_data = {
 	'text': {
 		'desc': {
 			'tx':     f'Create, sign and send an {gc.proj_name} transaction',
-			'swaptx': f'Create, sign and send a DEX swap transaction with {gc.proj_name} inputs and outputs',
+			'swaptx': f'Create, sign and send a DEX swap transaction from one {gc.proj_name} tracking wallet to another',
 		}[target],
 		'usage':   '[opts] {u_args} [addr file ...] [seed source ...]',
 		'options': """
@@ -98,22 +98,23 @@ opts_data = {
 			-- -z, --show-hash-presets Show information on available hash presets
 		""",
 		'notes': """
-{c}\n{F}
+{c}
+{n_at}
+
+{F}
 
                                  SIGNING NOTES
 {s}
 Seed source files must have the canonical extensions listed in the 'FileExt'
 column below:
 
-{n_at}
-
 {f}
 
 {x}"""
 	},
 	'code': {
 		'usage': lambda cfg, proto, help_notes, s: s.format(
-			u_args  = help_notes('txcreate_args', target)),
+			u_args  = help_notes('txcreate_args')),
 		'options': lambda cfg, proto, help_notes, s: s.format(
 			gc      = gc,
 			cfg     = cfg,
@@ -132,13 +133,13 @@ column below:
 			fe_dfl  = cfg._autoset_opts['fee_estimate_mode'].choices[0],
 			x_all   = fmt_list(cfg._autoset_opts['swap_proto'].choices, fmt='no_spc'),
 			x_dfl   = cfg._autoset_opts['swap_proto'].choices[0]),
-		'notes': lambda cfg, help_notes, s: s.format(
-			c       = help_notes('txcreate'),
+		'notes': lambda cfg, help_mod, help_notes, s: s.format(
+			c       = help_mod('txcreate'),
 			F       = help_notes('fee'),
-			s       = help_notes('txsign'),
 			n_at    = help_notes('address_types'),
 			f       = help_notes('fmt_codes'),
-			x       = help_notes('txcreate_examples')),
+			s       = help_mod('txsign'),
+			x       = help_mod('txcreate_examples'))
 	}
 }
 

+ 2 - 2
mmgen/main_txsign.py

@@ -89,8 +89,8 @@ column below:
 			ss      = help_notes('dfl_subseeds'),
 			ss_max  = SubSeedIdxRange.max_idx,
 			cu      = proto.coin),
-		'notes': lambda help_notes, s: s.format(
-			t       = help_notes('txsign'),
+		'notes': lambda help_mod, help_notes, s: s.format(
+			t       = help_mod('txsign'),
 			f       = help_notes('fmt_codes')),
 	}
 }

+ 1 - 1
mmgen/main_wallet.py

@@ -138,7 +138,7 @@ opts_data = {
 		'notes': lambda cfg, help_mod, help_notes, s: s.format(
 			f       = help_notes('fmt_codes'),
 			n_ss    = ('', help_mod('seedsplit')+'\n\n')[do_ss_note],
-			n_sw    = ('', help_notes('subwallet')+'\n\n')[do_sw_note],
+			n_sw    = ('', help_mod('subwallet')+'\n\n')[do_sw_note],
 			n_pw    = help_notes('passwd'),
 			n_bw    = ('', '\n\n'+help_notes('brainwallet'))[do_bw_note]
 		)