diff --git a/src/cutecoin/core/account.py b/src/cutecoin/core/account.py
index c83ae933303a9150ade0864933835eab2bedfaea..0effe4565f2a3d0127460ca3f87643189f08d494 100644
--- a/src/cutecoin/core/account.py
+++ b/src/cutecoin/core/account.py
@@ -324,42 +324,10 @@ class Account(QObject):
         :param cutecoin.core.community.Community community: The community target of the certification
         :param str pubkey: The certified identity pubkey
         """
-        blockid = ""
-        selfcert = None
-
-        def build_certification_data(reply):
-            if reply.error() == QNetworkReply.NoError:
-                strdata = bytes(reply.readAll()).decode('utf-8')
-                json_data = json.loads(strdata)
-                nonlocal blockid
-                blockid = community.blockid(json_data)
-                future_certdata.set_result(True)
-
-        def build_certification_selfcert(reply):
-            if reply.error() == QNetworkReply.NoError:
-                strdata = bytes(reply.readAll()).decode('utf-8')
-                json_data = json.loads(strdata)
-                nonlocal selfcert
-                selfcert = identity.selfcert(community, json_data)
-                future_selfcert.set_result(True)
-
         logging.debug("Certdata")
-        future_certdata = asyncio.Future()
-        reply = community.bma_access.request(qtbma.blockchain.Current)
-        reply.finished.connect(lambda: build_certification_data(reply))
-        yield from future_certdata
-
-        logging.debug("Identity")
+        blockid = yield from community.blockid()
         identity = yield from self._identities_registry.future_lookup(pubkey, community)
-        logging.debug("YEILDDDDDDDDDdD")
-
-        logging.debug("Selfcert")
-        future_selfcert = asyncio.Future()
-        reply = community.bma_access.request( qtbma.wot.Lookup, req_args={'search': pubkey})
-        reply.finished.connect(lambda: build_certification_selfcert(reply))
-        yield from future_selfcert
-
-        logging.debug("End")
+        selfcert = yield from identity.selfcert(community)
         certification = Certification(PROTOCOL_VERSION, community.currency,
                                       self.pubkey, pubkey,
                                       blockid['number'], blockid['hash'], None)
@@ -485,40 +453,12 @@ class Account(QObject):
         :param community: The community target of the membership document
         :param str mstype: The type of membership demand. "IN" to join, "OUT" to leave
         '''
-        blockid = ""
-        selfcert = None
         logging.debug("Send membership")
 
-        def build_membership_data(reply):
-            if reply.error() == QNetworkReply.NoError:
-                strdata = bytes(reply.readAll()).decode('utf-8')
-                json_data = json.loads(strdata)
-                nonlocal blockid
-                blockid = community.blockid(json_data)
-                future_msdata.set_result(True)
-            else:
-                raise ConnectionError(self.tr("Failed to get data build membership document"))
-
-        def build_selfcert(reply):
-            if reply.error() == QNetworkReply.NoError:
-                strdata = bytes(reply.readAll()).decode('utf-8')
-                json_data = json.loads(strdata)
-                nonlocal selfcert
-                selfcert = self.identity(community).selfcert(community, json_data)
-                future_selfcert.set_result(True)
-            else:
-                raise ConnectionError(self.tr("Failed to get data build membership document"))
-
-        future_msdata = asyncio.Future()
-        reply = community.bma_access.request(qtbma.blockchain.Current)
-        reply.finished.connect(lambda: build_membership_data(reply))
-        logging.debug("msdata")
-        yield from future_msdata
-        future_selfcert = asyncio.Future()
-        reply = community.bma_access.request( qtbma.wot.Lookup, req_args={'search': self.pubkey})
-        reply.finished.connect(lambda: build_selfcert(reply))
-        logging.debug("selfcert")
-        yield from future_selfcert
+        blockid = yield from community.blockid()
+        self_identity = yield from self._identities_registry.future_lookup(self.pubkey, community)
+        selfcert = yield from self_identity.selfcert(community)
+
         membership = Membership(PROTOCOL_VERSION, community.currency,
                                 selfcert.pubkey, blockid['number'],
                                 blockid['hash'], mstype, selfcert.uid,
diff --git a/src/cutecoin/core/community.py b/src/cutecoin/core/community.py
index 3bcb11dc0dde06b20e95f0191ab568438e79ef05..5a0eb89d7ffaac755ddd8e48c4e986ee77d5bcab 100644
--- a/src/cutecoin/core/community.py
+++ b/src/cutecoin/core/community.py
@@ -8,6 +8,7 @@ import logging
 import hashlib
 import re
 import time
+import asyncio
 
 from PyQt5.QtCore import QObject, pyqtSignal
 from requests.exceptions import RequestException
@@ -247,12 +248,14 @@ class Community(QObject):
                                 req_args={'number': number})
         return data
 
-    def blockid(self, block):
+    @asyncio.coroutine
+    def blockid(self):
         '''
         Get the block id.
 
         :return: The current block ID as [NUMBER-HASH] format.
         '''
+        block = yield from self.bma_access.future_request(qtbma.blockchain.Current)
         signed_raw = "{0}{1}\n".format(block['raw'], block['signature'])
         block_hash = hashlib.sha1(signed_raw.encode("ascii")).hexdigest().upper()
         block_number = block['number']
diff --git a/src/cutecoin/core/net/api/bma/access.py b/src/cutecoin/core/net/api/bma/access.py
index 8d6ce80d1927217911118303d130489e63a3ae90..6294ea4157d645c9b1cd15f56dc0972f62aeb9fc 100644
--- a/src/cutecoin/core/net/api/bma/access.py
+++ b/src/cutecoin/core/net/api/bma/access.py
@@ -4,6 +4,7 @@ from . import blockchain, network, node, tx, wot, ConnectionHandler
 from .....tools.exceptions import NoPeerAvailable
 import logging
 import json
+import asyncio
 import random
 
 class BmaAccess(QObject):
@@ -66,17 +67,22 @@ class BmaAccess(QObject):
                             'value': data[d]})
         return entries
 
-    def get(self, caller, request, req_args={}, get_args={}, tries=0):
-        """
-        Get Json data from the specified URL
-        :rtype : dict
-        """
-        cache_key = (str(request),
+    @staticmethod
+    def _gen_cache_key(request, req_args, get_args):
+        return (str(request),
                      str(tuple(frozenset(sorted(req_args.keys())))),
                      str(tuple(frozenset(sorted(req_args.values())))),
                      str(tuple(frozenset(sorted(get_args.keys())))),
                      str(tuple(frozenset(sorted(get_args.values())))))
 
+    def _get_from_cache(self, request, req_args, get_args):
+        """
+        Get data from the cache
+        :param request: The requested data
+        :param cache_key: The key
+        :return:
+        """
+        cache_key = BmaAccess._gen_cache_key(request, req_args, get_args)
         if cache_key in self._data.keys():
             need_reload = False
             if 'metadata' in self._data[cache_key]:
@@ -89,6 +95,50 @@ class BmaAccess(QObject):
         else:
             need_reload = True
             ret_data = request.null_value
+        return need_reload, ret_data
+
+    def _update_cache(self, request, req_args, get_args, data):
+        """
+        Update data in cache and returns True if cached data changed
+        :param class request: A bma request class calling for data
+        :param dict req_args: Arguments to pass to the request constructor
+        :param dict get_args: Arguments to pass to the request __get__ method
+        :param dict data: Json data to save in cache
+        :return: True if data changed
+        :rtype: bool
+        """
+        cache_key = BmaAccess._gen_cache_key(request, req_args, get_args)
+        if cache_key not in self._data:
+            self._data[cache_key] = {}
+
+            if 'metadata' not in self._data[cache_key]:
+                self._data[cache_key]['metadata'] = {}
+
+            if 'value' not in self._data[cache_key]:
+                self._data[cache_key]['value'] = {}
+            self._data[cache_key]['metadata']['block'] = self._network.latest_block
+
+            if self._data[cache_key]['value'] != data:
+                self._data[cache_key]['value'] = data
+                return True
+        return False
+
+    def get(self, caller, request, req_args={}, get_args={}, tries=0):
+        """
+        Get Json data from the specified URL and emit "inner_data_changed"
+        on the caller if the data changed.
+
+        :param PyQt5.QtCore.QObject caller: The objet calling
+        :param class request: A bma request class calling for data
+        :param dict req_args: Arguments to pass to the request constructor
+        :param dict get_args: Arguments to pass to the request __get__ method
+        :return: The cached data
+        :rtype: dict
+        """
+        data = self._get_from_cache(request, req_args, get_args)
+        need_reload = data[0]
+        ret_data = data[1]
+        cache_key = BmaAccess._gen_cache_key(request, req_args, get_args)
 
         if need_reload:
             #Move to network nstead of community
@@ -99,16 +149,53 @@ class BmaAccess(QObject):
                     self._pending_requests[cache_key].append(caller)
                     logging.debug("Callers".format(self._pending_requests[cache_key]))
             else:
-                reply = self.request(request, req_args, get_args)
+                reply = self.simple_request(request, req_args, get_args)
                 logging.debug("New pending request {0}, caller {1}".format(cache_key, caller))
                 self._pending_requests[cache_key] = [caller]
                 reply.finished.connect(lambda:
                                          self.handle_reply(request, req_args, get_args, tries))
         return ret_data
 
-    def request(self, request, req_args={}, get_args={}):
+    def future_request(self, request, req_args={}, get_args={}):
         '''
-        Start a request to the network.
+        Start a request to the network and returns a future.
+
+        :param class request: A bma request class calling for data
+        :param dict req_args: Arguments to pass to the request constructor
+        :param dict get_args: Arguments to pass to the request __get__ method
+        :return: The future data
+        :rtype: dict
+        '''
+        def handle_future_reply(reply):
+            if reply.error() == QNetworkReply.NoError:
+                strdata = bytes(reply.readAll()).decode('utf-8')
+                json_data = json.loads(strdata)
+                self._update_cache(request, req_args, get_args, json_data)
+                future_data.set_result(json_data)
+
+        future_data = asyncio.Future()
+        data = self._get_from_cache(request, req_args, get_args)
+        need_reload = data[0]
+
+        if need_reload:
+            nodes = self._network.synced_nodes
+            if len(nodes) > 0:
+                node = random.choice(nodes)
+                server = node.endpoint.conn_handler().server
+                port = node.endpoint.conn_handler().port
+                conn_handler = ConnectionHandler(self._network.network_manager, server, port)
+                req = request(conn_handler, **req_args)
+                reply = req.get(**get_args)
+                reply.finished.connect(lambda: handle_future_reply(reply))
+            else:
+                raise NoPeerAvailable(self.currency, len(nodes))
+        else:
+            future_data.set_result(data[1])
+        return future_data
+
+    def simple_request(self, request, req_args={}, get_args={}):
+        '''
+        Start a request to the network but don't cache its result.
 
         :param class request: A bma request class calling for data
         :param dict req_args: Arguments to pass to the request constructor
@@ -131,31 +218,12 @@ class BmaAccess(QObject):
     def handle_reply(self, request, req_args, get_args, tries):
         reply = self.sender()
         logging.debug("Handling QtNetworkReply for {0}".format(str(request)))
-        cache_key = (str(request),
-                     str(tuple(frozenset(sorted(req_args.keys())))),
-                     str(tuple(frozenset(sorted(req_args.values())))),
-                     str(tuple(frozenset(sorted(get_args.keys())))),
-                     str(tuple(frozenset(sorted(get_args.values())))))
+        cache_key = BmaAccess._gen_cache_key(request, req_args, get_args)
+
         if reply.error() == QNetworkReply.NoError:
             strdata = bytes(reply.readAll()).decode('utf-8')
             json_data = json.loads(strdata)
-            #logging.debug("Data in reply : {0}".format(strdata))
-
-            if cache_key not in self._data:
-                self._data[cache_key] = {}
-
-            if 'metadata' not in self._data[cache_key]:
-                self._data[cache_key]['metadata'] = {}
-
-            if 'value' not in self._data[cache_key]:
-                self._data[cache_key]['value'] = {}
-            self._data[cache_key]['metadata']['block'] = self._network.latest_block
-
-            change = False
-            if self._data[cache_key]['value'] != json_data:
-                change = True
-            if change:
-                self._data[cache_key]['value'] = json_data
+            if self._update_cache(request, req_args, get_args):
                 logging.debug(self._pending_requests.keys())
                 for caller in self._pending_requests[cache_key]:
                     logging.debug("Emit change for {0} : {1} ".format(caller, request))
diff --git a/src/cutecoin/core/registry/identities.py b/src/cutecoin/core/registry/identities.py
index 9c618c1603c1ef183caf4184fda536e23aee47a3..753ca38476c76cbe54921bbbfe0a674a74a7700f 100644
--- a/src/cutecoin/core/registry/identities.py
+++ b/src/cutecoin/core/registry/identities.py
@@ -62,7 +62,7 @@ class IdentitiesRegistry:
         else:
             identity = Identity.empty(pubkey)
             self._instances[pubkey] = identity
-            reply = community.bma_access.request(qtbma.wot.Lookup, req_args={'search': pubkey})
+            reply = community.bma_access.simple_request(qtbma.wot.Lookup, req_args={'search': pubkey})
             reply.finished.connect(lambda: self.handle_lookup(reply, identity))
         return identity
 
@@ -94,7 +94,7 @@ class IdentitiesRegistry:
         else:
             identity = Identity.empty(pubkey)
             self._instances[pubkey] = identity
-            reply = community.bma_access.request(qtbma.wot.Lookup, req_args={'search': pubkey})
+            reply = community.bma_access.simple_request(qtbma.wot.Lookup, req_args={'search': pubkey})
             reply.finished.connect(lambda: handle_reply(reply))
         logging.debug("Return")
         yield from future_identity
diff --git a/src/cutecoin/core/registry/identity.py b/src/cutecoin/core/registry/identity.py
index 32d94f928d82459005d240ef3fbfd7925a3e9421..ad26e014a25719491ab1a6a08f9f40bd289cf5f9 100644
--- a/src/cutecoin/core/registry/identity.py
+++ b/src/cutecoin/core/registry/identity.py
@@ -6,6 +6,7 @@ Created on 11 févr. 2014
 
 import logging
 import time
+import asyncio
 
 from ucoinpy.documents.certification import SelfCertification
 from cutecoin.tools.exceptions import Error, NoPeerAvailable,\
@@ -60,7 +61,8 @@ class Identity(QObject):
 
         return cls(uid, pubkey, status)
 
-    def selfcert(self, community, lookup_data):
+    @asyncio.coroutine
+    def selfcert(self, community):
         """
         Get the identity self certification.
         This request is not cached in the person object.
