diff --git a/lib/ucoin/__init__.py b/lib/ucoin/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..6f72c61da64512c194e3d338a9e4bc463d1c4e46
--- /dev/null
+++ b/lib/ucoin/__init__.py
@@ -0,0 +1,211 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Caner Candan <caner@candan.fr>, http://caner.candan.fr
+#
+
+__all__ = ['api']
+
+__author__ = 'uCoin team'
+__version__ = '0.2'
+__nonsense__ = 'uCoin'
+
+import requests
+import logging
+import gnupg
+import json
+
+settings = {
+    'server': 'localhost',
+    'port': 8081,
+    'auth': False,
+}
+
+logger = logging.getLogger("ucoin")
+
+
+class Response:
+    """Wrapper of requests.Response class in order to verify signed message."""
+
+    def __init__(self, response):
+        """
+        Arguments:
+        - `self`:
+        - `response`:
+        """
+
+        self.response = response
+        self.status_code = response.status_code
+        self.headers = response.headers
+
+        if settings.get('auth'):
+            self.verified, clear, self.signature = self.split_n_verify(response)
+
+            if not self.verified:
+                raise ValueError('bad signature verification')
+
+            self.text = self.clear_text = clear
+            self.content = self.clear_content = self.text.encode('ascii')
+        else:
+            self.text = response.text
+            self.content = response.content
+
+    def json(self):
+        if not settings.get('auth'):
+            return self.response.json()
+
+        return json.loads(self.text)
+
+    def split_n_verify(self, response):
+        """
+        Split the signed message thanks to the boundary
+        value got in content-type header.
+
+        returns a tuple with the status, the clear message and the signature.
+
+        `response`: the response returns by requests.get() needed
+        to access to headers and response content.
+        """
+
+        begin = '-----BEGIN PGP SIGNATURE-----'
+        end = '-----END PGP SIGNATURE-----'
+        boundary_pattern = 'boundary='
+
+        content_type = response.headers['content-type']
+        boundary = content_type[content_type.index(boundary_pattern)+len(boundary_pattern):]
+        boundary = boundary[:boundary.index(';')].strip()
+
+        data = [x.strip() for x in response.text.split('--%s' % boundary)]
+
+        clear = data[1]
+        signed = data[2][data[2].index(begin):]
+        clearsigned = '-----BEGIN PGP SIGNED MESSAGE-----\nHash: SHA1\n\n%s\n%s' % (clear, signed)
+
+        return (bool(settings['gpg'].verify(clearsigned)), clear, signed)
+
+
+class API:
+    """APIRequest is a class used as an interface.
+    The intermediate derivated classes are the modules
+    and the leaf classes are the API requests."""
+
+    def __init__(self, module, server=None, port=None):
+        """
+        Asks a module in order to create the url
+         used then by derivated classes.
+
+        Arguments:
+        - `module`: module name
+        """
+
+        self.module = module
+        self.server = server
+        self.port = port
+
+        self.headers = {}
+
+        if settings['auth']:
+            self.headers['Accept'] = 'multipart/signed'
+
+    def reverse_url(self, path):
+        """
+        Reverses the url using self.url and path given in parameter.
+
+        Arguments:
+        - `path`: the request path
+        """
+
+        url = 'http://%s:%d/%s' % (self.server if self.server
+                                                else settings['server'],
+                                   self.port if self.port
+                                                else settings['port'],
+                                   self.module)
+        return url + path
+
+    def get(self, **kwargs):
+        """wrapper of overloaded __get__ method."""
+
+        return self.__get__(**kwargs)
+
+    def post(self, **kwargs):
+        """wrapper of overloaded __post__ method."""
+
+        logger.debug('do some work with')
+
+        data = self.__post__(**kwargs)
+
+        logger.debug('and send back')
+
+        return data
+
+    def __get__(self, **kwargs):
+        """interface purpose for GET request"""
+
+        pass
+
+    def __post__(self, **kwargs):
+        """interface purpose for POST request"""
+
+        pass
+
+    def requests_get(self, path, **kwargs):
+        """
+        Requests GET wrapper in order to use API parameters.
+
+        Arguments:
+        - `path`: the request path
+        """
+
+        response = None
+
+        if not settings.get('auth'):
+            response = requests.get(self.reverse_url(path), params=kwargs,
+                                    headers=self.headers)
+        else:
+            response = Response(requests.get(self.reverse_url(path),
+                                             params=kwargs, headers=self.headers))
+
+        if response.status_code != 200:
+            raise ValueError('status code != 200 => %d (%s)'
+                             % (response.status_code, response.text))
+
+        return response
+
+    def requests_post(self, path, **kwargs):
+        """
+        Requests POST wrapper in order to use API parameters.
+
+        Arguments:
+        - `path`: the request path
+        """
+
+        response = requests.post(self.reverse_url(path),
+                                 data=kwargs, headers=self.headers)
+
+        if response.status_code != 200:
+            raise ValueError('status code != 200 => %d (%s)'
+                             % (response.status_code, response.text))
+
+        return response
+
+    def merkle_easy_parser(self, path, begin=None, end=None):
+        root = self.requests_get(path, leaves='true').json()
+        for leaf in root['leaves'][begin:end]:
+            yield self.requests_get(path, leaf=leaf).json()['leaf']
+
+from . import pks
+from . import hdc
+from . import wrappers
+from . import network
diff --git a/lib/ucoin/hdc/__init__.py b/lib/ucoin/hdc/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..fbfe1cd3df612ff8ef2dc2915c6cf2d8a7265681
--- /dev/null
+++ b/lib/ucoin/hdc/__init__.py
@@ -0,0 +1,29 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Caner Candan <caner@candan.fr>, http://caner.candan.fr
+#
+
+from .. import API
+from .. import logging
+
+logger = logging.getLogger("ucoin/hdc")
+
+
+class HDC(API):
+    def __init__(self, module='hdc', server=None, port=None):
+        super().__init__(module, server, port)
+
+from . import amendments, coins, transactions
diff --git a/lib/ucoin/hdc/amendments/__init__.py b/lib/ucoin/hdc/amendments/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..eada4013355063d5c43b3a1eb76e2bfc49a45f56
--- /dev/null
+++ b/lib/ucoin/hdc/amendments/__init__.py
@@ -0,0 +1,66 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Caner Candan <caner@candan.fr>, http://caner.candan.fr
+#
+
+from .. import HDC
+from .. import logging
+
+logger = logging.getLogger("ucoin/hdc/amendments")
+
+
+class Base(HDC):
+    def __init__(self, server=None, port=None):
+        super().__init__('hdc/amendments', server, port)
+
+
+class Promoted(Base):
+    """GET the current promoted amendment (amendment
+    which received enough votes to be accepted)."""
+
+    def __init__(self, number=None, server=None, port=None):
+        """
+        Uses number to fit the result.
+
+        Arguments:
+        - `number`: amendment number
+        """
+
+        super().__init__(server, port)
+
+        self.number = number
+
+    def __get__(self, **kwargs):
+        if not self.number:
+            return self.requests_get('/promoted', **kwargs).json()
+
+        return self.requests_get('/promoted/%d' % self.number, **kwargs).json()
+
+
+class Votes(Base):
+    """GET an index of votes received by this node."""
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/votes', **kwargs).json()
+
+    def __post__(self, **kwargs):
+        assert 'amendment' in kwargs
+        assert 'signature' in kwargs
+        assert 'peer' in kwargs
+
+        return self.requests_post('/votes', **kwargs).json()
+
+from . import view
diff --git a/lib/ucoin/hdc/amendments/view.py b/lib/ucoin/hdc/amendments/view.py
new file mode 100644
index 0000000000000000000000000000000000000000..02a74f1eea3a335703cbbdd3f8876a8365b85e50
--- /dev/null
+++ b/lib/ucoin/hdc/amendments/view.py
@@ -0,0 +1,41 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Caner Candan <caner@candan.fr>, http://caner.candan.fr
+#
+
+from .. import HDC
+from .. import logging
+
+logger = logging.getLogger("ucoin/hdc/amendments/view")
+
+
+class View(HDC):
+    def __init__(self, amendment_id, server=None, port=None):
+        super().__init__('hdc/amendments/view/%s' % amendment_id, server, port)
+
+
+class Self(View):
+    """Shows the raw data of the amendment [AMENDMENT_ID]."""
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/self', **kwargs).json()
+
+
+class Signatures(View):
+    """GET the signatures of the Community listed in this amendment."""
+
+    def __get__(self, **kwargs):
+        return self.merkle_easy_parser('/signatures')
diff --git a/lib/ucoin/hdc/coins/__init__.py b/lib/ucoin/hdc/coins/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..a4915137e5e78e0dd88b0d1b40816e3cdf8253c2
--- /dev/null
+++ b/lib/ucoin/hdc/coins/__init__.py
@@ -0,0 +1,36 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Caner Candan <caner@candan.fr>, http://caner.candan.fr
+#
+
+from .. import HDC
+from .. import logging
+
+logger = logging.getLogger("ucoin/hdc/coins")
+
+
+class Coins(HDC):
+    def __init__(self, pgp_fingerprint, server=None, port=None):
+        super().__init__('hdc/coins/%s' % pgp_fingerprint, server, port)
+
+
+class List(Coins):
+    """GET a list of coins owned by [PGP_FINGERPRINT]."""
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/list', **kwargs).json()
+
+from . import view
diff --git a/lib/ucoin/hdc/coins/view.py b/lib/ucoin/hdc/coins/view.py
new file mode 100644
index 0000000000000000000000000000000000000000..8489bc015fd284290ad9c580b70dd458de814170
--- /dev/null
+++ b/lib/ucoin/hdc/coins/view.py
@@ -0,0 +1,42 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Caner Candan <caner@candan.fr>, http://caner.candan.fr
+#
+
+from .. import HDC
+from .. import logging
+
+logger = logging.getLogger("ucoin/hdc/coins/view")
+
+
+class Base(HDC):
+    def __init__(self, coin_id, server=None, port=None):
+        super().__init__('hdc/coins/view/%s' % coin_id, server, port)
+
+
+class Owner(Base):
+    """GET a coin owner + justifying transaction if it exists."""
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/owner', **kwargs).json()
+
+
+class History(Base):
+    """GET a coin owner + justifying transaction
+    for each state a coin has gone trough."""
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/history', **kwargs).json()
diff --git a/lib/ucoin/hdc/transactions/__init__.py b/lib/ucoin/hdc/transactions/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..60ac2d0645e9de5d609eed80e4851b6c42dc4114
--- /dev/null
+++ b/lib/ucoin/hdc/transactions/__init__.py
@@ -0,0 +1,135 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Caner Candan <caner@candan.fr>, http://caner.candan.fr
+#
+
+from .. import HDC
+from .. import logging
+
+logger = logging.getLogger("ucoin/hdc/transactions")
+
+
+class Base(HDC):
+    def __init__(self, server=None, port=None):
+        super().__init__('hdc/transactions', server, port)
+
+
+class Process(Base):
+    """POST a transaction."""
+
+    def __post__(self, **kwargs):
+        assert 'transaction' in kwargs
+        assert 'signature' in kwargs
+
+        return self.requests_post('/process', **kwargs).json()
+
+
+class Last(Base):
+    """GET the last received transaction."""
+
+    def __init__(self, count=None, server=None, port=None):
+        """
+        Arguments:
+        - `count`: Integer indicating to
+            retrieve the last [COUNT] transactions.
+        """
+
+        super().__init__(server, port)
+
+        self.count = count
+
+    def __get__(self, **kwargs):
+        if not self.count:
+            return self.requests_get('/last', **kwargs).json()
+
+        return self.requests_get('/last/%d' % self.count, **kwargs).json()
+
+
+class Sender(Base):
+    """GET all the transactions sent by this sender and stored
+    by this node (should contain all transactions of the sender)."""
+
+    def __init__(self, pgp_fingerprint, begin=None, end=None, server=None, port=None):
+        """
+        Arguments:
+        - `pgp_fingerprint`: PGP fingerprint of the
+        key we want to see sent transactions.
+        - `begin`: integer value used by the
+         merkle parser to know when to begin requesting.
+        - `end`: integer value used by the
+         merkle parser to know when to end requesting.
+        """
+
+        super().__init__(server, port)
+
+        self.pgp_fingerprint = pgp_fingerprint
+        self.begin = begin
+        self.end = end
+
+    def __get__(self, **kwargs):
+        return self.merkle_easy_parser('/sender/%s' % self.pgp_fingerprint,
+                                       begin=self.begin, end=self.end)
+
+
+class Recipient(Base):
+    """GET all the transactions received for
+        this recipient stored by this node."""
+
+    def __init__(self, pgp_fingerprint, begin=None, end=None,
+                 server=None, port=None):
+        """
+        Arguments:
+        - `pgp_fingerprint`: PGP fingerprint of the
+            key we want to see sent transactions.
+        - `begin`: integer value used by the
+            merkle parser to know when to begin requesting.
+        - `end`: integer value used by the
+            merkle parser to know when to end requesting.
+        """
+
+        super().__init__(server, port)
+
+        self.pgp_fingerprint = pgp_fingerprint
+        self.begin = begin
+        self.end = end
+
+    def __get__(self, **kwargs):
+        return self.merkle_easy_parser('/recipient/%s' % self.pgp_fingerprint,
+                                       begin=self.begin, end=self.end)
+
+
+#TODO: Manager /refering/pgp_fingerprint/tx_number/
+class Refering(Base):
+    """GET all the transactions refering to source
+        transaction #[TX_NUMBER] issued by [PGP_FINGERPRINT]."""
+
+    def __init__(self, pgp_fingerprint, tx_number, server=None, port=None):
+        """
+        Arguments:
+        - `transaction_id`: The transaction unique identifier.
+        """
+
+        super().__init__(server, port)
+
+        self.pgp_fingerprint = pgp_fingerprint
+        self.tx_number = tx_number
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/refering/%s/%d'
+                                 % (self.pgp_fingerprint, self.tx_number),
+                                 **kwargs).json()
+
+from . import sender
diff --git a/lib/ucoin/hdc/transactions/sender/__init__.py b/lib/ucoin/hdc/transactions/sender/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..f7913c6e6b45754e479a8b0d0b925d0e35d0b2bc
--- /dev/null
+++ b/lib/ucoin/hdc/transactions/sender/__init__.py
@@ -0,0 +1,80 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Caner Candan <caner@candan.fr>, http://caner.candan.fr
+#
+
+from ... import HDC
+from ... import logging
+
+logger = logging.getLogger("ucoin/hdc/transactions/sender")
+
+
+class Base(HDC):
+    """Get the last received transaction of a PGP key."""
+
+    def __init__(self, pgp_fingerprint, server=None, port=None):
+        """
+        Arguments:
+        - `pgp_fingerprint`: PGP fingerprint of the key
+         we want to see sent transactions.
+        """
+
+        super().__init__('hdc/transactions/sender/%s' % pgp_fingerprint,
+                          server, port)
+
+
+class Last(Base):
+    """Get the last received transaction of a PGP key."""
+
+    def __init__(self, pgp_fingerprint, count=None, from_=None,
+                server=None, port=None):
+        """
+        Arguments:
+        - `count`: Integer indicating to retrieve the last [COUNT] transactions
+        """
+
+        super().__init__(pgp_fingerprint, server, port)
+
+        self.count = count
+        self.from_ = from_
+
+    def __get__(self, **kwargs):
+        if not self.count:
+            return self.requests_get('/last', **kwargs).json()
+
+        if not self.from_:
+            return self.request_get('/last/%d' % self.count, **kwargs).json()
+
+        return self.requests_get('/last/%d/%d' % (self.count, self.from_),
+                                  **kwargs).json()
+
+
+class View(Base):
+    """GET the transaction of given TRANSACTION_ID."""
+
+    def __init__(self, pgp_fingerprint, tx_number,
+                  server=None, port=None):
+        """
+        Arguments:
+        - `count`: Integer indicating to retrieve the last [COUNT] transactions
+        """
+
+        super().__init__(pgp_fingerprint, server, port)
+
+        self.tx_number = tx_number
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/view/%d' % self.tx_number, **kwargs).json()
diff --git a/lib/ucoin/network/__init__.py b/lib/ucoin/network/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..b791fd978f5939573143003f28829a222b88f856
--- /dev/null
+++ b/lib/ucoin/network/__init__.py
@@ -0,0 +1,72 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Caner Candan <caner@candan.fr>, http://caner.candan.fr
+#
+
+from .. import API
+from .. import logging
+
+logger = logging.getLogger("ucoin/ucg")
+
+
+class Network(API):
+    def __init__(self, module='ucg', server=None, port=None):
+        super().__init__(module, server, port)
+
+
+class Pubkey(Network):
+    """GET the public key of the peer."""
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/pubkey', **kwargs).text
+
+
+class Peering(Network):
+    """GET peering information about a peer."""
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/peering', **kwargs).json()
+
+
+class Wallet(Network):
+    """GET/POST Wallet entries."""
+
+    def __init__(self, pgp_fingerprint=None, server=None, port=None):
+        """
+        Use the pgp fingerprint parameter in order to fit the result.
+
+        Arguments:
+        - `pgp_fingerprint`: pgp fingerprint to use as a filter
+        """
+
+        super().__init__(server, port)
+
+        self.pgp_fingerprint = pgp_fingerprint
+
+    def __get__(self, **kwargs):
+        if not self.pgp_fingerprint:
+            return self.merkle_easy_parser('/wallet')
+
+        return self.merkle_easy_parser('/wallet/%s'
+                                       % self.pgp_fingerprint).json()
+
+    def __post__(self, **kwargs):
+        assert 'entry' in kwargs
+        assert 'signature' in kwargs
+
+        return self.requests_post('/wallet', **kwargs)
+
+from . import peering
diff --git a/lib/ucoin/network/peering/__init__.py b/lib/ucoin/network/peering/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..f0ddc3780268534557fc45f9b29d5abeca164cf6
--- /dev/null
+++ b/lib/ucoin/network/peering/__init__.py
@@ -0,0 +1,62 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Caner Candan <caner@candan.fr>, http://caner.candan.fr
+#networkfrom .. import UCG, logging
+
+from .. import Network
+from .. import logging
+
+logger = logging.getLogger("ucoin/network/peering")
+
+
+class Base(Network):
+    def __init__(self, server=None, port=None):
+        super().__init__('network/peering', server, port)
+
+
+class Peers(Base):
+    """GET peering entries of every node inside the currency network."""
+
+    def __get__(self, **kwargs):
+        """creates a generator with one peering entry per iteration."""
+
+        return self.merkle_easy_parser('/peers')
+
+    def __post__(self, **kwargs):
+        assert 'entry' in kwargs
+        assert 'signature' in kwargs
+
+        return self.requests_post('/peers', **kwargs).json()
+
+class Forward(Base):
+    """POST a UCG forward document to this node in order to be sent back incoming transactions."""
+
+    def __post__(self, **kwargs):
+        assert 'forward' in kwargs
+        assert 'signature' in kwargs
+
+        return self.requests_post('/forward', **kwargs).json()
+
+class Status(Base):
+    """POST a UCG status document to this node in order notify of its status."""
+
+    def __post__(self, **kwargs):
+        assert 'status' in kwargs
+        assert 'signature' in kwargs
+
+        return self.requests_post('/status', **kwargs).json()
+
+from . import peers
diff --git a/lib/ucoin/network/peering/peers.py b/lib/ucoin/network/peering/peers.py
new file mode 100644
index 0000000000000000000000000000000000000000..f69d314aac00a532c5305ebbcc307e1005e4b8f3
--- /dev/null
+++ b/lib/ucoin/network/peering/peers.py
@@ -0,0 +1,79 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Caner Candan <caner@candan.fr>, http://caner.candan.fr
+#
+from .. import Network
+from .. import logging
+
+logger = logging.getLogger("ucoin/network/peering/peers")
+
+class Base(Network):
+    def __init__(self, server=None, port=None):
+        super().__init__('network/peering/peers', server, port)
+
+class Stream(Base):
+    """GET a list of peers this node is listening to/by for ANY incoming transaction."""
+
+    def __init__(self, request, pgp_fingerprint=None, server=None, port=None):
+        """
+        Use the pgp fingerprint parameter in order to fit the result.
+
+        Arguments:
+        - `request`: select the stream request
+        - `pgp_fingerprint`: pgp fingerprint to use as a filter
+        """
+
+        super().__init__(server, port)
+
+        self.request = request
+        self.pgp_fingerprint = pgp_fingerprint
+
+
+class UpStream(Stream):
+    """GET a list of peers this node is listening to for ANY incoming transaction."""
+
+    def __init__(self, pgp_fingerprint=None, server=None, port=None):
+        """
+        Use the pgp fingerprint parameter in order to fit the result.
+
+        Arguments:
+        - `pgp_fingerprint`: pgp fingerprint to use as a filter
+        """
+
+        super().__init__('upstream', pgp_fingerprint, server, port)
+
+    def __get__(self, **kwargs):
+        """returns the corresponding peer list."""
+
+        return self.requests_get('/upstream/%s' % (self.request, self.pgp_fingerprint), **kwargs).json()
+
+class DownStream(Stream):
+    """GET a list of peers this node is listening by for ANY incoming transaction."""
+
+    def __init__(self, pgp_fingerprint=None, server=None, port=None):
+        """
+        Use the pgp fingerprint parameter in order to fit the result.
+
+        Arguments:
+        - `pgp_fingerprint`: pgp fingerprint to use as a filter
+        """
+
+        super().__init__('downstream', pgp_fingerprint, server, port)
+
+    def __get__(self, **kwargs):
+        """returns the corresponding peer list."""
+
+        return self.requests_get('/downstream/%s' % (self.request, self.pgp_fingerprint), **kwargs).json()
diff --git a/lib/ucoin/pks/__init__.py b/lib/ucoin/pks/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..809acbb7f82f2ee4508feee3f5c02627a829bf13
--- /dev/null
+++ b/lib/ucoin/pks/__init__.py
@@ -0,0 +1,60 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Caner Candan <caner@candan.fr>, http://caner.candan.fr
+#
+
+from .. import API
+from .. import logging
+
+logger = logging.getLogger("ucoin/pks")
+
+
+class PKS(API):
+    def __init__(self, module='pks', server=None, port=None):
+        super().__init__(module, server, port)
+
+
+class Add(PKS):
+    """POST ASCII-armored OpenPGP certificates."""
+
+    def __post__(self, **kwargs):
+        assert 'keytext' in kwargs
+        assert 'keysign' in kwargs
+
+        return self.requests_post('/add', **kwargs)
+
+
+class Lookup(PKS):
+    """Allows to search for OpenPGP certificates, according to HKP draft."""
+
+    def __get__(self, **kwargs):
+        assert 'search' in kwargs
+        assert 'op' in kwargs
+
+        r = self.requests_get('/lookup', **kwargs)
+
+        if kwargs['op'] == 'get': return r.text
+
+        return r.json()
+
+
+class All(PKS):
+    """GET all the received public keys."""
+
+    def __get__(self, **kwargs):
+        """creates a generator with one public key per iteration."""
+
+        return self.merkle_easy_parser('/all')
diff --git a/lib/ucoin/registry/__init__.py b/lib/ucoin/registry/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..c3793a484c8e17ca6346c79e31664293d66c5187
--- /dev/null
+++ b/lib/ucoin/registry/__init__.py
@@ -0,0 +1,38 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+from .. import API
+from .. import logging
+
+logger = logging.getLogger("ucoin/registry")
+
+
+class Registry(API):
+    def __init__(self, module='registry', server=None, port=None):
+        super().__init__(module, server, port)
+
+
+class Parameters(Registry):
+    """GET parameters used by this community."""
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/parameters', **kwargs).json()
+
+
+class Amendment(Registry):
+    """GET parameters used by this community."""
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/amendment', **kwargs).json()
diff --git a/lib/ucoin/registry/amendment/__init__.py b/lib/ucoin/registry/amendment/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..7ef12380be969bba04806537db538e79e71eaa2c
--- /dev/null
+++ b/lib/ucoin/registry/amendment/__init__.py
@@ -0,0 +1,37 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+from .. import Registry
+from .. import logging
+
+logger = logging.getLogger("ucoin/registry")
+
+
+class Base(Registry):
+    def __init__(self, server=None, port=None):
+        super().__init__('registry/amendment', server, port)
+
+
+class Vote(Base):
+
+    """GET the vote of current node for given amendment number
+    (both amendment + signature).
+    Such vote may be used by any node to broadcast the whole network."""
+
+    def __init__(self, am_number=None, server=None, port=None):
+        super().__init__(server, port)
+
+    def __get__(self, **kwargs):
+        return self.merkle_easy_parser('/%s/vote' % self.am_number)
diff --git a/lib/ucoin/registry/community/__init__.py b/lib/ucoin/registry/community/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..6c21d5e5a59fdd5323f0421d574efca5d93fb556
--- /dev/null
+++ b/lib/ucoin/registry/community/__init__.py
@@ -0,0 +1,38 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+from .. import Registry
+from .. import logging
+
+logger = logging.getLogger("ucoin/registry")
+
+
+class Base(Registry):
+    def __init__(self, server=None, port=None):
+        super().__init__('registry/community', server, port)
+
+
+class Members(Base):
+    """GET the members present in the Community for this amendment."""
+
+    def __get__(self, **kwargs):
+        return self.merkle_easy_parser('/members')
+
+
+class Voters(Base):
+    """GET the voters listed in this amendment."""
+
+    def __get__(self, **kwargs):
+        return self.merkle_easy_parser('/voters')
diff --git a/lib/ucoin/registry/community/members.py b/lib/ucoin/registry/community/members.py
new file mode 100644
index 0000000000000000000000000000000000000000..55de75cd892c72e4a5d3e7e6397cfa42a53d3501
--- /dev/null
+++ b/lib/ucoin/registry/community/members.py
@@ -0,0 +1,65 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+
+from .. import Registry
+from .. import logging
+
+logger = logging.getLogger("ucoin/registry/community")
+
+
+class Base(Registry):
+    def __init__(self, server=None, port=None):
+        super().__init__('hdc/registry/community', server, port)
+
+
+class Current(Base):
+    """GET the last valid membership document for member pgp_fingerprint"""
+
+    def __init__(self, pgp_fingerprint=None, server=None, port=None):
+        """
+        Uses number to fit the result.
+
+        Arguments:
+        - `number`: amendment number
+        """
+
+        super().__init__(server, port)
+
+        self.pgp_fingerprint = pgp_fingerprint
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/members/%s/current' % self.pgp_fingerprint,
+                                 **kwargs).json()
+
+
+class History(Base):
+    """GET the all received and stored membership documents"""
+
+    def __init__(self, pgp_fingerprint=None, server=None, port=None):
+        """
+        Uses number to fit the result.
+
+        Arguments:
+        - `number`: amendment number
+        """
+
+        super().__init__(server, port)
+
+        self.pgp_fingerprint = pgp_fingerprint
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/members/%s/history' % self.pgp_fingerprint,
+                                 **kwargs).json()
diff --git a/lib/ucoin/registry/community/voters.py b/lib/ucoin/registry/community/voters.py
new file mode 100644
index 0000000000000000000000000000000000000000..9f403502f137772bba3cf67b4b4039542efdc3bc
--- /dev/null
+++ b/lib/ucoin/registry/community/voters.py
@@ -0,0 +1,65 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+
+from .. import Registry
+from .. import logging
+
+logger = logging.getLogger("ucoin/registry/community")
+
+
+class Base(Registry):
+    def __init__(self, server=None, port=None):
+        super().__init__('hdc/registry/community', server, port)
+
+
+class Current(Base):
+    """GET the last valid membership document for member pgp_fingerprint"""
+
+    def __init__(self, pgp_fingerprint=None, server=None, port=None):
+        """
+        Uses number to fit the result.
+
+        Arguments:
+        - `number`: amendment number
+        """
+
+        super().__init__(server, port)
+
+        self.pgp_fingerprint = pgp_fingerprint
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/voters/%s/current' % self.pgp_fingerprint,
+                                 **kwargs).json()
+
+
+class History(Base):
+    """GET the all received and stored membership documents"""
+
+    def __init__(self, pgp_fingerprint=None, server=None, port=None):
+        """
+        Uses number to fit the result.
+
+        Arguments:
+        - `number`: amendment number
+        """
+
+        super().__init__(server, port)
+
+        self.pgp_fingerprint = pgp_fingerprint
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/voters/%s/history' % self.pgp_fingerprint,
+                                 **kwargs).json()
diff --git a/lib/ucoin/wrappers/__init__.py b/lib/ucoin/wrappers/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..55b11c19314f98130db7c060adc5969362954c84
--- /dev/null
+++ b/lib/ucoin/wrappers/__init__.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python3
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Caner Candan <caner@candan.fr>, http://caner.candan.fr
+#
+
+import logging
+from .. import pks, hdc, settings
+import network
+
+logger = logging.getLogger("wrappers")
+
+class Wrapper:
+    def __init__(self, server=None, port=None):
+        self.server = server
+        self.port = port
+
+    def __call__(self):
+        pass
+
+from . import transactions, coins
diff --git a/lib/ucoin/wrappers/coins.py b/lib/ucoin/wrappers/coins.py
new file mode 100644
index 0000000000000000000000000000000000000000..1793a0f98a5162b685690dab7127e98e526e36f3
--- /dev/null
+++ b/lib/ucoin/wrappers/coins.py
@@ -0,0 +1,86 @@
+#!/usr/bin/env python3
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Caner Candan <caner@candan.fr>, http://caner.candan.fr
+#
+
+import logging
+from . import Wrapper, pks, ucg, hdc, settings
+
+logger = logging.getLogger("coins")
+
+class Coins(Wrapper):
+    def __init__(self, pgp_fingerprint, server=None, port=None):
+        super().__init__(server, port)
+
+        self.pgp_fingerprint = pgp_fingerprint
+
+class Get(Coins):
+    def __init__(self, pgp_fingerprint, values, server=None, port=None):
+        super().__init__(pgp_fingerprint, server, port)
+
+        self.values = values
+
+    def __call__(self):
+        __list = hdc.coins.List(self.pgp_fingerprint, self.server, self.port).get()
+        coins = {}
+        for c in __list['coins']:
+            for id in c['ids']:
+                n,b,p,t,i = id.split('-')
+                amount = int(b) * 10**int(p)
+                if amount not in coins: coins[amount] = []
+                coins[amount].append({'issuer': c['issuer'], 'number': int(n), 'base': int(b), 'power': int(p), 'type': t, 'type_number': int(i), 'amount': amount})
+
+        issuers = {}
+        for v in self.values:
+            if v in coins and coins[v]:
+                c = coins[v].pop()
+                issuers[c['issuer']] = issuers.get(c['issuer']) or []
+                issuers[c['issuer']].append(c)
+            else:
+                raise ValueError('You do not have enough coins of value (%d)' % v)
+
+        res = ''
+        for i, issuer in enumerate(issuers):
+            if i > 0: res += ','
+            res += issuer
+            for c in issuers[issuer]:
+                res += ':%(number)d' % c
+
+        return res
+
+class List(Coins):
+    def __init__(self, pgp_fingerprint, limit=None, server=None, port=None):
+        super().__init__(pgp_fingerprint, server, port)
+
+        self.limit = limit
+
+    def __call__(self):
+        __list = hdc.coins.List(self.pgp_fingerprint, self.server, self.port).get()
+        coins = []
+        __sum = 0
+
+        for c in __list['coins']:
+            for id in c['ids']:
+                n,b,p,t,i = id.split('-')
+                amount = int(b) * 10**int(p)
+                __dict = {'issuer': c['issuer'], 'number': int(n), 'base': int(b), 'power': int(p), 'type': t, 'type_number': int(i), 'amount': amount}
+
+                if not self.limit or self.limit >= amount:
+                    coins.append(__dict)
+                    __sum += amount
+
+        return __sum, coins
diff --git a/lib/ucoin/wrappers/transactions.py b/lib/ucoin/wrappers/transactions.py
new file mode 100644
index 0000000000000000000000000000000000000000..f4cc1f5bec5d154a2015ffe0de1fa8ad08599c52
--- /dev/null
+++ b/lib/ucoin/wrappers/transactions.py
@@ -0,0 +1,255 @@
+#!/usr/bin/env python3
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Caner Candan <caner@candan.fr>, http://caner.candan.fr
+#
+
+import hashlib, logging
+from . import Wrapper, pks, ucg, hdc, settings
+
+logger = logging.getLogger("transactions")
+
+class Transaction(Wrapper):
+    def __init__(self, type, pgp_fingerprint, message='', keyid=None, peering=None, server=None, port=None):
+        super().__init__(server, port)
+        self.keyid = keyid
+        self.pgp_fingerprint = pgp_fingerprint
+        self.message = message
+        self.type = type
+        self.error = None
+        self.peering = peering
+
+    def __call__(self):
+        try:
+            last_tx = hdc.transactions.sender.Last(self.pgp_fingerprint, server=self.server, port=self.port).get()
+        except ValueError:
+            last_tx = None
+
+        context_data = {}
+        context_data.update(settings)
+        context_data.update(self.peering if self.peering else ucg.Peering().get())
+        context_data['version'] = 1
+        context_data['number'] = 0 if not last_tx else last_tx['transaction']['number']+1
+        context_data['previousHash'] = hashlib.sha1(("%(raw)s%(signature)s" % last_tx).encode('ascii')).hexdigest().upper() if last_tx else None
+        context_data['message'] = self.message
+        context_data['type'] = self.type
+        context_data['fingerprint'] = self.pgp_fingerprint
+        context_data.update(self.get_context_data())
+
+        tx = """\
+Version: %(version)d
+Currency: %(currency)s
+Sender: %(fingerprint)s
+Number: %(number)d
+""" % context_data
+
+        if last_tx: tx += "PreviousHash: %(previousHash)s\n" % context_data
+
+        try:
+            tx += self.get_message(context_data)
+        except ValueError as e:
+            self.error = e
+            return False
+
+        tx += """\
+Comment:
+%(message)s
+""" % context_data
+
+        tx = tx.replace("\n", "\r\n")
+        txs = settings['gpg'].sign(tx, keyid=self.keyid, detach=True)
+
+        return self.process(tx, txs)
+
+    def get_context_data(self):
+        return {}
+
+    def get_message(self, context_data, tx=''):
+        return tx
+
+    def get_error(self):
+        return self.error
+
+    def process(self, tx, txs):
+        try:
+            hdc.transactions.Process(self.server, self.port).post(transaction=tx, signature=txs)
+        except ValueError as e:
+            self.error = str(e)
+        else:
+            return True
+
+        return False
+
+    def parse_coins(self, coins_message):
+        coins = []
+        for coin in coins_message.split(','):
+            data = coin.split(':')
+            issuer, numbers = data[0], data[1:]
+            for number in numbers:
+                view = hdc.coins.View(issuer, int(number), self.server, self.port).get()
+                if view['owner'] != self.pgp_fingerprint:
+                    raise ValueError('Trying to divide a coin you do not own (%s)' % view['id'])
+                coins.append(view)
+        return coins
+
+    def get_coins_sum(self, coins):
+        __sum = 0
+        for coin in coins:
+            base, power = coin['id'].split('-')[2:4]
+            __sum += int(base) * 10**int(power)
+        return __sum
+
+    def check_coins_sum(self, __sum):
+        m = re.match(r'^(\d)(0*)$', str(__sum))
+        if not m: raise ValueError('bad sum value %d' % __sum)
+
+class Transfer(Transaction):
+    def __init__(self, pgp_fingerprint, recipient, coins, message='', keyid=None, server=None, port=None):
+        super().__init__('TRANSFER', pgp_fingerprint, message, keyid=keyid, server=server, port=port)
+
+        self.recipient = recipient
+        self.coins = coins
+
+    def get_message(self, context_data, tx=''):
+        context_data['recipient'] = self.recipient
+
+        tx += """\
+Recipient: %(recipient)s
+Type: %(type)s
+Coins:
+""" % context_data
+
+        for coin in self.coins.split(','):
+            data = coin.split(':')
+            issuer = data[0]
+
+            for number in data[1:]:
+                context_data.update(hdc.coins.View(issuer, int(number), self.server, self.port).get())
+                tx += '%(id)s, %(transaction)s\n' % context_data
+        return tx
+
+
+class RawTransfer(Transaction):
+    def __init__(self, pgp_fingerprint, recipient, coins, message='', keyid=None, server=None, port=None):
+        super().__init__('TRANSFER', pgp_fingerprint, message, keyid=keyid, server=server, port=port)
+
+        self.recipient = recipient
+        self.coins = coins
+
+    def get_message(self, context_data, tx=''):
+        context_data['recipient'] = self.recipient
+
+        tx += """\
+Recipient: %(recipient)s
+Type: %(type)s
+Coins:
+""" % context_data
+
+        for coin in self.coins:
+            data = coin.split('-')
+            context_data.update(hdc.coins.View(data[0], int(data[1]), self.server, self.port).get())
+            tx += '%(id)s, %(transaction)s\n' % context_data
+
+        return tx
+
+
+class MonoTransaction(Transaction):
+    def get_next_coin_number(self, coins):
+        number = 0
+        for c in coins:
+            candidate = int(c['id'].split('-')[1])
+            if candidate > number: number = candidate
+        return number+1
+
+    def get_message(self, context_data, tx=''):
+        tx += """\
+Recipient: %(fingerprint)s
+Type: %(type)s
+Coins:
+""" % context_data
+
+        try:
+            last_issuance = hdc.transactions.sender.issuance.Last(self.pgp_fingerprint, self.server, self.port).get()
+        except ValueError:
+            last_issuance = None
+
+        context_data['previous_idx'] = 0 if not last_issuance else self.get_next_coin_number(last_issuance['transaction']['coins'])
+
+        tx += self.get_mono_message(context_data)
+
+        return tx
+
+    def get_mono_message(self, context_data, tx=''):
+        return tx
+
+class Issue(MonoTransaction):
+    def __init__(self, pgp_fingerprint, amendment, coins, message='', keyid=None, server=None, port=None):
+        super().__init__('ISSUANCE', pgp_fingerprint, message, keyid=keyid, server=server, port=port)
+
+        self.amendment = amendment
+        self.coins = coins
+
+    def get_mono_message(self, context_data, tx=''):
+        context_data['amendment'] = self.amendment
+
+        for idx, coin in enumerate(self.coins):
+            context_data['idx'] = idx + context_data['previous_idx']
+            context_data['base'], context_data['power'] = [int(x) for x in coin.split(',')]
+            tx += '%(fingerprint)s-%(idx)d-%(base)d-%(power)d-A-%(amendment)d\n' % context_data
+
+        return tx
+
+class Fusion(MonoTransaction):
+    def __init__(self, pgp_fingerprint, coins, message='', keyid=None, server=None, port=None):
+        super().__init__('FUSION', pgp_fingerprint, message, keyid=keyid, server=server, port=port)
+
+        self.coins = coins
+
+    def get_mono_message(self, context_data, tx=''):
+        coins = self.parse_coins(self.coins)
+        self.check_coins_sum(self.get_coins_sum(coins))
+
+        context_data['base'], context_data['power'] = int(m.groups()[0]), len(m.groups()[1])
+        tx += '%(fingerprint)s-%(previous_idx)d-%(base)d-%(power)d-F-%(number)d\n' % context_data
+
+        for coin in coins: tx += '%(id)s, %(transaction)s\n' % coin
+
+        return tx
+
+class Divide(MonoTransaction):
+    def __init__(self, pgp_fingerprint, old_coins, new_coins, message='', keyid=None, server=None, port=None):
+        super().__init__('DIVISION', pgp_fingerprint, message, keyid=keyid, server=server, port=port)
+
+        self.old_coins = old_coins
+        self.new_coins = new_coins
+
+    def get_mono_message(self, context_data, tx=''):
+        old_coins = self.parse_coins(self.old_coins)
+        old_coins_sum = self.get_coins_sum(old_coins)
+
+        new_coins_sum = 0
+        for idx, coin in enumerate(self.new_coins):
+            context_data['idx'] = idx + context_data['previous_idx']
+            context_data['base'], context_data['power'] = [int(x) for x in coin.split(',')]
+            new_coins_sum += context_data['base'] * 10**context_data['power']
+            tx += '%(fingerprint)s-%(idx)d-%(base)d-%(power)d-D-%(number)d\n' % context_data
+
+        if old_coins_sum != new_coins_sum:
+            raise ValueError('Amount of old coins (%d) is not equal to new coins (%d)' % (old_coins_sum, new_coins_sum))
+
+        for coin in old_coins: tx += '%(id)s, %(transaction)s\n' % coin
+
+        return tx