main_wallet.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #!/usr/bin/env python
  2. #
  3. # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
  4. # Copyright (C)2013-2016 Philemon <mmgen-py@yandex.com>
  5. #
  6. # This program is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation, either version 3 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. """
  19. mmgen/main_wallet: Entry point for MMGen wallet-related scripts
  20. """
  21. import os,re
  22. from mmgen.common import *
  23. from mmgen.seed import SeedSource
  24. from mmgen.obj import MMGenWalletLabel
  25. bn = os.path.basename(sys.argv[0])
  26. invoked_as = re.sub(r'^wallet','',bn.split('-')[-1])
  27. usage = '[opts] [infile]'
  28. nargs = 1
  29. iaction = 'convert'
  30. oaction = 'convert'
  31. bw_note = opts.bw_note
  32. pw_note = opts.pw_note
  33. if invoked_as == 'gen':
  34. desc = 'Generate an {pnm} wallet from a random seed'
  35. opt_filter = 'ehdoJlLpPqrSvz'
  36. usage = '[opts]'
  37. oaction = 'output'
  38. nargs = 0
  39. elif invoked_as == 'conv':
  40. desc = 'Convert an {pnm} wallet from one format to another'
  41. opt_filter = None
  42. elif invoked_as == 'chk':
  43. desc = 'Check validity of an {pnm} wallet'
  44. opt_filter = 'ehiHOlpPqrvz'
  45. iaction = 'input'
  46. elif invoked_as == 'passchg':
  47. desc = 'Change the password, hash preset or label of an {pnm} wallet'
  48. opt_filter = 'ehdiHkKOlLmpPqrSvz'
  49. iaction = 'input'
  50. bw_note = ''
  51. else:
  52. die(1,"'%s': unrecognized invocation" % bn)
  53. opts_data = {
  54. # Can't use: share/Opts doesn't know anything about fmt codes
  55. # 'sets': [('hidden_incog_output_params',bool,'out_fmt','hi')],
  56. 'desc': desc.format(pnm=g.proj_name),
  57. 'usage': usage,
  58. 'options': """
  59. -h, --help Print this help message.
  60. -d, --outdir= d Output files to directory 'd' instead of working dir.
  61. -e, --echo-passphrase Echo passphrases and other user input to screen.
  62. -i, --in-fmt= f {iaction} from wallet format 'f' (see FMT CODES below).
  63. -o, --out-fmt= f {oaction} to wallet format 'f' (see FMT CODES below).
  64. -H, --hidden-incog-input-params=f,o Read hidden incognito data from file
  65. 'f' at offset 'o' (comma-separated).
  66. -J, --hidden-incog-output-params=f,o Write hidden incognito data to file
  67. 'f' at offset 'o' (comma-separated). If file 'f'
  68. doesn't exist, it will be created and filled with
  69. random data.
  70. -O, --old-incog-fmt Specify old-format incognito input.
  71. -k, --keep-passphrase Reuse passphrase of input wallet for output wallet.
  72. -K, --keep-hash-preset Reuse hash preset of input wallet for output wallet.
  73. -l, --seed-len= l Specify wallet seed length of 'l' bits. This option
  74. is required only for brainwallet and incognito inputs
  75. with non-standard (< {g.seed_len}-bit) seed lengths.
  76. -L, --label= l Specify a label 'l' for output wallet.
  77. -m, --keep-label Reuse label of input wallet for output wallet.
  78. -p, --hash-preset= p Use the scrypt hash parameters defined by preset 'p'
  79. for password hashing (default: '{g.hash_preset}').
  80. -z, --show-hash-presets Show information on available hash presets.
  81. -P, --passwd-file= f Get wallet passphrase from file 'f'.
  82. -q, --quiet Produce quieter output; suppress some warnings.
  83. -r, --usr-randchars=n Get 'n' characters of additional randomness from user
  84. (min={g.min_urandchars}, max={g.max_urandchars}, default={g.usr_randchars}).
  85. -S, --stdout Write wallet data to stdout instead of file.
  86. -v, --verbose Produce more verbose output.
  87. """.format(
  88. g=g,
  89. iaction=capfirst(iaction),
  90. oaction=capfirst(oaction),
  91. ),
  92. 'notes': """
  93. {pw_note}{bw_note}
  94. FMT CODES:
  95. {f}
  96. """.format(
  97. f='\n '.join(SeedSource.format_fmt_codes().splitlines()),
  98. pw_note=pw_note,
  99. bw_note=('','\n\n' + bw_note)[bool(bw_note)]
  100. )
  101. }
  102. cmd_args = opts.init(opts_data,opt_filter=opt_filter)
  103. if opt.label:
  104. opt.label = MMGenWalletLabel(opt.label,msg="Error in option '--label'")
  105. if len(cmd_args) < nargs \
  106. and not opt.hidden_incog_input_params and not opt.in_fmt:
  107. die(1,'An input file or input format must be specified')
  108. elif len(cmd_args) > nargs \
  109. or (len(cmd_args) == nargs and opt.hidden_incog_input_params):
  110. msg('No input files may be specified' if invoked_as == 'gen'
  111. else 'Too many input files specified')
  112. opts.usage()
  113. if cmd_args: check_infile(cmd_args[0])
  114. if not invoked_as == 'chk': do_license_msg()
  115. if invoked_as in ('conv','passchg'): msg(green('Processing input wallet'))
  116. ss_in = None if invoked_as == 'gen' \
  117. else SeedSource(*cmd_args,passchg=invoked_as=='passchg')
  118. if invoked_as == 'chk': sys.exit()
  119. if invoked_as in ('conv','passchg'): msg(green('Processing output wallet'))
  120. ss_out = SeedSource(ss=ss_in,passchg=invoked_as=='passchg')
  121. if invoked_as == 'gen': qmsg("This wallet's Seed ID: %s" % ss_out.seed.sid.hl())
  122. ss_out.write_to_file()