lso_dict = sol.load(lso_file)
    flash_cookies = list()

### This is code adapted from KU Leuven crawler code written by
### Gunes Acar and Marc Juarez
from pyamf import sol
import fnmatch
import os

#TODO: Linux only
FLASH_DIRS = ['~/.macromedia/Flash_Player/#SharedObjects/']

class FlashCookie(object):
    filename = ''
    domain = ''
    local_path = ''
    key = ''
    content = ''

def gen_find_files(filepat, top):
    """
    http://example.com
    returns filenames that matches the given pattern under() a given dir
    """
    for path, _, filelist in os.walk(top):
        for name in fnmatch.filter(filelist, filepat):
            yield os.path.join(path, name)

def get_flash_cookies(mod_since=0):
    """Return a list of Flash cookies (Local Shared Objects)."""
    flash_cookies = list()
    for top_dir in FLASH_DIRS:
        top_dir = os.path.expanduser(top_dir)
        for lso_file in gen_find_files("*.sol", top_dir):
            mtime = os.path.getmtime(lso_file)
            if mtime > mod_since:
                try:
                    flash_cookies.extend(parse_flash_cookies(lso_file))
                except (KeyboardInterrupt, SystemExit):
                    raise
                except Exception as e:
                    print "Exception reading", lso_file
                    print e
                    pass
    return flash_cookies

def parse_flash_cookies(lso_file):

    for k, v in lso_dict.iteritems():
        flash_cookie = FlashCookie()
        flash_cookie.local_path = lso_file.split("#SharedObjects/")[1]
        flash_cookie.filename = os.path.basename(lso_file)
        flash_cookie.domain = lso_file.split("#SharedObjects/")[1].split("/")[1]
        flash_cookie.key = unicode(k)
        try:
            flash_cookie.content = unicode(v)
        except UnicodeDecodeError:
            # obj is byte string
            ascii_text = str(v).encode('string_escape')
            flash_cookie.content = unicode(ascii_text)

        flash_cookies.append(flash_cookie)
    return flash_cookies


for k, v in lso_dict.iteritems():
        flash_cookie = FlashCookie()
        flash_cookie.local_path = lso_file.split("#SharedObjects/")[1]
        flash_cookie.filename = os.path.basename(lso_file)
        flash_cookie.domain = lso_file.split("#SharedObjects/")[1].split("/")[1]
        flash_cookie.key = unicode(k)
        try:
            flash_cookie.content = unicode(v)
        except UnicodeDecodeError:
            # obj is byte string
            ascii_text = str(v).encode('string_escape')
            flash_cookie.content = unicode(ascii_text)

        flash_cookies.append(flash_cookie)

### This is code adapted from KU Leuven crawler code written by
### Gunes Acar and Marc Juarez
from pyamf import sol
import fnmatch
import os

#TODO: Linux only
FLASH_DIRS = ['~/.macromedia/Flash_Player/#SharedObjects/']

class FlashCookie(object):
    filename = ''
    domain = ''
    local_path = ''
    key = ''
    content = ''

def gen_find_files(filepat, top):
    """
    http://example.com
    returns filenames that matches the given pattern under() a given dir
    """
    for path, _, filelist in os.walk(top):
        for name in fnmatch.filter(filelist, filepat):
            yield os.path.join(path, name)

def get_flash_cookies(mod_since=0):
    """Return a list of Flash cookies (Local Shared Objects)."""
    flash_cookies = list()
    for top_dir in FLASH_DIRS:
        top_dir = os.path.expanduser(top_dir)
        for lso_file in gen_find_files("*.sol", top_dir):
            mtime = os.path.getmtime(lso_file)
            if mtime > mod_since:
                try:
                    flash_cookies.extend(parse_flash_cookies(lso_file))
                except (KeyboardInterrupt, SystemExit):
                    raise
                except Exception as e:
                    print "Exception reading", lso_file
                    print e
                    pass
    return flash_cookies

def parse_flash_cookies(lso_file):
    lso_dict = sol.load(lso_file)
    flash_cookies = list()


### This is code adapted from KU Leuven crawler code written by
### Gunes Acar and Marc Juarez
from pyamf import sol
import fnmatch
import os

#TODO: Linux only
FLASH_DIRS = ['~/.macromedia/Flash_Player/#SharedObjects/']

class FlashCookie(object):
    filename = ''
    domain = ''
    local_path = ''
    key = ''
    content = ''

def gen_find_files(filepat, top):
    """
    http://example.com
    returns filenames that matches the given pattern under() a given dir
    """
    for path, _, filelist in os.walk(top):
        for name in fnmatch.filter(filelist, filepat):
            yield os.path.join(path, name)

def get_flash_cookies(mod_since=0):
    """Return a list of Flash cookies (Local Shared Objects)."""
    flash_cookies = list()
    for top_dir in FLASH_DIRS:
        top_dir = os.path.expanduser(top_dir)
        for lso_file in gen_find_files("*.sol", top_dir):
            mtime = os.path.getmtime(lso_file)
            if mtime > mod_since:
                try:
                    flash_cookies.extend(parse_flash_cookies(lso_file))
                except (KeyboardInterrupt, SystemExit):
                    raise
                except Exception as e:
                    print "Exception reading", lso_file
                    print e
                    pass
    return flash_cookies

def parse_flash_cookies(lso_file):
    lso_dict = sol.load(lso_file)
    flash_cookies = list()
    for k, v in lso_dict.iteritems():
        flash_cookie = FlashCookie()
        flash_cookie.local_path = lso_file.split("#SharedObjects/")[1]
        flash_cookie.filename = os.path.basename(lso_file)
        flash_cookie.domain = lso_file.split("#SharedObjects/")[1].split("/")[1]
        flash_cookie.key = unicode(k)
        try:
            flash_cookie.content = unicode(v)
        except UnicodeDecodeError:
            # obj is byte string
            ascii_text = str(v).encode('string_escape')
            flash_cookie.content = unicode(ascii_text)

        flash_cookies.append(flash_cookie)


### This is code adapted from KU Leuven crawler code written by
### Gunes Acar and Marc Juarez
from pyamf import sol
import fnmatch
import os

#TODO: Linux only
FLASH_DIRS = ['~/.macromedia/Flash_Player/#SharedObjects/']

class FlashCookie(object):
    filename = ''
    domain = ''
    local_path = ''
    key = ''
    content = ''

def gen_find_files(filepat, top):
    """
    http://example.com
    returns filenames that matches the given pattern under() a given dir
    """
    for path, _, filelist in os.walk(top):
        for name in fnmatch.filter(filelist, filepat):
            yield os.path.join(path, name)

def get_flash_cookies(mod_since=0):
    """Return a list of Flash cookies (Local Shared Objects)."""
    flash_cookies = list()
    for top_dir in FLASH_DIRS:
        top_dir = os.path.expanduser(top_dir)
        for lso_file in gen_find_files("*.sol", top_dir):
            mtime = os.path.getmtime(lso_file)
            if mtime > mod_since:
                try:
                    flash_cookies.extend(parse_flash_cookies(lso_file))
                except (KeyboardInterrupt, SystemExit):
                    raise
                except Exception as e:
                    print "Exception reading", lso_file
                    print e
                    pass
    return flash_cook

def parse_flash_cookies(lso_file):
    lso_dict = sol.load(lso_file)
    flash_cookies = list()
    for k, v in lso_dict.iteritems():
        flash_cookie = FlashCookie()
        flash_cookie.local_path = lso_file.split("#SharedObjects/")[1]
        flash_cookie.filename = os.path.basename(lso_file)
        flash_cookie.domain = lso_file.split("#SharedObjects/")[1].split("/")[1]
        flash_cookie.key = unicode(k)
        try:
            flash_cookie.content = unicode(v)
        except UnicodeDecodeError:
            # obj is byte string
            ascii_text = str(v).encode('string_escape')
            flash_cookie.content = unicode(ascii_text)

        flash_cookies.append(flash_cookie)
    return flash_cookies


    for path, _, filelist in os.walk(top):
        for name in fnmatch.filter(filelist, filepat):
            yield os.path.join(path, name)

### This is code adapted from KU Leuven crawler code written by
### Gunes Acar and Marc Juarez
from pyamf import sol
import fnmatch
import os

#TODO: Linux only
FLASH_DIRS = ['~/.macromedia/Flash_Player/#SharedObjects/']

class FlashCookie(object):
    filename = ''
    domain = ''
    local_path = ''
    key = ''
    content = ''

def gen_find_files(filepat, top):
    """
    http://example.com
    returns filenames that matches the given pattern under() a given dir
    """

def get_flash_cookies(mod_since=0):
    """Return a list of Flash cookies (Local Shared Objects)."""
    flash_cookies = list()
    for top_dir in FLASH_DIRS:
        top_dir = os.path.expanduser(top_dir)
        for lso_file in gen_find_files("*.sol", top_dir):
            mtime = os.path.getmtime(lso_file)
            if mtime > mod_since:
                try:
                    flash_cookies.extend(parse_flash_cookies(lso_file))
                except (KeyboardInterrupt, SystemExit):
                    raise
                except Exception as e:
                    print "Exception reading", lso_file
                    print e
                    pass
    return flash_cookies

def parse_flash_cookies(lso_file):
    lso_dict = sol.load(lso_file)
    flash_cookies = list()
    for k, v in lso_dict.iteritems():
        flash_cookie = FlashCookie()
        flash_cookie.local_path = lso_file.split("#SharedObjects/")[1]
        flash_cookie.filename = os.path.basename(lso_file)
        flash_cookie.domain = lso_file.split("#SharedObjects/")[1].split("/")[1]
        flash_cookie.key = unicode(k)
        try:
            flash_cookie.content = unicode(v)
        except UnicodeDecodeError:
            # obj is byte string
            ascii_text = str(v).encode('string_escape')
            flash_cookie.content = unicode(ascii_text)

        flash_cookies.append(flash_cookie)
    return flash_cookies


if mtime > mod_since:
                try:
                    flash_cookies.extend(parse_flash_cookies(lso_file))
                except (KeyboardInterrupt, SystemExit):
                    raise
                except Exception as e:
                    print "Exception reading", lso_file
                    print e
                    pass

### This is code adapted from KU Leuven crawler code written by
### Gunes Acar and Marc Juarez
from pyamf import sol
import fnmatch
import os

#TODO: Linux only
FLASH_DIRS = ['~/.macromedia/Flash_Player/#SharedObjects/']

class FlashCookie(object):
    filename = ''
    domain = ''
    local_path = ''
    key = ''
    content = ''

def gen_find_files(filepat, top):
    """
    http://example.com
    returns filenames that matches the given pattern under() a given dir
    """
    for path, _, filelist in os.walk(top):
        for name in fnmatch.filter(filelist, filepat):
            yield os.path.join(path, name)

