# Path: jmbase/jmbase/support.py
# def get_log():
#     """
#     provides joinmarket logging instance
#     :return: log instance
#     """
#     return log
# 
# def bintohex(b):
#     """Convert bytes to a hex string"""
#     return binascii.hexlify(b).decode('utf8')
# 
# def hextobin(h):
#     """Convert a hex string to bytes"""
#     return binascii.unhexlify(h.encode('utf8'))
# 
# def utxo_to_utxostr(u):
#     if not isinstance(u, tuple):
#         return (False, "utxo is not a tuple.")
#     if not len(u) == 2:
#         return (False, "utxo should have two elements.")
#     if not isinstance(u[0], bytes):
#         return (False, "txid should be bytes.")
#     if not isinstance(u[1], int):
#         return (False, "index should be int.")
#     if u[1] < 0:
#         return (False, "index must be a positive integer.")
#     if not len(u[0]) == 32:
#         return (False, "txid must be 32 bytes.")
#     txid = binascii.hexlify(u[0]).decode("ascii")
#     return (True, txid + ":" + str(u[1]))


import os
import jmbitcoin as btc
from twisted.application.service import Service
from twisted.internet import task
from jmclient.configure import jm_single
from jmbase import (get_log, utxo_to_utxostr,
                    hextobin, bintohex)
                    source_mixdepth = self.wallet_service.get_details(
                        source_path)[0]
                    if not tweaked_spk == out_spk:
                        jlog.error("The spk derived from the pubkey does "
                                   "not match the scriptPubkey returned from "
                                   "the snicker module - code error.")
                        return False
                    # before import, we should derive the tweaked *private* key
                    # from the tweak, also; failure of this critical sanity check
                    # is a code error. If the recreated private key matches, we
                    # import to the wallet. Note that this happens *before* pushing
                    # the coinjoin transaction to the network, which is advisably
                    # conservative (never possible to have broadcast a tx without
                    # having already stored the output's key).
                    success, msg = self.wallet_service.check_tweak_matches_and_import(
                        addr, tweak, tweaked_key, source_mixdepth)
                    if not success:
                        jlog.error(msg)
                        return False

                    # TODO condition on automatic brdcst or not
                    if not jm_single().bc_interface.pushtx(tx.serialize()):
                        # this represents an error about state (or conceivably,
                        # an ultra-short window in which the spent utxo was
                        # consumed in another transaction), but not really
                        # an internal logic error, so we do NOT return False
                        jlog.error("Failed to broadcast SNICKER coinjoin: " +\
                                   bintohex(tx.GetTxid()[::-1]))
                        jlog.info(btc.human_readable_transaction(tx))
                    jlog.info("Successfully broadcast SNICKER coinjoin: " +\

# Path: jmbase/jmbase/support.py
# def get_log():
#     """
#     provides joinmarket logging instance
#     :return: log instance
#     """
#     return log
# 
# def bintohex(b):
#     """Convert bytes to a hex string"""
#     return binascii.hexlify(b).decode('utf8')
# 
# def hextobin(h):
#     """Convert a hex string to bytes"""
#     return binascii.unhexlify(h.encode('utf8'))
# 
# def utxo_to_utxostr(u):
#     if not isinstance(u, tuple):
#         return (False, "utxo is not a tuple.")
#     if not len(u) == 2:
#         return (False, "utxo should have two elements.")
#     if not isinstance(u[0], bytes):
#         return (False, "txid should be bytes.")
#     if not isinstance(u[1], int):
#         return (False, "index should be int.")
#     if u[1] < 0:
#         return (False, "index must be a positive integer.")
#     if not len(u[0]) == 32:
#         return (False, "txid must be 32 bytes.")
#     txid = binascii.hexlify(u[0]).decode("ascii")
#     return (True, txid + ":" + str(u[1]))


# Path: jmclient/jmclient/snicker_receiver.py
import os
import jmbitcoin as btc
from twisted.application.service import Service
from twisted.internet import task
from jmclient.configure import jm_single
from jmbase import (get_log, utxo_to_utxostr,
                    hextobin, bintohex)

                    source_mixdepth = self.wallet_service.get_details(
                        source_path)[0]
                    if not tweaked_spk == out_spk:
                        jlog.error("The spk derived from the pubkey does "
                                   "not match the scriptPubkey returned from "
                                   "the snicker module - code error.")
                        return False
                    # before import, we should derive the tweaked *private* key
                    # from the tweak, also; failure of this critical sanity check
                    # is a code error. If the recreated private key matches, we
                    # import to the wallet. Note that this happens *before* pushing
                    # the coinjoin transaction to the network, which is advisably
                    # conservative (never possible to have broadcast a tx without
                    # having already stored the output's key).
                    success, msg = self.wallet_service.check_tweak_matches_and_import(
                        addr, tweak, tweaked_key, source_mixdepth)
                    if not success:
                        jlog.error(msg)
                        return False

                    # TODO condition on automatic brdcst or not
                    if not jm_single().bc_interface.pushtx(tx.serialize()):
                        # this represents an error about state (or conceivably,
                        # an ultra-short window in which the spent utxo was
                        # consumed in another transaction), but not really
                        # an internal logic error, so we do NOT return False
                        jlog.error("Failed to broadcast SNICKER coinjoin: " +\
                                   bintohex(tx.GetTxid()[::-1]))
                        jlog.info(btc.human_readable_transaction(tx))
                    jlog.info("Successfully broadcast SNICKER coinjoin: " +\

                                  bintohex(tx.GetTxid()[::-1]))