def main(): """This module signs the downloaded JSON files from Coinkite's co-signing page.""" if len(sys.argv) < 2: print "Usage: python signTxCoinkiteJSON.py <JSON path>" exit(1) # Get path from cli inputPath = sys.argv[1] f = open(sys.argv[1], 'r') signData = json.load(f) requestData = json.loads(signData['contents']) # Get Dongle dongle = getDongle(False) # Bool is debug mode app = btchip(dongle) # Authenticate with dongle pin = getpass.getpass("PIN: ") app.verifyPin(pin) result = signCoinkiteJSON(app, dongle, requestData) body = createReturnJSON(app, dongle, result) fName = 'output-' + requestData['request'] + '-' + requestData['cosigner'] + '.json' fOut = open(fName, 'w') fOut.write(json.dumps(body)) fOut.close() print "Output written to " + fName
def get_ledger_wallet(): app = False try: dongle = getDongle(False) app = btchip(dongle) except Exception: app = False return app
def main(coinkite_ref, user_refnum, api_key, api_secret): """Co-sign transactions using the Coinkite API. It lists pending transactions, prompts for an ID to sign, displays the tx details and signs. It requires an API key with the 'co-sign' permission. """ if not len(api_key) or not len(api_secret): print "ERROR: Specify a COINKITE_API_KEY and COINKITE_API_SECRET in settings.py or via flags." exit(1) print "This script will sign a multisig transaction using the Coinkite API." print "NOTE: This is a work in progress and may be buggy." # Get Dongle dongle = getDongle(False) # Bool is debug mode app = btchip(dongle) # Authenticate with dongle pin = getpass.getpass("PIN: ") app.verifyPin(pin) # Create a requestor object r = CKRequestor(str(api_key), str(api_secret)) # Get the ref we're signing print "Getting transaction details..." tx = r.get('/v1/detail/' + coinkite_ref) co = r.get('/v1/co-sign/' + coinkite_ref) # print r.get('/v1/list/need_sigs') print txDetails(tx, co, printUserRefs=(not user_refnum)) # FIXME talk to Coinkite, this is sometimes true when it shouldn't be # assertCondition(not tx.detail.is_completed, "This transaction is already complete!") if not user_refnum: user_refnum = raw_input("Your user ref (put this in settings.COINKITE_USER_REF in the future): ") assertCondition(not co.has_signed_already[user_refnum], "This transaction has already been signed by this user!") # signing time signTX = r.get('/v1/co-sign/' + coinkite_ref + '/' + user_refnum) result = signCoinkiteJSON(app, dongle, signTX.signing_info) putResult = r.put('/v1/co-sign/' + coinkite_ref + '/' + user_refnum + '/sign', \ _data={'signatures': result['signatures']}) print "Result: %s" % (putResult.message)
def waitDongle(currentDialog, persoData): try: if persoData['client'] <> None: try: persoData['client'].dongle.close() except: pass dongle = getDongle(True) persoData['client'] = btchip(dongle) persoData['client'].getFirmwareVersion()['version'].split(".") return True except BTChipException,e: if e.sw == 0x6faa: QMessageBox.information(currentDialog, "BTChip Setup", "Please unplug the dongle and plug it again", "OK") return False if QMessageBox.question(currentDialog, "BTChip setup", "BTChip dongle not found. It might be in the wrong mode. Try unplugging und plugging it back in again, then press 'OK'", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) == QMessageBox.Yes: return False else: raise Exception("Aborted by user")
def main(): if len(sys.argv) < 2: print "Usage: python getKey.py <path>" exit(1) # Get path from cli inputPath = sys.argv[1] parsedPath = parsePath(inputPath) # Optional setup dongle = getDongle(False) app = btchip(dongle) # Authenticate pin = getpass.getpass("PIN: ") app.verifyPin(pin) printPath(app, parsedPath)
def setup(seed, testnet=False): network = "Testnet" if testnet else "Mainnet" print "Chip will be used on network: " + network pin = getpass.getpass("New PIN: ") dongle = getDongle(False) app = btchip(dongle) try: if testnet: app.setup(btchip.OPERATION_MODE_RELAXED_WALLET, btchip.FEATURE_RFC6979|btchip.FEATURE_NO_2FA_P2SH, 111, 196, pin, None, btchip.QWERTY_KEYMAP, seed) else: app.setup(btchip.OPERATION_MODE_RELAXED_WALLET, btchip.FEATURE_RFC6979|btchip.FEATURE_NO_2FA_P2SH, 0, 5, pin, None, btchip.QWERTY_KEYMAP, seed) except BTChipException as e: if e.sw == 0x6985: print "ERROR: Chip is already set up. If you want to set it up with a new seed, run resetChip.py first." exit(1) # Authenticate to stop key from emitting the seed anymore app.verifyPin(pin)
def main(): if len(sys.argv) < 2: print "Usage: python signBitID.py <path>" exit(1) path = parsePath(sys.argv[1]) # magic hack to turn off 2FA path = re.sub(r'(\d+)(\')?$', "\g<1>" + str(0xb11e) + "\g<2>", path) dongle = getDongle(False) app = btchip(dongle) # Authenticate pin = getpass.getpass("PIN: ") app.verifyPin(pin) challenge = raw_input("Copy/Paste your challenge: ") publicKey = app.getWalletPublicKey(path) print "Address: " + str(publicKey['address']) print "Signed message: " + signMessage(app, dongle, path, challenge, use2FA=False)
REDEEMSCRIPT = bytearray("52210269694830114e4b1f6ef565ce4efb933681032d30333c80df713df6b60a4c62832102f43b905e9e35ccd22757faedf9eceb652dc9ba198a3904d43f4298def0213eb521037b9e3578dd3b5559d613bc2641931e6ce7d55a9d081b07347888d7d17a2b910253ae".decode('hex')) SIGNATURE_0 = bytearray("3044022056cb1b781fd04cfe6c04756ad56d02e5512f3fe7f411bc22d1594da5c815a393022074ad7f4d47af7c3f8a7ddf0ba2903f986a88649b0018ce1538c379b304a6a23801".decode('hex')) SIGNATURE_1 = bytearray("304402205545419c4aded39c7f194b3f8c828f90e8d9352c756f7c131ed50e189c02f29a02201b160503d7310df49055b04a327e185fc22dfe68f433594ed7ce526d99a5026001".decode('hex')) SIGNATURE_2 = bytearray("30440220634fbbfaaea74d42280a8c9e56c97418af04539f93458e85285d15462aec7712022041ba27a5644642a2f5b3c02610235ec2c6115bf4137bb51181cbc0a3a54dc0db01".decode('hex')) # Armory supporttx TRANSACTION = bytearray("0100000001008338137ef80601faf283aa896bfd80ebb842e290122253cada1afcb876160c00000000fc004730440220634fbbfaaea74d42280a8c9e56c97418af04539f93458e85285d15462aec7712022041ba27a5644642a2f5b3c02610235ec2c6115bf4137bb51181cbc0a3a54dc0db0147304402205545419c4aded39c7f194b3f8c828f90e8d9352c756f7c131ed50e189c02f29a02201b160503d7310df49055b04a327e185fc22dfe68f433594ed7ce526d99a50260014c6952210269694830114e4b1f6ef565ce4efb933681032d30333c80df713df6b60a4c62832102f43b905e9e35ccd22757faedf9eceb652dc9ba198a3904d43f4298def0213eb521037b9e3578dd3b5559d613bc2641931e6ce7d55a9d081b07347888d7d17a2b910253aeffffffff02809698000000000017a914c0c3b6ada732c797881d00de6c350eec96e3d22287f02925020000000017a914e2a227eb40dfce902f2c1d80ddafa798b16d22c38700000000".decode('hex')) # Armory txoutscript output = get_output_script([["0.1", bytearray("a914c0c3b6ada732c797881d00de6c350eec96e3d22287".decode('hex'))], ["0.3599", bytearray("a914e2a227eb40dfce902f2c1d80ddafa798b16d22c387".decode('hex'))]]); if output<>OUTPUT: raise BTChipException("Invalid output script encoding"); # Optional setup dongle = getDongle(True) app = btchip(dongle) try: app.setup(btchip.OPERATION_MODE_RELAXED_WALLET, btchip.FEATURE_RFC6979|btchip.FEATURE_NO_2FA_P2SH, 111, 196, "1234", None, btchip.QWERTY_KEYMAP, SEED) except: pass # Authenticate app.verifyPin("1234") # Get the trusted input associated to the UTXO transaction = bitcoinTransaction(UTX) print transaction trustedInput = app.getTrustedInput(transaction, UTXO_INDEX) # Start composing the transaction app.startUntrustedTransaction(True, 0, [trustedInput], REDEEMSCRIPT) app.finalizeInputFull(OUTPUT) signature1 = app.untrustedHashSign("0'/0/1", "") if signature1 <> SIGNATURE_1:
return value, value_size def extract_pkh_from_locking_script(script): if len(script) == 25: if script[0:1] == OP_DUP and script[1:2] == OP_HASH160: if read_varint(script, 2)[0] == 20: return script[3:23] else: raise Exception( 'Non-standard public key hash length (should be 20)') raise Exception('Non-standard locking script type (should be P2PKH)') dongle = getDongle(False) app = btchip(dongle) # Each of the UTXOs (utxos_to_send list) will become an input in the new transaction. # For each of those inputs, create a Ledger's 'trusted input', that will be used by the device to sign a transaction trusted_inputs = [] # arg_inputs: list of dicts # { # 'locking_script': <Locking script of the UTXO used as an input. Used in the process of signing # transaction.>, # 'outputIndex': <index of the UTXO within the previus transaction>, # 'txid': <hash of the previus transaction>, # 'bip32_path': <BIP32 path of the HW key controlling UTXO's destination>, # 'pubkey': <Public key obtained from the HW using the bip32_path.> # 'signature' <Signature obtained as a result of processing the input. It will be used as a part of the # unlocking script.>
def check_hw_wallet(): printdbg('checking hw wallet') #client = None client = None signing = False if TYPE_HW_WALLET.lower().startswith("keepkey"): from keepkeylib.client import KeepKeyClient from keepkeylib.transport_hid import HidTransport import keepkeylib.ckd_public as bip32 try: devices = HidTransport.enumerate() except Exception as e: err_msg = str(e.args) print_err_exit(get_caller_name(), get_function_name(), err_msg) if len(devices) == 0: print('===> No HW Wallet found') signing = False else: try: print('===> keepkey HW Wallet found') transport = HidTransport(devices[0]) client = KeepKeyClient(transport) signing = True except Exception as e: err_msg = str(e.args) print_err_exit(get_caller_name(), get_function_name(), err_msg) elif TYPE_HW_WALLET.lower().startswith("trezor"): from trezorlib.client import TrezorClient from trezorlib.transport_hid import HidTransport import trezorlib.ckd_public as bip32 try: devices = HidTransport.enumerate() except Exception as e: err_msg = str(e.args) print_err_exit(get_caller_name(), get_function_name(), err_msg) if len(devices) == 0: print('===> No HW Wallet found') signing = False else: try: print('===> trezor HW Wallet found') transport = HidTransport(devices[0]) client = TrezorClient(transport) signing = True except Exception as e: err_msg = str(e.args) print_err_exit(get_caller_name(), get_function_name(), err_msg) elif TYPE_HW_WALLET.lower().startswith("ledgernanos"): #from btchip.btchip import * #from btchip.btchipUtils import * try: devices = getDongle(False) except Exception as e: err_msg = str(e.args) print_err_exit(get_caller_name(), get_function_name(), err_msg) if not devices: print('===> No HW Wallet found') signing = False else: try: print('===> Ledger nano s HW Wallet found') client = btchip(devices) signing = True except Exception as e: err_msg = str(e.args) print_err_exit(get_caller_name(), get_function_name(), err_msg) if client is not None: if TYPE_HW_WALLET.lower().startswith("ledgernanos"): pass else: try: wallet_supported_coins = list_coins(client) except Exception as e: err_msg = str(e.args) print_err_exit(get_caller_name(), get_function_name(), err_msg) if coin_name not in wallet_supported_coins: err_msg = 'only following coins supported by wallet\n\t' + \ str(wallet_supported_coins) ''' print_err_exit( get_caller_name(), get_function_name(), err_msg) ''' else: err_msg = "Can't run dashmnb without hw wallet" print_err_exit(get_caller_name(), get_function_name(), err_msg) if TYPE_HW_WALLET.lower().startswith("ledgernanos"): mpath = get_mpath() return client, signing, mpath else: try: mpath = get_mpath() bip32_path = client.expand_path(mpath) xpub = bip32.serialize( client.get_public_node(bip32_path).node, (0x0488B21E if MAINNET else 0x043587CF)) except AssertionError as e: err_msg = str(e.args) print_err_exit(get_caller_name(), get_function_name(), err_msg) except Exception as e: err_msg = str(e.args) print_err_exit(get_caller_name(), get_function_name(), err_msg) except KeyboardInterrupt: print_err_exit(get_caller_name(), get_function_name(), "KeyboardInterrupt") printdbg('check_hw_wallet : signing : %s' % signing) printdbg('check_hw_wallet : xpub[:7] : %s' % xpub[:7]) printdbg('check_hw_wallet : xpub[-7:] : %s' % xpub[-7:]) printdbg('check_hw_wallet : mpath : %s' % mpath) return client, signing, bip32, mpath, xpub