From 037c6bfb6f90041578a1f1e4c378a170a735b152 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Fri, 31 Jan 2025 16:00:47 +0000 Subject: [PATCH] opts, help: contextual command options The following invocations now display a different set of options: $ mmgen-txcreate --help $ mmgen-txcreate --help --coin=eth This feature was formerly available only for global options --- mmgen/cfg.py | 2 - mmgen/data/version | 2 +- mmgen/help/__init__.py | 37 +++++++++---- mmgen/main_addrgen.py | 73 +++++++++++++------------- mmgen/main_txcreate.py | 71 ++++++++++++------------- mmgen/main_txdo.py | 115 +++++++++++++++++++++-------------------- mmgen/main_wallet.py | 84 +++++++++++++++--------------- mmgen/opts.py | 26 ++++++---- 8 files changed, 218 insertions(+), 192 deletions(-) diff --git a/mmgen/cfg.py b/mmgen/cfg.py index d84c3f08..2c361f5c 100755 --- a/mmgen/cfg.py +++ b/mmgen/cfg.py @@ -433,7 +433,6 @@ class Config(Lockable): cfg = None, opts_data = None, init_opts = None, - opt_filter = None, parse_only = False, parsed_opts = None, need_proto = True, @@ -455,7 +454,6 @@ class Config(Lockable): cfg = self, opts_data = opts_data, init_opts = init_opts, - opt_filter = opt_filter, parsed_opts = parsed_opts, need_proto = need_proto) self._uopt_src = 'cmdline' diff --git a/mmgen/data/version b/mmgen/data/version index 9eb885ae..2a38aa01 100644 --- a/mmgen/data/version +++ b/mmgen/data/version @@ -1 +1 @@ -15.1.dev12 +15.1.dev13 diff --git a/mmgen/help/__init__.py b/mmgen/help/__init__.py index 14d24455..931eb377 100755 --- a/mmgen/help/__init__.py +++ b/mmgen/help/__init__.py @@ -118,23 +118,16 @@ class Help: return nl.join(gen_output()) + '\n' -class CmdHelp(Help): +class CmdHelp_v1(Help): help_type = 'options' data_desc = 'opts_data' def gen_text(self, opts): - opt_filter = opts.opt_filter - from ..opts import cmd_opts_pat + from ..opts import cmd_opts_v1_pat skipping = False for line in opts.opts_data['text']['options'].strip().splitlines(): - if m := cmd_opts_pat.match(line): - if opt_filter: - if m[1] in opt_filter: - skipping = False - else: - skipping = True - continue + if m := cmd_opts_v1_pat.match(line): yield '{} --{} {}'.format( (f'-{m[1]},', ' ')[m[1] == '-'], m[2], @@ -142,6 +135,28 @@ class CmdHelp(Help): elif not skipping: yield line +class CmdHelp_v2(CmdHelp_v1): + + def gen_text(self, opts): + from ..opts import cmd_opts_v2_help_pat + skipping = False + coin_filter_codes = opts.global_filter_codes.coin + cmd_filter_codes = opts.opts_data['filter_codes'] + for line in opts.opts_data['text']['options'][1:].rstrip().splitlines(): + m = cmd_opts_v2_help_pat.match(line) + if m[1] == '+': + if not skipping: + yield line[6:] + elif m[1] in coin_filter_codes and m[2] in cmd_filter_codes: + yield '{} --{} {}'.format( + (f'-{m[3]},', ' ')[m[3] == '-'], + m[4], + m[6] + ) if m[4] else m[6] + skipping = False + else: + skipping = True + class GlobalHelp(Help): help_type = 'global_options' @@ -166,7 +181,7 @@ class GlobalHelp(Help): def print_help(cfg, opts): if cfg.help: - help_cls = CmdHelp + help_cls = CmdHelp_v2 if 'filter_codes' in opts.opts_data else CmdHelp_v1 else: help_cls = GlobalHelp diff --git a/mmgen/main_addrgen.py b/mmgen/main_addrgen.py index 16823464..3802258c 100755 --- a/mmgen/main_addrgen.py +++ b/mmgen/main_addrgen.py @@ -30,16 +30,17 @@ if gc.prog_name == 'mmgen-keygen': gen_what = 'keys' gen_clsname = 'KeyAddrList' gen_desc = 'secret keys' - opt_filter = None + filter_codes = ['-', 'k'] note_addrkey = 'By default, both addresses and secret keys are generated.\n\n' else: gen_what = 'addresses' gen_clsname = 'AddrList' gen_desc = 'addresses' - opt_filter = 'hbcdeEiHOkKlpzPqrStUv-' + filter_codes = ['-'] note_addrkey = '' opts_data = { + 'filter_codes': filter_codes, 'sets': [('print_checksum', True, 'quiet', True)], 'text': { 'desc': f""" @@ -48,39 +49,39 @@ opts_data = { """, 'usage':'[opts] [seed source] ', 'options': """ --h, --help Print this help message ---, --longhelp Print help message for long (global) options --A, --no-addresses Print only secret keys, no addresses --c, --print-checksum Print address list checksum and exit --d, --outdir= d Output files to directory 'd' instead of working dir --e, --echo-passphrase Echo passphrase or mnemonic to screen upon entry --i, --in-fmt= f Input is from wallet format 'f' (see FMT CODES below) --H, --hidden-incog-input-params=f,o Read hidden incognito data from file - 'f' at offset 'o' (comma-separated) --O, --old-incog-fmt Specify old-format incognito input --k, --use-internal-keccak-module Force use of the internal keccak module --K, --keygen-backend=n Use backend 'n' for public key generation. Options - for {coin_id}: {kgs} --l, --seed-len= l Specify wallet seed length of 'l' bits. This option - is required only for brainwallet and incognito inputs - with non-standard (< {dsl}-bit) seed lengths. --p, --hash-preset= p Use the scrypt hash parameters defined by preset 'p' - for password hashing (default: '{gc.dfl_hash_preset}') --z, --show-hash-presets Show information on available hash presets --P, --passwd-file= f Get wallet passphrase from file 'f' --q, --quiet Produce quieter output; suppress some warnings --r, --usr-randchars=n Get 'n' characters of additional randomness from user - (min={cfg.min_urandchars}, max={cfg.max_urandchars}, default={cfg.usr_randchars}) --S, --stdout Print {what} to stdout --t, --type=t Choose address type. Options: see ADDRESS TYPES below - (default: {dmat}) --U, --subwallet= U Generate {what} for subwallet 'U' (see SUBWALLETS - below) --V, --viewkeys Print viewkeys, omitting secret keys --v, --verbose Produce more verbose output --x, --b16 Print secret keys in hexadecimal too -""", - 'notes': """ + -- -h, --help Print this help message + -- --, --longhelp Print help message for long (global) options + -k -A, --no-addresses Print only secret keys, no addresses + -- -c, --print-checksum Print address list checksum and exit + -- -d, --outdir= d Output files to directory 'd' instead of working dir + -- -e, --echo-passphrase Echo passphrase or mnemonic to screen upon entry + -- -i, --in-fmt= f Input is from wallet format 'f' (see FMT CODES below) + -- -H, --hidden-incog-input-params=f,o Read hidden incognito data from file + + 'f' at offset 'o' (comma-separated) + -- -O, --old-incog-fmt Specify old-format incognito input + -- -k, --use-internal-keccak-module Force use of the internal keccak module + -- -K, --keygen-backend=n Use backend 'n' for public key generation. Options + + for {coin_id}: {kgs} + -- -l, --seed-len= l Specify wallet seed length of 'l' bits. This option + + is required only for brainwallet and incognito inputs + + with non-standard (< {dsl}-bit) seed lengths. + -- -p, --hash-preset= p Use the scrypt hash parameters defined by preset 'p' + + for password hashing (default: '{gc.dfl_hash_preset}') + -- -z, --show-hash-presets Show information on available hash presets + -- -P, --passwd-file= f Get wallet passphrase from file 'f' + -- -q, --quiet Produce quieter output; suppress some warnings + -- -r, --usr-randchars=n Get 'n' characters of additional randomness from user + + (min={cfg.min_urandchars}, max={cfg.max_urandchars}, default={cfg.usr_randchars}) + -- -S, --stdout Print {what} to stdout + -- -t, --type=t Choose address type. Options: see ADDRESS TYPES below + + (default: {dmat}) + -- -U, --subwallet= U Generate {what} for subwallet 'U' (see SUBWALLETS + + below) + -k -V, --viewkeys Print viewkeys, omitting secret keys + -- -v, --verbose Produce more verbose output + -k -x, --b16 Print secret keys in hexadecimal too + """, + 'notes': """ NOTES FOR THIS COMMAND @@ -124,7 +125,7 @@ FMT CODES: } } -cfg = Config(opts_data=opts_data, opt_filter=opt_filter, need_amt=False) +cfg = Config(opts_data=opts_data, need_amt=False) proto = cfg._proto diff --git a/mmgen/main_txcreate.py b/mmgen/main_txcreate.py index d14d985d..3a20b8aa 100755 --- a/mmgen/main_txcreate.py +++ b/mmgen/main_txcreate.py @@ -25,46 +25,47 @@ from .cfg import gc, Config from .util import fmt_list, async_run opts_data = { + 'filter_codes': ['-'], 'sets': [('yes', True, 'quiet', True)], 'text': { 'desc': f'Create a transaction with outputs to specified coin or {gc.proj_name} addresses', 'usage': '[opts] {u_args} [addr file ...]', 'options': """ --h, --help Print this help message ---, --longhelp Print help message for long (global) options --a, --autosign Create a transaction for offline autosigning (see - ‘mmgen-autosign’). The removable device is mounted and - unmounted automatically --A, --fee-adjust= f Adjust transaction fee by factor 'f' (see below) --B, --no-blank Don't blank screen before displaying {a_info} --c, --comment-file=f Source the transaction's comment from file 'f' --C, --fee-estimate-confs=c Desired number of confirmations for fee estimation - (default: {cfg.fee_estimate_confs}) --d, --outdir= d Specify an alternate directory 'd' for output --D, --contract-data=D Path to hex-encoded contract data (ETH only) --E, --fee-estimate-mode=M Specify the network fee estimate mode. Choices: - {fe_all}. Default: {fe_dfl!r} --f, --fee= f Transaction fee, as a decimal {cu} amount or as - {fu} (an integer followed by {fl!r}). - See FEE SPECIFICATION below. If omitted, fee will be - calculated using network fee estimation. --g, --gas= g Specify start gas amount in Wei (ETH only) --i, --info Display {a_info} and exit --I, --inputs= i Specify transaction inputs (comma-separated list of - MMGen IDs or coin addresses). Note that ALL unspent - outputs associated with each address will be included. --l, --locktime= t Lock time (block height or unix seconds) (default: 0) --L, --autochg-ignore-labels Ignore labels when autoselecting change addresses --m, --minconf= n Minimum number of confirmations required to spend - outputs (default: 1) --q, --quiet Suppress warnings; overwrite files without prompting --R, --no-rbf Make transaction non-replaceable (non-replace-by-fee - according to BIP 125) --v, --verbose Produce more verbose output --V, --vsize-adj= f Adjust transaction's estimated vsize by factor 'f' --y, --yes Answer 'yes' to prompts, suppress non-essential output --X, --cached-balances Use cached balances (Ethereum only) -""", + -- -h, --help Print this help message + -- --, --longhelp Print help message for long (global) options + -- -a, --autosign Create a transaction for offline autosigning (see + + ‘mmgen-autosign’). The removable device is mounted and + + unmounted automatically + -- -A, --fee-adjust= f Adjust transaction fee by factor 'f' (see below) + -- -B, --no-blank Don't blank screen before displaying {a_info} + -- -c, --comment-file=f Source the transaction's comment from file 'f' + b- -C, --fee-estimate-confs=c Desired number of confirmations for fee estimation + + (default: {cfg.fee_estimate_confs}) + -- -d, --outdir= d Specify an alternate directory 'd' for output + e- -D, --contract-data=D Path to file containing hex-encoded contract data + b- -E, --fee-estimate-mode=M Specify the network fee estimate mode. Choices: + + {fe_all}. Default: {fe_dfl!r} + -- -f, --fee= f Transaction fee, as a decimal {cu} amount or as + + {fu} (an integer followed by {fl!r}). + + See FEE SPECIFICATION below. If omitted, fee will be + + calculated using network fee estimation. + e- -g, --gas= g Specify start gas amount in Wei + -- -i, --info Display {a_info} and exit + -- -I, --inputs= i Specify transaction inputs (comma-separated list of + + MMGen IDs or coin addresses). Note that ALL unspent + + outputs associated with each address will be included. + b- -l, --locktime= t Lock time (block height or unix seconds) (default: 0) + b- -L, --autochg-ignore-labels Ignore labels when autoselecting change addresses + -- -m, --minconf= n Minimum number of confirmations required to spend + + outputs (default: 1) + -- -q, --quiet Suppress warnings; overwrite files without prompting + b- -R, --no-rbf Make transaction non-replaceable (non-replace-by-fee + + according to BIP 125) + -- -v, --verbose Produce more verbose output + b- -V, --vsize-adj= f Adjust transaction's estimated vsize by factor 'f' + -- -y, --yes Answer 'yes' to prompts, suppress non-essential output + e- -X, --cached-balances Use cached balances + """, 'notes': '\n{c}\n{F}\n{x}', }, 'code': { diff --git a/mmgen/main_txdo.py b/mmgen/main_txdo.py index e8eff769..d97564b5 100755 --- a/mmgen/main_txdo.py +++ b/mmgen/main_txdo.py @@ -25,68 +25,69 @@ from .util import die, fmt_list, async_run from .subseed import SubSeedIdxRange opts_data = { + 'filter_codes': ['-'], 'sets': [('yes', True, 'quiet', True)], 'text': { 'desc': f'Create, sign and send an {gc.proj_name} transaction', 'usage': '[opts] {u_args} [addr file ...] [seed source ...]', 'options': """ --h, --help Print this help message ---, --longhelp Print help message for long (global) options --A, --fee-adjust= f Adjust transaction fee by factor 'f' (see below) --b, --brain-params=l,p Use seed length 'l' and hash preset 'p' for - brainwallet input --B, --no-blank Don't blank screen before displaying {a_info} --c, --comment-file= f Source the transaction's comment from file 'f' --C, --fee-estimate-confs=c Desired number of confirmations for fee estimation - (default: {cfg.fee_estimate_confs}) --d, --outdir= d Specify an alternate directory 'd' for output --D, --contract-data= D Path to hex-encoded contract data (ETH only) --e, --echo-passphrase Print passphrase to screen when typing it --E, --fee-estimate-mode=M Specify the network fee estimate mode. Choices: - {fe_all}. Default: {fe_dfl!r} --f, --fee= f Transaction fee, as a decimal {cu} amount or as - {fu} (an integer followed by {fl!r}). - See FEE SPECIFICATION below. If omitted, fee will be - calculated using network fee estimation. --g, --gas= g Specify start gas amount in Wei (ETH only) --H, --hidden-incog-input-params=f,o Read hidden incognito data from file - 'f' at offset 'o' (comma-separated) --i, --in-fmt= f Input is from wallet format 'f' (see FMT CODES below) --I, --inputs= i Specify transaction inputs (comma-separated list of - MMGen IDs or coin addresses). Note that ALL unspent - outputs associated with each address will be included. --l, --seed-len= l Specify wallet seed length of 'l' bits. This option - is required only for brainwallet and incognito inputs - with non-standard (< {dsl}-bit) seed lengths. --k, --keys-from-file=f Provide additional keys for non-{pnm} addresses --K, --keygen-backend=n Use backend 'n' for public key generation. Options - for {coin_id}: {kgs} --l, --locktime= t Lock time (block height or unix seconds) (default: 0) --L, --autochg-ignore-labels Ignore labels when autoselecting change addresses --m, --minconf=n Minimum number of confirmations required to spend - outputs (default: 1) --M, --mmgen-keys-from-file=f Provide keys for {pnm} addresses in a key- - address file (output of '{pnl}-keygen'). Permits - online signing without an {pnm} seed source. The - key-address file is also used to verify {pnm}-to-{cu} - mappings, so the user should record its checksum. --O, --old-incog-fmt Specify old-format incognito input --p, --hash-preset= p Use the scrypt hash parameters defined by preset 'p' - for password hashing (default: '{gc.dfl_hash_preset}') --P, --passwd-file= f Get {pnm} wallet passphrase from file 'f' --R, --no-rbf Make transaction non-replaceable (non-replace-by-fee - according to BIP 125) --q, --quiet Suppress warnings; overwrite files without prompting --u, --subseeds= n The number of subseed pairs to scan for (default: {ss}, - maximum: {ss_max}). Only the default or first supplied - wallet is scanned for subseeds. --v, --verbose Produce more verbose output --V, --vsize-adj= f Adjust transaction's estimated vsize by factor 'f' --X, --cached-balances Use cached balances (Ethereum only) --y, --yes Answer 'yes' to prompts, suppress non-essential output --z, --show-hash-presets Show information on available hash presets -""", - 'notes': """ + -- -h, --help Print this help message + -- --, --longhelp Print help message for long (global) options + -- -A, --fee-adjust= f Adjust transaction fee by factor 'f' (see below) + -- -b, --brain-params=l,p Use seed length 'l' and hash preset 'p' for + + brainwallet input + -- -B, --no-blank Don't blank screen before displaying {a_info} + -- -c, --comment-file= f Source the transaction's comment from file 'f' + b- -C, --fee-estimate-confs=c Desired number of confirmations for fee estimation + + (default: {cfg.fee_estimate_confs}) + -- -d, --outdir= d Specify an alternate directory 'd' for output + e- -D, --contract-data= D Path to file containing hex-encoded contract data + -- -e, --echo-passphrase Print passphrase to screen when typing it + b- -E, --fee-estimate-mode=M Specify the network fee estimate mode. Choices: + + {fe_all}. Default: {fe_dfl!r} + -- -f, --fee= f Transaction fee, as a decimal {cu} amount or as + + {fu} (an integer followed by {fl!r}). + + See FEE SPECIFICATION below. If omitted, fee will be + + calculated using network fee estimation. + e- -g, --gas= g Specify start gas amount in Wei + -- -H, --hidden-incog-input-params=f,o Read hidden incognito data from file + + 'f' at offset 'o' (comma-separated) + -- -i, --in-fmt= f Input is from wallet format 'f' (see FMT CODES below) + -- -I, --inputs= i Specify transaction inputs (comma-separated list of + + MMGen IDs or coin addresses). Note that ALL unspent + + outputs associated with each address will be included. + -- -l, --seed-len= l Specify wallet seed length of 'l' bits. This option + + is required only for brainwallet and incognito inputs + + with non-standard (< {dsl}-bit) seed lengths. + -- -k, --keys-from-file=f Provide additional keys for non-{pnm} addresses + -- -K, --keygen-backend=n Use backend 'n' for public key generation. Options + + for {coin_id}: {kgs} + b- -l, --locktime= t Lock time (block height or unix seconds) (default: 0) + b- -L, --autochg-ignore-labels Ignore labels when autoselecting change addresses + -- -m, --minconf=n Minimum number of confirmations required to spend + + outputs (default: 1) + -- -M, --mmgen-keys-from-file=f Provide keys for {pnm} addresses in a key- + + address file (output of '{pnl}-keygen'). Permits + + online signing without an {pnm} seed source. The + + key-address file is also used to verify {pnm}-to-{cu} + + mappings, so the user should record its checksum. + -- -O, --old-incog-fmt Specify old-format incognito input + -- -p, --hash-preset= p Use the scrypt hash parameters defined by preset 'p' + + for password hashing (default: '{gc.dfl_hash_preset}') + -- -P, --passwd-file= f Get {pnm} wallet passphrase from file 'f' + b- -R, --no-rbf Make transaction non-replaceable (non-replace-by-fee + + according to BIP 125) + -- -q, --quiet Suppress warnings; overwrite files without prompting + -- -u, --subseeds= n The number of subseed pairs to scan for (default: {ss}, + + maximum: {ss_max}). Only the default or first supplied + + wallet is scanned for subseeds. + -- -v, --verbose Produce more verbose output + b- -V, --vsize-adj= f Adjust transaction's estimated vsize by factor 'f' + e- -X, --cached-balances Use cached balances + -- -y, --yes Answer 'yes' to prompts, suppress non-essential output + -- -z, --show-hash-presets Show information on available hash presets + """, + 'notes': """ {c}\n{F} SIGNING NOTES diff --git a/mmgen/main_wallet.py b/mmgen/main_wallet.py index 5eca7ece..ceebd856 100755 --- a/mmgen/main_wallet.py +++ b/mmgen/main_wallet.py @@ -45,78 +45,80 @@ invoked_as = { dsw = f'the default or specified {gc.proj_name} wallet' -# full: defhHiJkKlLmoOpPqrSvz- if invoked_as == 'gen': desc = f'Generate an {gc.proj_name} wallet from a random seed' - opt_filter = 'ehdoJlLpPqrSvz-' usage = '[opts]' oaction = 'output' nargs = 0 elif invoked_as == 'conv': desc = 'Convert ' + dsw + ' from one format to another' - opt_filter = 'dehHiJkKlLmNoOpPqrSvz-' elif invoked_as == 'chk': desc = 'Check validity of ' + dsw - opt_filter = 'ehiHOlpPqrvz-' iaction = 'input' elif invoked_as == 'passchg': desc = 'Change the passphrase, hash preset or label of ' + dsw - opt_filter = 'efhdiHkKOlLmNpPqrSvz-' iaction = 'input' do_bw_note = False elif invoked_as == 'subgen': desc = 'Generate a subwallet from ' + dsw - opt_filter = 'dehHiJkKlLmNoOpPqrSvz-' # omitted: f usage = '[opts] [infile] ' iaction = 'input' oaction = 'output' do_sw_note = True elif invoked_as == 'seedsplit': desc = 'Generate a seed share from ' + dsw - opt_filter = 'dehHiJlLMNIoOpPqrSvz-' usage = '[opts] [infile] [:]:' iaction = 'input' oaction = 'output' do_ss_note = True opts_data = { + 'filter_codes': { + # Write In-fmt Out-fmt Keep-pass Force-update Master-share passwd-file-New-only + 'chk': ['-', 'i'], + 'conv': ['-', 'w', 'i', 'o', 'k', 'n'], + 'gen': ['-', 'w', 'o'], + 'passchg': ['-', 'w', 'i', 'k', 'f', 'n'], + 'seedsplit': ['-', 'w', 'i', 'o', 'm', 'n'], + 'subgen': ['-', 'w', 'i', 'o', 'k', 'n'], + }[invoked_as], 'text': { 'desc': desc, 'usage': usage, 'options': """ --h, --help Print this help message ---, --longhelp Print help message for long (global) options --d, --outdir= d Output files to directory 'd' instead of working dir --e, --echo-passphrase Echo passphrases and other user input to screen --f, --force-update Force update of wallet even if nothing has changed --i, --in-fmt= f {iaction} from wallet format 'f' (see FMT CODES below) --o, --out-fmt= f {oaction} to wallet format 'f' (see FMT CODES below) --H, --hidden-incog-input-params=f,o Read hidden incognito data from file - 'f' at offset 'o' (comma-separated) --J, --hidden-incog-output-params=f,o Write hidden incognito data to file - 'f' at offset 'o' (comma-separated). File 'f' will be - created if necessary and filled with random data. --O, --old-incog-fmt Specify old-format incognito input --k, --keep-passphrase Reuse passphrase of input wallet for output wallet --K, --keep-hash-preset Reuse hash preset of input wallet for output wallet --l, --seed-len= l Specify wallet seed length of 'l' bits. This option - is required only for brainwallet and incognito inputs - with non-standard (< {dsl}-bit) seed lengths. --L, --label= l Specify a label 'l' for output wallet --m, --keep-label Reuse label of input wallet for output wallet --M, --master-share=i Use a master share with index 'i' (min:{ms_min}, max:{ms_max}) --p, --hash-preset= p Use the scrypt hash parameters defined by preset 'p' - for password hashing (default: '{gc.dfl_hash_preset}') --z, --show-hash-presets Show information on available hash presets --P, --passwd-file= f Get wallet passphrase from file 'f' --N, --passwd-file-new-only Use passwd file only for new, not existing, wallet --q, --quiet Produce quieter output; suppress some warnings --r, --usr-randchars=n Get 'n' characters of additional randomness from user - (min={cfg.min_urandchars}, max={cfg.max_urandchars}, default={cfg.usr_randchars}) --S, --stdout Write wallet data to stdout instead of file --v, --verbose Produce more verbose output -""", - 'notes': """ + -- -h, --help Print this help message + -- --, --longhelp Print help message for long (global) options + -w -d, --outdir= d Output files to directory 'd' instead of working dir + -- -e, --echo-passphrase Echo passphrases and other user input to screen + -f -f, --force-update Force update of wallet even if nothing has changed + -i -i, --in-fmt= f {iaction} from wallet format 'f' (see FMT CODES below) + -o -o, --out-fmt= f {oaction} to wallet format 'f' (see FMT CODES below) + -i -H, --hidden-incog-input-params=f,o Read hidden incognito data from file + + 'f' at offset 'o' (comma-separated) + -o -J, --hidden-incog-output-params=f,o Write hidden incognito data to file + + 'f' at offset 'o' (comma-separated). File 'f' will be + + created if necessary and filled with random data. + -i -O, --old-incog-fmt Specify old-format incognito input + -k -k, --keep-passphrase Reuse passphrase of input wallet for output wallet + -k -K, --keep-hash-preset Reuse hash preset of input wallet for output wallet + -- -l, --seed-len= l Specify wallet seed length of 'l' bits. This option + + is required only for brainwallet and incognito inputs + + with non-standard (< {dsl}-bit) seed lengths. + -w -L, --label= l Specify a label 'l' for output wallet + -k -m, --keep-label Reuse label of input wallet for output wallet + -m -M, --master-share=i Use a master share with index 'i' (min:{ms_min}, max:{ms_max}) + -- -p, --hash-preset= p Use the scrypt hash parameters defined by preset 'p' + + for password hashing (default: '{gc.dfl_hash_preset}') + -- -z, --show-hash-presets Show information on available hash presets + -- -P, --passwd-file= f Get wallet passphrase from file 'f' + -n -N, --passwd-file-new-only Use passwd file only for new, not existing, wallet + -- -q, --quiet Produce quieter output; suppress some warnings + -- -r, --usr-randchars=n Get 'n' characters of additional randomness from user + + (min={cfg.min_urandchars}, max={cfg.max_urandchars}, default={cfg.usr_randchars}) + -w -S, --stdout Write wallet data to stdout instead of file + -- -v, --verbose Produce more verbose output + """, + 'notes': """ {n_ss}{n_sw}{n_pw}{n_bw} @@ -145,7 +147,7 @@ FMT CODES: } } -cfg = Config(opts_data=opts_data, opt_filter=opt_filter, need_proto=False) +cfg = Config(opts_data=opts_data, need_proto=False) cmd_args = cfg._args diff --git a/mmgen/opts.py b/mmgen/opts.py index 84ebaedf..6737aa4a 100755 --- a/mmgen/opts.py +++ b/mmgen/opts.py @@ -150,30 +150,41 @@ def process_uopts(cfg, opts_data, opts, need_proto): return uopts, uargs -cmd_opts_pat = re.compile(r'^-([a-zA-Z0-9-]), --([a-zA-Z0-9-]{2,64})(=| )(.+)') +cmd_opts_v1_pat = re.compile(r'^-([a-zA-Z0-9-]), --([a-zA-Z0-9-]{2,64})(=| )(.+)') + +cmd_opts_v2_pat = re.compile(r'^\t\t\t(.)(.) -([a-zA-Z0-9-]), --([a-z0-9-]{2,64})(=| )(.+)') +cmd_opts_v2_help_pat = re.compile(r'^\t\t\t(.)(.) (?:-([a-zA-Z0-9-]), --([a-z0-9-]{2,64})(=| ))?(.+)') global_opts_pat = re.compile(r'^\t\t\t(.)(.) --([a-z0-9-]{2,64})(=| )(.+)') global_opts_help_pat = re.compile(r'^\t\t\t(.)(.) (?:--([{}a-zA-Z0-9-]{2,64})(=| ))?(.+)') opt_tuple = namedtuple('cmdline_option', ['name', 'has_parm']) -def parse_opts(cfg, opts_data, opt_filter, global_opts_data, global_filter_codes, need_proto): +def parse_opts(cfg, opts_data, global_opts_data, global_filter_codes, need_proto): - def parse_cmd(): + def parse_v1(): for line in opts_data['text']['options'].strip().splitlines(): - m = cmd_opts_pat.match(line) - if m and (not opt_filter or m[1] in opt_filter): + if m := cmd_opts_v1_pat.match(line): ret = opt_tuple(m[2].replace('-', '_'), m[3] == '=') yield (m[1], ret) yield (m[2], ret) + def parse_v2(): + cmd_filter_codes = opts_data['filter_codes'] + for line in opts_data['text']['options'].splitlines(): + m = cmd_opts_v2_pat.match(line) + if m and m[1] in global_filter_codes.coin and m[2] in cmd_filter_codes: + ret = opt_tuple(m[4].replace('-', '_'), m[5] == '=') + yield (m[3], ret) + yield (m[4], ret) + def parse_global(): for line in global_opts_data['text']['options'].splitlines(): m = global_opts_pat.match(line) if m and m[1] in global_filter_codes.coin and m[2] in global_filter_codes.cmd: yield (m[3], opt_tuple(m[3].replace('-', '_'), m[4] == '=')) - opts = tuple(parse_cmd()) + tuple(parse_global()) + opts = tuple((parse_v2 if 'filter_codes' in opts_data else parse_v1)()) + tuple(parse_global()) uopts, uargs = process_uopts(cfg, opts_data, dict(opts), need_proto) @@ -229,7 +240,6 @@ class Opts: cfg, opts_data, init_opts, # dict containing opts to pre-initialize - opt_filter, # whitelist of opt letters; all others are skipped parsed_opts, need_proto): @@ -237,7 +247,6 @@ class Opts: raise RuntimeError(f'{len(sys.argv) - 1}: too many command-line arguments') opts_data = opts_data or opts_data_dfl - self.opt_filter = opt_filter self.global_filter_codes = self.get_global_filter_codes(need_proto) self.opts_data = opts_data @@ -245,7 +254,6 @@ class Opts: po = parsed_opts or parse_opts( cfg, opts_data, - opt_filter, self.global_opts_data, self.global_filter_codes, need_proto)