def main(): parser = argparse.ArgumentParser( description='DigitalOracle HD multisig command line utility', formatter_class=argparse.RawDescriptionHelpFormatter, ) parser.add_argument('-e', '--email', help='e-mail for create') parser.add_argument( '-p', '--phone', help='phone number for create - in the format +14155551212') parser.add_argument('-n', '--network', default='BTC', choices=NETWORK_NAMES) parser.add_argument('-i', "--inputpath", nargs='+', help='HD subkey path for each input (example: 0/2/15)') parser.add_argument( '-c', "--changepath", nargs='+', help= 'HD subkey path for each change output (example: 0/2/15) or a dash for non-change outputs' ) parser.add_argument( '-s', "--spendid", help= 'an additional hex string to disambiguate spends to the same address') parser.add_argument( '-u', "--baseurl", help= 'the API endpoint, defaults to the sandbox - https://s.digitaloracle.co/' ) parser.add_argument('-v', "--verbose", default=0, action="count", help="Verbosity, use more -v flags for more verbosity") parser.add_argument('command', help="""a command""") parser.add_argument('item', nargs='+', help="""a key""") parser.epilog = textwrap.dedent(""" Items: * P:wallet_passphrase - a secret for deriving an HD hierarchy with private keys * xpub - an account extended public key for deriving an HD hierarchy with public keys only * FILE.bin - unsigned transaction binary * FILE.hex - unsigned transaction hex Commands: * dump - dump the public subkeys * create - create Oracle account based on the supplied leading key with with any additional keys * address - get the deposit address for a subkey path * sign - sign a transaction, tx.bin or tx.hex must be supplied. Only one subkey path is supported. Notes: * --subkey is applicable for the address and sign actions, but not the create action """) args = parser.parse_args() keys = [] txs = [] for item in args.item: key = None tx = None if item.startswith('P:'): s = item[2:] key = BIP32Node.from_master_secret(s.encode('utf8'), netcode=args.network) keys.append(key) else: try: key = Key.from_text(item) keys.append(key) except encoding.EncodingError: pass if key is None: if os.path.exists(item): try: with open(item, "rb") as f: if f.name.endswith("hex"): f = io.BytesIO( codecs.getreader("hex_codec")(f).read()) tx = Tx.parse(f) txs.append(tx) try: tx.parse_unspents(f) except Exception as ex: pass continue except Exception as ex: print('could not parse %s %s' % (item, ex), file=sys.stderr) pass if tx is None and key is None: print('could not understand item %s' % (item, )) account = MultisigAccount(keys, complete=False) oracle = Oracle(account, tx_db=get_tx_db(), base_url=args.baseurl) oracle.verbose = args.verbose if args.command == 'dump': sub_keys = [ key.subkey_for_path(path or "") for key, path in izip_longest(keys, args.inputpath) ] for key in sub_keys: print(key.wallet_key(as_private=False)) elif args.command == 'create': calls = [] if args.email: calls.append('email') if args.phone: calls.append('phone') parameters = { "levels": [{ "asset": "BTC", "period": 60, "value": 0.001 }, { "delay": 0, "calls": calls }] } oracle.create(parameters, email=args.email, phone=args.phone) elif args.command == 'address': oracle.get() path = args.inputpath[0] if args.inputpath else "" payto = account.payto_for_path(path) if args.verbose > 0: sub_keys = [key.subkey_for_path(path) for key in account.keys] print("* account keys") print(account.keys) print("* child keys") for key in sub_keys: print(key.wallet_key(as_private=False)) print("* address") print(payto.address(netcode=args.network)) elif args.command == 'sign': oracle.get() scripts = [account.script_for_path(path) for path in args.inputpath] change_paths = [ None if path == '-' else path for path in (args.changepath or []) ] for tx in txs: print(tx.id()) print(b2h(stream_to_bytes(tx.stream))) sub_keys = [ keys[0].subkey_for_path(path) for path in args.inputpath ] # sign locally local_sign(tx, scripts, sub_keys) # have Oracle sign result = oracle.sign_with_paths(tx, args.inputpath, change_paths, spend_id=args.spendid) print("Result:") print(result) if 'transaction' in result: print("Hex serialized transaction:") print(b2h(stream_to_bytes(result['transaction'].stream))) else: print('unknown command %s' % (args.command, ), file=sys.stderr)
def main(): parser = argparse.ArgumentParser( description="DigitalOracle HD multisig command line utility", formatter_class=argparse.RawDescriptionHelpFormatter, ) parser.add_argument("-e", "--email", help="e-mail for create") parser.add_argument("-p", "--phone", help="phone number for create - in the format +14155551212") parser.add_argument("-n", "--network", default="BTC", choices=NETWORK_NAMES) parser.add_argument("-i", "--inputpath", nargs="+", help="HD subkey path for each input (example: 0/2/15)") parser.add_argument( "-c", "--changepath", nargs="+", help="HD subkey path for each change output (example: 0/2/15) or a dash for non-change outputs", ) parser.add_argument("-s", "--spendid", help="an additional hex string to disambiguate spends to the same address") parser.add_argument( "-u", "--baseurl", help="the API endpoint, defaults to the sandbox - https://s.digitaloracle.co/" ) parser.add_argument( "-v", "--verbose", default=0, action="count", help="Verbosity, use more -v flags for more verbosity" ) parser.add_argument("command", help="""a command""") parser.add_argument("item", nargs="+", help="""a key""") parser.epilog = textwrap.dedent( """ Items: * P:wallet_passphrase - a secret for deriving an HD hierarchy with private keys * xpub - an account extended public key for deriving an HD hierarchy with public keys only * FILE.bin - unsigned transaction binary * FILE.hex - unsigned transaction hex Commands: * dump - dump the public subkeys * create - create Oracle account based on the supplied leading key with with any additional keys * address - get the deposit address for a subkey path * sign - sign a transaction, tx.bin or tx.hex must be supplied. Only one subkey path is supported. Notes: * --subkey is applicable for the address and sign actions, but not the create action """ ) args = parser.parse_args() keys = [] txs = [] for item in args.item: key = None tx = None if item.startswith("P:"): s = item[2:] key = BIP32Node.from_master_secret(s.encode("utf8"), netcode=args.network) keys.append(key) else: try: key = Key.from_text(item) keys.append(key) except encoding.EncodingError: pass if key is None: if os.path.exists(item): try: with open(item, "rb") as f: if f.name.endswith("hex"): f = io.BytesIO(codecs.getreader("hex_codec")(f).read()) tx = Tx.parse(f) txs.append(tx) try: tx.parse_unspents(f) except Exception as ex: pass continue except Exception as ex: print("could not parse %s %s" % (item, ex), file=sys.stderr) pass if tx is None and key is None: print("could not understand item %s" % (item,)) account = MultisigAccount(keys, complete=False) oracle = Oracle(account, tx_db=get_tx_db(), base_url=args.baseurl) oracle.verbose = args.verbose if args.command == "dump": sub_keys = [key.subkey_for_path(path or "") for key, path in izip_longest(keys, args.inputpath)] for key in sub_keys: print(key.wallet_key(as_private=False)) elif args.command == "create": calls = [] if args.email: calls.append("email") if args.phone: calls.append("phone") parameters = {"levels": [{"asset": "BTC", "period": 60, "value": 0.001}, {"delay": 0, "calls": calls}]} oracle.create(parameters, email=args.email, phone=args.phone) elif args.command == "address": oracle.get() path = args.inputpath[0] if args.inputpath else "" payto = account.payto_for_path(path) if args.verbose > 0: sub_keys = [key.subkey_for_path(path) for key in account.keys] print("* account keys") print(account.keys) print("* child keys") for key in sub_keys: print(key.wallet_key(as_private=False)) print("* address") print(payto.address(netcode=args.network)) elif args.command == "sign": oracle.get() scripts = [account.script_for_path(path) for path in args.inputpath] change_paths = [None if path == "-" else path for path in (args.changepath or [])] for tx in txs: print(tx.id()) print(b2h(stream_to_bytes(tx.stream))) sub_keys = [keys[0].subkey_for_path(path) for path in args.inputpath] # sign locally local_sign(tx, scripts, sub_keys) # have Oracle sign result = oracle.sign_with_paths(tx, args.inputpath, change_paths, spend_id=args.spendid) print("Result:") print(result) if "transaction" in result: print("Hex serialized transaction:") print(b2h(stream_to_bytes(result["transaction"].stream))) else: print("unknown command %s" % (args.command,), file=sys.stderr)