diff --git a/src/cutecoin/core/account.py b/src/cutecoin/core/account.py
index 2a8f01a376073f3cfff35bba7e4392eb3c65de52..aad96327eab228fe8b031b498dc2358d810db7f7 100644
--- a/src/cutecoin/core/account.py
+++ b/src/cutecoin/core/account.py
@@ -178,38 +178,13 @@ class Account(object):
                 sources.append(s)
         return sources
 
-    def transactions_received(self, community):
-        received = []
-        for w in self.wallets:
-            for tx in w.transactions_received(community):
-                # Lets remove transactions from our own wallets
-                pubkeys = [wallet.pubkey for wallet in self.wallets]
-                if tx[1].issuers[0] not in pubkeys:
-                    received.append(tx)
-        return received
-
-    def transactions_sent(self, community):
+    def transfers(self, community):
         sent = []
         for w in self.wallets:
-            for tx in w.transactions_sent(community):
-                # Lets remove transactions to our own wallets
-                pubkeys = [wallet.pubkey for wallet in self.wallets]
-                outputs = [o for o in tx[1].outputs if o.pubkey not in pubkeys]
-                if len(outputs) > 0:
-                    sent.append(tx)
+            for transfer in w.transfers(community):
+                sent.append(transfer)
         return sent
 
-    def transactions_awaiting(self, community):
-        awaiting = []
-        for w in self.wallets:
-            for tx in w.transactions_awaiting(community):
-                # Lets remove transactions to our own wallets
-                pubkeys = [wallet.pubkey for wallet in self.wallets]
-                outputs = [o for o in tx[1].outputs if o.pubkey not in pubkeys]
-                if len(outputs) > 0:
-                    awaiting.append(tx)
-        return awaiting
-
     def member_of(self, community):
         pubkeys = community.members_pubkeys()
         if self.pubkey not in pubkeys:
diff --git a/src/cutecoin/core/transfer.py b/src/cutecoin/core/transfer.py
new file mode 100644
index 0000000000000000000000000000000000000000..7718396c8d06d864c50c5256102f6b8dae9a446a
--- /dev/null
+++ b/src/cutecoin/core/transfer.py
@@ -0,0 +1,81 @@
+'''
+Created on 31 janv. 2015
+
+@author: inso
+'''
+
+from ucoinpy.api import bma
+from ucoinpy.documents.transaction import Transaction
+
+
+class Transfer(object):
+    '''
+    A transaction
+    '''
+    TO_SEND = 0
+    AWAITING = 1
+    VALIDATED = 2
+    REFUSED = 3
+    SENT = 4
+    DROPPED = 5
+
+    def __init__(self, txdoc, state, metadata):
+        '''
+        Constructor
+        '''
+        self.txdoc = txdoc
+        self.state = state
+        self.metadata = metadata
+
+    @classmethod
+    def initiate(cls, txdoc, block, amount):
+        return cls(txdoc, Transfer.TO_SEND, {'block': block,
+                                             'amount': amount,
+                                             'issuer': txdoc.issuers[0]})
+
+    @classmethod
+    def create_validated(cls, txdoc, metadata):
+        return cls(txdoc, Transfer.VALIDATED, metadata)
+
+    @classmethod
+    def load(cls, data):
+        txdoc = Transaction.from_signed_raw(data['txdoc'])
+        return cls(txdoc, data['state'], data['metadata'])
+
+    def jsonify(self):
+        return {'txdoc': self.txdoc.signed_raw(),
+                'state': self.state,
+                'metadata': self.metadata}
+
+    def send(self, community):
+        try:
+            community.broadcast(bma.tx.Process,
+                        post_args={'transaction': self.txdoc.signed_raw()})
+            self.state = Transfer.AWAITING
+        except ValueError as e:
+            if '400' in e:
+                self.state = Transfer.REFUSED
+            raise
+        finally:
+            self.metadata['block'] = community.current_blockid['number']
+            self.metadata['time'] = community.get_block().time
+
+    def check_registered(self, tx, metadata):
+        if tx.signed_raw() == self.txdoc.signed_raw():
+            self.state = Transfer.VALIDATED
+            self.metadata = metadata
+        if metadata['block'] > self.metadata['block'] + 15:
+            self.state = Transfer.REFUSED
+
+
+class Received(Transfer):
+    def __init__(self, txdoc, metadata):
+        '''
+        Constructor
+        '''
+        super().__init__(txdoc, Transfer.VALIDATED, metadata)
+
+    @classmethod
+    def load(cls, data):
+        txdoc = Transaction.from_signed_raw(data['txdoc'])
+        return cls(txdoc, data['metadata'])
diff --git a/src/cutecoin/core/wallet.py b/src/cutecoin/core/wallet.py
index 925da2a997ada03157861c43e8496b047309f729..d30607c182b2a5d134efdb74722ce0e8731542d3 100644
--- a/src/cutecoin/core/wallet.py
+++ b/src/cutecoin/core/wallet.py
@@ -10,6 +10,7 @@ from ucoinpy.documents.block import Block
 from ucoinpy.documents.transaction import InputSource, OutputSource, Transaction
 from ucoinpy.key import SigningKey
 from ..tools.exceptions import NotEnoughMoneyError, NoPeerAvailable