def get_flash_cookies(mod_since=0):
    """Return a list of Flash cookies (Local Shared Objects)."""
    flash_cookies = list()
    for top_dir in FLASH_DIRS:
        top_dir = os.path.expanduser(top_dir)
        for lso_file in gen_find_files("*.sol", top_dir):
            mtime = os.path.getmtime(lso_file)

    return flash_cookies

def parse_flash_cookies(lso_file):
    lso_dict = sol.load(lso_file)
    flash_cookies = list()
    for k, v in lso_dict.iteritems():
        flash_cookie = FlashCookie()
        flash_cookie.local_path = lso_file.split("#SharedObjects/")[1]
        flash_cookie.filename = os.path.basename(lso_file)
        flash_cookie.domain = lso_file.split("#SharedObjects/")[1].split("/")[1]
        flash_cookie.key = unicode(k)
        try:
            flash_cookie.content = unicode(v)
        except UnicodeDecodeError:
            # obj is byte string
            ascii_text = str(v).encode('string_escape')
            flash_cookie.content = unicode(ascii_text)

        flash_cookies.append(flash_cookie)
    return flash_cookies


for name in fnmatch.filter(filelist, filepat):
            yield os.path.join(path, name)

### This is code adapted from KU Leuven crawler code written by
### Gunes Acar and Marc Juarez
from pyamf import sol
import fnmatch
import os

#TODO: Linux only
FLASH_DIRS = ['~/.macromedia/Flash_Player/#SharedObjects/']

class FlashCookie(object):
    filename = ''
    domain = ''
    local_path = ''
    key = ''
    content = ''

def gen_find_files(filepat, top):
    """
    http://example.com
    returns filenames that matches the given pattern under() a given dir
    """
    for path, _, filelist in os.walk(top):


try:
            flash_cookie.content = unicode(v)
        except UnicodeDecodeError:
            # obj is byte string
            ascii_text = str(v).encode('string_escape')
            flash_cookie.content = unicode(ascii_text)

### This is code adapted from KU Leuven crawler code written by
### Gunes Acar and Marc Juarez
from pyamf import sol
import fnmatch
import os

#TODO: Linux only
FLASH_DIRS = ['~/.macromedia/Flash_Player/#SharedObjects/']

class FlashCookie(object):
    filename = ''
    domain = ''
    local_path = ''
    key = ''
    content = ''

def gen_find_files(filepat, top):
    """
    http://example.com
    returns filenames that matches the given pattern under() a given dir
    """
    for path, _, filelist in os.walk(top):
        for name in fnmatch.filter(filelist, filepat):
            yield os.path.join(path, name)

def get_flash_cookies(mod_since=0):
    """Return a list of Flash cookies (Local Shared Objects)."""
    flash_cookies = list()
    for top_dir in FLASH_DIRS:
        top_dir = os.path.expanduser(top_dir)
        for lso_file in gen_find_files("*.sol", top_dir):
            mtime = os.path.getmtime(lso_file)
            if mtime > mod_since:
                try:
                    flash_cookies.extend(parse_flash_cookies(lso_file))
                except (KeyboardInterrupt, SystemExit):
                    raise
                except Exception as e:
                    print "Exception reading", lso_file
                    print e
                    pass
    return flash_cookies

def parse_flash_cookies(lso_file):
    lso_dict = sol.load(lso_file)
    flash_cookies = list()
    for k, v in lso_dict.iteritems():
        flash_cookie = FlashCookie()
        flash_cookie.local_path = lso_file.split("#SharedObjects/")[1]
        flash_cookie.filename = os.path.basename(lso_file)
        flash_cookie.domain = lso_file.split("#SharedObjects/")[1].split("/")[1]
        flash_cookie.key = unicode(k)

        flash_cookies.append(flash_cookie)
    return flash_cookies


### This is code adapted from KU Leuven crawler code written by
### Gunes Acar and Marc Juarez
from pyamf import sol
import fnmatch
import os

#TODO: Linux only
FLASH_DIRS = ['~/.macromedia/Flash_Player/#SharedObjects/']

class FlashCookie(object):
    filename = ''
    domain = ''
    local_path = ''
    key = ''
    content = ''

def gen_find_files(filepat, top):
    """
    http://example.com
    returns filenames that matches the given pattern under() a given dir
    """
    for path, _, filelist in os.walk(top):
        for name in fnmatch.filter(filelist, filepat):
            yield os.path.join(path, name)

def get_flash_cookies(mod_since=0):
    """Return a list of Flash cookies (Local Shared Objects)."""
    flash_cookies = list()
    for top_dir in FLASH_DIRS:
        top_dir = os.path.expanduser(top_dir)
        for lso_fil

e in gen_find_files("*.sol", top_dir):
            mtime = os.path.getmtime(lso_file)
            if mtime > mod_since:
                try:
                    flash_cookies.extend(parse_flash_cookies(lso_file))
                except (KeyboardInterrupt, SystemExit):
                    raise
                except Exception as e:
                    print "Exception reading", lso_file
                    print e
                    pass
    return flash_cookies

def parse_flash_cookies(lso_file):
    lso_dict = sol.load(lso_file)
    flash_cookies = list()
    for k, v in lso_dict.iteritems():
        flash_cookie = FlashCookie()
        flash_cookie.local_path = lso_file.split("#SharedObjects/")[1]
        flash_cookie.filename = os.path.basename(lso_file)
        flash_cookie.domain = lso_file.split("#SharedObjects/")[1].split("/")[1]
        flash_cookie.key = unicode(k)
        try:
            flash_cookie.content = unicode(v)
        except UnicodeDecodeError:
            # obj is byte string
            ascii_text = str(v).encode('string_escape')
            flash_cookie.content = unicode(ascii_text)

        flash_cookies.append(flash_cookie)
    return flash_cookies


from binascii import hexlify
from functools import lru_cache
from typing import List

from pytezos.crypto import Key, blake2b_32
from pytezos.encoding import base58_decode, base58_encode
from pytezos.rpc.node import RpcQuery
from pytezos.rpc.helpers import HelpersMixin

def filter_contents(entity, kind):
    if isinstance(kind, str):
        kind = {kind}
    elif isinstance(kind, list):
        kind = set(kind)

    def iter_contents(op):
        for content in op['contents']:
            internal = content.get('metadata', {}).get('internal_operation_results', [])

            if not kind or content['kind'] in kind:
                if internal:
                    del content['metadata']['internal_operation_results']
                yield content

            for result in internal:
                if not kind or result['kind'] in kind:
                    yield result

    if isinstance(entity, dict):
        return list(iter_contents(entity))

    if isinstance(entity, list):
        contents = list()
        if len(entity) and isinstance(entity[0], list):
            for op_list in entity:
                for op in op_list:
                    contents.extend(iter_contents(op))
        else:
            for op in entity:
                contents.extend(iter_contents(op))
        return contents

    raise ValueError(entity, kind)

class OperationList(RpcQuery):

    def contents(self, kind=None):
        return filter_contents(self(), kind)

class OperationListList(RpcQuery):

    @lru_cache(maxsize=None)
    def __getitem__(self, item):
        if isinstance(item, tuple):
            return self._child_class(
                path=f'{self._path}/{item[0]}/{item[1]}',
                node=self._node,
                cache=self._cache
            )
        elif isinstance(item, int):
            return OperationList(
                path=f'{self._path}/{item}',
                node=self._node,
                cache=self._cache,
                child_class=self._child_class
            )
        else:
            raise NotImplementedError(item)

    @property
    def endorsements(self):
        """
        The first list contains the endorsements (kind `endorsement`)
        :return: RPCQuery instance
        """
        return self[0]

    @property

"""
        The second list contains all the operations regarding votes and proposals (kind `proposals`, `ballot`)
        :return: RPCQuery instance
        """
        return self[1]

    @property
    def anonymous(self):
        """
        The third list contains anonymous operations (kind `seed_nonce_revelation`, `double_endorsement_evidence`,
            `double_baking_evidence`, `activate_account`)
        :return: RPCQuery instance
        """
        return self[2]

    @property
    def managers(self):
        """
        The last one contains the manager operations (`reveal`, `transaction`, `origination`, `delegation`)
        :return: RPCQuery instance
        """
        return self[3]

    def contents(self, kind=None) -> List[dict]:
        return filter_contents(self(), kind)

class Operation(RpcQuery, HelpersMixin):

    def __init__(self, data=None, *args, **kwargs):
        super(Operation, self).__init__(*args, **kwargs)
        self._data = data if data else dict()

    def __repr__(self):
        if self._data:
            return str(self._data)
        return super(Operation, self).__repr__()

    def __call__(self, *args, **kwargs):
        if self._data:
            return self._data
        return super(Operation, self).__call__(*args, **kwargs)

    @classmethod
    def from_data(cls, data: dict):
        return Operation(data)

    def watermark(self):
        content = self.get('contents')[0]
        kind = content['kind']
        if kind in ['endorsement', 'seed_nonce_revelation']:
            return '02' + self.get_chain_watermark()
        if kind in ['transaction', 'origination', 'delegation', 'reveal', 'ballot', 'proposals', 'activate_account']:
            return '03'
        raise NotImplementedError(kind)

    def source(self):
        content = self.get('contents')[0]
        kind = content['kind']
        if kind in ['endorsement']:
            return content['metadata']['delegate']
        if kind == 'activate_account':
            return content['pkh']
        if kind in ['transaction', 'origination', 'delegation', 'reveal', 'ballot', 'proposals']:
            return content['source']
        raise NotImplementedError(f'Operation `{kind}` is anonymous.')

    def protocol(self):
        try:
            protocol = self.get('protocol')
        except KeyError:
            branch = self.get("branch")
            protocol = self._node.get(f'chains/main/blocks/{branch}/header').get('protocol')
        return protocol

    def unsigned_data(self) -> dict:
        operation = self()
        return {
            'branch': operation['branch'],
            'contents': [
                {k: v for k, v in c.items() if k != 'metadata'}
                for c in operation['contents']
            ]
        }

    def signed_data(self) -> dict:
        return {
            'protocol': self.protocol(),
            'signature': self.get('signature'),
            **self.unsigned_data()
        }

    def unsigned_bytes(self):
        return self.watermark() + self.forge()

    def signed_bytes(self):
        signature_bytes = hexlify(base58_decode(self.get('signature'))).decode()
        return self.forge() + signature_bytes

    def calculate_hash(self):
        hash_digest = blake2b_32(self.signed_bytes()).digest()
        return base58_encode(hash_digest, b'o').decode()

    def forge(self):
        return self._node.post(
            path='chains/main/blocks/head/helpers/forge/operations',
            json=self.unsigned_data(),
            cache=True
        )

    def sign(self, key):
        if isinstance(key, str):
            key = Key(key)
        if not isinstance(key, Key):
            raise ValueError('Base58 encoded secret key or Key instance required.')

        self._data['signature'] = key.sign(self.unsigned_bytes(), generic=True)
        return self._data['signature']

    def preapply(self, branch=None):
        operation = self.signed_data()
        if branch is None:
            branch = operation['branch']

        data = self._node.post(
            path=f'chains/main/blocks/{branch}/helpers/preapply/operations',
            json=[operation],
            cache=True
        )
        self._data['contents'] = data[0]['contents']
        return data

    def verify_signature(self):
        pk = self.get_public_key(self.source())
        Key(pk).verify(self.get('signature'), self.unsigned_bytes())

    def contents(self, kind=None):
        return filter_contents(self(), kind)


