# Path: jmbase/jmbase/support.py
# def jmprint(msg, level="info"):
#     """ Provides the ability to print messages
#     with consistent formatting, outside the logging system
#     (in case you don't want the standard log format).
#     Example applications are: REPL style stuff, and/or
#     some very important / user workflow affecting communication.
#     Note that this exclusively for console printout, NOT for
#     logging to file (chromalog will handle file streams
#     properly, but this will not).
#     """
#     if not level in jm_color_map.keys():
#         raise Exception("Unsupported formatting")
# 
#     if sys.stdout.isatty():
#         # .colorize_message function does a .format() on the string,
#         # which does not work with string-ified json; this should
#         # result in output as intended:
#         msg = msg.replace('{', '{{')
#         msg = msg.replace('}', '}}')
# 
#     fmtfn = eval(level)
#     fmtd_msg = fmtfn(msg)
#     if sys.stdout.isatty():
#         print(jm_colorizer.colorize_message(fmtd_msg))
#     else:
#         print(fmtd_msg)
# 
# 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]))
# 
# EXIT_SUCCESS = 0
# 
# Path: jmbase/jmbase/twisted_utils.py
# def stop_reactor():
#     if not _custom_stop_reactor_is_set:
#         _stop_reactor()
#     else:
#         custom_stop_reactor()


import collections
import time
import sys
import jmbitcoin as btc
from decimal import Decimal
from copy import deepcopy
from twisted.internet import reactor
from twisted.internet import task
from twisted.application.service import Service
from numbers import Integral
from jmclient.configure import jm_single, get_log
from jmclient.output import fmt_tx_data
from jmclient.blockchaininterface import (INF_HEIGHT, BitcoinCoreInterface,
    BitcoinCoreNoHistoryInterface)
from jmclient.wallet import FidelityBondMixin, BaseWallet
from jmbase import (stop_reactor, hextobin, utxo_to_utxostr,
                    jmprint, EXIT_SUCCESS)
        self.callbacks["unconfirmed"] = {}
        self.callbacks["confirmed"] = {}

        self.restart_callback = None

        # transactions we are actively monitoring,
        # i.e. they are not new but we want to track:
        self.active_txids = []
        # to ensure transactions are only processed once:
        self.processed_txids = []

        self.set_autofreeze_warning_cb()

    def update_blockheight(self):
        """ Can be called manually (on startup, or for tests)
        but will be called as part of main monitoring
        loop to ensure new transactions are added at
        the right height.
        Any failure of the RPC call must result in this returning
        False, otherwise return True (means self.current_blockheight
        has been correctly updated).
        """

        def critical_error():
            jlog.error("Critical error updating blockheight.")
            # this cleanup (a) closes the wallet, removing the lock
            # and (b) signals to clients that the service is no longer
            # in a running state, both of which can be useful
            # post reactor shutdown.
            self.stopService()

# Path: jmbase/jmbase/support.py
# def jmprint(msg, level="info"):
#     """ Provides the ability to print messages
#     with consistent formatting, outside the logging system
#     (in case you don't want the standard log format).
#     Example applications are: REPL style stuff, and/or
#     some very important / user workflow affecting communication.
#     Note that this exclusively for console printout, NOT for
#     logging to file (chromalog will handle file streams
#     properly, but this will not).
#     """
#     if not level in jm_color_map.keys():
#         raise Exception("Unsupported formatting")
# 
#     if sys.stdout.isatty():
#         # .colorize_message function does a .format() on the string,
#         # which does not work with string-ified json; this should
#         # result in output as intended:
#         msg = msg.replace('{', '{{')
#         msg = msg.replace('}', '}}')
# 
#     fmtfn = eval(level)
#     fmtd_msg = fmtfn(msg)
#     if sys.stdout.isatty():
#         print(jm_colorizer.colorize_message(fmtd_msg))
#     else:
#         print(fmtd_msg)
# 
# 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]))
# 
# EXIT_SUCCESS = 0
# 
# Path: jmbase/jmbase/twisted_utils.py
# def stop_reactor():
#     if not _custom_stop_reactor_is_set:
#         _stop_reactor()
#     else:
#         custom_stop_reactor()


# Path: jmclient/jmclient/wallet_service.py
import collections
import time
import sys
import jmbitcoin as btc
from decimal import Decimal
from copy import deepcopy
from twisted.internet import reactor
from twisted.internet import task
from twisted.application.service import Service
from numbers import Integral
from jmclient.configure import jm_single, get_log
from jmclient.output import fmt_tx_data
from jmclient.blockchaininterface import (INF_HEIGHT, BitcoinCoreInterface,
    BitcoinCoreNoHistoryInterface)
from jmclient.wallet import FidelityBondMixin, BaseWallet
from jmbase import (stop_reactor, hextobin, utxo_to_utxostr,
                    jmprint, EXIT_SUCCESS)

        self.callbacks["unconfirmed"] = {}
        self.callbacks["confirmed"] = {}

        self.restart_callback = None

        # transactions we are actively monitoring,
        # i.e. they are not new but we want to track:
        self.active_txids = []
        # to ensure transactions are only processed once:
        self.processed_txids = []

        self.set_autofreeze_warning_cb()

    def update_blockheight(self):
        """ Can be called manually (on startup, or for tests)
        but will be called as part of main monitoring
        loop to ensure new transactions are added at
        the right height.
        Any failure of the RPC call must result in this returning
        False, otherwise return True (means self.current_blockheight
        has been correctly updated).
        """

        def critical_error():
            jlog.error("Critical error updating blockheight.")
            # this cleanup (a) closes the wallet, removing the lock
            # and (b) signals to clients that the service is no longer
            # in a running state, both of which can be useful
            # post reactor shutdown.
            self.stopService()

            stop_reactor()