+from cutecoin.core.transfer import Transfer, Received
 import logging
 
 
@@ -18,49 +19,29 @@ class Cache():
         self.latest_block = 0
         self.wallet = wallet
 
-        self.tx_sent = []
-        self.tx_awaiting = []
-        self.tx_received = []
-        self.tx_to_send = []
+        self._transfers = []
         self.available_sources = []
 
     def load_from_json(self, data):
-        self.tx_received = []
-        self.tx_sent = []
-        self.tx_awaiting = []
+        self._transfers = []
         logging.debug(data)
 
-        data_received = data['received']
-        for r in data_received:
-            self.tx_received.append((r['block'], Transaction.from_signed_raw(r['raw'])))
-
-        data_sent = data['sent']
+        data_sent = data['transfers']
         for s in data_sent:
-            self.tx_sent.append((r['block'], Transaction.from_signed_raw(s['raw'])))
-
-        data_awaiting = data['awaiting']
-        for s in data_awaiting:
-            self.tx_awaiting.append((r['block'], Transaction.from_signed_raw(s['raw'])))
+            if s['metadata']['issuer'] == self.wallet.pubkey:
+                self._transfers.append(Transfer.load(s))
+            else:
+                self._transfers.append(Received.load(s))
 
-        if 'sources' in data:
-            data_sources = data['sources']
-            for s in data_sources:
-                self.available_sources.append(InputSource.from_inline(s['inline']))
+        for s in data['sources']:
+            self.available_sources.append(InputSource.from_inline(s['inline']))
 
         self.latest_block = data['latest_block']
 
     def jsonify(self):
-        data_received = []
-        for r in self.tx_received:
-            data_received.append({'block': r[0], 'raw': r[1].signed_raw()})
-
-        data_sent = []
-        for s in self.tx_sent:
-            data_sent.append({'block': r[0], 'raw': s[1].signed_raw()})
-
-        data_awaiting = []
-        for s in self.tx_awaiting:
-            data_awaiting.append({'block': r[0], 'raw': s[1].signed_raw()})
+        data_transfer = []
+        for s in self._transfers:
+            data_transfer.append(s.jsonify())
 
         data_sources = []
         for s in self.available_sources:
@@ -68,19 +49,12 @@ class Cache():
             data_sources.append({'inline': "{0}\n".format(s.inline())})
 
         return {'latest_block': self.latest_block,
-                'received': data_received,
-                'sent': data_sent,
-                'awaiting': data_awaiting,
+                'transfers': data_transfer,
                 'sources': data_sources}
 
-    def latest_sent(self, community):
-        return self.tx_sent
-
-    def awaiting(self, community):
-        return self.tx_awaiting
-
-    def latest_received(self, community):
-        return self.tx_received
+    @property
+    def transfers(self):
+        return self._transfers
 
     def refresh(self, community):
         current_block = 0
@@ -106,21 +80,44 @@ class Cache():
             for block_number in parsed_blocks:
                 block = community.request(bma.blockchain.Block,
                                   req_args={'number': block_number})
-                signed_raw = "{0}{1}\n".format(block['raw'], block['signature'])
+                signed_raw = "{0}{1}\n".format(block['raw'],
+                                               block['signature'])
                 block_doc = Block.from_signed_raw(signed_raw)
+                metadata = {'block': block_number,
+                            'time': block_doc.time}
                 for tx in block_doc.transactions:
-                    in_outputs = [o for o in tx.outputs
-                                  if o.pubkey == self.wallet.pubkey]
-                    if len(in_outputs) > 0:
-                        self.tx_received.append((block_number, tx))
-
-                    in_inputs = [i for i in tx.issuers if i == self.wallet.pubkey]
-                    if len(in_inputs) > 0:
-                        # remove from waiting transactions list the one which were
-                        # validated in the blockchain
-                        self.tx_awaiting = [awaiting[1] for awaiting in self.tx_awaiting
-                                             if awaiting[1].compact() != tx.compact()]
-                        self.tx_sent.append((block_number, tx))
+                    metadata['issuer'] = tx.issuers[0]
+                    receivers = [o.pubkey for o in tx.outputs
+                                 if o.pubkey != metadata['issuer']]
+                    metadata['receiver'] = receivers[0]
+
+                    in_issuers = len([i for i in tx.issuers
+                                 if i == self.wallet.pubkey]) > 0
+                    if in_issuers:
+                        outputs = [o for o in tx.outputs
+                                   if o.pubkey != self.wallet.pubkey]
+                        amount = 0
+                        for o in outputs:
+                            amount += o.amount
+                        metadata['amount'] = amount
+
+                        awaiting = [t for t in self._transfers
+                                    if t.state == Transfer.AWAITING]
+                        awaiting_docs = [t.txdoc for t in awaiting]
+                        if tx not in awaiting_docs:
+                            transfer = Transfer.create_validated(tx, metadata)
+                            self._transfers.append(transfer)
+                        for transfer in awaiting:
+                            transfer.check_registered(tx, metadata)
+                    else:
+                        outputs = [o for o in tx.outputs
+                                   if o.pubkey == self.wallet.pubkey]
+                        if len(outputs) > 0:
+                            amount = 0
+                            for o in outputs:
+                                amount += o.amount
+                            metadata['amount'] = amount
+                            self._transfers.append(Received(tx, metadata))
 
             if current_block > self.latest_block:
                     self.available_sources = self.wallet.sources(community)
@@ -259,13 +256,12 @@ class Wallet(object):
 
         tx.sign([key])
         logging.debug("Transaction : {0}".format(tx.signed_raw()))
-        try:
-            community.broadcast(bma.tx.Process,
-                        post_args={'transaction': tx.signed_raw()})
-            block_number = community.current_blockid()['number']
-            self.caches[community.currency].tx_awaiting.append((block_number, tx))
-        except:
-            raise
+
+        block_number = community.current_blockid()['number']
+
+        transfer = Transfer.initiate(tx, block_number, amount)
+        transfer.send()
+        self.caches[community.currency]._transfers.append(transfer)
 
     def sources(self, community):
         data = community.request(bma.tx.Sources,
@@ -275,20 +271,8 @@ class Wallet(object):
             tx.append(InputSource.from_bma(s))
         return tx
 
-    def transactions_awaiting(self, community):
-        return self.caches[community.currency].awaiting(community)
-
-    def transactions_sent(self, community):
-        return self.caches[community.currency].latest_sent(community)
-
-    def transactions_received(self, community):
-        return self.caches[community.currency].latest_received(community)
-
-    def get_text(self, community):
-        return "%s : \n \
-%d %s \n \
-%.2f UD" % (self.name, self.value(community), community.currency,
-                          self.relative_value(community))
+    def transfers(self, community):
+        return self.caches[community.currency].transfers
 
     def jsonify(self):
         return {'walletid': self.walletid,
diff --git a/src/cutecoin/models/txhistory.py b/src/cutecoin/models/txhistory.py
index 23454beff53824396d3cee5df60f9688ff472cc2..6e01cd053f3e88dabb03cca1aeefe5ecf25fa8ff 100644
--- a/src/cutecoin/models/txhistory.py
+++ b/src/cutecoin/models/txhistory.py
@@ -5,9 +5,11 @@ Created on 5 févr. 2014
 '''
 
 import logging
+from ..core.transfer import Transfer, Received
 from ..core.person import Person
 from ..tools.exceptions import PersonNotFoundError
-from PyQt5.QtCore import QAbstractTableModel, Qt, QVariant, QSortFilterProxyModel, QDateTime
+from PyQt5.QtCore import QAbstractTableModel, Qt, QVariant, QSortFilterProxyModel, \
+                        QDateTime, QModelIndex
 from PyQt5.QtGui import QFont
 
 
@@ -27,12 +29,13 @@ class TxFilterProxyModel(QSortFilterProxyModel):
         self.ts_to = ts_to
 
     def filterAcceptsRow(self, sourceRow, sourceParent):
-        def in_period(tx):
-            block = self.community.get_block(tx[0])
-            return (block.mediantime in range(self.ts_from, self.ts_to))
+        def in_period(date):
+            return (QDateTime(date).toTime_t() in range(self.ts_from, self.ts_to))
 
-        tx = self.sourceModel().transactions[sourceRow]
-        return in_period(tx)
+        date_col = self.sourceModel().columns.index('Date')
+        source_index = self.sourceModel().index(sourceRow, date_col)
+        date = self.sourceModel().data(source_index, Qt.DisplayRole)
+        return in_period(date)
 
     def lessThan(self, left, right):
         """
@@ -70,12 +73,10 @@ class HistoryTableModel(QAbstractTableModel):
         self.account = account
         self.community = community
         self.columns = ('Date', 'UID/Public key', 'Payment', 'Deposit', 'Comment')
-        self.transactions = self.account.transactions_sent(self.community) + \
-         self.account.transactions_awaiting(self.community) + \
-         self.account.transactions_received(self.community)
+        self.transfers = self.account.transfers(community)
 
     def rowCount(self, parent):
-        return len(self.transactions)
+        return len(self.transfers)
 
     def columnCount(self, parent):
         return len(self.columns)
@@ -84,16 +85,10 @@ class HistoryTableModel(QAbstractTableModel):
         if role == Qt.DisplayRole:
             return self.columns[section]
 
-    def data_received(self, tx):
-        outputs = []
-        amount = 0
-        for o in tx[1].outputs:
-            pubkeys = [w.pubkey for w in self.account.wallets]
-            if o.pubkey in pubkeys:
-                outputs.append(o)
-                amount += o.amount
-        comment = tx[1].comment
-        pubkey = tx[1].issuers[0]
+    def data_received(self, transfer):
+        amount = transfer.metadata['amount']
+        comment = transfer.txdoc.comment
+        pubkey = transfer.metadata['issuer']
         try:
             #sender = Person.lookup(pubkey, self.community).name
             sender = Person.lookup(pubkey, self.community)
@@ -101,7 +96,7 @@ class HistoryTableModel(QAbstractTableModel):
             #sender = "pub:{0}".format(pubkey[:5])
             sender = pubkey
 
-        date_ts = self.community.get_block(tx[0]).time
+        date_ts = transfer.metadata['time']
         date = QDateTime.fromTime_t(date_ts)
 
         amount_ref = self.account.units_to_ref(amount, self.community)
@@ -110,17 +105,11 @@ class HistoryTableModel(QAbstractTableModel):
         return (date.date(), sender, "", "{0:.2f} {1}".format(amount_ref, ref_name),
                 comment)
 
-    def data_sent(self, tx):
-        amount = 0
-        outputs = []
-        for o in tx[1].outputs:
-            pubkeys = [w.pubkey for w in self.account.wallets]
-            if o.pubkey not in pubkeys:
-                outputs.append(o)
-                amount += o.amount
-
-        comment = tx[1].comment
-        pubkey = outputs[0].pubkey
+    def data_sent(self, transfer):
+        amount = transfer.metadata['amount']
+
+        comment = transfer.txdoc.comment
+        pubkey = transfer.metadata['receiver']
         try:
             #receiver = Person.lookup(pubkey, self.community).name
             receiver = Person.lookup(pubkey, self.community)
@@ -128,7 +117,7 @@ class HistoryTableModel(QAbstractTableModel):
             #receiver = "pub:{0}".format(pubkey[:5])
             receiver = pubkey
 
-        date_ts = self.community.get_block(tx[0]).time
+        date_ts = transfer.metadata['time']
         date = QDateTime.fromTime_t(date_ts)
 
         amount_ref = self.account.units_to_ref(-amount, self.community)
@@ -144,17 +133,16 @@ class HistoryTableModel(QAbstractTableModel):
         if not index.isValid():
             return QVariant()
 
+        transfer = self.transfers[row]
         if role == Qt.DisplayRole:
-            if self.transactions[row] in self.account.transactions_sent(self.community) \
-                or self.transactions[row] in self.account.transactions_awaiting(self.community):
-                return self.data_sent(self.transactions[row])[col]
-
-            if self.transactions[row] in self.account.transactions_received(self.community):
-                return self.data_received(self.transactions[row])[col]
+            if type(transfer) is Received:
+                return self.data_received(transfer)[col]
+            else:
+                return self.data_sent(transfer)[col]
 
         if role == Qt.FontRole:
             font = QFont()
-            if self.transactions[row] in self.account.transactions_awaiting(self.community):
+            if transfer.state == Transfer.AWAITING:
                 font.setItalic(True)
             else:
                 font.setItalic(False)