from binascii import hexlify
from functools import lru_cache
from typing import List

from pytezos.crypto import Key, blake2b_32
from pytezos.encoding import base58_decode, base58_encode
from pytezos.rpc.node import RpcQuery
from pytezos.rpc.helpers import HelpersMixin

def filter_contents(entity, kind):
    if isinstance(kind, str):
        kind = {kind}
    elif isinstance(kind, list):
        kind = set(kind)

    def iter_contents(op):
        for content in op['contents']:
            internal = content.get('metadata', {}).get('internal_operation_results', [])

            if not kind or content['kind'] in kind:
                if internal:
                    del content['metadata']['internal_operation_results']
                yield content

            for result in internal:
                if not kind or result['kind'] in kind:
                    yield result

    if isinstance(entity, dict):
        return list(iter_contents(entity))

    if isinstance(entity, list):
        contents = list()
        if len(entity) and isinstance(entity[0], list):
            for op_list in entity:
                for op in op_list:
                    contents.extend(iter_contents(op))
        else:
            for op in entity:
                contents.extend(iter_contents(op))
        return contents

    raise ValueError(entity, kind)

class OperationList(RpcQuery):

    def contents(self, kind=None):
        return filter_contents(self(), kind)

class OperationListList(RpcQuery):

    @lru_cache(maxsize=None)
    def __getitem__(self, item):
        if isinstance(item, tuple):
            return self._child_class(
                path=f'{self._path}/{item[0]}/{item[1]}',
                node=self._node,
                cache=self._cache
            )
        elif isinstance(item, int):
            return OperationList(
                path=f'{self._path}/{item}',
                node=self._node,
                cache=self._cache,
                child_class=self._child_class
            )
        else:
            raise NotImplementedError(item)

    @property
    def endorsements(self):
        """
        The first list contains the endorsements (kind `endorsement`)
        :return: RPCQuery instance
        """
        return self[0]

    @property
    def votes(self):
        """
        The second list contains all the operations regarding votes and proposals (kind `proposals`, `ballot`)
        :return: RPCQuery instance
        """
        return self[1]

    @property
    def anonymous(self):
        """
        The third list contains anonymous operations (kind `seed_nonce_revelation`, `double_endorsement_evidence`,
            `double_baking_evidence`, `activate_account`)
        :return: RPCQuery instance
        """
        return self[2]

    @property
    def managers(self):
        """
        The last one contains the manager operations (`reveal`, `transaction`, `origination`, `delegation`)
        :return: RPCQuery instance
        """
        return self[3]

    def contents(self, kind=None) -> List[dict]:
        return filter_contents(self(), kind)

class Operation(RpcQuery, HelpersMixin):

    def __init__(self, data=None, *args, **kwargs):
        super(Operation, self).__init__(*args, **kwargs)
        self._data = data if data else dict()

    def __repr__(self):
        if self._data:
            return str(self._data)
        return super(Operation, self).__repr__()

    def __call__(self, *args, **kwargs):
        if self._data:
            return self._data
        return super(Operation, self).__call__(*args, **kwargs)

    @classmethod
    def from_data(cls, data: dict):

    def watermark(self):
        content = self.get('contents')[0]
        kind = content['kind']
        if kind in ['endorsement', 'seed_nonce_revelation']:
            return '02' + self.get_chain_watermark()
        if kind in ['transaction', 'origination', 'delegation', 'reveal', 'ballot', 'proposals', 'activate_account']:
            return '03'
        raise NotImplementedError(kind)

    def source(self):
        content = self.get('contents')[0]
        kind = content['kind']
        if kind in ['endorsement']:
            return content['metadata']['delegate']
        if kind == 'activate_account':
            return content['pkh']
        if kind in ['transaction', 'origination', 'delegation', 'reveal', 'ballot', 'proposals']:
            return content['source']
        raise NotImplementedError(f'Operation `{kind}` is anonymous.')

    def protocol(self):
        try:
            protocol = self.get('protocol')
        except KeyError:
            branch = self.get("branch")
            protocol = self._node.get(f'chains/main/blocks/{branch}/header').get('protocol')
        return protocol

    def unsigned_data(self) -> dict:
        operation = self()
        return {
            'branch': operation['branch'],
            'contents': [
                {k: v for k, v in c.items() if k != 'metadata'}
                for c in operation['contents']
            ]
        }

    def signed_data(self) -> dict:
        return {
            'protocol': self.protocol(),
            'signature': self.get('signature'),
            **self.unsigned_data()
        }

    def unsigned_bytes(self):
        return self.watermark() + self.forge()

    def signed_bytes(self):
        signature_bytes = hexlify(base58_decode(self.get('signature'))).decode()
        return self.forge() + signature_bytes

    def calculate_hash(self):
        hash_digest = blake2b_32(self.signed_bytes()).digest()
        return base58_encode(hash_digest, b'o').decode()

    def forge(self):
        return self._node.post(
            path='chains/main/blocks/head/helpers/forge/operations',
            json=self.unsigned_data(),
            cache=True
        )

    def sign(self, key):
        if isinstance(key, str):
            key = Key(key)
        if not isinstance(key, Key):
            raise ValueError('Base58 encoded secret key or Key instance required.')

        self._data['signature'] = key.sign(self.unsigned_bytes(), generic=True)
        return self._data['signature']

    def preapply(self, branch=None):
        operation = self.signed_data()
        if branch is None:
            branch = operation['branch']

        data = self._node.post(
            path=f'chains/main/blocks/{branch}/helpers/preapply/operations',
            json=[operation],
            cache=True
        )
        self._data['contents'] = data[0]['contents']
        return data

    def verify_signature(self):
        pk = self.get_public_key(self.source())
        Key(pk).verify(self.get('signature'), self.unsigned_bytes())

    def contents(self, kind=None):
        return filter_contents(self(), kind)


if isinstance(key, str):
            key = Key(key)
        if not isinstance(key, Key):
            raise ValueError('Base58 encoded secret key or Key instance required.')

from binascii import hexlify
from functools import lru_cache
from typing import List

from pytezos.crypto import Key, blake2b_32
from pytezos.encoding import base58_decode, base58_encode
from pytezos.rpc.node import RpcQuery
from pytezos.rpc.helpers import HelpersMixin

def filter_contents(entity, kind):
    if isinstance(kind, str):
        kind = {kind}
    elif isinstance(kind, list):
        kind = set(kind)

    def iter_contents(op):
        for content in op['contents']:
            internal = content.get('metadata', {}).get('internal_operation_results', [])

            if not kind or content['kind'] in kind:
                if internal:
                    del content['metadata']['internal_operation_results']
                yield content

            for result in internal:
                if not kind or result['kind'] in kind:
                    yield result

    if isinstance(entity, dict):
        return list(iter_contents(entity))

    if isinstance(entity, list):
        contents = list()
        if len(entity) and isinstance(entity[0], list):
            for op_list in entity:
                for op in op_list:
                    contents.extend(iter_contents(op))
        else:
            for op in entity:
                contents.extend(iter_contents(op))
        return contents

    raise ValueError(entity, kind)

class OperationList(RpcQuery):

    def contents(self, kind=None):
        return filter_contents(self(), kind)

class OperationListList(RpcQuery):

    @lru_cache(maxsize=None)
    def __getitem__(self, item):
        if isinstance(item, tuple):
            return self._child_class(
                path=f'{self._path}/{item[0]}/{item[1]}',
                node=self._node,
                cache=self._cache
            )
        elif isinstance(item, int):
            return OperationList(
                path=f'{self._path}/{item}',
                node=self._node,
                cache=self._cache,
                child_class=self._child_class
            )
        else:
            raise NotImplementedError(item)

    @property
    def endorsements(self):
        """
        The first list contains the endorsements (kind `endorsement`)
        :return: RPCQuery instance
        """
        return self[0]

    @property
    def votes(self):
        """
        The second list contains all the operations regarding votes and proposals (kind `proposals`, `ballot`)
        :return: RPCQuery instance
        """
        return self[1]

    @property
    def anonymous(self):
        """
        The third list contains anonymous operations (kind `seed_nonce_revelation`, `double_endorsement_evidence`,
            `double_baking_evidence`, `activate_account`)
        :return: RPCQuery instance
        """
        return self[2]

    @property
    def managers(self):
        """
        The last one contains the manager operations (`reveal`, `transaction`, `origination`, `delegation`)
        :return: RPCQuery instance
        """
        return self[3]

    def contents(self, kind=None) -> List[dict]:
        return filter_contents(self(), kind)

class Operation(RpcQuery, HelpersMixin):

    def __init__(self, data=None, *args, **kwargs):
        super(Operation, self).__init__(*args, **kwargs)
        self._data = data if data else dict()

    def __repr__(self):
        if self._data:
            return str(self._data)
        return super(Operation, self).__repr__()

    def __call__(self, *args, **kwargs):
        if self._data:
            return self._data
        return super(Operation, self).__call__(*args, **kwargs)

    @classmethod
    def from_data(cls, data: dict):
        return Operation(data)

    def watermark(self):
        content = self.get('contents')[0]
        kind = content['kind']
        if kind in ['endorsement', 'seed_nonce_revelation']:
            return '02' + self.get_chain_watermark()
        if kind in ['transaction', 'origination', 'delegation', 'reveal', 'ballot', 'proposals', 'activate_account']:
            return '03'
        raise NotImplementedError(kind)

    def source(self):
        content = self.get('contents')[0]
        kind = content['kind']
        if kind in ['endorsement']:
            return content['metadata']['delegate']
        if kind == 'activate_account':
            return content['pkh']
        if kind in ['transaction', 'origination', 'delegation', 'reveal', 'ballot', 'proposals']:
            return content['source']
        raise NotImplementedError(f'Operation `{kind}` is anonymous.')

    def protocol(self):
        try:
            protocol = self.get('protocol')
        except KeyError:
            branch = self.get("branch")
            protocol = self._node.get(f'chains/main/blocks/{branch}/header').get('protocol')
        return protocol

    def unsigned_data(self) -> dict:
        operation = self()
        return {
            'branch': operation['branch'],
            'contents': [
                {k: v for k, v in c.items() if k != 'metadata'}
                for c in operation['contents']
            ]
        }

    def signed_data(self) -> dict:
        return {
            'protocol': self.protocol(),
            'signature': self.get('signature'),
            **self.unsigned_data()
        }

    def unsigned_bytes(self):
        return self.watermark() + self.forge()

    def signed_bytes(self):
        signature_bytes = hexlify(base58_decode(self.get('signature'))).decode()
        return self.forge() + signature_bytes

    def calculate_hash(self):
        hash_digest = blake2b_32(self.signed_bytes()).digest()
        return base58_encode(hash_digest, b'o').decode()

    def forge(self):
        return self._node.post(
            path='chains/main/blocks/head/helpers/forge/operations',
            json=self.unsigned_data(),
            cache=True
        )

    def sign(self, key):

        self._data['signature'] = key.sign(self.unsigned_bytes(), generic=True)
        return self._data['signature']

    def preapply(self, branch=None):
        operation = self.signed_data()
        if branch is None:
            branch = operation['branch']

        data = self._node.post(
            path=f'chains/main/blocks/{branch}/helpers/preapply/operations',
            json=[operation],
            cache=True
        )
        self._data['contents'] = data[0]['contents']
        return data

    def verify_signature(self):
        pk = self.get_public_key(self.source())
        Key(pk).verify(self.get('signature'), self.unsigned_bytes())

    def contents(self, kind=None):
        return filter_contents(self(), kind)


