__init__.py 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #!/usr/bin/env python3
  2. #
  3. # mmgen = Multi-Mode GENerator, a command-line cryptocurrency wallet
  4. # Copyright (C)2013-2022 The MMGen Project <mmgen@tuta.io>
  5. # Licensed under the GNU General Public License, Version 3:
  6. # https://www.gnu.org/licenses
  7. # Public project repositories:
  8. # https://github.com/mmgen/mmgen
  9. # https://gitlab.com/mmgen/mmgen
  10. """
  11. tx.__init__: transaction class initializer
  12. """
  13. from ..objmethods import MMGenObject
  14. def _base_proto_subclass(clsname,modname,proto):
  15. if proto:
  16. clsname = ('Token' if proto.tokensym else '') + clsname
  17. modname = 'mmgen.proto.{}.tx.{}'.format( proto.base_proto_coin.lower(), modname )
  18. else:
  19. modname = 'mmgen.tx.base'
  20. import importlib
  21. return getattr( importlib.import_module(modname), clsname )
  22. def _get_cls_info(clsname,modname,args,kwargs):
  23. assert args == (), f'{clsname}.chk1: only keyword args allowed in {clsname} initializer'
  24. if 'proto' in kwargs:
  25. proto = kwargs['proto']
  26. elif 'data' in kwargs:
  27. proto = kwargs['data']['proto']
  28. elif 'filename' in kwargs:
  29. from .file import MMGenTxFile
  30. proto = MMGenTxFile.get_proto( kwargs['filename'], quiet_open=True )
  31. elif clsname == 'Base':
  32. proto = None
  33. else:
  34. raise ValueError(
  35. f"{clsname} must be instantiated with 'proto','data' or 'filename' keyword" )
  36. if clsname == 'Completed':
  37. from ..util import get_extension
  38. from .completed import Completed
  39. ext = get_extension( kwargs['filename'] )
  40. cls = Completed.ext_to_cls( ext, proto )
  41. if not cls:
  42. die(1,f'{ext!r}: unrecognized file extension for CompletedTX')
  43. clsname = cls.__name__
  44. modname = cls.__module__.split('.')[-1]
  45. kwargs['proto'] = proto
  46. return ( proto, clsname, modname, kwargs )
  47. def _get_obj( _clsname, _modname, *args, **kwargs ):
  48. """
  49. determine cls/mod/proto and pass them to _base_proto_subclass() to get a transaction instance
  50. """
  51. proto,clsname,modname,kwargs = _get_cls_info(_clsname,_modname,args,kwargs)
  52. return _base_proto_subclass( clsname, modname, proto )(*args,**kwargs)
  53. async def _get_obj_async( _clsname, _modname, *args, **kwargs ):
  54. proto,clsname,modname,kwargs = _get_cls_info(_clsname,_modname,args,kwargs)
  55. # NB: tracking wallet needed to retrieve the 'symbol' and 'decimals' parameters of token addr
  56. # (see twctl:import_token()).
  57. # No twctl required for the Unsigned and Signed(data=unsigned.__dict__) classes used during
  58. # signing.
  59. if proto and proto.tokensym and clsname in ('New','OnlineSigned'):
  60. from ..tw.ctl import TwCtl
  61. kwargs['twctl'] = await TwCtl(proto)
  62. return _base_proto_subclass( clsname, modname, proto )(*args,**kwargs)
  63. def _get(clsname,modname):
  64. return lambda *args,**kwargs: _get_obj(clsname,modname,*args,**kwargs)
  65. def _get_async(clsname,modname):
  66. return lambda *args,**kwargs: _get_obj_async(clsname,modname,*args,**kwargs)
  67. BaseTX = _get('Base', 'base')
  68. UnsignedTX = _get('Unsigned', 'unsigned')
  69. NewTX = _get_async('New', 'new')
  70. CompletedTX = _get_async('Completed', 'completed')
  71. SignedTX = _get_async('Signed', 'signed')
  72. OnlineSignedTX = _get_async('OnlineSigned', 'online')
  73. BumpTX = _get_async('Bump', 'bump')