docs: def btc_tx_sign(tx_hex, idx, prevout_script, prevout_amount, private_key_info, scriptsig_type, hashcode=SIGHASH_ALL, hashcodes=None, redeem_script=None, witness_script=None):
      """
      Insert a scriptsig for an input that will later be spent by a p2pkh, p2pk, or p2sh scriptPubkey.
  
      @private_key_info is either a single private key, or a dict with 'redeem_script' and 'private_keys' defined.
  
      @redeem_script, if given, must NOT start with the varint encoding its length.
      However, it must otherwise be a hex string
  
      Return the transaction with the @idx'th scriptSig filled in.
      """
      new_tx = None
      
      # print 'sign input {} as {}'.format(idx, scriptsig_type)
  
      if scriptsig_type in ['p2pkh', 'p2pk']:
          if not btc_is_singlesig(private_key_info):
              raise ValueError('Need only one private key for {}'.format(scriptsig_type))
  
          pk = ecdsalib.ecdsa_private_key(str(private_key_info))
          pubk = pk.public_key()
          pub = pubk.to_hex()
  
          sig = btc_tx_make_input_signature(tx_hex, idx, prevout_script, private_key_info, hashcode)
  
          # print 'non-segwit sig: {}'.format(sig)
          # print 'non-segwit pubk: {}'.format(pub)
  
          # NOTE: sig and pub need to be hex-encoded
          txobj = btc_tx_deserialize(str(tx_hex))
  
          if scriptsig_type == 'p2pkh':
              # scriptSig + scriptPubkey is <signature> <pubkey> OP_DUP OP_HASH160 <pubkeyhash> OP_EQUALVERIFY OP_CHECKSIG
              txobj['ins'][idx]['script'] = btc_script_serialize([sig, pub])
  
          else:
              # p2pk
              # scriptSig + scriptPubkey is <signature> <pubkey> OP_CHECKSIG
              txobj['ins'][idx]['script'] = btc_script_serialize([sig])
  
          new_tx = btc_tx_serialize(txobj)
  
      elif scriptsig_type == 'p2wpkh' or scriptsig_type == 'p2sh-p2wpkh':
          # must be a segwit singlesig bundle
          if not btc_is_singlesig_segwit(private_key_info):
              raise ValueError('Keys are not for p2wpkh or p2sh-p2wpkh')
  
          privkey_str = str(btc_get_singlesig_privkey(private_key_info))
          pk = ecdsalib.ecdsa_private_key(privkey_str)
          pubk = pk.public_key()
          pub = keylib.key_formatting.compress(pubk.to_hex())
  
          # special bip141 rule: this is always 0x1976a914{20-byte-pubkey-hash}88ac
          prevout_script_sighash = '76a914' + hashing.bin_hash160(pub.decode('hex')).encode('hex') + '88ac'
  
          sig = btc_tx_make_input_signature_segwit(tx_hex, idx, prevout_amount, prevout_script_sighash, privkey_str, hashcode)
  
          txobj = btc_tx_deserialize(str(tx_hex))
          txobj['ins'][idx]['witness_script'] = btc_witness_script_serialize([sig, pub])
  
          if scriptsig_type == 'p2wpkh':
              # native
              # NOTE: sig and pub need to be hex-encoded
              txobj['ins'][idx]['script'] = ''
  
              if redeem_script:
                  # goes in scriptSig 
                  txobj['ins'][idx]['script'] = btc_script_serialize([redeem_script])
  
          else:
              # p2sh-p2wpkh
              redeem_script = btc_make_p2sh_p2wpkh_redeem_script(pub)
              txobj['ins'][idx]['script'] = redeem_script
  
              # print 'scriptsig {} from {} is {}'.format(pub, privkey_str, txobj['ins'][idx]['script'])
  
          new_tx = btc_tx_serialize(txobj)
  
          # print 'scriptsig type: {}'.format(scriptsig_type)
          # print 'segwit scriptsig: {}'.format(txobj['ins'][idx]['script'])
          # print 'segwit witness script: {}'.format(txobj['ins'][idx]['witness_script'])
  
      elif scriptsig_type == 'p2wsh' or scriptsig_type == 'p2sh-p2wsh':
          # only support p2wsh for multisig purposes at this time
          if not btc_is_multisig_segwit(private_key_info):
              raise ValueError('p2wsh requires a multisig key bundle')
  
          native = None
          if scriptsig_type == 'p2wsh':
              native = True
          else:
              native = False
  
          new_tx = btc_tx_sign_multisig_segwit(tx_hex, idx, prevout_amount, private_key_info['redeem_script'], private_key_info['private_keys'], hashcode=hashcode, hashcodes=hashcodes, native=native)
         
          txobj = btc_tx_deserialize(new_tx)
  
          # print 'segwit scriptsig: {}'.format(txobj['ins'][idx]['script'])
          # print 'segwit witness script: {}'.format(txobj['ins'][idx]['witness_script'])
  
      elif scriptsig_type == 'p2sh':
      
          if not redeem_script:
              # p2sh multisig
              if not btc_is_multisig(private_key_info):
                  raise ValueError('No redeem script given, and not a multisig key bundle')
  
              new_tx = btc_tx_sign_multisig(tx_hex, idx, private_key_info['redeem_script'], private_key_info['private_keys'], hashcode=hashcode)
  
          else:
              # NOTE: sig and pub need to be hex-encoded
              txobj = btc_tx_deserialize(str(tx_hex))
  
              # scriptSig + scriptPubkey is <redeem script> OP_HASH160 <script hash> OP_EQUAL
              txobj['ins'][idx]['script'] = btc_script_serialize([redeem_script]) 
              new_tx = btc_tx_serialize(txobj)
  
      else:
          raise ValueError("Unknown script type {}".format(scriptsig_type))
  
      return new_tx