diff --git a/__init__.py b/__init__.py
index 62ea64ab7eb9621e6623d25cbfb44325ae526778..38a920998b23a4645a39eff0789e6bb6b8e88108 100644
--- a/__init__.py
+++ b/__init__.py
@@ -177,9 +177,9 @@ class API:
 
         return response
 
-    def merkle_easy_parser(self, path):
+    def merkle_easy_parser(self, path, begin=None, end=None):
         root = self.requests_get(path, leaves='true').json()
-        for leaf in root['leaves']:
+        for leaf in root['leaves'][begin:end]:
             yield self.requests_get(path, leaf=leaf).json()['leaf']
 
 from . import pks, ucg, hdc, wrappers
diff --git a/hdc/transactions/__init__.py b/hdc/transactions/__init__.py
index cc230c0ae2e9b60515223d9b468c9cd0b19d7abb..61b6bb61ce0d79816aecd0645d20e14802aded8e 100644
--- a/hdc/transactions/__init__.py
+++ b/hdc/transactions/__init__.py
@@ -71,34 +71,42 @@ class Last(Base):
 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):
+    def __init__(self, pgp_fingerprint, begin=None, end=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__()
 
         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)
+        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):
+    def __init__(self, pgp_fingerprint, begin=None, end=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__()
 
         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)
+        return self.merkle_easy_parser('/recipient/%s' % self.pgp_fingerprint, begin=self.begin, end=self.end)
 
 class View(Base):
     """GET the transaction of given TRANSACTION_ID."""
diff --git a/wrappers/__init__.py b/wrappers/__init__.py
index d4a272760f74cc98cc7ea12e80c85028b5738dd7..2e7f868a60bc02826c92644038f2d16810c14448 100644
--- a/wrappers/__init__.py
+++ b/wrappers/__init__.py
@@ -17,7 +17,7 @@
 # Caner Candan <caner@candan.fr>, http://caner.candan.fr
 #
 
-import hashlib, logging
+import logging
 from .. import pks, ucg, hdc, settings
 
 logger = logging.getLogger("wrappers")
@@ -26,170 +26,4 @@ class Wrapper:
     def __call__(self):
         pass
 
-class Transaction(Wrapper):
-    def __init__(self, type, pgp_fingerprint, message=''):
-        self.pgp_fingerprint = pgp_fingerprint
-        self.message = message
-        self.type = type
-
-    def __call__(self):
-        try:
-            last_tx = hdc.transactions.sender.Last(self.pgp_fingerprint).get()
-        except ValueError:
-            last_tx = None
-
-        context_data = {}
-        context_data.update(settings)
-        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.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
-
-        tx += self.get_message(context_data)
-
-        tx += """\
-Comment:
-%(message)s
-""" % context_data
-
-        tx = tx.replace("\n", "\r\n")
-        txs = settings['gpg'].sign(tx, detach=True)
-
-        return self.process(tx, txs)
-
-    def get_context_data(self):
-        return {}
-
-    def get_message(self, context_data, tx=''):
-        return tx
-
-    def process(self, tx, txs):
-        try:
-            hdc.transactions.Process().post(transaction=tx, signature=txs)
-        except ValueError as e:
-            print(e)
-        else:
-            return True
-
-        return False
-
-class Transfer(Transaction):
-    def __init__(self, pgp_fingerprint, recipient, coins, message=''):
-        super().__init__('TRANSFER', pgp_fingerprint, message)
-        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)).get())
-                tx += '%(id)s, %(transaction)s\n' % context_data
-
-        return tx
-
-class Issue(Transaction):
-    def __init__(self, pgp_fingerprint, amendment, coins, message=''):
-        super().__init__('ISSUANCE', pgp_fingerprint, message)
-        self.amendment = amendment
-        self.coins = coins
-
-    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=''):
-        context_data['amendment'] = self.amendment
-
-        tx += """\
-Recipient: %(fingerprint)s
-Type: %(type)s
-Coins:
-""" % context_data
-
-        try:
-            last_issuance = hdc.transactions.sender.issuance.Last(self.pgp_fingerprint).get()
-        except ValueError:
-            last_issuance = None
-
-        previous_idx = 0 if not last_issuance else self.get_next_coin_number(last_issuance['transaction']['coins'])
-
-        for idx, coin in enumerate(self.coins):
-            context_data['idx'] = idx+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 CoinsWrapper(Wrapper):
-    def __init__(self, pgp_fingerprint):
-        self.pgp_fingerprint = pgp_fingerprint
-
-class CoinsGet(CoinsWrapper):
-    def __init__(self, pgp_fingerprint, values):
-        super().__init__(pgp_fingerprint)
-        self.values = values
-
-    def __call__(self):
-        __list = hdc.coins.List(self.pgp_fingerprint).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)
-                coins[amount] = {'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:
-                c = coins[v]
-                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 CoinsList(CoinsWrapper):
-    def __call__(self):
-        __list = hdc.coins.List(self.pgp_fingerprint).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}
-                coins.append(__dict)
-                __sum += amount
-        return __sum, coins
+from . import transactions, coins
diff --git a/wrappers/coins.py b/wrappers/coins.py
new file mode 100644
index 0000000000000000000000000000000000000000..106898563ce98ed6360d72796cfeb2197e12f224
--- /dev/null
+++ b/wrappers/coins.py
@@ -0,0 +1,82 @@
+#!/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):
+        self.pgp_fingerprint = pgp_fingerprint
+
+class Get(Coins):
+    def __init__(self, pgp_fingerprint, values):
+        super().__init__(pgp_fingerprint)
+        self.values = values
+
+    def __call__(self):
+        __list = hdc.coins.List(self.pgp_fingerprint).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):
+        super().__init__(pgp_fingerprint)
+        self.limit = limit
+
+    def __call__(self):
+        __list = hdc.coins.List(self.pgp_fingerprint).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/wrappers/transactions.py b/wrappers/transactions.py
new file mode 100644
index 0000000000000000000000000000000000000000..670dbffaab7902c6c9db435ee2d9fa69a845c0e8
--- /dev/null
+++ b/wrappers/transactions.py
@@ -0,0 +1,224 @@
+#!/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='', peering=None):
+        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).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, 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().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)).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=''):
+        super().__init__('TRANSFER', pgp_fingerprint, message)
+        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)).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).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=''):
+        super().__init__('ISSUANCE', pgp_fingerprint, message)
+        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=''):
+        super().__init__('FUSION', pgp_fingerprint, message)
+        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=''):
+        super().__init__('DIVISION', pgp_fingerprint, message)
+        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