# Path: jmbase/jmbase/support.py
# def hextobin(h):
#     """Convert a hex string to bytes"""
#     return binascii.unhexlify(h.encode('utf8'))


import abc
import base64
import threading
from twisted.internet import reactor
from jmdaemon import encrypt_encode, decode_decrypt, COMMAND_PREFIX,\
    NICK_HASH_LENGTH, NICK_MAX_ENCODED, plaintext_commands,\
    encrypted_commands, commitment_broadcast_list, offername_list,\
    fidelity_bond_cmd_list
from jmbase.support import get_log
from jmbase import hextobin
from functools import wraps

    def get_encryption_box(self, cmd, nick):
        """Establish whether the message is to be
        encrypted/decrypted based on the command string.
        If so, retrieve the appropriate crypto_box object
        and return. """
        if cmd in plaintext_commands:
            return None, False
        else:
            return self.daemon.get_crypto_box_from_nick(nick), True

    @check_privmsg
    def prepare_privmsg(self, nick, cmd, message, mc=None):
        # should we encrypt?
        box, encrypt = self.get_encryption_box(cmd, nick)
        if encrypt:
            if not box:
                log.debug('error, dont have encryption box object for ' + nick +
                          ', dropping message')
                return
            message = encrypt_encode(message.encode('ascii'), box)

        #Anti-replay measure: append the message channel identifier
        #to the signature; this prevents cross-channel replay but NOT
        #same-channel replay (in case of snooper after dropped connection
        #on this channel).
        if mc is None:
            if nick in self.active_channels:
                hostid = self.active_channels[nick].hostid
            else:

# Path: jmbase/jmbase/support.py
# def hextobin(h):
#     """Convert a hex string to bytes"""
#     return binascii.unhexlify(h.encode('utf8'))


# Path: jmdaemon/jmdaemon/message_channel.py
import abc
import base64
import threading
from twisted.internet import reactor
from jmdaemon import encrypt_encode, decode_decrypt, COMMAND_PREFIX,\
    NICK_HASH_LENGTH, NICK_MAX_ENCODED, plaintext_commands,\
    encrypted_commands, commitment_broadcast_list, offername_list,\
    fidelity_bond_cmd_list
from jmbase.support import get_log
from jmbase import hextobin
from functools import wraps


    def get_encryption_box(self, cmd, nick):
        """Establish whether the message is to be
        encrypted/decrypted based on the command string.
        If so, retrieve the appropriate crypto_box object
        and return. """
        if cmd in plaintext_commands:
            return None, False
        else:
            return self.daemon.get_crypto_box_from_nick(nick), True

    @check_privmsg
    def prepare_privmsg(self, nick, cmd, message, mc=None):
        # should we encrypt?
        box, encrypt = self.get_encryption_box(cmd, nick)
        if encrypt:
            if not box:
                log.debug('error, dont have encryption box object for ' + nick +
                          ', dropping message')
                return
            message = encrypt_encode(message.encode('ascii'), box)

        #Anti-replay measure: append the message channel identifier
        #to the signature; this prevents cross-channel replay but NOT
        #same-channel replay (in case of snooper after dropped connection
        #on this channel).
        if mc is None:
            if nick in self.active_channels:
                hostid = self.active_channels[nick].hostid
            else:

                log.info("Failed to send message to: " + str(nick) + \