diff --git a/mmgen/tool.py b/mmgen/tool.py index c6b7b548..eb9a043e 100755 --- a/mmgen/tool.py +++ b/mmgen/tool.py @@ -1087,3 +1087,116 @@ class MMGenToolCmd( MMGenToolCmdRPC, MMGenToolCmdMonero, ): pass + +class tool_api( + MMGenToolCmdUtil, + MMGenToolCmdCoin, + MMGenToolCmdMnemonic, + ): + """ + API providing access to a subset of methods from the mmgen.tool module + + Example: + from mmgen.tool import tool_api + tool = tool_api() + + # Set the coin and network: + tool.init_coin('btc','mainnet') + + # Print available address types: + tool.print_addrtypes() + + # Set the address type: + tool.addrtype = 'segwit' + + # Disable user entropy gathering (optional, reduces security): + tool.usr_randchars = 0 + + # Generate a random BTC segwit keypair: + wif,addr = tool.randpair() + + # Set coin, network and address type: + tool.init_coin('ltc','testnet') + tool.addrtype = 'bech32' + + # Generate a random LTC testnet Bech32 keypair: + wif,addr = tool.randpair() + """ + + def __init__(self): + """ + Initializer - takes no arguments + """ + if not hasattr(opt,'version'): + opts.init({'text': { 'desc': '', 'usage':'', 'options':'' }}) + opt.use_old_ed25519 = None + opt.type = None + + def init_coin(self,coinsym,network): + """ + Initialize a coin/network pair + Valid choices for coins: one of the symbols returned by the 'coins' attribute + Valid choices for network: 'mainnet','testnet','regtest' + """ + from mmgen.protocol import init_coin,init_genonly_altcoins + init_genonly_altcoins(coinsym) + if network == 'regtest': + g.regtest = True + return init_coin(coinsym,{'mainnet':False,'testnet':True,'regtest':True}[network]) + + @property + def coins(self): + """The available coins""" + from mmgen.protocol import CoinProtocol + from mmgen.altcoin import CoinInfo + return sorted(set(CoinProtocol.list_coins() + [c.symbol for c in CoinInfo.get_supported_coins(g.network)])) + + @property + def coin(self): + """The currently configured coin""" + return g.coin + + @property + def network(self): + """The currently configured network""" + if g.network == 'testnet': + return ('testnet','regtest')[g.regtest] + else: + return g.network + + @property + def addrtypes(self): + """ + The available address types for current coin/network pair. The + first-listed is the default + """ + return [MMGenAddrType(t).name for t in g.proto.mmtypes] + + def print_addrtypes(self): + """ + Print the available address types for current coin/network pair along with + a description. The first-listed is the default + """ + for t in [MMGenAddrType(s) for s in g.proto.mmtypes]: + print('{:<12} - {}'.format(t.name,t.desc)) + + @property + def addrtype(self): + """The currently configured address type (is assignable)""" + return opt.type + + @addrtype.setter + def addrtype(self,val): + opt.type = val + + @property + def usr_randchars(self): + """ + The number of keystrokes of entropy to be gathered from the user. + Setting to zero disables user entropy gathering. + """ + return opt.usr_randchars + + @usr_randchars.setter + def usr_randchars(self,val): + opt.usr_randchars = val diff --git a/test/tooltest2.py b/test/tooltest2.py index 4a8b3d22..c88c7e3c 100755 --- a/test/tooltest2.py +++ b/test/tooltest2.py @@ -55,6 +55,7 @@ opts_data = { 'usage':'[options] [command]...', 'options': """ -h, --help Print this help message +-A, --tool-api Test the tool_api subsystem -C, --coverage Produce code coverage info using trace module -d, --die-on-missing Abort if no test data found for given command --, --longhelp Print help message for long options (common options) @@ -834,13 +835,34 @@ def run_test(gid,cmd_name): opt.quiet = oq_save return ret + def tool_api(cmd_name,args,out,opts,exec_code): + from mmgen.tool import tool_api + tool = tool_api() + if opts: + for o in opts: + if o.startswith('--type='): + tool.addrtype = o.split('=')[1] + pargs,kwargs = [],{} + for a in args: + if '=' in a: + a1,a2 = a.split('=') + kwargs[a1] = int(a2) if is_int(a2) else a2 + else: + pargs.append(a) + return getattr(tool,cmd_name)(*pargs,**kwargs) + for d in data: args,out,opts,exec_code = d + tuple([None] * (4-len(d))) stdin_input = None if args and type(args[0]) == bytes: stdin_input = args[0] args[0] = '-' - if opt.fork: + + if opt.tool_api: + if args and args[0 ]== '-': + continue + cmd_out = tool_api(cmd_name,args,out,opts,exec_code) + elif opt.fork: cmd_out = fork_cmd(cmd_name,args,out,opts,exec_code) else: if stdin_input and g.platform == 'win': @@ -923,6 +945,10 @@ sys.argv = [sys.argv[0]] + ['--skip-cfg-file'] + sys.argv[1:] cmd_args = opts.init(opts_data,add_opts=['use_old_ed25519']) +if opt.tool_api: + del tests['Wallet'] + del tests['File'] + import mmgen.tool as tool if opt.list_tests: