diff --git a/wrappers/__init__.py b/wrappers/__init__.py
index 3845696e38c2ecb34fedb9578d4012840abf2a95..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,229 +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
-        self.error = None
-
-    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)
-
-        if self.error: return False
-
-        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
-
-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=''):
-        context_data['coins'] = self.coins
-
-        coins = []
-        for coin in context_data['coins'].split(','):
-            data = coin.split(':')
-            issuer, numbers = data[0], data[1:]
-            for number in numbers:
-                coins.append(ucoin.hdc.coins.View(issuer, int(number)).get())
-
-        __sum = 0
-        for coin in coins:
-            base, power = coin['id'].split('-')[2:4]
-            __sum += int(base) * 10**int(power)
-
-        m = re.match(r'^(\d)(0*)$', str(__sum))
-
-        if not m:
-            self.error = 'bad sum value %d' % __sum
-            return tx
-
-        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:
-            context_data.update(coin)
-            tx += '%(id)s, %(transaction)s\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)
-                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 CoinsList(CoinsWrapper):
-    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
+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..e44ba09a2c65586b6dcfddb1f3e90da6be09c277
--- /dev/null
+++ b/wrappers/transactions.py
@@ -0,0 +1,191 @@
+#!/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=''):
+        self.pgp_fingerprint = pgp_fingerprint
+        self.message = message
+        self.type = type
+        self.error = None
+
+    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)
+
+        if self.error: return False
+
+        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
+
+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=''):
+        context_data['coins'] = self.coins
+
+        coins = []
+        for coin in context_data['coins'].split(','):
+            data = coin.split(':')
+            issuer, numbers = data[0], data[1:]
+            for number in numbers:
+                coins.append(ucoin.hdc.coins.View(issuer, int(number)).get())
+
+        __sum = 0
+        for coin in coins:
+            base, power = coin['id'].split('-')[2:4]
+            __sum += int(base) * 10**int(power)
+
+        m = re.match(r'^(\d)(0*)$', str(__sum))
+
+        if not m:
+            self.error = 'bad sum value %d' % __sum
+            return tx
+
+        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:
+            context_data.update(coin)
+            tx += '%(id)s, %(transaction)s\n' % context_data
+
+        return tx