@@ -70,7 +72,7 @@ class Identity(QObject):
         :rtype: ucoinpy.documents.certification.SelfCertification
         """
         timestamp = 0
-
+        lookup_data = yield from community.bma_access.future_request(qtbma.wot.Lookup, req_args={'search': self.pubkey})
         for result in lookup_data['results']:
             if result["pubkey"] == self.pubkey:
                 uids = result['uids']
@@ -86,6 +88,7 @@ class Identity(QObject):
                                          timestamp,
                                          uid,
                                          signature)
+        return None
 
     def get_join_date(self, community):
         """
diff --git a/src/cutecoin/core/wallet.py b/src/cutecoin/core/wallet.py
index 8053cf60c2ed50d9de91447ca3a4341e85d3b7c7..6d757faa9ec93766a355d724276884a467159805 100644
--- a/src/cutecoin/core/wallet.py
+++ b/src/cutecoin/core/wallet.py
@@ -138,7 +138,7 @@ class Cache():
             # Lets look if transactions took too long to be validated
             awaiting = [t for t in self._transfers
                         if t.state == Transfer.AWAITING]
-            tx_history = community.bma_access.request(qtbma.tx.history.Blocks,
+            tx_history = community.bma_access.simple_request(qtbma.tx.history.Blocks,
                                                       req_args={'pubkey': self.wallet.pubkey,
                                                              'from_':self.latest_block,
                                                              'to_': self.current_block})
@@ -352,7 +352,7 @@ class Wallet(QObject):
         '''
         time = community.get_block().mediantime
         block_number = community.current_blockid()['number']
-        block = community.request(bma.blockchain.Block,
+        block = community.simple_request(bma.blockchain.Block,
                                   req_args={'number': block_number})
         txid = len(block['transactions'])
         key = None
diff --git a/src/cutecoin/gui/wot_tab.py b/src/cutecoin/gui/wot_tab.py
index 4d1854ebe4b2c2b1ad7944e757025686673e5340..679c12fffa11531d214bbd6e4b6df2aa5aac4865 100644
--- a/src/cutecoin/gui/wot_tab.py
+++ b/src/cutecoin/gui/wot_tab.py
@@ -135,7 +135,7 @@ class WotTabWidget(QWidget, Ui_WotTabWidget):
         if len(text) < 2:
             return False
         try:
-            response = self.community.request(bma.wot.Lookup, {'search': text})
+            response = self.community.simple_request(bma.wot.Lookup, {'search': text})
         except Exception as e:
             logging.debug('bma.wot.Lookup request error : ' + str(e))
             return False