self._data['signature'] = key.sign(self.unsigned_bytes(), generic=True)

from binascii import hexlify
from functools import lru_cache
from typing import List

from pytezos.crypto import Key, blake2b_32
from pytezos.encoding import base58_decode, base58_encode
from pytezos.rpc.node import RpcQuery
from pytezos.rpc.helpers import HelpersMixin

def filter_contents(entity, kind):
    if isinstance(kind, str):
        kind = {kind}
    elif isinstance(kind, list):
        kind = set(kind)

    def iter_contents(op):
        for content in op['contents']:
            internal = content.get('metadata', {}).get('internal_operation_results', [])

            if not kind or content['kind'] in kind:
                if internal:
                    del content['metadata']['internal_operation_results']
                yield content

            for result in internal:
                if not kind or result['kind'] in kind:
                    yield result

    if isinstance(entity, dict):
        return list(iter_contents(entity))

    if isinstance(entity, list):
        contents = list()
        if len(entity) and isinstance(entity[0], list):
            for op_list in entity:
                for op in op_list:
                    contents.extend(iter_contents(op))
        else:
            for op in entity:
                contents.extend(iter_contents(op))
        return contents

    raise ValueError(entity, kind)

class OperationList(RpcQuery):

    def contents(self, kind=None):
        return filter_contents(self(), kind)

class OperationListList(RpcQuery):

    @lru_cache(maxsize=None)
    def __getitem__(self, item):
        if isinstance(item, tuple):
            return self._child_class(
                path=f'{self._path}/{item[0]}/{item[1]}',
                node=self._node,
                cache=self._cache
            )
        elif isinstance(item, int):
            return OperationList(
                path=f'{self._path}/{item}',
                node=self._node,
                cache=self._cache,
                child_class=self._child_class
            )
        else:
            raise NotImplementedError(item)

    @property
    def endorsements(self):
        """
        The first list contains the endorsements (kind `endorsement`)
        :return: RPCQuery instance
        """
        return self[0]

    @property
    def votes(self):
        """
        The second list contains all the operations regarding votes and proposals (kind `proposals`, `ballot`)
        :return: RPCQuery instance
        """
        return self[1]

    @property
    def anonymous(self):
        """
        The third list contains anonymous operations (kind `seed_nonce_revelation`, `double_endorsement_evidence`,
            `double_baking_evidence`, `activate_account`)
        :return: RPCQuery instance
        """
        return self[2]

    @property
    def managers(self):
        """
        The last one contains the manager operations (`reveal`, `transaction`, `origination`, `delegation`)
        :return: RPCQuery instance
        """
        return self[3]

    def contents(self, kind=None) -> List[dict]:
        return filter_contents(self(), kind)

class Operation(RpcQuery, HelpersMixin):

    def __init__(self, data=None, *args, **kwargs):
        super(Operation, self).__init__(*args, **kwargs)
        self._data = data if data else dict()

    def __repr__(self):
        if self._data:
            return str(self._data)
        return super(Operation, self).__repr__()

    def __call__(self, *args, **kwargs):
        if self._data:
            return self._data
        return super(Operation, self).__call__(*args, **kwargs)

    @classmethod
    def from_data(cls, data: dict):
        return Operation(data)

    def watermark(self):
        content = self.get('contents')[0]
        kind = content['kind']
        if kind in ['endorsement', 'seed_nonce_revelation']:
            return '02' + self.get_chain_watermark()
        if kind in ['transaction', 'origination', 'delegation', 'reveal', 'ballot', 'proposals', 'activate_account']:
            return '03'
        raise NotImplementedError(kind)

    def source(self):
        content = self.get('contents')[0]
        kind = content['kind']
        if kind in ['endorsement']:
            return content['metadata']['delegate']
        if kind == 'activate_account':
            return content['pkh']
        if kind in ['transaction', 'origination', 'delegation', 'reveal', 'ballot', 'proposals']:
            return content['source']
        raise NotImplementedError(f'Operation `{kind}` is anonymous.')

    def protocol(self):
        try:
            protocol = self.get('protocol')
        except KeyError:
            branch = self.get("branch")
            protocol = self._node.get(f'chains/main/blocks/{branch}/header').get('protocol')
        return protocol

    def unsigned_data(self) -> dict:
        operation = self()
        return {
            'branch': operation['branch'],
            'contents': [
                {k: v for k, v in c.items() if k != 'metadata'}
                for c in operation['contents']
            ]
        }

    def signed_data(self) -> dict:
        return {
            'protocol': self.protocol(),
            'signature': self.get('signature'),
            **self.unsigned_data()
        }

    def unsigned_bytes(self):
        return self.watermark() + self.forge()

    def signed_bytes(self):
        signature_bytes = hexlify(base58_decode(self.get('signature'))).decode()
        return self.forge() + signature_bytes

    def calculate_hash(self):
        hash_digest = blake2b_32(self.signed_bytes()).digest()
        return base58_encode(hash_digest, b'o').decode()

    def forge(self):
        return self._node.post(
            path='chains/main/blocks/head/helpers/forge/operations',
            json=self.unsigned_data(),
            cache=True
        )

    def sign(self, key):
        if isinstance(key, str):
            key = Key(key)
        if not isinstance(key, Key):
            raise ValueError('Base58 encoded secret key or Key instance required.')

        return self._data['signature']

    def preapply(self, branch=None):
        operation = self.signed_data()
        if branch is None:
            branch = operation['branch']

        data = self._node.post(
            path=f'chains/main/blocks/{branch}/helpers/preapply/operations',
            json=[operation],
            cache=True
        )
        self._data['contents'] = data[0]['contents']
        return data

    def verify_signature(self):
        pk = self.get_public_key(self.source())
        Key(pk).verify(self.get('signature'), self.unsigned_bytes())

    def contents(self, kind=None):
        return filter_contents(self(), kind)


from binascii import hexlify
from functools import lru_cache
from typing import List

from pytezos.crypto import Key, blake2b_32
from pytezos.encoding import base58_decode, base58_encode
from pytezos.rpc.node import RpcQuery
from pytezos.rpc.helpers import HelpersMixin

def filter_contents(entity, kind):
    if isinstance(kind, str):
        kind = {kind}
    elif isinstance(kind, list):
        kind = set(kind)

    def iter_contents(op):
        for content in op['contents']:
            internal = content.get('metadata', {}).get('internal_operation_results', [])

            if not kind or content['kind'] in kind:
                if internal:
                    del content['metadata']['internal_operation_results']
                yield content

            for result in internal:
                if not kind or result['kind'] in kind:
                    yield result

    if isinstance(entity, dict):
        return list(iter_contents(entity))

    if isinstance(entity, list):
        contents = list()
        if len(entity) and isinstance(entity[0], list):
            for op_list in entity:
                for op in op_list:
                    contents.extend(iter_contents(op))
        else:
            for op in entity:
                contents.extend(iter_contents(op))
        return contents

    raise ValueError(entity, kind)

class OperationList(RpcQuery):

    def contents(self, kind=None):
        return filter_contents(self(), kind)

class OperationListList(RpcQuery):

    @lru_cache(maxsize=None)
    def __getitem__(self, item):
        if isinstance(item, tuple):
            return self._child_class(
                path=f'{self._path}/{item[0]}/{item[1]}',
                node=self._node,
                cache=self._cache
            )
        elif isinstance(item, int):
            return OperationList(
                path=f'{self._path}/{item}',
                node=self._node,
                cache=self._cache,
                child_class=self._child_class
            )
        else:
            raise NotImplementedError(item)

    @property
    def endorsements(self):
        """
        The first list contains the endorsements (kind `endorsement`)
        :return: RPCQuery instance
        """
        return self[0]

    @property
    def votes(self):
        """
        The second list contains all the operations regarding votes and proposals (kind `proposals`, `ballot`)
        :return: RPCQuery instance
        """
        return self[1]

    @property
    def anonymous(self):
        """
        The third list contains anonymous operations (kind `seed_nonce_revelation`, `double_endorsement_evidence`,
            `double_baking_evidence`, `activate_account`)
        :return: RPCQuery instance
        """
        return self[2]

    @property
    def managers(self):
        """
        The last one contains the manager operations (`reveal`, `transaction`, `origination`, `delegation`)
        :return: RPCQuery instance
        """
        return self[3]

    def contents(self, kind=None) -> List[dict]:
        return filter_contents(self(), kind)

