wallet.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #!/usr/bin/env python3
  2. #
  3. # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
  4. # Copyright (C)2013-2022 The MMGen Project <mmgen@tuta.io>
  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. tool/wallet.py: Wallet routines for the 'mmgen-tool' utility
  20. """
  21. from .common import tool_cmd_base
  22. from ..opts import opt
  23. from ..fileutil import get_seed_file
  24. from ..subseed import SubSeedList
  25. from ..seedsplit import MasterShareIdx
  26. from ..wallet import Wallet
  27. class tool_cmd(tool_cmd_base):
  28. "key, address or subseed generation from an MMGen wallet"
  29. def __init__(self,cmdname=None,proto=None,mmtype=None):
  30. if cmdname in ('gen_key','gen_addr'):
  31. self.need_proto = True
  32. super().__init__(cmdname=cmdname,proto=proto,mmtype=mmtype)
  33. def get_subseed(self,subseed_idx:str,wallet=''):
  34. "get the Seed ID of a single subseed by Subseed Index for default or specified wallet"
  35. opt.quiet = True
  36. sf = get_seed_file([wallet] if wallet else [],1)
  37. return Wallet(sf).seed.subseed(subseed_idx).sid
  38. def get_subseed_by_seed_id(self,seed_id:str,wallet='',last_idx=SubSeedList.dfl_len):
  39. "get the Subseed Index of a single subseed by Seed ID for default or specified wallet"
  40. opt.quiet = True
  41. sf = get_seed_file([wallet] if wallet else [],1)
  42. ret = Wallet(sf).seed.subseed_by_seed_id( seed_id, last_idx )
  43. return ret.ss_idx if ret else None
  44. def list_subseeds(self,subseed_idx_range:str,wallet=''):
  45. "list a range of subseed Seed IDs for default or specified wallet"
  46. opt.quiet = True
  47. sf = get_seed_file([wallet] if wallet else [],1)
  48. from ..subseed import SubSeedIdxRange
  49. return Wallet(sf).seed.subseeds.format( *SubSeedIdxRange(subseed_idx_range) )
  50. def list_shares(self,
  51. share_count: int,
  52. id_str = 'default',
  53. master_share: f'(min:1, max:{MasterShareIdx.max_val}, 0=no master share)' = 0,
  54. wallet = '' ):
  55. "list the Seed IDs of the shares resulting from a split of default or specified wallet"
  56. opt.quiet = True
  57. sf = get_seed_file([wallet] if wallet else [],1)
  58. return Wallet(sf).seed.split( share_count, id_str, master_share ).format()
  59. def gen_key(self,mmgen_addr:str,wallet=''):
  60. "generate a single WIF key for specified MMGen address from default or specified wallet"
  61. return self._gen_keyaddr( mmgen_addr, 'wif', wallet )
  62. def gen_addr(self,mmgen_addr:str,wallet=''):
  63. "generate a single MMGen address from default or specified wallet"
  64. return self._gen_keyaddr( mmgen_addr, 'addr', wallet )
  65. def _gen_keyaddr(self,mmgen_addr,target,wallet=''):
  66. from ..addr import MMGenID
  67. from ..addrlist import AddrList,AddrIdxList
  68. addr = MMGenID( self.proto, mmgen_addr )
  69. opt.quiet = True
  70. sf = get_seed_file([wallet] if wallet else [],1)
  71. ss = Wallet(sf)
  72. if ss.seed.sid != addr.sid:
  73. from ..util import die
  74. die(1,f'Seed ID of requested address ({addr.sid}) does not match wallet ({ss.seed.sid})')
  75. d = AddrList(
  76. proto = self.proto,
  77. seed = ss.seed,
  78. addr_idxs = AddrIdxList(str(addr.idx)),
  79. mmtype = addr.mmtype ).data[0]
  80. return { 'wif': d.sec.wif, 'addr': d.addr }[target]