class Operation(RpcQuery, HelpersMixin):

    def __init__(self, data=None, *args, **kwargs):
        super(Operation, self).__init__(*args, **kwargs)
        self._data = data if data else dict()

    def __repr__(self):
        if self._data:
            return str(self._data)
        return super(Operation, self).__repr__()

    def __call__(self, *args, **kwargs):
        if self._data:
            return self._data
        return super(Operation, self).__call__(*args, **kwargs)

    @classmethod
    def from_data(cls, data: dict):
        return Operation(data)

    def watermark(self):
        content = self.get('contents')[0]
        kind = content['kind']
        if kind in ['endorsement', 'seed_nonce_revelation']:
            return '02' + self.get_chain_watermark()
        if kind in ['transaction', 'origination', 'delegation', 'reveal', 'ballot', 'proposals', 'activate_account']:
            return '03'
        raise NotImplementedError(kind)

    def source(self):
        content = self.get('contents')[0]
        kind = content['kind']
        if kind in ['endorsement']:
            return content['metadata']['delegate']
        if kind == 'activate_account':
            return content['pkh']
        if kind in ['transaction', 'origination', 'delegation', 'reveal', 'ballot', 'proposals']:
            return content['source']
        raise NotImplementedError(f'Operation `{kind}` is anonymous.')

    def protocol(self):
        try:
            protocol = self.get('protocol')
        except KeyError:
            branch = self.get("branch")
            protocol = self._node.get(f'chains/main/blocks/{branch}/header').get('protocol')
        return protocol

    def unsigned_data(self) -> dict:
        operation = self()
        return {
            'branch': operation['branch'],
            'contents': [
                {k: v for k, v in c.items() if k != 'metadata'}
                for c in operation['contents']
            ]
        }

    def signed_data(self) -> dict:
        return {
            'protocol': self.protocol(),
            'signature': self.get('signature'),
            **self.unsigned_data()
        }

    def unsigned_bytes(self):
        return self.watermark() + self.forge()

    def signed_bytes(self):
        signature_bytes = hexlify(base58_decode(self.get('signature'))).decode()
        return self.forge() + signature_bytes

    def calculate_hash(self):
        hash_digest = blake2b_32(self.signed_bytes()).digest()
        return base58_encode(hash_digest, b'o').decode()

    def forge(self):
        return self._node.post(
            path='chains/main/blocks/head/helpers/forge/operations',
            json=self.unsigned_data(),
            cache=True
        )

    def sign(self, key):
        if isinstance(key, str):
            key = Key(key)
        if not isinstance(key, Key):
            raise ValueError('Base58 encoded secret key or Key instance required.')

        self._data['signature'] = key.sign(self.unsigned_bytes(), generic=True)

    def preapply(self, branch=None):
        operation = self.signed_data()
        if branch is None:
            branch = operation['branch']

        data = self._node.post(
            path=f'chains/main/blocks/{branch}/helpers/preapply/operations',
            json=[operation],
            cache=True
        )
        self._data['contents'] = data[0]['contents']
        return data

    def verify_signature(self):
        pk = self.get_public_key(self.source())
        Key(pk).verify(self.get('signature'), self.unsigned_bytes())

    def contents(self, kind=None):
        return filter_contents(self(), kind)


from binascii import hexlify
from functools import lru_cache
from typing import List

from pytezos.crypto import Key, blake2b_32
from pytezos.encoding import base58_decode, base58_encode
from pytezos.rpc.node import RpcQuery
from pytezos.rpc.helpers import HelpersMixin

def filter_contents(entity, kind):
    if isinstance(kind, str):
        kind = {kind}
    elif isinstance(kind, list):
        kind = set(kind)

    def iter_contents(op):
        for content in op['contents']:
            internal = content.get('metadata', {}).get('internal_operation_results', [])

            if not kind or content['kind'] in kind:
                if internal:
                    del content['metadata']['internal_operation_results']
                yield content

            for result in internal:
                if not kind or result['kind'] in kind:
                    yield result

    if isinstance(entity, dict):
        return list(iter_contents(entity))

    if isinstance(entity, list):
        contents = list()
        if len(entity) and isinstance(entity[0], list):
            for op_list in entity:
                for op in op_list:
                    contents.extend(iter_contents(op))
        else:
            for op in entity:
                contents.extend(iter_contents(op))
        return contents

    raise ValueError(entity, kind)

class OperationList(RpcQuery):

    def contents(self, kind=None):
        return filter_contents(self(), kind)

class OperationListList(RpcQuery):

    @lru_cache(maxsize=None)
    def __getitem__(self, item):
        if isinstance(item, tuple):
            return self._child_class(
                path=f'{self._path}/{item[0]}/{item[1]}',
                node=self._node,
                cache=self._cache
            )
        elif isinstance(item, int):
            return OperationList(
                path=f'{self._path}/{item}',
                node=self._node,
                cache=self._cache,
                child_class=self._child_class
            )
        else:
            raise NotImplementedError(item)

    @property
    def endorsements(self):
        """
        The first list contains the endorsements (kind `endorsement`)
        :return: RPCQuery instance
        """
        return self[0]

    @property
    def votes(self):
        """
        The second list contains all the operations regarding votes and proposals (kind `proposals`, `ballot`)
        :return: RPCQuery instance
        """
        return self[1]

    @property
    def anonymous(self):
        """
        The third list contains anonymous operations (kind `seed_nonce_revelation`, `double_endorsement_evidence`,
            `double_baking_evidence`, `activate_account`)
        :return: RPCQuery instance
        """
        return self[2]

    @property
    def managers(self):
        """
        The last one contains the manager operations (`reveal`, `transaction`, `origination`, `delegation`)
        :return: RPCQuery instance
        """
        return self[3]

    def contents(self, kind=None) -> List[dict]:
        return filter_contents(self(), kind)

class Operation(RpcQuery, HelpersMixin):

    def __init__(self, data=None, *args, **kwargs):
        super(Operation, self).__init__(*args, **kwargs)
        self._data = data if data else dict()

    def __repr__(self):
        if self._data:
            return str(self._data)
        return super(Operation, self).__repr__()

    def __call__(self, *args, **kwargs):
        if self._data:
            return self._data
        return super(Operation, self).__call__(*args, **kwargs)

    @classmethod
    def from_data(cls, data: dict):
        return Operation(data)

    def watermark(self):
        content = self.get('contents')[0]
        kind = content['kind']
        if kind in ['endorsement', 'seed_nonce_revelation']:
            return '02' + self.get_chain_watermark()
        if kind in ['transaction', 'origination', 'delegation', 'reveal', 'ballot', 'proposals', 'activate_account']:
            return '03'
        raise NotImplementedError(kind)

    def source(self):
        content = self.get('contents')[0]
        kind = content['

        if kind in ['endorsement']:
            return content['metadata']['delegate']
        if kind == 'activate_account':
            return content['pkh']
        if kind in ['transaction', 'origination', 'delegation', 'reveal', 'ballot', 'proposals']:
            return content['source']
        raise NotImplementedError(f'Operation `{kind}` is anonymous.')

    def protocol(self):
        try:
            protocol = self.get('protocol')
        except KeyError:
            branch = self.get("branch")
            protocol = self._node.get(f'chains/main/blocks/{branch}/header').get('protocol')
        return protocol

    def unsigned_data(self) -> dict:
        operation = self()
        return {
            'branch': operation['branch'],
            'contents': [
                {k: v for k, v in c.items() if k != 'metadata'}
                for c in operation['contents']
            ]
        }

    def signed_data(self) -> dict:
        return {
            'protocol': self.protocol(),
            'signature': self.get('signature'),
            **self.unsigned_data()
        }

    def unsigned_bytes(self):
        return self.watermark() + self.forge()

    def signed_bytes(self):
        signature_bytes = hexlify(base58_decode(self.get('signature'))).decode()
        return self.forge() + signature_bytes

    def calculate_hash(self):
        hash_digest = blake2b_32(self.signed_bytes()).digest()
        return base58_encode(hash_digest, b'o').decode()

    def forge(self):
        return self._node.post(
            path='chains/main/blocks/head/helpers/forge/operations',
            json=self.unsigned_data(),
            cache=True
        )

    def sign(self, key):
        if isinstance(key, str):
            key = Key(key)
        if not isinstance(key, Key):
            raise ValueError('Base58 encoded secret key or Key instance required.')

        self._data['signature'] = key.sign(self.unsigned_bytes(), generic=True)
        return self._data['signature']

    def preapply(self, branch=None):
        operation = self.signed_data()
        if branch is None:
            branch = operation['branch']

        data = self._node.post(
            path=f'chains/main/blocks/{branch}/helpers/preapply/operations',
            json=[operation],
            cache=True
        )
        self._data['contents'] = data[0]['contents']
        return data

    def verify_signature(self):
        pk = self.get_public_key(self.source())
        Key(pk).verify(self.get('signature'), self.unsigned_bytes())

    def contents(self, kind=None):
        return filter_contents(self(), kind)


from binascii import hexlify
from functools import lru_cache
from typing import List

from pytezos.crypto import Key, blake2b_32
from pytezos.encoding import base58_decode, base58_encode
from pytezos.rpc.node import RpcQuery
from pytezos.rpc.helpers import HelpersMixin

def filter_contents(entity, kind):
    if isinstance(kind, str):
        kind = {kind}
    elif isinstance(kind, list):
        kind = set(kind)

    def iter_contents(op):
        for content in op['contents']:
            internal = content.get('metadata', {}).get('internal_operation_results', [])

            if not kind or content['kind'] in kind:
                if internal:
                    del content['metadata']['internal_operation_results']
                yield content

            for result in internal:
                if not kind or result['kind'] in kind:
                    yield result

    if isinstance(entity, dict):
        return list(iter_contents(entity))

    if isinstance(entity, list):
        contents = list()
        if len(entity) and isinstance(entity[0], list):
            for op_list in entity:
                for op in op_list:
                    contents.extend(iter_contents(op))
        else:
            for op in entity:
                contents.extend(iter_contents(op))
        return contents

    raise ValueError(entity, kind)

class OperationList(RpcQuery):

    def contents(self, kind=None):
        return filter_contents(self(), kind)

class OperationListList(RpcQuery):

    @lru_cache(maxsize=None)
    def __getitem__(self, item):
        if isinstance(item, tuple):
            return self._child_class(
                path=f'{self._path}/{item[0]}/{item[1]}',
                node=self._node,
                cache=self._cache
            )
        elif isinstance(item, int):
            return OperationList(
                path=f'{self._path}/{item}',
                node=self._node,
                cache=self._cache,
                child_class=self._child_class
            )
        else:
            raise NotImplementedError(item)

    @property
    def endorsements(self):
        """
        The first list contains the endorsements (kind `endorsement`)
        :return: RPCQuery instance
        """
        return self[0]

    @property
    def votes(self):
        """
        The second list contains all the operations regarding votes and proposals (kind `proposals`, `ballot`)
        :return: RPCQuery instance
        """

    @property
    def anonymous(self):
        """
        The third list contains anonymous operations (kind `seed_nonce_revelation`, `double_endorsement_evidence`,
            `double_baking_evidence`, `activate_account`)
        :return: RPCQuery instance
        """
        return self[2]

    @property
    def managers(self):
        """
        The last one contains the manager operations (`reveal`, `transaction`, `origination`, `delegation`)
        :return: RPCQuery instance
        """
        return self[3]

    def contents(self, kind=None) -> List[dict]:
        return filter_contents(self(), kind)

class Operation(RpcQuery, HelpersMixin):

    def __init__(self, data=None, *args, **kwargs):
        super(Operation, self).__init__(*args, **kwargs)
        self._data = data if data else dict()

    def __repr__(self):
        if self._data:
            return str(self._data)
        return super(Operation, self).__repr__()

    def __call__(self, *args, **kwargs):
        if self._data:
            return self._data
        return super(Operation, self).__call__(*args, **kwargs)

    @classmethod
    def from_data(cls, data: dict):
        return Operation(data)

    def watermark(self):
        content = self.get('contents')[0]
        kind = content['kind']
        if kind in ['endorsement', 'seed_nonce_revelation']:
            return '02' + self.get_chain_watermark()
        if kind in ['transaction', 'origination', 'delegation', 'reveal', 'ballot', 'proposals', 'activate_account']:
            return '03'
        raise NotImplementedError(kind)

    def source(self):
        content = self.get('contents')[0]
        kind = content['kind']
        if kind in ['endorsement']:
            return content['metadata']['delegate']
        if kind == 'activate_account':
            return content['pkh']
        if kind in ['transaction', 'origination', 'delegation', 'reveal', 'ballot', 'proposals']:
            return content['source']
        raise NotImplementedError(f'Operation `{kind}` is anonymous.')

    def protocol(self):
        try:
            protocol = self.get('protocol')
        except KeyError:
            branch = self.get("branch")
            protocol = self._node.get(f'chains/main/blocks/{branch}/header').get('protocol')
        return protocol

    def unsigned_data(self) -> dict:
        operation = self()
        return {
            'branch': operation['branch'],
            'contents': [
                {k: v for k, v in c.items() if k != 'metadata'}
                for c in operation['contents']
            ]
        }

    def signed_data(self) -> dict:
        return {
            'protocol': self.protocol(),
            'signature': self.get('signature'),
            **self.unsigned_data()
        }

    def unsigned_bytes(self):
        return self.watermark() + self.forge()

    def signed_bytes(self):
        signature_bytes = hexlify(base58_decode(self.get('signature'))).decode()
        return self.forge() + signature_bytes

    def calculate_hash(self):
        hash_digest = blake2b_32(self.signed_bytes()).digest()
        return base58_encode(hash_digest, b'o').decode()

    def forge(self):
        return self._node.post(
            path='chains/main/blocks/head/helpers/forge/operations',
            json=self.unsigned_data(),
            cache=True
        )

    def sign(self, key):
        if isinstance(key, str):
            key = Key(key)
        if not isinstance(key, Key):
            raise ValueError('Base58 encoded secret key or Key instance required.')

        self._data['signature'] = key.sign(self.unsigned_bytes(), generic=True)
        return self._data['signature']

    def preapply(self, branch=None):
        operation = self.signed_data()
        if branch is None:
            branch = operation['branch']

        data = self._node.post(
            path=f'chains/main/blocks/{branch}/helpers/preapply/operations',
            json=[operation],
            cache=True
        )
        self._data['contents'] = data[0]['contents']
        return data

    def verify_signature(self):
        pk = self.get_public_key(self.source())
        Key(pk).verify(self.get('signature'), self.unsigned_bytes())

    def contents(self, kind=None):
        return filter_contents(self(), kind)


if isinstance(entity, list):
        contents = list()
        if len(entity) and isinstance(entity[0], list):
            for op_list in entity:
                for op in op_list:
                    contents.extend(iter_contents(op))
        else:
            for op in entity:
                contents.extend(iter_contents(op))
        return contents

from binascii import hexlify
from functools import lru_cache
from typing import List

from pytezos.crypto import Key, blake2b_32
from pytezos.encoding import base58_decode, base58_encode
from pytezos.rpc.node import RpcQuery
from pytezos.rpc.helpers import HelpersMixin

def filter_contents(entity, kind):
    if isinstance(kind, str):
        kind = {kind}
    elif isinstance(kind, list):
        kind = set(kind)

    def iter_contents(op):
        for content in op['contents']:
            internal = content.get('metadata', {}).get('internal_operation_results', [])

            if not kind or content['kind'] in kind:
                if internal:
                    del content['metadata']['internal_operation_results']
                yield content

            for result in internal:
                if not kind or result['kind'] in kind:
                    yield result

    if isinstance(entity, dict):
        return list(iter_contents(entity))

    raise ValueError(entity, kind)

class OperationList(RpcQuery):

    def contents(self, kind=None):
        return filter_contents(self(), kind)

class OperationListList(RpcQuery):

    @lru_cache(maxsize=None)
    def __getitem__(self, item):
        if isinstance(item, tuple):
            return self._child_class(
                path=f'{self._path}/{item[0]}/{item[1]}',
                node=self._node,
                cache=self._cache
            )
        elif isinstance(item, int):
            return OperationList(
                path=f'{self._path}/{item}',
                node=self._node,
                cache=self._cache,
                child_class=self._child_class
            )
        else:
            raise NotImplementedError(item)

    @property
    def endorsements(self):
        """
        The first list contains the endorsements (kind `endorsement`)
        :return: RPCQuery instance
        """
        return self[0]

    @property
    def votes(self):
        """
        The second list contains all the operations regarding votes and proposals (kind `proposals`, `ballot`)
        :return: RPCQuery instance
        """
        return self[1]

    @property
    def anonymous(self):
        """
        The third list contains anonymous operations (kind `seed_nonce_revelation`, `double_endorsement_evidence`,
            `double_baking_evidence`, `activate_account`)
        :return: RPCQuery instance
        """
        return self[2]

    @property
    def managers(self):
        """
        The last one contains the manager operations (`reveal`, `transaction`, `origination`, `delegation`)
        :return: RPCQuery instance
        """
        return self[3]

    def contents(self, kind=None) -> List[dict]:
        return filter_contents(self(), kind)

class Operation(RpcQuery, HelpersMixin):

    def __init__(self, data=None, *args, **kwargs):
        super(Operation, self).__init__(*args, **kwargs)
        self._data = data if data else dict()

    def __repr__(self):
        if self._data:
            return str(self._data)
        return super(Operation, self).__repr__()

    def __call__(self, *args, **kwargs):
        if self._data:
            return self._data
        return super(Operation, self).__call__(*args, **kwargs)

    @classmethod
    def from_data(cls, data: dict):
        return Operation(data)

    def watermark(self):
        content = self.get('contents')[0]
        kind = content['kind']
        if kind in ['endorsement', 'seed_nonce_revelation']:
            return '02' + self.get_chain_watermark()
        if kind in ['transaction', 'origination', 'delegation', 'reveal', 'ballot', 'proposals', 'activate_account']:
            return '03'
        raise NotImplementedError(kind)

    def source(self):
        content = self.get('contents')[0]
        kind = content['kind']
        if kind in ['endorsement']:
            return content['metadata']['delegate']
        if kind == 'activate_account':
            return content['pkh']
        if kind in ['transaction', 'origination', 'delegation', 'reveal', 'ballot', 'proposals']:
            return content['source']
        raise NotImplementedError(f'Operation `{kind}` is anonymous.')

    def protocol(self):
        try:
            protocol = self.get('protocol')
        except KeyError:
            branch = self.get("branch")
            protocol = self._node.get(f'chains/main/blocks/{branch}/header').get('protocol')
        return protocol

    def unsigned_data(self) -> dict:
        operation = self()
        return {
            'branch': operation['branch'],
            'contents': [
                {k: v for k, v in c.items() if k != 'metadata'}
                for c in operation['contents']
            ]
        }

    def signed_data(self) -> dict:
        return {
            'protocol': self.protocol(),
            'signature': self.get('signature'),
            **self.unsigned_data()
        }

    def unsigned_bytes(self):
        return self.watermark() + self.forge()

    def signed_bytes(self):
        signature_bytes = hexlify(base58_decode(self.get('signature'))).decode()
        return self.forge() + signature_bytes

    def calculate_hash(self):
        hash_digest = blake2b_32(self.signed_bytes()).digest()
        return base58_encode(hash_digest, b'o').decode()

    def forge(self):
        return self._node.post(
            path='chains/main/blocks/head/helpers/forge/operations',
            json=self.unsigned_data(),
            cache=True
        )

    def sign(self, key):
        if isinstance(key, str):
            key = Key(key)
        if not isinstance(key, Key):
            raise ValueError('Base58 encoded secret key or Key instance required.')

        self._data['signature'] = key.sign(self.unsigned_bytes(), generic=True)
        return self._data['signature']

    def preapply(self, branch=None):
        operation = self.signed_data()
        if branch is None:
            branch = operation['branch']

        data = self._node.post(
            path=f'chains/main/blocks/{branch}/helpers/preapply/operations',
            json=[operation],
            cache=True
        )
        self._data['contents'] = data[0]['contents']
        return data

    def verify_signature(self):
        pk = self.get_public_key(self.source())
        Key(pk).verify(self.get('signature'), self.unsigned_bytes())

    def contents(self, kind=None):
        return filter_contents(self(), kind)


for op in entity:
                contents.extend(iter_contents(op))

from binascii import hexlify
from functools import lru_cache
from typing import List

from pytezos.crypto import Key, blake2b_32
from pytezos.encoding import base58_decode, base58_encode
from pytezos.rpc.node import RpcQuery
from pytezos.rpc.helpers import HelpersMixin

def filter_contents(entity, kind):
    if isinstance(kind, str):
        kind = {kind}
    elif isinstance(kind, list):
        kind = set(kind)

    def iter_contents(op):
        for content in op['contents']:
            internal = content.get('metadata', {}).get('internal_operation_results', [])

            if not kind or content['kind'] in kind:
                if internal:
                    del content['metadata']['internal_operation_results']
                yield content

            for result in internal:
                if not kind or result['kind'] in kind:
                    yield result

    if isinstance(entity, dict):
        return list(iter_contents(entity))

    if isinstance(entity, list):
        contents = list()
        if len(entity) and isinstance(entity[0], list):
            for op_list in entity:
                for op in op_list:
                    contents.extend(iter_contents(op))
        else:

        return contents

    raise ValueError(entity, kind)

class OperationList(RpcQuery):

    def contents(self, kind=None):
        return filter_contents(self(), kind)

class OperationListList(RpcQuery):

    @lru_cache(maxsize=None)
    def __getitem__(self, item):
        if isinstance(item, tuple):
            return self._child_class(
                path=f'{self._path}/{item[0]}/{item[1]}',
                node=self._node,
                cache=self._cache
            )
        elif isinstance(item, int):
            return OperationList(
                path=f'{self._path}/{item}',
                node=self._node,
                cache=self._cache,
                child_class=self._child_class
            )
        else:
            raise NotImplementedError(item)

    @property
    def endorsements(self):
        """
        The first list contains the endorsements (kind `endorsement`)
        :return: RPCQuery instance
        """
        return self[0]

    @property
    def votes(self):
        """
        The second list contains all the operations regarding votes and proposals (kind `proposals`, `ballot`)
        :return: RPCQuery instance
        """
        return self[1]

    @property
    def anonymous(self):
        """
        The third list contains anonymous operations (kind `seed_nonce_revelation`, `double_endorsement_evidence`,
            `double_baking_evidence`, `activate_account`)
        :return: RPCQuery instance
        """
        return self[2]

    @property
    def managers(self):
        """
        The last one contains the manager operations (`reveal`, `transaction`, `origination`, `delegation`)
        :return: RPCQuery instance
        """
        return self[3]

    def contents(self, kind=None) -> List[dict]:
        return filter_contents(self(), kind)

class Operation(RpcQuery, HelpersMixin):

    def __init__(self, data=None, *args, **kwargs):
        super(Operation, self).__init__(*args, **kwargs)
        self._data = data if data else dict()

    def __repr__(self):
        if self._data:
            return str(self._data)
        return super(Operation, self).__repr__()

    def __call__(self, *args, **kwargs):
        if self._data:
            return self._data
        return super(Operation, self).__call__(*args, **kwargs)

    @classmethod
    def from_data(cls, data: dict):
        return Operation(data)

    def watermark(self):
        content = self.get('contents')[0]
        kind = content['kind']
        if kind in ['endorsement', 'seed_nonce_revelation']:
            return '02' + self.get_chain_watermark()
        if kind in ['transaction', 'origination', 'delegation', 'reveal', 'ballot', 'proposals', 'activate_account']:
            return '03'
        raise NotImplementedError(kind)

    def source(self):
        content = self.get('contents')[0]
        kind = content['kind']
        if kind in ['endorsement']:
            return content['metadata']['delegate']
        if kind == 'activate_account':
            return content['pkh']
        if kind in ['transaction', 'origination', 'delegation', 'reveal', 'ballot', 'proposals']:
            return content['source']
        raise NotImplementedError(f'Operation `{kind}` is anonymous.')

    def protocol(self):
        try:
            protocol = self.get('protocol')
        except KeyError:
            branch = self.get("branch")
            protocol = self._node.get(f'chains/main/blocks/{branch}/header').get('protocol')
        return protocol

    def unsigned_data(self) -> dict:
        operation = self()
        return {
            'branch': operation['branch'],
            'contents': [
                {k: v for k, v in c.items() if k != 'metadata'}
                for c in operation['contents']
            ]
        }

    def signed_data(self) -> dict:
        return {
            'protocol': self.protocol(),
            'signature': self.get('signature'),
            **self.unsigned_data()
        }

    def unsigned_bytes(self):
        return self.watermark() + self.forge()

    def signed_bytes(self):
        signature_bytes = hexlify(base58_decode(self.get('signature'))).decode()
        return self.forge() + signature_bytes

    def calculate_hash(self):
        hash_digest = blake2b_32(self.signed_bytes()).digest()
        return base58_encode(hash_digest, b'o').decode()

    def forge(self):
        return self._node.post(
            path='chains/main/blocks/head/helpers/forge/operations',
            json=self.unsigned_data(),
            cache=True
        )

    def sign(self, key):
        if isinstance(key, str):
            key = Key(key)
        if not isinstance(key, Key):
            raise ValueError('Base58 encoded secret key or Key instance required.')

        self._data['signature'] = key.sign(self.unsigned_bytes(), generic=True)
        return self._data['signature']

    def preapply(self, branch=None):
        operation = self.signed_data()
        if branch is None:
            branch = operation['branch']

        data = self._node.post(
            path=f'chains/main/blocks/{branch}/helpers/preapply/operations',
            json=[operation],
            cache=True
        )
        self._data['contents'] = data[0]['contents']
        return data

    def verify_signature(self):
        pk = self.get_public_key(self.source())
        Key(pk).verify(self.get('signature'), self.unsigned_bytes())

    def contents(self, kind=None):
        return filter_contents(self(), kind)


try:
            protocol = self.get('protocol')
        except KeyError:
            branch = self.get("branch")
            protocol = self._node.get(f'chains/main/blocks/{branch}/header').get('protocol')

from binascii import hexlify
from functools import lru_cache
from typing import List

from pytezos.crypto import Key, blake2b_32
from pytezos.encoding import base58_decode, base58_encode
from pytezos.rpc.node import RpcQuery
from pytezos.rpc.helpers import HelpersMixin

def filter_contents(entity, kind):
    if isinstance(kind, str):
        kind = {kind}
    elif isinstance(kind, list):
        kind = set(kind)

    def iter_contents(op):
        for content in op['contents']:
            internal = content.get('metadata', {}).get('internal_operation_results', [])

            if not kind or content['kind'] in kind:
                if internal:
                    del content['metadata']['internal_operation_results']
                yield content

            for result in internal:
                if not kind or result['kind'] in kind:
                    yield result

    if isinstance(entity, dict):
        return list(iter_contents(entity))

    if isinstance(entity, list):
        contents = list()
        if len(entity) and isinstance(entity[0], list):
            for op_list in entity:
                for op in op_list:
                    contents.extend(iter_contents(op))
        else:
            for op in entity:
                contents.extend(iter_contents(op))
        return contents

    raise ValueError(entity, kind)

class OperationList(RpcQuery):

    def contents(self, kind=None):
        return filter_contents(self(), kind)

class OperationListList(RpcQuery):

    @lru_cache(maxsize=None)
    def __getitem__(self, item):
        if isinstance(item, tuple):
            return self._child_class(
                path=f'{self._path}/{item[0]}/{item[1]}',
                node=self._node,
                cache=self._cache
            )
        elif isinstance(item, int):
            return OperationList(
                path=f'{self._path}/{item}',
                node=self._node,
                cache=self._cache,
                child_class=self._child_class
            )
        else:
            raise NotImplementedError(item)

    @property
    def endorsements(self):
        """
        The first list contains the endorsements (kind `endorsement`)
        :return: RPCQuery instance
        """
        return self[0]

    @property
    def votes(self):
        """
        The second list contains all the operations regarding votes and proposals (kind `proposals`, `ballot`)
        :return: RPCQuery instance
        """
        return self[1]

    @property
    def anonymous(self):
        """
        The third list contains anonymous operations (kind `seed_nonce_revelation`, `double_endorsement_evidence`,
            `double_baking_evidence`, `activate_account`)
        :return: RPCQuery instance
        """
        return self[2]

    @property
    def managers(self):
        """
        The last one contains the manager operations (`reveal`, `transaction`, `origination`, `delegation`)
        :return: RPCQuery instance
        """
        return self[3]

    def contents(self, kind=None) -> List[dict]:
        return filter_contents(self(), kind)

class Operation(RpcQuery, HelpersMixin):

    def __init__(self, data=None, *args, **kwargs):
        super(Operation, self).__init__(*args, **kwargs)
        self._data = data if data else dict()

    def __repr__(self):
        if self._data:
            return str(self._data)
        return super(Operation, self).__repr__()

    def __call__(self, *args, **kwargs):
        if self._data:
            return self._data
        return super(Operation, self).__call__(*args, **kwargs)

    @classmethod
    def from_data(cls, data: dict):
        return Operation(data)

    def watermark(self):
        content = self.get('contents')[0]
        kind = content['kind']
        if kind in ['endorsement', 'seed_nonce_revelation']:
            return '02' + self.get_chain_watermark()
        if kind in ['transaction', 'origination', 'delegation', 'reveal', 'ballot', 'proposals', 'activate_account']:
            return '03'
        raise NotImplementedError(kind)

    def source(self):
        content = self.get('contents')[0]
        kind = content['kind']
        if kind in ['endorsement']:
            return content['metadata']['delegate']
        if kind == 'activate_account':
            return content['pkh']
        if kind in ['transaction', 'origination', 'delegation', 'reveal', 'ballot', 'proposals']:
            return content['source']
        raise NotImplementedError(f'Operation `{kind}` is anonymous.')

    def protocol(self):

        return protocol

    def unsigned_data(self) -> dict:
        operation = self()
        return {
            'branch': operation['branch'],
            'contents': [
                {k: v for k, v in c.items() if k != 'metadata'}
                for c in operation['contents']
            ]
        }

    def signed_data(self) -> dict:
        return {
            'protocol': self.protocol(),
            'signature': self.get('signature'),
            **self.unsigned_data()
        }

    def unsigned_bytes(self):
        return self.watermark() + self.forge()

    def signed_bytes(self):
        signature_bytes = hexlify(base58_decode(self.get('signature'))).decode()
        return self.forge() + signature_bytes

    def calculate_hash(self):
        hash_digest = blake2b_32(self.signed_bytes()).digest()
        return base58_encode(hash_digest, b'o').decode()

    def forge(self):
        return self._node.post(
            path='chains/main/blocks/head/helpers/forge/operations',
            json=self.unsigned_data(),
            cache=True
        )

    def sign(self, key):
        if isinstance(key, str):
            key = Key(key)
        if not isinstance(key, Key):
            raise ValueError('Base58 encoded secret key or Key instance required.')

        self._data['signature'] = key.sign(self.unsigned_bytes(), generic=True)
        return self._data['signature']

    def preapply(self, branch=None):
        operation = self.signed_data()
        if branch is None:
            branch = operation['branch']

        data = self._node.post(
            path=f'chains/main/blocks/{branch}/helpers/preapply/operations',
            json=[operation],
            cache=True
        )
        self._data['contents'] = data[0]['contents']
        return data

    def verify_signature(self):
        pk = self.get_public_key(self.source())
        Key(pk).verify(self.get('signature'), self.unsigned_bytes())

    def contents(self, kind=None):
        return filter_contents(self(), kind)


from binascii import hexlify
from functools import lru_cache
from typing import List

from pytezos.crypto import Key, blake2b_32
from pytezos.encoding import base58_decode, base58_encode
from pytezos.rpc.node import RpcQuery
from pytezos.rpc.helpers import HelpersMixin

def filter_contents(entity, kind):
    if isinstance(kind, str):
        kind = {kind}
    elif isinstance(kind, list):
        kind = set(kind)

    def iter_contents(op):
        for content in op['contents']:
            internal = content.get('metadata', {}).get('internal_operation_results', [])

            if not kind or content['kind'] in kind:
                if internal:
                    del content['metadata']['internal_operation_results']
                yield content

            for result in internal:
                if not kind or result['kind'] in kind:
                    yield result

    if isinstance(entity, dict):
        return list(iter_contents(entity))

    if isinstance(entity, list):
        contents = list()
        if len(entity) and isinstance(entity[0], list):
            for op_list in entity:
                for op in op_list:
                    contents.extend(iter_contents(op))
        else:
            for op in entity:
                contents.extend(iter_contents(op))
        return contents

    raise ValueError(entity, kind)

class OperationList(RpcQuery):

    def contents(self, kind=None):
        return filter_contents(self(), kind)

class OperationListList(RpcQuery):

    @lru_cache(maxsize=None)
    def __getitem__(self, item):
        if isinstance(item, tuple):
            return self._child_class(
                path=f'{self._path}/{item[0]}/{item[1]}',
                node=self._node,
                cache=self._cache
            )
        elif isinstance(item, int):
            return OperationList(
                path=f'{self._path}/{item}',
                node=self._node,
                cache=self._cache,
                child_class=self._child_class
            )
        else:
            raise NotImplementedError(item)

    @property
    def endorsements(self):
        """
        The first list contains the endorsements (kind `endorsement`)
        :return: RPCQuery instance
        """
        return self[0]

    @property
    def votes(self):
        """
        The second list contains all the operations regarding votes and proposals (kind `proposals`, `ballot`)

    :return: RPCQuery instance
        """
        return self[1]

    @property
    def anonymous(self):
        """
        The third list contains anonymous operations (kind `seed_nonce_revelation`, `double_endorsement_evidence`,
            `double_baking_evidence`, `activate_account`)
        :return: RPCQuery instance
        """
        return self[2]

    @property
    def managers(self):
        """
        The last one contains the manager operations (`reveal`, `transaction`, `origination`, `delegation`)
        :return: RPCQuery instance
        """
        return self[3]

    def contents(self, kind=None) -> List[dict]:
        return filter_contents(self(), kind)

class Operation(RpcQuery, HelpersMixin):

    def __init__(self, data=None, *args, **kwargs):
        super(Operation, self).__init__(*args, **kwargs)
        self._data = data if data else dict()

    def __repr__(self):
        if self._data:
            return str(self._data)
        return super(Operation, self).__repr__()

    def __call__(self, *args, **kwargs):
        if self._data:
            return self._data
        return super(Operation, self).__call__(*args, **kwargs)

    @classmethod
    def from_data(cls, data: dict):
        return Operation(data)

    def watermark(self):
        content = self.get('contents')[0]
        kind = content['kind']
        if kind in ['endorsement', 'seed_nonce_revelation']:
            return '02' + self.get_chain_watermark()
        if kind in ['transaction', 'origination', 'delegation', 'reveal', 'ballot', 'proposals', 'activate_account']:
            return '03'
        raise NotImplementedError(kind)

    def source(self):
        content = self.get('contents')[0]
        kind = content['kind']
        if kind in ['endorsement']:
            return content['metadata']['delegate']
        if kind == 'activate_account':
            return content['pkh']
        if kind in ['transaction', 'origination', 'delegation', 'reveal', 'ballot', 'proposals']:
            return content['source']
        raise NotImplementedError(f'Operation `{kind}` is anonymous.')

    def protocol(self):
        try:
            protocol = self.get('protocol')
        except KeyError:
            branch = self.get("branch")
            protocol = self._node.get(f'chains/main/blocks/{branch}/header').get('protocol')
        return protocol

    def unsigned_data(self) -> dict:
        operation = self()
        return {
            'branch': operation['branch'],
            'contents': [
                {k: v for k, v in c.items() if k != 'metadata'}
                for c in operation['contents']
            ]
        }

    def signed_data(self) -> dict:
        return {
            'protocol': self.protocol(),
            'signature': self.get('signature'),
            **self.unsigned_data()
        }

    def unsigned_bytes(self):
        return self.watermark() + self.forge()

    def signed_bytes(self):
        signature_bytes = hexlify(base58_decode(self.get('signature'))).decode()
        return self.forge() + signature_bytes

    def calculate_hash(self):
        hash_digest = blake2b_32(self.signed_bytes()).digest()
        return base58_encode(hash_digest, b'o').decode()

    def forge(self):
        return self._node.post(
            path='chains/main/blocks/head/helpers/forge/operations',
            json=self.unsigned_data(),
            cache=True
        )

    def sign(self, key):
        if isinstance(key, str):
            key = Key(key)
        if not isinstance(key, Key):
            raise ValueError('Base58 encoded secret key or Key instance required.')

        self._data['signature'] = key.sign(self.unsigned_bytes(), generic=True)
        return self._data['signature']

    def preapply(self, branch=None):
        operation = self.signed_data()
        if branch is None:
            branch = operation['branch']

        data = self._node.post(
            path=f'chains/main/blocks/{branch}/helpers/preapply/operations',
            json=[operation],
            cache=True
        )
        self._data['contents'] = data[0]['contents']
        return data

    def verify_signature(self):
        pk = self.get_public_key(self.source())
        Key(pk).verify(self.get('signature'), self.unsigned_bytes())

    def contents(self, kind=None):
        return filter_contents(self(), kind)


"""A decision tree."""

from typing import Optional, List

from tensorflow_decision_forests.component.py_tree import node as node_lib

class Tree(object):
  """A single decision tree."""

  def __init__(self,
               root: Optional[node_lib.AbstractNode],
               label_classes: Optional[List[str]] = None):
    self._root = root
    self._label_classes = label_classes

  @property
  def root(self):
    return self._root

  @property
  def label_classes(self):
    return self._label_classes

content = "Tree("
    if self._root:
      content += f"{self._root}"
    else:
      content += "None"

    content += ",label_classes={self.label_classes})"
    return content


"""A decision tree."""

from typing import Optional, List

from tensorflow_decision_forests.component.py_tree import node as node_lib

class Tree(object):
  """A single decision tree."""

  def __init__(self,
               root: Optional[node_lib.AbstractNode],
               label_classes: Optional[List[str]] = None):
    self._root = root
    self._label_classes = label_classes

  @property
  def root(self):

  @property
  def label_classes(self):
    return self._label_classes

  def __repr__(self):
    content = "Tree("
    if self._root:
      content += f"{self._root}"
    else:
      content += "None"

    content += ",label_classes={self.label_classes})"
    return content


content = "Tree("
    if self._root:
      content += f"{self._root}"
    else:
      content += "None"

"""A decision tree."""

from typing import Optional, List

from tensorflow_decision_forests.component.py_tree import node as node_lib

class Tree(object):
  """A single decision tree."""

  def __init__(self,
               root: Optional[node_lib.AbstractNode],
               label_classes: Optional[List[str]] = None):
    self._root = root
    self._label_classes = label_classes

  @property
  def root(self):
    return self._root

  @property
  def label_classes(self):
    return self._label_classes

  def __repr__(self):

    content += ",label_classes={self.label_classes})"
    return content


"""A decision tree."""

from typing import Optional, List

from tensorflow_decision_forests.component.py_tree import node as node_lib

class Tree(object):
  """A single decision tree."""

  def __init__(self,
               root: Optional[node_lib.AbstractNode],
               label_classes: Optional[List[str]] = None):
    self._root = root
    self._label_classes = label_classes

  @property
  def root(self):
    return self._root

  @property
  def label_classes(self):
    return self._label_classes

  def __repr__(self):
    content = "Tree("
    if self._root:
      content += f"{self._root}"
    else:
      content += "None"


"""A decision tree."""

from typing import Optional, List

from tensorflow_decision_forests.component.py_tree import node as node_lib

class Tree(object):
  """A single decision tree."""

  def __init__(self,
               root: Optional[node_lib.AbstractNode],
               label_classes: Optional[List[str]] = None):
    self._root = root
    self._label_classes = label_classes

  @property
  def root(self):
    return self._root

  @property
  def label_classes(self):
    return self._label_classes

  def __repr__(self):
    content = "Tree("
    if self._root:
      content += f"{self._root}"
    else:
      content += "None"

    content += ",label_classes={self.label_classes})"


"""A decision tree."""

from typing import Optional, List

from tensorflow_decision_forests.component.py_tree import node as node_lib

class Tree(object):
  """A single decision tree."""

  def __init__(self,
               root: Optional[node_lib.AbstractNode],
               label_classes: Optional[List[str]] = None):
    self._root = root
    self._label_classes = label_classes

  @property
  def root(self):
    return


if self._root:
      content += f"{self._root}"
    else:
      content += "None"

"""A decision tree."""

from typing import Optional, List

from tensorflow_decision_forests.component.py_tree import node as node_lib

class Tree(object):
  """A single decision tree."""

  def __init__(self,
               root: Optional[node_lib.AbstractNode],
               label_classes: Optional[List[str]] = None):
    self._root = root
    self._label_classes = label_classes

  @property
  def root(self):
    return self._root

  @property
  def label_classes(self):
    return self._label_classes

  def __repr__(self):
    content = "Tree("


content += ",label_classes={self.label_classes})"
    return content


import torch
import numpy as np
from scipy.stats import pearsonr, spearmanr

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

print('Compute Pearson Correlation...')

    preds = []
    out_label_ids = []
    for i, (tokens, labels) in enumerate(loader):
        tokens = tokens.to(device)

        with torch.no_grad():
            pred = model(tokens)  # (B, C)

        preds.append(pred.cpu().numpy())
        out_label_ids.append(labels.cpu().numpy())

    preds=np.concatenate(preds)
    out_label_ids=np.concatenate(out_label_ids)
    preds=preds.squeeze()
    out_label_ids=out_label_ids.squeeze()

    pearson_corr = pearsonr(preds, out_label_ids)[0]
    spearman_corr = spearmanr(preds, out_label_ids)[0]

    return (pearson_corr + spearman_corr) / 2


print('Compute Pearson Correlation...')

    preds = []
    out_label_ids = []
    for i, (tokens, labels) in enumerate(loader):
        tokens = tokens.to(device)

        with torch.no_grad():
            pred = model(tokens)  # (B, C)

        preds.append(pred.cpu().numpy())
        out_label_ids.append(labels.cpu().numpy())

import torch
import numpy as np
from scipy.stats import pearsonr, spearmanr

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

def test_pearson(loader, model):

    preds=np.concatenate(preds)
    out_label_ids=np.concatenate(out_label_ids)
    preds=preds.squeeze()
    out_label_ids=out_label_ids.squeeze()

    pearson_corr = pearsonr(preds, out_label_ids)[0]
    spearman_corr = spearmanr(preds, out_label_ids)[0]

    return (pearson_corr + spearman_corr) / 2


preds=np.concatenate(preds)
    out_label_ids=np.concatenate(out_label_ids)
    preds=preds.squeeze()

import torch
import numpy as np
from scipy.stats import pearsonr, spearmanr

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

def test_pearson(loader, model):
    print('Compute Pearson Correlation...')

    preds = []
    out_label_ids = []
    for i, (tokens, labels) in enumerate(loader):
        tokens = tokens.to(device)

        with torch.no_grad():
            pred = model(tokens)  # (B, C)

        preds.append(pred.cpu().numpy())
        out_label_ids.append(labels.cpu().numpy())

    out_label_ids=out_label_ids.squeeze()

    pearson_corr = pearsonr(preds, out_label_ids)[0]
    spearman_corr = spearmanr(preds, out_label_ids)[0]

    return (pearson_corr + spearman_corr) / 2


out_label_ids=out_label_ids.squeeze()

    pearson_corr = pearsonr(preds, out_label_ids)[0]
    spearman_corr = spearmanr(preds, out_label_ids)[0]

    return (pearson_corr + spearman_corr) / 2

import torch
import numpy as np
from scipy.stats import pearsonr, spearmanr

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

def test_pearson(loader, model):
    print('Compute Pearson Correlation...')

    preds = []
    out_label_ids = []
    for i, (tokens, labels) in enumerate(loader):
        tokens = tokens.to(device)

        with torch.no_grad():
            pred = model(tokens)  # (B, C)

        preds.append(pred.cpu().numpy())
        out_label_ids.append(labels.cpu().numpy())

    preds=np.concatenate(preds)
    out_label_ids=np.concatenate(out_label_ids)
    preds=preds.squeeze()