diff --git a/src/sakia/data/graphs/__init__.py b/src/sakia/data/graphs/__init__.py
index 21318ddce99b0385dca8da9f9e90ca2314b4df3e..ed8f7ac56cb500a3e4a7cc3dd2ecfdd1d2388629 100644
--- a/src/sakia/data/graphs/__init__.py
+++ b/src/sakia/data/graphs/__init__.py
@@ -1,3 +1,2 @@
 from .base_graph import BaseGraph
-from .wot_graph import WoTGraph
-from .explorer_graph import ExplorerGraph
\ No newline at end of file
+from .wot_graph import WoTGraph
\ No newline at end of file
diff --git a/src/sakia/data/graphs/base_graph.py b/src/sakia/data/graphs/base_graph.py
index 58b6b946ecc35cc051440dec05e4e2aa2e12341d..e7903efb83d5c6020e036529f9070799739c1728 100644
--- a/src/sakia/data/graphs/base_graph.py
+++ b/src/sakia/data/graphs/base_graph.py
@@ -8,32 +8,32 @@ from sakia.constants import MAX_CONFIRMATIONS
 
 
 class BaseGraph(QObject):
-    def __init__(self, app, community, nx_graph=None):
+    def __init__(self, app, blockchain_service, identities_service, nx_graph):
         """
         Init Graph instance
-        :param sakia.core.app.Application app: Application instance
-        :param sakia.core.community.Community community: Community instance
+        :param sakia.app.Application app: Application instance
+        :param sakia.services.BlockchainService blockchain_service: Blockchain service instance
+        :param sakia.services.IdentitiesService identities_service: Identities service instance
         :param networkx.Graph nx_graph: The networkx graph
         :return:
         """
         super().__init__()
         self.app = app
-        self.community = community
+        self.identities_service = identities_service
+        self.blockchain_service = blockchain_service
         # graph empty if None parameter
         self.nx_graph = nx_graph if nx_graph else networkx.DiGraph()
 
-    async def arc_status(self, cert_time):
+    def arc_status(self, cert_time):
         """
         Get arc status of a certification
         :param int cert_time: the timestamp of the certification
         :return: the certification time
         """
-        parameters = await self.community.parameters()
-        signature_validity = parameters['sigValidity']
+        parameters = self.blockchain_service.parameters()
         #  arc considered strong during 75% of signature validity time
-        arc_strong = int(signature_validity * 0.75)
+        arc_strong = int(parameters.sig_validity * 0.75)
         # display validity status
-        ts = time.time()
         if (time.time() - cert_time) > arc_strong:
             return EdgeStatus.WEAK
         else:
@@ -49,10 +49,10 @@ class BaseGraph(QObject):
         """
         # new node
         node_status = NodeStatus.NEUTRAL
-        is_member = await node_identity.is_member(self.community)
+        await self.identities_service.refresh_requirements(node_identity)
         if node_identity.pubkey == account_identity.pubkey:
             node_status += NodeStatus.HIGHLIGHTED
-        if is_member is False:
+        if node_identity.member is False:
             node_status += NodeStatus.OUT
         return node_status
 
@@ -64,12 +64,11 @@ class BaseGraph(QObject):
         :rtype: str
         """
         try:
-            current_confirmations = self.community.network.confirmations(block_number)
+            current_confirmations = min(max(block_number - self.blockchain_service.current_buid().number, 0), 6)
 
             if MAX_CONFIRMATIONS > current_confirmations:
-                if self.app.preferences['expert_mode']:
-                    return "{0}/{1}".format(current_confirmations,
-                                                              MAX_CONFIRMATIONS)
+                if self.app.parameters.expert_mode:
+                    return "{0}/{1}".format(current_confirmations, MAX_CONFIRMATIONS)
                 else:
                     confirmation = current_confirmations / MAX_CONFIRMATIONS * 100
                     return "{0} %".format(QLocale().toString(float(confirmation), 'f', 0))
@@ -99,79 +98,78 @@ class BaseGraph(QObject):
     async def add_certifier_list(self, certifier_list, identity, account_identity):
         """
         Add list of certifiers to graph
-        :param list certifier_list: List of certifiers from api
-        :param sakia.core.registry.Identity identity:   identity instance which is certified
-        :param sakia.core.registry.Identity account_identity:   Account identity instance
+        :param List[sakia.data.entities.Certification] certifier_list: List of certified from api
+        :param sakia.data.entities.Identity identity:   identity instance which is certified
+        :param sakia.data.entities.Identity account_identity:   Account identity instance
         :return:
         """
-        if self.community:
-            try:
-                #  add certifiers of uid
-                for certifier in tuple(certifier_list):
-                    node_status = await self.node_status(certifier['identity'], account_identity)
-                    metadata = {
-                        'text': certifier['identity'].uid,
-                        'tooltip': certifier['identity'].pubkey,
-                        'status': node_status
-                    }
-                    self.nx_graph.add_node(certifier['identity'].pubkey, attr_dict=metadata)
-
-                    arc_status = await self.arc_status(certifier['cert_time'])
-                    sig_validity = (await self.community.parameters())['sigValidity']
-                    arc = {
-                        'status': arc_status,
-                        'tooltip': QLocale.toString(
-                            QLocale(),
-                            QDateTime.fromTime_t(certifier['cert_time'] + sig_validity).date(),
-                            QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
-                        ),
-                        'cert_time': certifier['cert_time'],
-                        'confirmation_text': self.confirmation_text(certifier['block_number'])
-                    }
-
-                    self.nx_graph.add_edge(certifier['identity'].pubkey, identity.pubkey, attr_dict=arc, weight=len(certifier_list))
-            except NoPeerAvailable as e:
-                logging.debug(str(e))
+        try:
+            #  add certifiers of uid
+            for certification in tuple(certifier_list):
+                certifier = self.identities_service.get_identity(certification.certifier)
+                node_status = await self.node_status(certifier, account_identity)
+                metadata = {
+                    'text': certifier.uid,
+                    'tooltip': certifier.pubkey,
+                    'status': node_status
+                }
+                self.nx_graph.add_node(certifier.pubkey, attr_dict=metadata)
+
+                arc_status = self.arc_status(certification.timestamp)
+                sig_validity = self.blockchain_service.parameters().sig_validity
+                arc = {
+                    'status': arc_status,
+                    'tooltip': QLocale.toString(
+                        QLocale(),
+                        QDateTime.fromTime_t(certification.timestamp + sig_validity).date(),
+                        QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
+                    ),
+                    'cert_time': certification.timestamp,
+                    'confirmation_text': self.confirmation_text(certification.block)
+                }
+
+                self.nx_graph.add_edge(certifier.pubkey, identity.pubkey, attr_dict=arc, weight=len(certifier_list))
+        except NoPeerAvailable as e:
+            logging.debug(str(e))
 
     async def add_certified_list(self, certified_list, identity, account_identity):
         """
         Add list of certified from api to graph
-        :param list certified_list: List of certified from api
+        :param List[sakia.data.entities.Certification] certified_list: List of certified from api
         :param identity identity:   identity instance which is certifier
         :param identity account_identity:   Account identity instance
         :return:
         """
-
-        if self.community:
-            try:
-                # add certified by uid
-                for certified in tuple(certified_list):
-                    node_status = await self.node_status(certified['identity'], account_identity)
-                    metadata = {
-                        'text': certified['identity'].uid,
-                        'tooltip': certified['identity'].pubkey,
-                        'status': node_status
-                    }
-                    self.nx_graph.add_node(certified['identity'].pubkey, attr_dict=metadata)
-
-                    arc_status = await self.arc_status(certified['cert_time'])
-                    sig_validity = (await self.community.parameters())['sigValidity']
-                    arc = {
-                        'status': arc_status,
-                        'tooltip': QLocale.toString(
-                            QLocale(),
-                            QDateTime.fromTime_t(certified['cert_time'] + sig_validity).date(),
-                            QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
-                        ),
-                        'cert_time': certified['cert_time'],
-                        'confirmation_text': self.confirmation_text(certified['block_number'])
-                    }
-
-                    self.nx_graph.add_edge(identity.pubkey, certified['identity'].pubkey, attr_dict=arc,
-                                           weight=len(certified_list))
-
-            except NoPeerAvailable as e:
-                logging.debug(str(e))
+        try:
+            # add certified by uid
+            for certification in tuple(certified_list):
+                certified = self.identities_service.get_identity(certification.certified)
+                node_status = await self.node_status(certified, account_identity)
+                metadata = {
+                    'text': certified.uid,
+                    'tooltip': certified.pubkey,
+                    'status': node_status
+                }
+                self.nx_graph.add_node(certified.pubkey, attr_dict=metadata)
+
+                arc_status = self.arc_status(certification.timestamp)
+                sig_validity = self.blockchain_service.parameters().sig_validity
+                arc = {
+                    'status': arc_status,
+                    'tooltip': QLocale.toString(
+                        QLocale(),
+                        QDateTime.fromTime_t(certification.timestamp + sig_validity).date(),
+                        QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
+                    ),
+                    'cert_time': certification.timestamp,
+                    'confirmation_text': self.confirmation_text(certification.block)
+                }
+
+                self.nx_graph.add_edge(identity.pubkey, certified.pubkey, attr_dict=arc,
+                                       weight=len(certified_list))
+
+        except NoPeerAvailable as e:
+            logging.debug(str(e))
 
     def add_identity(self, identity, status):
         """
diff --git a/src/sakia/data/graphs/explorer_graph.py b/src/sakia/data/graphs/explorer_graph.py
deleted file mode 100644
index 43a99c4e01fb2fed3605453c837b0dc1fe85f1e5..0000000000000000000000000000000000000000
--- a/src/sakia/data/graphs/explorer_graph.py
+++ /dev/null
@@ -1,106 +0,0 @@
-import logging
-import networkx
-import asyncio
-from PyQt5.QtCore import pyqtSignal
-from .base_graph import BaseGraph
-from ..graphs.constants import EdgeStatus, NodeStatus
-
-
-class ExplorerGraph(BaseGraph):
-
-    graph_changed = pyqtSignal()
-    current_identity_changed = pyqtSignal(str)
-
-    def __init__(self, app, community, nx_graph=None):
-        """
-        Init ExplorerGraph instance
-        :param sakia.core.app.Application app: Application instance
-        :param sakia.core.community.Community community: Community instance
-        :param networkx.Graph nx_graph: The networkx graph
-        :return:
-        """
-        super().__init__(app, community, nx_graph)
-        self.exploration_task = None
-        self.explored_identity = None
-        self.steps = 0
-
-    def start_exploration(self, identity, steps):
-        """
-        Start exploration of the wot from given identity
-        :param sakia.core.registry.Identity identity: The identity source of exploration
-        :param int steps: The number of steps from identity to explore
-        """
-        if self.exploration_task:
-            if self.explored_identity is not identity or steps != self.steps:
-                self.exploration_task.cancel()
-            else:
-                return
-        self.nx_graph.clear()
-        self.explored_identity = identity
-        self.steps = steps
-        self.exploration_task = asyncio.ensure_future(self._explore(identity, steps))
-
-    def stop_exploration(self):
-        """
-        Stop current exploration task, if present.
-        """
-        if self.exploration_task:
-            self.exploration_task.cancel()
-            self.exploration_task = None
-
-    async def _explore(self, identity, steps):
-        """
-        Scan graph recursively
-        :param sakia.core.registry.Identity identity:   identity instance from where we start
-        :param int steps: The number of steps from given identity to explore
-        :return: False when the identity is added in the graph
-        """
-        # functions keywords args are persistent... Need to reset it with None trick
-        logging.debug("search %s in " % identity.uid)
-
-        explored = []
-        explorable = {0: [identity]}
-        current_identity = identity
-        self.nx_graph.clear()
-        self.add_identity(current_identity, NodeStatus.HIGHLIGHTED)
-        self.nx_graph.node[current_identity.pubkey]['is_sentry'] = False
-        self.graph_changed.emit()
-        for step in range(1, steps + 1):
-            explorable[step] = []
-
-        for step in range(0, steps):
-            while len(explorable[step]) > 0:
-                current_identity = explorable[step].pop()
-                # for each pubkey connected...
-                if current_identity not in explored:
-                    self.current_identity_changed.emit(current_identity.pubkey)
-                    node = self.add_identity(current_identity, NodeStatus.NEUTRAL)
-                    self.nx_graph.node[current_identity.pubkey]['is_sentry'] = False
-                    logging.debug("New identity explored : {pubkey}".format(pubkey=current_identity.pubkey[:5]))
-                    self.graph_changed.emit()
-
-                    certifier_list = await current_identity.unique_valid_certifiers_of(self.app.identities_registry,
-                                                                                             self.community)
-                    await self.add_certifier_list(certifier_list, current_identity, identity)
-                    logging.debug("New identity certifiers : {pubkey}".format(pubkey=current_identity.pubkey[:5]))
-
-                    is_sentry = self.is_sentry(len(certifier_list), await self.community.nb_members())
-                    self.nx_graph.node[current_identity.pubkey]['is_sentry'] = is_sentry
-
-                    self.graph_changed.emit()
-
-
-                    certified_list = await current_identity.unique_valid_certified_by(self.app.identities_registry,
-                                                                                            self.community)
-                    await self.add_certified_list(certified_list, current_identity, identity)
-                    logging.debug("New identity certified : {pubkey}".format(pubkey=current_identity.pubkey[:5]))
-                    self.graph_changed.emit()
-
-                    for cert in certified_list + certifier_list:
-                        if cert['identity'] not in explorable[step + 1]:
-                            explorable[step + 1].append(cert['identity'])
-
-                    explored.append(current_identity)
-                    logging.debug("New identity explored : {pubkey}".format(pubkey=current_identity.pubkey[:5]))
-                    self.graph_changed.emit()
-        self.current_identity_changed.emit("")
diff --git a/src/sakia/data/graphs/wot_graph.py b/src/sakia/data/graphs/wot_graph.py
index 60ab1cd28b9ece3c61eab094f059ddda35be54ab..abe9cfb35c5b1bebd42c429c2ae3568911a3ab1d 100644
--- a/src/sakia/data/graphs/wot_graph.py
+++ b/src/sakia/data/graphs/wot_graph.py
@@ -6,35 +6,37 @@ from .constants import NodeStatus
 
 
 class WoTGraph(BaseGraph):
-    def __init__(self, app, community, nx_graph=None):
+    def __init__(self, app, blockchain_service, identities_service, nx_graph=None):
         """
         Init WoTGraph instance
-        :param sakia.core.app.Application app: Application instance
-        :param sakia.core.community.Community community: Community instance
+        :param sakia.app.Application app: the app
+        :param sakia.data.entities.Connection connection: the connection
+        :param sakia.services.BlockchainService blockchain_service: the blockchain service
+        :param sakia.services.IdentitiesService identities_service: the identities service
         :param networkx.Graph nx_graph: The networkx graph
         :return:
         """
-        super().__init__(app, community, nx_graph)
+        super().__init__(app, blockchain_service, identities_service, nx_graph)
 
-    async def initialize(self, center_identity, account_identity):
-        node_status = await self.node_status(center_identity, account_identity)
+    async def initialize(self, center_identity, connection_identity):
+        node_status = await self.node_status(center_identity, connection_identity)
 
         self.add_identity(center_identity, node_status)
 
         # create Identity from node metadata
-        certifier_coro = asyncio.ensure_future(center_identity.unique_valid_certifiers_of(self.app.identities_registry,
-                                                                        self.community))
-        certified_coro = asyncio.ensure_future(center_identity.unique_valid_certified_by(self.app.identities_registry,
-                                                                       self.community))
+        certifier_coro = asyncio.ensure_future(self.identities_service.load_certifiers_of(center_identity))
+        certified_coro = asyncio.ensure_future(self.identities_service.load_certified_by(center_identity))
 
-        certifier_list, certified_list = await asyncio.gather(certifier_coro, certified_coro)
+        await asyncio.gather(certifier_coro, certified_coro)
 
         # populate graph with certifiers-of
+        certifier_list = self.identities_service.certifications_received(center_identity.pubkey)
         certifier_coro = asyncio.ensure_future(self.add_certifier_list(certifier_list,
-                                                                       center_identity, account_identity))
+                                                                       center_identity, connection_identity))
         # populate graph with certified-by
+        certified_list = self.identities_service.certifications_sent(center_identity.pubkey)
         certified_coro = asyncio.ensure_future(self.add_certified_list(certified_list,
-                                                                       center_identity, account_identity))
+                                                                       center_identity, connection_identity))
 
         await asyncio.gather(certifier_coro, certified_coro)
 
@@ -61,21 +63,20 @@ class WoTGraph(BaseGraph):
 
         return path
 
-    async def explore_to_find_member(self, account_identity, to_identity):
+    async def explore_to_find_member(self, from_identity, to_identity):
         """
         Scan graph to find identity
-        :param sakia.core.registry.Identity from_identity: Scan starting point
-        :param sakia.core.registry.Identity to_identity: Scan goal
+        :param sakia.data.entities.Identity from_identity: Scan starting point
+        :param sakia.data.entities.Identity to_identity: Scan goal
         """
         explored = []
-        explorable = [account_identity]
+        explorable = [from_identity]
 
         while len(explorable) > 0:
             current = explorable.pop()
-            certified_list = await current.unique_valid_certified_by(self.app.identities_registry,
-                                                                                    self.community)
+            certified_list = await self.identities_service.certifications_sent(current.pubkey)
 
-            await self.add_certified_list(certified_list, current, account_identity)
+            await self.add_certified_list(certified_list, current, from_identity)
             if to_identity.pubkey in [data['identity'].pubkey for data in certified_list]:
                 return True
 
diff --git a/src/sakia/data/processors/certifications.py b/src/sakia/data/processors/certifications.py
index c49d9253c9f10fe8b2b7e121b2ae0f39f393b8bf..17455bb5f8fce020aaab4067d13b27f9a1593ae4 100644
--- a/src/sakia/data/processors/certifications.py
+++ b/src/sakia/data/processors/certifications.py
@@ -26,6 +26,24 @@ class CertificationsProcessor:
         return cls(app.db.certifications_repo, app.db.identities_repo,
                    BmaConnector(NodesProcessor(app.db.nodes_repo)))
 
+    def certifications_sent(self, currency, pubkey):
+        """
+        Get the list of certifications sent for a given pubkey
+        :param str currency:
+        :param str pubkey:
+        :rtype: List[sakia.data.entities.Certification]
+        """
+        return self._certifications_repo.get_all(currency=currency, certifier=pubkey)
+
+    def certifications_received(self, currency, pubkey):
+        """
+        Get the list of certifications sent for a given pubkey
+        :param str currency:
+        :param str pubkey:
+        :rtype: List[sakia.data.entities.Certification]
+        """
+        return self._certifications_repo.get_all(currency=currency, certified=pubkey)
+
     def create_certification(self, currency, cert, blockstamp):
         """
         Creates a certification and insert it in the db
diff --git a/src/sakia/gui/navigation/controller.py b/src/sakia/gui/navigation/controller.py
index f45fabc385ee161def41b07757020215f30a5e38..cccc645ab84d4abc33686bbef14d05ef9407355a 100644
--- a/src/sakia/gui/navigation/controller.py
+++ b/src/sakia/gui/navigation/controller.py
@@ -7,7 +7,6 @@ from .network.controller import NetworkController
 from .identities.controller import IdentitiesController
 from .informations.controller import InformationsController
 from .graphs.wot.controller import WotController
-from .graphs.explorer.controller import ExplorerController
 from sakia.data.repositories import ConnectionsRepo
 from sakia.data.entities import Connection
 from PyQt5.QtCore import pyqtSignal
@@ -34,8 +33,7 @@ class NavigationController(ComponentController):
             'Network': NetworkController,
             'Identities': IdentitiesController,
             'Informations': InformationsController,
-            'Wot': WotController,
-            'Explorer': ExplorerController
+            'Wot': WotController
         }
         self.view.current_view_changed.connect(self.handle_view_change)
 
diff --git a/src/sakia/gui/navigation/graphs/base/controller.py b/src/sakia/gui/navigation/graphs/base/controller.py
index 9417e02b891ab038083abf4dc85c3eb10f273887..a8e57dc263f850c9c65df9cda7bf1760da3e750e 100644
--- a/src/sakia/gui/navigation/graphs/base/controller.py
+++ b/src/sakia/gui/navigation/graphs/base/controller.py
@@ -62,13 +62,12 @@ class BaseGraphController(ComponentController):
         """
         raise NotImplementedError("refresh not implemented")
 
-    @asyncify
-    async def node_context_menu(self, pubkey):
+    def node_context_menu(self, pubkey):
         """
         Open the node context menu
         :param str pubkey: the pubkey of the node to open
         """
-        identity = await self.model.get_identity(pubkey)
+        identity = self.model.get_identity(pubkey)
         menu = ContextMenu.from_data(self.view, self.model.app, self.model.account, self.model.community, self.password_asker,
                                      (identity,))
         menu.view_identity_in_wot.connect(self.draw_graph)
diff --git a/src/sakia/gui/navigation/graphs/base/graph_tab.py b/src/sakia/gui/navigation/graphs/base/graph_tab.py
deleted file mode 100644
index 9879cfb65c114babe56a74ae85b93902e29e77b8..0000000000000000000000000000000000000000
--- a/src/sakia/gui/navigation/graphs/base/graph_tab.py
+++ /dev/null
@@ -1,114 +0,0 @@
-from PyQt5.QtWidgets import QWidget
-from PyQt5.QtCore import pyqtSlot, QEvent, QLocale, QDateTime, pyqtSignal, QObject
-from PyQt5.QtGui import QCursor
-
-from ...tools.exceptions import MembershipNotFoundError
-from ...tools.decorators import asyncify, once_at_a_time
-from ...core.registry import BlockchainState
-from ..widgets.context_menu import ContextMenu
-
-
-class GraphTabWidget(QObject):
-
-    money_sent = pyqtSignal()
-
-    def __init__(self, app, account=None, community=None, password_asker=None, widget=QWidget):
-        """
-        :param sakia.core.app.Application app: Application instance
-        :param sakia.core.app.Application app: Application instance
-        :param sakia.core.Account account: The account displayed in the widget
-        :param sakia.core.Community community: The community displayed in the widget
-        :param sakia.gui.Password_Asker: password_asker: The widget to ask for passwords
-        :param class widget: The class of the graph tab
-        """
-        super().__init__()
-
-        self.widget = widget()
-        self.account = account
-        self.community = community
-        self.password_asker = password_asker
-
-        self.app = app
-
-
-    @once_at_a_time
-    @asyncify
-    async def refresh_informations_frame(self):
-        parameters = self.community.parameters
-        try:
-            identity = await self.account.identity(self.community)
-            membership = identity.membership(self.community)
-            renew_block = membership['blockNumber']
-            last_renewal = self.community.get_block(renew_block)['medianTime']
-            expiration = last_renewal + parameters['sigValidity']
-        except MembershipNotFoundError:
-            last_renewal = None
-            expiration = None
-
-        certified = await identity.unique_valid_certified_by(self.app.identities_registry, self.community)
-        certifiers = await identity.unique_valid_certifiers_of(self.app.identities_registry, self.community)
-        if last_renewal and expiration:
-            date_renewal = QLocale.toString(
-                QLocale(),
-                QDateTime.fromTime_t(last_renewal).date(), QLocale.dateFormat(QLocale(), QLocale.LongFormat)
-            )
-            date_expiration = QLocale.toString(
-                QLocale(),
-                QDateTime.fromTime_t(expiration).date(), QLocale.dateFormat(QLocale(), QLocale.LongFormat)
-            )
-
-            if self.account.pubkey in self.community.members_pubkeys():
-                # set infos in label
-                self.label_general.setText(
-                    self.tr("""
-                    <table cellpadding="5">
-                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
-                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
-                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
-                    </table>
-                    """).format(
-                        self.account.name, self.account.pubkey,
-                        self.tr("Membership"),
-                        self.tr("Last renewal on {:}, expiration on {:}").format(date_renewal, date_expiration),
-                        self.tr("Your web of trust"),
-                        self.tr("Certified by {:} members; Certifier of {:} members").format(len(certifiers),
-                                                                                             len(certified))
-                    )
-                )
-            else:
-                # set infos in label
-                self.label_general.setText(
-                    self.tr("""
-                    <table cellpadding="5">
-                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
-                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
-                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
-                    </table>
-                    """).format(
-                        self.account.name, self.account.pubkey,
-                        self.tr("Not a member"),
-                        self.tr("Last renewal on {:}, expiration on {:}").format(date_renewal, date_expiration),
-                        self.tr("Your web of trust"),
-                        self.tr("Certified by {:} members; Certifier of {:} members").format(len(certifiers),
-                                                                                             len(certified))
-                    )
-                )
-        else:
-            # set infos in label
-            self.label_general.setText(
-                self.tr("""
-                <table cellpadding="5">
-                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
-                <tr><td align="right"><b>{:}</b></td></tr>
-                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
-                </table>
-                """).format(
-                    self.account.name, self.account.pubkey,
-                    self.tr("Not a member"),
-                    self.tr("Your web of trust"),
-                    self.tr("Certified by {:} members; Certifier of {:} members").format(len(certifiers),
-                                                                                         len(certified))
-                )
-            )
-
-
diff --git a/src/sakia/gui/navigation/graphs/base/model.py b/src/sakia/gui/navigation/graphs/base/model.py
index 8e3abc814303391e21240d8c9e43174735fecd42..c52f269303b920d62e235f4bd8b23db00174f62f 100644
--- a/src/sakia/gui/navigation/graphs/base/model.py
+++ b/src/sakia/gui/navigation/graphs/base/model.py
@@ -6,16 +6,26 @@ class BaseGraphModel(ComponentModel):
     The model of Navigation component
     """
 
-    def __init__(self, parent, app, account, community):
+    def __init__(self, parent, app, connection, blockchain_service, identities_service):
+        """
+        Constructor of a model of WoT component
+
+        :param sakia.gui.identities.controller.IdentitiesController parent: the controller
+        :param sakia.app.Application app: the app
+        :param sakia.data.entities.Connection connection: the connection
+        :param sakia.services.BlockchainService blockchain_service: the blockchain service
+        :param sakia.services.IdentitiesService identities_service: the identities service
+        """
         super().__init__(parent)
         self.app = app
-        self.account = account
-        self.community = community
+        self.connection = connection
+        self.blockchain_service = blockchain_service
+        self.identities_service = identities_service
 
-    async def get_identity(self, pubkey):
+    def get_identity(self, pubkey):
         """
         Get identity from pubkey
         :param str pubkey: Identity pubkey
         :rtype: sakia.core.registry.Identity
         """
-        return await self.app.identities_registry.future_find(pubkey, self.community)
+        return self.identities_service.get_identity(pubkey, self.community)
diff --git a/src/sakia/gui/navigation/graphs/explorer/__init__.py b/src/sakia/gui/navigation/graphs/explorer/__init__.py
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/sakia/gui/navigation/graphs/explorer/controller.py b/src/sakia/gui/navigation/graphs/explorer/controller.py
deleted file mode 100644
index 5124dfaf450d06c4f1344820c9229e37d8d70b99..0000000000000000000000000000000000000000
--- a/src/sakia/gui/navigation/graphs/explorer/controller.py
+++ /dev/null
@@ -1,93 +0,0 @@
-import asyncio
-
-from sakia.decorators import asyncify, once_at_a_time
-from sakia.gui.sub.search_user.controller import SearchUserController
-from .model import ExplorerModel
-from .view import ExplorerView
-from ..base.controller import BaseGraphController
-
-
-class ExplorerController(BaseGraphController):
-    """
-    The homescreen view
-    """
-
-    def __init__(self, parent, view, model, password_asker=None):
-        """
-        Constructor of the explorer component
-
-        :param sakia.gui.graphs.explorer.view.ExplorerView: the view
-        :param sakia.gui.graphs.explorer.model.ExplorerModel model: the model
-        """
-        super().__init__(parent, view, model, password_asker)
-        self.set_scene(view.scene())
-        self.reset()
-        self.view.button_go.clicked.connect(self.start_exploration)
-        self.model.graph.graph_changed.connect(self.refresh)
-        self.model.graph.current_identity_changed.connect(self.view.update_current_identity)
-
-    def center_on_identity(self, identity):
-        """
-        Draw community graph centered on the identity
-
-        :param sakia.core.registry.Identity identity: Center identity
-        """
-        asyncio.ensure_future(self.draw_graph(identity))
-
-    def start_exploration(self):
-        self.model.graph.stop_exploration()
-        self.model.graph.start_exploration(self.model.identity, self.view.steps())
-
-    @property
-    def view(self) -> ExplorerView:
-        return self._view
-
-    @property
-    def model(self) -> ExplorerModel:
-        return self._model
-
-    @classmethod
-    def create(cls, parent, app, **kwargs):
-        account = kwargs['account']
-        community = kwargs['community']
-
-        view = ExplorerView(parent.view)
-        model = ExplorerModel(None, app, account, community)
-        explorer = cls(parent, view, model)
-        model.setParent(explorer)
-        search_user = SearchUserController.create(explorer, app, **{'account': account,
-                                                                    'community': community})
-        explorer.view.set_search_user(search_user.view)
-        search_user.identity_selected.connect(explorer.center_on_identity)
-        return explorer
-
-    async def draw_graph(self, identity):
-        """
-        Draw community graph centered on the identity
-
-        :param sakia.core.registry.Identity identity: Center identity
-        """
-        self.view.update_wot(self.model.graph.nx_graph, identity)
-
-    @once_at_a_time
-    @asyncify
-    async def refresh(self):
-        """
-        Refresh graph scene to current metadata
-        """
-        await self.draw_graph(self.model.identity)
-        self.view.update_wot(self.model.graph.nx_graph, self.model.identity)
-
-    @once_at_a_time
-    @asyncify
-    async def reset(self, checked=False):
-        """
-        Reset graph scene to wallet identity
-        """
-        # draw graph in qt scene
-        self.view.scene().clear()
-        self.view.reset_steps()
-        maximum_steps = await self.model.maximum_steps()
-        self.view.set_steps_max(maximum_steps)
-        await self.model.set_identity(None)
-        await self.draw_graph(self.model.identity)
diff --git a/src/sakia/gui/navigation/graphs/explorer/edge.py b/src/sakia/gui/navigation/graphs/explorer/edge.py
deleted file mode 100644
index 085538aac0961cce51fb0b0922e4077f6a850fc2..0000000000000000000000000000000000000000
--- a/src/sakia/gui/navigation/graphs/explorer/edge.py
+++ /dev/null
@@ -1,156 +0,0 @@
-import math
-
-from PyQt5.QtCore import Qt, QRectF, QLineF, QPointF, QSizeF, \
-                        qFuzzyCompare
-from PyQt5.QtGui import QColor, QPen, QPolygonF
-
-from sakia.data.graphs.constants import EdgeStatus
-from ..base.edge import BaseEdge
-
-
-class ExplorerEdge(BaseEdge):
-    def __init__(self, source_node, destination_node, metadata, nx_pos, steps, steps_max):
-        """
-        Create an arc between two nodes
-
-        :param Node source_node: Source node of the arc
-        :param Node destination_node: Destination node of the arc
-        :param dict metadata: Arc metadata
-        :param dict nx_pos: The position generated by nx_graph
-        :param int steps: The steps from the center identity
-        :param int steps_max: The steps max of the graph
-        """
-        super().__init__(source_node, destination_node, metadata, nx_pos)
-
-        self.source_point = self.destination_point
-        self.steps = steps
-        self.steps_max = steps_max
-        self.highlighted = False
-
-        self.arrow_size = 5
-        #  cursor change on hover
-        self.setAcceptHoverEvents(True)
-        self.setZValue(0)
-        self._line_styles = {
-            EdgeStatus.STRONG: Qt.SolidLine,
-            EdgeStatus.WEAK: Qt.DashLine
-        }
-        self.timeline = None
-
-    @property
-    def line_style(self):
-        return self._line_styles[self.status]
-
-    # virtual function require subclassing
-    def boundingRect(self):
-        """
-        Return the bounding rectangle size
-
-        :return: QRectF
-        """
-        if not self.source or not self.destination:
-            return QRectF()
-        pen_width = 1.0
-        extra = (pen_width + self.arrow_size) / 2.0
-
-        return QRectF(
-            self.source_point, QSizeF(
-                self.destination_point.x() - self.source_point.x(),
-                self.destination_point.y() - self.source_point.y()
-            )
-        ).normalized().adjusted(
-            -extra,
-            -extra,
-            extra,
-            extra
-        )
-
-    def paint(self, painter, option, widget):
-        """
-        Customize line adding an arrow head
-
-        :param QPainter painter: Painter instance of the item
-        :param option:  Painter option of the item
-        :param widget:  Widget instance
-        """
-        if not self.source or not self.destination:
-            return
-        line = QLineF(self.source_point, self.destination_point)
-        if qFuzzyCompare(line.length(), 0):
-            return
-
-        # Draw the line itself
-        color = QColor()
-        color.setHsv(120 - 60 / self.steps_max * self.steps,
-                     180 + 50 / self.steps_max * self.steps,
-                     150 + 80 / self.steps_max * self.steps)
-        if self.highlighted:
-            color.setHsv(0, 0, 0)
-
-        style = self.line_style
-
-        painter.setPen(QPen(color, 1, style, Qt.RoundCap, Qt.RoundJoin))
-        painter.drawLine(line)
-        painter.setPen(QPen(color, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
-
-        # Draw the arrows
-        angle = math.acos(line.dx() / line.length())
-        if line.dy() >= 0:
-            angle = (2.0 * math.pi) - angle
-
-        #  arrow in the middle of the arc
-        hpx = line.p1().x() + (line.dx() / 2.0)
-        hpy = line.p1().y() + (line.dy() / 2.0)
-        head_point = QPointF(hpx, hpy)
-
-        painter.setPen(QPen(color, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
-        destination_arrow_p1 = head_point + QPointF(
-            math.sin(angle - math.pi / 3) * self.arrow_size,
-            math.cos(angle - math.pi / 3) * self.arrow_size)
-        destination_arrow_p2 = head_point + QPointF(
-            math.sin(angle - math.pi + math.pi / 3) * self.arrow_size,
-            math.cos(angle - math.pi + math.pi / 3) * self.arrow_size)
-
-        painter.setBrush(color)
-        painter.drawPolygon(QPolygonF([head_point, destination_arrow_p1, destination_arrow_p2]))
-
-        if self.metadata["confirmation_text"]:
-            painter.drawText(head_point, self.metadata["confirmation_text"])
-
-    def move_source_point(self, node_id, x, y):
-        """
-        Move to corresponding position
-        :param str node_id: the node id
-        :param float x: x coordinates
-        :param float y: y coordinates
-        :return:
-        """
-        if node_id == self.source:
-            self.source_point = QPointF(x, y)
-            self.update(self.boundingRect())
-
-    def move_destination_point(self, node_id, x, y):
-        """
-        Move to corresponding position
-        :param str node_id: the node id
-        :param float x: x coordinates
-        :param float y: y coordinates
-        :return:
-        """
-        if node_id == self.destination:
-            self.destination_point = QPointF(x, y)
-            self.update(self.boundingRect())
-
-    def highlight(self):
-        """
-        Highlight the edge in the scene
-        """
-        self.highlighted = True
-        self.update(self.boundingRect())
-
-    def neutralize(self):
-        """
-        Neutralize the edge in the scene
-        """
-        self.highlighted = False
-        self.update(self.boundingRect())
diff --git a/src/sakia/gui/navigation/graphs/explorer/explorer.ui b/src/sakia/gui/navigation/graphs/explorer/explorer.ui
deleted file mode 100644
index c8ccca83a0ab54c652b6643b9ed6e32bf124b207..0000000000000000000000000000000000000000
--- a/src/sakia/gui/navigation/graphs/explorer/explorer.ui
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>ExplorerWidget</class>
- <widget class="QWidget" name="ExplorerWidget">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>522</width>
-    <height>442</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Form</string>
-  </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
-   <item>
-    <widget class="ExplorerGraphicsView" name="graphics_view">
-     <property name="viewportUpdateMode">
-      <enum>QGraphicsView::BoundingRectViewportUpdate</enum>
-     </property>
-    </widget>
-   </item>
-   <item>
-    <layout class="QHBoxLayout" name="horizontalLayout">
-     <property name="topMargin">
-      <number>6</number>
-     </property>
-     <item>
-      <spacer name="horizontalSpacer">
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>40</width>
-         <height>20</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-     <item>
-      <widget class="QLabel" name="label">
-       <property name="text">
-        <string>Steps</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QSlider" name="steps_slider">
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="tickPosition">
-        <enum>QSlider::TicksBothSides</enum>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QPushButton" name="button_go">
-       <property name="text">
-        <string>Go</string>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-  </layout>
- </widget>
- <customwidgets>
-  <customwidget>
-   <class>ExplorerGraphicsView</class>
-   <extends>QGraphicsView</extends>
-   <header>sakia.gui.navigation.graphs.explorer.graphics_view</header>
-  </customwidget>
- </customwidgets>
- <resources>
-  <include location="../../../../../../res/icons/icons.qrc"/>
- </resources>
- <connections/>
- <slots>
-  <slot>reset()</slot>
-  <slot>search()</slot>
-  <slot>select_node()</slot>
- </slots>
-</ui>
diff --git a/src/sakia/gui/navigation/graphs/explorer/graphics_view.py b/src/sakia/gui/navigation/graphs/explorer/graphics_view.py
deleted file mode 100644
index 3229282c5f63c2cd16d79cf7ffa0d40df6b8ba7b..0000000000000000000000000000000000000000
--- a/src/sakia/gui/navigation/graphs/explorer/graphics_view.py
+++ /dev/null
@@ -1,43 +0,0 @@
-from PyQt5.QtCore import Qt
-from PyQt5.QtGui import QPainter, QWheelEvent
-from PyQt5.QtWidgets import QGraphicsView
-from .scene import ExplorerScene
-
-
-class ExplorerGraphicsView(QGraphicsView):
-    def __init__(self, parent=None):
-        """
-        Create View to display scene
-
-        :param parent:  [Optional, default=None] Parent widget
-        """
-        super().__init__(parent)
-
-        self.setScene(ExplorerScene(self))
-
-        self.setCacheMode(QGraphicsView.CacheBackground)
-        self.setViewportUpdateMode(QGraphicsView.BoundingRectViewportUpdate)
-        self.setRenderHint(QPainter.Antialiasing)
-        self.setRenderHint(QPainter.SmoothPixmapTransform)
-
-    def wheelEvent(self, event: QWheelEvent):
-        """
-        Zoom in/out on the mouse cursor
-        """
-        # zoom only when CTRL key pressed
-        if (event.modifiers() & Qt.ControlModifier) == Qt.ControlModifier:
-            steps = event.angleDelta().y() / 15 / 8
-
-            if steps == 0:
-                event.ignore()
-                return
-
-            # scale factor 1.25
-            sc = pow(1.25, steps)
-            self.scale(sc, sc)
-            self.centerOn(self.mapToScene(event.pos()))
-            event.accept()
-        #  act normally on scrollbar
-        else:
-            # transmit event to parent class wheelevent
-            super().wheelEvent(event)
\ No newline at end of file
diff --git a/src/sakia/gui/navigation/graphs/explorer/model.py b/src/sakia/gui/navigation/graphs/explorer/model.py
deleted file mode 100644
index 110b2410dd13bfd3b4bd12a93b6fe3228e5c136b..0000000000000000000000000000000000000000
--- a/src/sakia/gui/navigation/graphs/explorer/model.py
+++ /dev/null
@@ -1,55 +0,0 @@
-from sakia.errors import NoPeerAvailable
-
-from sakia.data.graphs import ExplorerGraph
-from ..base.model import BaseGraphModel
-
-
-class ExplorerModel(BaseGraphModel):
-    """
-    The model of Navigation component
-    """
-
-    def __init__(self, parent, app, account, community):
-        super().__init__(parent, app, account, community)
-        self.app = app
-        self.account = account
-        self.community = community
-        self.explorer_graph = ExplorerGraph(self.app, self.community)
-        self.identity = None
-
-    @property
-    def graph(self):
-        """
-        Return underlying graph object
-        """
-        return self.explorer_graph
-
-    async def set_identity(self, identity):
-        """
-        Change current identity
-        If identity is None, it defaults to account identity
-        :param sakia.core.registry.Identity identity: the new identity to show
-        :return:
-        """
-        if identity:
-            self.identity = identity
-        else:
-            identity_account = await self.account.identity(self.community)
-            self.identity = identity_account
-
-    async def start_exploration(self, steps):
-        """
-        Get nx graph of current identity wot graph
-        :rtype: sakia.core.registry.Identity
-        """
-        return self.explorer_graph.start_exploration(self.identity, steps)
-
-    async def maximum_steps(self):
-        """
-        Get the maximum steps to display in the view
-        """
-        try:
-            parameters = await self.community.parameters()
-            return parameters['stepMax']
-        except NoPeerAvailable:
-            return 0
diff --git a/src/sakia/gui/navigation/graphs/explorer/node.py b/src/sakia/gui/navigation/graphs/explorer/node.py
deleted file mode 100644
index 19dda987cbf73bd95549b6818dbe5a7fd923f90a..0000000000000000000000000000000000000000
--- a/src/sakia/gui/navigation/graphs/explorer/node.py
+++ /dev/null
@@ -1,191 +0,0 @@
-import math
-
-from PyQt5.QtCore import Qt, QPointF, QTimeLine, QTimer
-from PyQt5.QtGui import QTransform, QColor, QPen, QBrush, QRadialGradient
-from PyQt5.QtWidgets import QGraphicsSimpleTextItem
-
-from sakia.data.graphs.constants import NodeStatus
-from ..base.node import BaseNode
-
-
-class ExplorerNode(BaseNode):
-    def __init__(self, nx_node, center_pos, nx_pos, steps, steps_max, small):
-        """
-        Create node in the graph scene
-
-        :param tuple nx_node: Node info
-        :param center_pos: The position of the center node
-        :param nx_pos: Position of the nodes in the graph
-        :param int steps: The steps from the center identity
-        :param int steps_max: The steps max of the graph
-        :param bool small: Small dots for big networks
-        """
-        super().__init__(nx_node, nx_pos)
-
-        self.steps = steps
-        self.steps_max = steps_max
-        self.highlighted = False
-        self.status_sentry = False
-
-        if small:
-            self.setRect(
-                0,
-                0,
-                10,
-                10
-            )
-            self.text_item = None
-        else:
-            # text inside ellipse
-            self.text_item = QGraphicsSimpleTextItem(self)
-            self.text_item.setText(self.text)
-            # center ellipse around text
-            self.setRect(
-                0,
-                0,
-                self.text_item.boundingRect().width() * 2,
-                self.text_item.boundingRect().height() * 2
-            )
-            # center text in ellipse
-            self.text_item.setPos(self.boundingRect().width() / 4.0, self.boundingRect().height() / 4.0)
-
-
-        #  set anchor to the center
-        self.setTransform(
-            QTransform().translate(-self.boundingRect().width() / 2.0, -self.boundingRect().height() / 2.0))
-
-        # cursor change on hover
-        self.setAcceptHoverEvents(True)
-        self.setZValue(1)
-
-        # animation and moves
-        self.timeline = None
-        self.loading_timer = QTimer()
-        self.loading_timer.timeout.connect(self.next_tick)
-        self.loading_counter = 0
-        self._refresh_colors()
-        self.setPos(center_pos)
-        self.move_to(nx_pos)
-
-    def update_metadata(self, metadata):
-        super().update_metadata(metadata)
-        self.status_sentry = self.metadata['is_sentry'] if 'is_sentry' in self.metadata else False
-        self._refresh_colors()
-
-    def _refresh_colors(self):
-        """
-        Refresh elements in the node
-        """
-        # color around ellipse
-        outline_color = QColor('grey')
-        outline_style = Qt.SolidLine
-        outline_width = 1
-        if self.status_wallet:
-            outline_width = 2
-        if not self.status_member:
-            outline_color = QColor('red')
-
-        if self.status_sentry:
-            outline_color = QColor('black')
-            outline_width = 3
-
-        self.setPen(QPen(outline_color, outline_width, outline_style))
-
-        if self.highlighted:
-            text_color = QColor('grey')
-        else:
-            text_color = QColor('black')
-
-        if self.status_wallet == NodeStatus.HIGHLIGHTED:
-            text_color = QColor('grey')
-
-        if self.text_item:
-            self.text_item.setBrush(QBrush(text_color))
-
-        # create gradient inside the ellipse
-        gradient = QRadialGradient(QPointF(0, self.boundingRect().height() / 4), self.boundingRect().width())
-        color = QColor()
-        color.setHsv(120 - 60 / self.steps_max * self.steps,
-                     180 + 50 / self.steps_max * self.steps,
-                     60 + 170 / self.steps_max * self.steps)
-        if self.highlighted:
-            color = color.darker(200)
-        color = color.lighter(math.fabs(math.sin(self.loading_counter / 100 * math.pi) * 100) + 100)
-        gradient.setColorAt(0, color)
-        gradient.setColorAt(1, color.darker(150))
-        self.setBrush(QBrush(gradient))
-
-    def move_to(self, nx_pos):
-        """
-        Move to corresponding position
-        :param nx_pos:
-        :return:
-        """
-        origin_x = self.x()
-        origin_y = self.y()
-        final_x = nx_pos[self.id][0]
-        final_y = nx_pos[self.id][1]
-
-        def frame_move(frame):
-            value = self.timeline.valueForTime(self.timeline.currentTime())
-            x = origin_x + (final_x - origin_x) * value
-            y = origin_y + (final_y - origin_y) * value
-            self.setPos(x, y)
-            if self.scene():
-                self.scene().node_moved.emit(self.id, x, y)
-
-        def timeline_ends():
-            self.setPos(final_x, final_y)
-            self.timeline = None
-
-        # Remember to hold the references to QTimeLine and QGraphicsItemAnimation instances.
-        # They are not kept anywhere, even if you invoke QTimeLine.start().
-        self.timeline = QTimeLine(1000)
-        self.timeline.setFrameRange(0, 100)
-        self.timeline.frameChanged.connect(frame_move)
-        self.timeline.finished.connect(timeline_ends)
-
-        self.timeline.start()
-
-    def highlight(self):
-        """
-        Highlight the edge in the scene
-        """
-        self.highlighted = True
-        self._refresh_colors()
-        self.update(self.boundingRect())
-
-    def neutralize(self):
-        """
-        Neutralize the edge in the scene
-        """
-        self.highlighted = False
-        self._refresh_colors()
-        self.update(self.boundingRect())
-
-    def start_loading_animation(self):
-        """
-        Neutralize the edge in the scene
-        """
-        if not self.loading_timer.isActive():
-            self.loading_timer.start(10)
-
-    def stop_loading_animation(self):
-        """
-        Neutralize the edge in the scene
-        """
-        self.loading_timer.stop()
-        self.loading_counter = 100
-        self._refresh_colors()
-        self.update(self.boundingRect())
-
-    def next_tick(self):
-        """
-        Next tick
-        :return:
-        """
-        self.loading_counter += 1
-        self.loading_counter %= 100
-        self._refresh_colors()
-        self.update(self.boundingRect())
-
diff --git a/src/sakia/gui/navigation/graphs/explorer/scene.py b/src/sakia/gui/navigation/graphs/explorer/scene.py
deleted file mode 100644
index 1036bc3809e94c3789e0eb5339355f24bba60b54..0000000000000000000000000000000000000000
--- a/src/sakia/gui/navigation/graphs/explorer/scene.py
+++ /dev/null
@@ -1,309 +0,0 @@
-import networkx
-import logging
-import math
-from PyQt5.QtCore import QPoint, pyqtSignal
-from PyQt5.QtWidgets import QGraphicsScene
-
-from .edge import ExplorerEdge
-from .node import ExplorerNode
-
-from ..base.scene import BaseScene
-
-
-class ExplorerScene(BaseScene):
-
-    node_moved = pyqtSignal(str, float, float)
-
-    def __init__(self, parent=None):
-        """
-        Create scene of the graph
-
-        :param parent: [Optional, default=None] Parent view
-        """
-        super().__init__(parent)
-
-        self.lastDragPos = QPoint()
-        self.setItemIndexMethod(QGraphicsScene.NoIndex)
-
-        # list of nodes in scene
-        self.nodes = dict()
-        #  axis of the scene for debug purpose
-        # self.addLine(-100, 0, 100, 0)
-        # self.addLine(0, -100, 0, 100)
-        self.node_hovered.connect(self.display_path_to)
-
-        # list of nodes in scene
-        self.nodes = dict()
-        self.edges = dict()
-        self.busy = None
-        self.nx_graph = None
-        self.identity = None
-        #  axis of the scene for debug purpose
-        # self.addLine(-100, 0, 100, 0)
-        # self.addLine(0, -100, 0, 100)
-
-    @staticmethod
-    def _init_layout(nx_graph):
-        """
-        Init the data of the layout
-        :param MultiGraph nx_graph:
-        """
-        data = {}
-        INF = len(nx_graph.nodes()) * len(nx_graph.nodes())
-
-        for node in nx_graph.nodes():
-            data[node] = {
-                'theta': None,
-                'scenter': INF,
-                'nchild': 0,
-                'sparent': None,
-                'stsize': 0.0,
-                'span': 0.0
-            }
-        return data
-
-    @staticmethod
-    def _set_nstep_to_center(nx_graph, data, current):
-        """
-        Set the number of steps to the center
-        :param networkx.MultiGraph nx_graph: the graph
-        :param dict data: the data of the layout
-        """
-        queue = [current]
-        while queue:
-            n = queue.pop()
-            nsteps = data[n]['scenter'] + 1
-            for edge in networkx.edges(nx_graph.to_undirected(), n):
-                next_node = edge[0] if edge[0] is not n else edge[1]
-                if data[next_node]['sparent']:
-                    continue
-                if nsteps < data[next_node]['scenter']:
-                    data[next_node]['scenter'] = nsteps
-                    data[next_node]['sparent'] = n
-                    data[n]['nchild'] += 1
-                    queue.append(next_node)
-
-    @staticmethod
-    def _set_parent_nodes(nx_graph, data, center):
-        """
-        Set the parent of each node
-        :param networkx.MultiGraph nx_graph: the graph
-        :param dict data: the data of the layout
-        :param str center: the id of the node at the center
-        """
-        unset = data[center]['scenter']
-        data[center]['scenter'] = 0
-        data[center]['sparent'] = None
-
-        logging.debug("Parent node of {0}".format(center))
-        ExplorerScene._set_nstep_to_center(nx_graph, data, center)
-        for node in nx_graph.nodes():
-            if data[node]['scenter'] == unset:
-                return -1
-        return max([n['scenter'] for n in data.values()])
-
-    @staticmethod
-    def _set_subtree_size(nx_graph, data):
-        """
-        Compute the subtree size of each node, which is the
-        number of leaves in subtree rooted to the node
-        :param networkx.MultiGraph nx_graph: the graph
-        :param dict data:
-        """
-        for node in nx_graph.nodes():
-            if data[node]['nchild'] > 0:
-                continue
-            data[node]['stsize'] += 1
-            parent = data[node]['sparent']
-            while parent:
-                data[parent]['stsize'] += 1
-                parent = data[parent]['sparent']
-
-    @staticmethod
-    def _set_subtree_spans(nx_graph, data, current):
-        """
-        Compute the subtree spans of each node
-        :param networkx.MultiGraph nx_graph: the graph
-        :param dict data: the data of the layout
-        :param str current: the current node which we compute the subtree
-        """
-        ratio = data[current]['span'] / data[current]['stsize']
-        for edge in nx_graph.to_undirected().edges(current):
-            next_node = edge[0] if edge[0] != current else edge[1]
-            if data[next_node]['sparent'] != current:
-                continue
-            if data[next_node]['span'] != 0.0:
-                continue
-
-            data[next_node]['span'] = ratio * data[next_node]['stsize']
-            if data[next_node]['nchild'] > 0:
-                ExplorerScene._set_subtree_spans(nx_graph, data, next_node)
-
-    @staticmethod
-    def _set_positions(nx_graph, data, current):
-        """
-        Compute the polar positions of each node
-        :param networkx.MultiDiGraph nx_graph: the graph
-        :param dict data: the data of the layout
-        :param str current: the current node which we compute the subtree
-        """
-        if not data[current]['sparent']:
-            theta = 0
-        else:
-            theta = data[current]['theta'] - data[current]['span'] / 2
-
-        for edge in nx_graph.to_undirected().edges(current):
-            next_node = edge[0] if edge[0] != current else edge[1]
-            if data[next_node]['sparent'] != current:
-                continue
-            if data[next_node]['theta']:
-                continue
-
-            data[next_node]['theta'] = theta + data[next_node]['span'] / 2.0
-            theta += data[next_node]['span']
-            if data[next_node]['nchild'] > 0:
-                ExplorerScene._set_positions(nx_graph, data, next_node)
-
-    @staticmethod
-    def twopi_layout(nx_graph, center=None):
-        """
-        Render the twopi layout. Ported from C code available at
-        https://github.com/ellson/graphviz/blob/master/lib/twopigen/circle.c
-
-        :param networkx.MultiDiGraph nx_graph: the networkx graph
-        :param str center: the centered node
-        :return:
-        """
-        if len(nx_graph.nodes()) == 0:
-            return {}
-
-        if len(nx_graph.nodes()) == 1:
-            return {nx_graph.nodes()[0]: (0, 0)}
-        #nx_graph = nx_graph.to_undirected()
-
-        data = ExplorerScene._init_layout(nx_graph)
-        if not center:
-            center = networkx.center(nx_graph)[0]
-        ExplorerScene._set_parent_nodes(nx_graph, data, center)
-        ExplorerScene._set_subtree_size(nx_graph, data)
-        data[center]['span'] = 2 * math.pi
-        ExplorerScene._set_subtree_spans(nx_graph, data, center)
-        data[center]['theta'] = 0.0
-        ExplorerScene._set_positions(nx_graph, data, center)
-
-        distances = networkx.shortest_path_length(nx_graph.to_undirected(), center)
-        nx_pos = {}
-        for node in nx_graph.nodes():
-            hyp = distances[node] + 1
-            theta = data[node]['theta']
-            nx_pos[node] = (hyp * math.cos(theta) * 100, hyp * math.sin(theta) * 100)
-        return nx_pos
-
-    def clear(self):
-        """
-        clear the scene
-        """
-        for node in self.nodes.values():
-            if node.timeline:
-                node.timeline.stop()
-
-        self.nodes.clear()
-        self.edges.clear()
-        super().clear()
-
-    def update_current_identity(self, identity_pubkey):
-        """
-        Update the current identity loaded
-
-        :param str identity_pubkey:
-        """
-        for node in self.nodes.values():
-            node.stop_loading_animation()
-
-        if identity_pubkey in self.nodes:
-            self.nodes[identity_pubkey].start_loading_animation()
-
-    def update_wot(self, nx_graph, identity, dist_max):
-        """
-        draw community graph
-
-        :param networkx.Graph nx_graph: graph to draw
-        :param sakia.core.registry.Identity identity: the wot of the identity
-        :param dist_max: the dist_max to display
-        """
-        #  clear scene
-        self.identity = identity
-        self.nx_graph = nx_graph.copy()
-
-        graph_pos = ExplorerScene.twopi_layout(nx_graph, center=identity.pubkey)
-        if len(nx_graph.nodes()) > 0:
-            distances = networkx.shortest_path_length(nx_graph.to_undirected(), identity.pubkey)
-        else:
-            distances = {}
-
-        # create networkx graph
-        for nx_node in nx_graph.nodes(data=True):
-            if nx_node[0] in self.nodes:
-                v = self.nodes[nx_node[0]]
-                v.move_to(graph_pos)
-                v.update_metadata(nx_node[1])
-            else:
-                center_pos = None
-                if len(nx_graph.edges(nx_node[0])) > 0:
-                    for edge in nx_graph.edges(nx_node[0]):
-                        neighbour = edge[0] if edge[0] != nx_node[0] else edge[1]
-                        if neighbour in self.nodes:
-                            center_pos = self.nodes[neighbour].pos()
-                            break
-                if not center_pos:
-                    if identity.pubkey in self.nodes:
-                        center_pos = self.nodes[identity.pubkey].pos()
-                    else:
-                        center_pos = QPoint(0, 0)
-
-                small = distances[nx_node[0]] > 1
-
-                v = ExplorerNode(nx_node, center_pos, graph_pos, distances[nx_node[0]], dist_max, small)
-                self.addItem(v)
-                self.nodes[nx_node[0]] = v
-
-        for edge in nx_graph.edges(data=True):
-            edge[2]["confirmation_text"] = ""
-            if (edge[0], edge[1]) not in self.edges:
-                distance = max(self.nodes[edge[0]].steps, self.nodes[edge[1]].steps)
-                explorer_edge = ExplorerEdge(edge[0], edge[1], edge[2], graph_pos, distance, dist_max)
-                self.node_moved.connect(explorer_edge.move_source_point)
-                self.node_moved.connect(explorer_edge.move_destination_point)
-                self.addItem(explorer_edge)
-                self.edges[(edge[0], edge[1])] = explorer_edge
-
-        self.update()
-
-    def display_path_to(self, node_id):
-        if node_id != self.identity.pubkey:
-            for edge in self.edges.values():
-                edge.neutralize()
-
-            for node in self.nodes.values():
-                node.neutralize()
-
-            path = []
-            try:
-                path = networkx.shortest_path(self.nx_graph, node_id, self.identity.pubkey)
-            except (networkx.exception.NetworkXError, networkx.exception.NetworkXNoPath) as e:
-                logging.debug(str(e))
-                try:
-                    path = networkx.shortest_path(self.nx_graph, self.identity.pubkey, node_id)
-                except (networkx.exception.NetworkXError, networkx.exception.NetworkXNoPath) as e:
-                    logging.debug(str(e))
-
-            for node, next_node in zip(path[:-1], path[1:]):
-                if (node, next_node) in self.edges:
-                    edge = self.edges[(node, next_node)]
-                elif (next_node, node) in self.edges:
-                    edge = self.edges[(next_node, node)]
-                if edge:
-                    edge.highlight()
-                    self.nodes[node].highlight()
-                    self.nodes[next_node].highlight()
-                    logging.debug("Update edge between {0} and {1}".format(node, next_node))
diff --git a/src/sakia/gui/navigation/graphs/explorer/view.py b/src/sakia/gui/navigation/graphs/explorer/view.py
deleted file mode 100644
index 0d2ccb88f7e3f7c5d2f690f30352fae626009ce1..0000000000000000000000000000000000000000
--- a/src/sakia/gui/navigation/graphs/explorer/view.py
+++ /dev/null
@@ -1,77 +0,0 @@
-from PyQt5.QtCore import QEvent
-from ..base.view import BaseGraphView
-from .explorer_uic import Ui_ExplorerWidget
-
-
-class ExplorerView(BaseGraphView, Ui_ExplorerWidget):
-    """
-    Wot graph view
-    """
-
-    def __init__(self, parent):
-        """
-        Constructor
-        """
-        super().__init__(parent)
-        self.setupUi(self)
-
-    def set_search_user(self, search_user):
-        """
-        Set the search user view in the gui
-        :param sakia.gui.search_user.view.SearchUserView search_user: the view
-        :return:
-        """
-        self.layout().insertWidget(0, search_user)
-
-    def set_steps_max(self, maximum):
-        """
-        Set the steps slider max value
-        :param int maximum: the max value
-        """
-        self.steps_slider.setMaximum(maximum)
-
-    def scene(self):
-        """
-        Get the scene of the underlying graphics view
-        :rtype: sakia.gui.graphs.explorer.scene.ExplorerScene
-        """
-        return self.graphics_view.scene()
-
-    def reset_steps(self):
-        """
-        Reset the steps slider
-        """
-        self.steps_slider.setValue(0)
-
-    def steps(self):
-        """
-        Get the number of steps selected
-        :return:
-        """
-        return self.steps_slider.value()
-
-    def update_wot(self, nx_graph, identity):
-        """
-        Display given wot around given identity
-        :param nx_graph:
-        :param identity:
-        :param steps:
-        :return:
-        """
-        # draw graph in qt scene
-        self.scene().update_wot(nx_graph, identity, self.steps_slider.maximum())
-
-    async def draw_graph(self):
-        """
-        Draw community graph centered on the identity
-
-        :param sakia.core.registry.Identity identity: Center identity
-        """
-        self.view.update_wot(self.model.graph.nx_graph, self.model.identity)
-
-    def update_current_identity(self, pubkey):
-        """
-        Change currently blinking identity
-        :param str pubkey:
-        """
-        self.scene().update_current_identity(pubkey)
diff --git a/src/sakia/gui/navigation/graphs/wot/controller.py b/src/sakia/gui/navigation/graphs/wot/controller.py
index 3dae41d1185eadc574f85f48b480b7f9723dc151..9df22776ab9118385379548ee860c25f4c4ef3ad 100644
--- a/src/sakia/gui/navigation/graphs/wot/controller.py
+++ b/src/sakia/gui/navigation/graphs/wot/controller.py
@@ -25,17 +25,18 @@ class WotController(BaseGraphController):
 
     @classmethod
     def create(cls, parent, app, **kwargs):
-        account = kwargs['account']
-        community = kwargs['community']
+        connection = kwargs['connection']
+        blockchain_service = kwargs['blockchain_service']
+        identities_service = kwargs['identities_service']
 
         view = WotView(parent.view)
-        model = WotModel(None, app, account, community)
+        model = WotModel(None, app, connection, blockchain_service, identities_service)
         wot = cls(parent, view, model)
         model.setParent(wot)
-        search_user = SearchUserController.create(wot, app, **{'account': account,
-                                                                    'community': community})
-        wot.view.set_search_user(search_user.view)
-        search_user.identity_selected.connect(wot.center_on_identity)
+        #search_user = SearchUserController.create(wot, app, **{'account': account,
+        #                                                            'community': community})
+        #wot.view.set_search_user(search_user.view)
+        #search_user.identity_selected.connect(wot.center_on_identity)
         return wot
 
     @property
@@ -69,7 +70,7 @@ class WotController(BaseGraphController):
         """
         Refresh graph scene to current metadata
         """
-        nx_graph = await self.model.get_nx_graph()
+        nx_graph = self.model.get_nx_graph()
         self.view.display_wot(nx_graph, self.model.identity)
         path = await self.model.get_shortest_path()
         if path:
diff --git a/src/sakia/gui/navigation/graphs/wot/model.py b/src/sakia/gui/navigation/graphs/wot/model.py
index d6c0440e14985e86e053867bc7b3fdb08ee01ae8..d1c85b38443c99f7114cbcbc4cab9f96ccc3c68e 100644
--- a/src/sakia/gui/navigation/graphs/wot/model.py
+++ b/src/sakia/gui/navigation/graphs/wot/model.py
@@ -7,12 +7,22 @@ class WotModel(BaseGraphModel):
     The model of Navigation component
     """
 
-    def __init__(self, parent, app, account, community):
-        super().__init__(parent, app, account, community)
+    def __init__(self, parent, app, connection, blockchain_service, identities_service):
+        """
+        Constructor of a model of WoT component
+
+        :param sakia.gui.identities.controller.IdentitiesController parent: the controller
+        :param sakia.app.Application app: the app
+        :param sakia.data.entities.Connection connection: the connection
+        :param sakia.services.BlockchainService blockchain_service: the blockchain service
+        :param sakia.services.IdentitiesService identities_service: the identities service
+        """
+        super().__init__(parent, app, connection, blockchain_service, identities_service)
         self.app = app
-        self.account = account
-        self.community = community
-        self.wot_graph = WoTGraph(self.app, self.community)
+        self.connection = connection
+        self.blockchain_service = blockchain_service
+        self.identities_service = identities_service
+        self.wot_graph = WoTGraph(self.app, self.blockchain_service, self.identities_service)
         self.identity = None
 
     async def set_identity(self, identity=None):
@@ -22,16 +32,16 @@ class WotModel(BaseGraphModel):
         :param sakia.core.registry.Identity identity: the new identity to show
         :return:
         """
-        identity_account = await self.account.identity(self.community)
+        connection_identity = self.identities_service.get_identity(self.connection.pubkey)
         if identity:
             self.identity = identity
         else:
-            self.identity = identity_account
+            self.identity = connection_identity
 
         # create empty graph instance
-        await self.wot_graph.initialize(self.identity, identity_account)
+        await self.wot_graph.initialize(self.identity, connection_identity)
 
-    async def get_nx_graph(self):
+    def get_nx_graph(self):
         """
         Get nx graph of current identity wot graph
         :rtype: sakia.core.registry.Identity
@@ -43,7 +53,7 @@ class WotModel(BaseGraphModel):
         Get shortest path between current identity and account
         :rtype: list[str]
         """
-        identity_account = await self.account.identity(self.community)
+        identity_account = self.identities_service.get_identity(self.connection.pubkey)
         # if selected member is not the account member...
         if self.identity.pubkey != identity_account.pubkey:
             path = await self.wot_graph.get_shortest_path_to_identity(self.identity, identity_account)
diff --git a/src/sakia/gui/navigation/graphs/wot/view.py b/src/sakia/gui/navigation/graphs/wot/view.py
index e4e404604c6c184641d6aa4440548be63e3cd1e2..f735745feb9d7715da9d62241192d8a19bd083f1 100644
--- a/src/sakia/gui/navigation/graphs/wot/view.py
+++ b/src/sakia/gui/navigation/graphs/wot/view.py
@@ -46,4 +46,4 @@ class WotView(BaseGraphView, Ui_WotWidget):
         :param path:
         :return:
         """
-        self.graphics_view.scene().update_path(nx_graph, path)
+        #self.graphics_view.scene().update_path(nx_graph, path)
diff --git a/src/sakia/gui/navigation/identities/model.py b/src/sakia/gui/navigation/identities/model.py
index 218985c6aac2f568c136012e8e570b25efeb6a65..b27282067e6b7fa5490cdf4c63a45402421c0972 100644
--- a/src/sakia/gui/navigation/identities/model.py
+++ b/src/sakia/gui/navigation/identities/model.py
@@ -44,13 +44,9 @@ class IdentitiesModel(ComponentModel):
         """
         if index.isValid() and index.row() < self.table_model.rowCount():
             source_index = self.table_model.mapToSource(index)
-            pubkey_col = self.table_model.sourceModel().columns_ids.index('pubkey')
-            pubkey_index = self.table_model.sourceModel().index(source_index.row(),
-                                                   pubkey_col)
-            pubkey = self.table_model.sourceModel().data(pubkey_index, Qt.DisplayRole)
-            identity_col = self.table_model.sourceModel().columns_ids.index('pubkey')
+            identity_col = self.table_model.sourceModel().columns_ids.index('identity')
             identity_index = self.table_model.sourceModel().index(source_index.row(),
-                                                   pubkey_col)
+                                                                  identity_col)
             identity = self.table_model.sourceModel().data(identity_index, Qt.DisplayRole)
             return True, identity
         return False, None
diff --git a/src/sakia/gui/navigation/model.py b/src/sakia/gui/navigation/model.py
index 296b3a841e1e89ce618858d55f4ba53ae339e8fd..49f97c0350d93ca4be4f32c2903bdfd60410a641 100644
--- a/src/sakia/gui/navigation/model.py
+++ b/src/sakia/gui/navigation/model.py
@@ -73,13 +73,16 @@ class NavigationModel(ComponentModel):
                             'identities_service': self.app.identities_services[connection.currency],
                         }
                     },
-            #        {
-            #            'node': {
-            #                'title': self.tr('Web of Trust'),
-            #                'icon': ':/icons/wot_icon',
-            #                'component': "Wot",
-            #            }
-            #        }
+                    {
+                        'node': {
+                            'title': self.tr('Web of Trust'),
+                            'icon': ':/icons/wot_icon',
+                            'component': "Wot",
+                            'connection': connection,
+                            'blockchain_service': self.app.blockchain_services[connection.currency],
+                            'identities_service': self.app.identities_services[connection.currency],
+                        }
+                    }
                 ]
             })
         return self.navigation
diff --git a/src/sakia/gui/sub/user_information/controller.py b/src/sakia/gui/sub/user_information/controller.py
index 9572ab0d89527b9d1aa5872e3d394e3ffbd2864b..db3cfab194a5ff2fb1e7c2c757c6d5f12760878f 100644
--- a/src/sakia/gui/sub/user_information/controller.py
+++ b/src/sakia/gui/sub/user_information/controller.py
@@ -54,7 +54,7 @@ class UserInformationController(ComponentController):
         if self.model.identity:
             self.view.show_busy()
             self.view.display_uid(self.model.identity.uid)
-            await self.model.update_identity()
+            await self.model.load_identity()
             self.view.display_identity_timestamps(self.model.identity.pubkey, self.model.identity.timestamp,
                                                   self.model.identity.membership_timestamp)
             self.view.hide_busy()
diff --git a/src/sakia/gui/sub/user_information/model.py b/src/sakia/gui/sub/user_information/model.py
index 5dd61b03e4caaa278affe0c5e05eb5a18ac8fd68..a14e74d318c3ea3d5fb07fe11dc10eb9b82d8a94 100644
--- a/src/sakia/gui/sub/user_information/model.py
+++ b/src/sakia/gui/sub/user_information/model.py
@@ -25,8 +25,10 @@ class UserInformationModel(ComponentModel):
         self.identity = identity
         self.identities_service = identities_service
 
-    async def update_identity(self):
+    async def load_identity(self):
         """
         Ask network service to request identity informations
         """
-        await self.network_service.update_memberships(self.identity)
+        await self.identities_service.load_memberships(self.identity)
+        await self.identities_service.load_certifiers_of(self.identity)
+        await self.identities_service.load_certified_by(self.identity)
diff --git a/src/sakia/services/identities.py b/src/sakia/services/identities.py
index 4d59cc156ebdf43b965a9805260067aa0f40e2fb..d07451b6f0e3ca24efb546b8f44d6357641c3179 100644
--- a/src/sakia/services/identities.py
+++ b/src/sakia/services/identities.py
@@ -66,9 +66,10 @@ class IdentitiesService(QObject):
                 return sig_period - (current_time - latest_time)
         return 0
 
-    async def update_memberships(self, identity):
+    async def load_memberships(self, identity):
         """
         Request the identity data and save it to written identities
+        It does nothing if the identity is already written and updated with blockchain lookups
         :param sakia.data.entities.Identity identity: the identity
         """
         if not identity.written_on:
@@ -94,27 +95,53 @@ class IdentitiesService(QObject):
             except NoPeerAvailable as e:
                 logging.debug(str(e))
 
-    async def update_certified_by(self, identity):
+    async def load_certifiers_of(self, identity):
         """
         Request the identity data and save it to written certifications
+        It does nothing if the identity is already written and updated with blockchain lookups
         :param sakia.data.entities.Identity identity: the identity
         """
-        try:
-            data = await self._bma_connector.get(self.currency, bma.wot.CertifiedBy, {'search': self.pubkey})
-            for certified_data in data['certifications']:
-                cert = Certification(self.currency, data["pubkey"],
-                                     certified_data["pubkey"], certified_data["sigDate"])
-                cert.block = certified_data["cert_time"]["number"]
-                cert.timestamp = certified_data["cert_time"]["medianTime"]
-                if certified_data['written']:
-                    cert.written_on = BlockUID(certified_data['written']['number'],
-                                               certified_data['written']['hash'])
-                self._certs_processor.commit_certification(cert)
-        except errors.DuniterError as e:
-            if e.ucode in (errors.NO_MATCHING_IDENTITY, errors.NO_MEMBER_MATCHING_PUB_OR_UID):
-                logging.debug("Certified by error : {0}".format(str(e)))
-        except NoPeerAvailable as e:
-            logging.debug(str(e))
+        if not identity.written_on:
+            try:
+                data = await self._bma_connector.get(self.currency, bma.wot.certifiers_of, {'search': identity.pubkey})
+                for certified_data in data['certifications']:
+                    cert = Certification(self.currency, data["pubkey"],
+                                         certified_data["pubkey"], certified_data["sigDate"])
+                    cert.block = certified_data["cert_time"]["number"]
+                    cert.timestamp = certified_data["cert_time"]["medianTime"]
+                    if certified_data['written']:
+                        cert.written_on = BlockUID(certified_data['written']['number'],
+                                                   certified_data['written']['hash'])
+                    self._certs_processor.commit_certification(cert)
+            except errors.DuniterError as e:
+                if e.ucode in (errors.NO_MATCHING_IDENTITY, errors.NO_MEMBER_MATCHING_PUB_OR_UID):
+                    logging.debug("Certified by error : {0}".format(str(e)))
+            except NoPeerAvailable as e:
+                logging.debug(str(e))
+
+    async def load_certified_by(self, identity):
+        """
+        Request the identity data and save it to written certifications
+        It does nothing if the identity is already written and updated with blockchain lookups
+        :param sakia.data.entities.Identity identity: the identity
+        """
+        if not identity.written_on:
+            try:
+                data = await self._bma_connector.get(self.currency, bma.wot.certified_by, {'search': identity.pubkey})
+                for certified_data in data['certifications']:
+                    cert = Certification(self.currency, data["pubkey"],
+                                         certified_data["pubkey"], certified_data["sigDate"])
+                    cert.block = certified_data["cert_time"]["number"]
+                    cert.timestamp = certified_data["cert_time"]["medianTime"]
+                    if certified_data['written']:
+                        cert.written_on = BlockUID(certified_data['written']['number'],
+                                                   certified_data['written']['hash'])
+                    self._certs_processor.commit_certification(cert)
+            except errors.DuniterError as e:
+                if e.ucode in (errors.NO_MATCHING_IDENTITY, errors.NO_MEMBER_MATCHING_PUB_OR_UID):
+                    logging.debug("Certified by error : {0}".format(str(e)))
+            except NoPeerAvailable as e:
+                logging.debug(str(e))
 
     def _parse_revocations(self, block):
         """
@@ -201,16 +228,19 @@ class IdentitiesService(QObject):
         :param sakia.data.entities.Identity identity:
         :return:
         """
-        requirements = await self._bma_connector.get(self.currency, bma.wot.Requirements,
-                                                     get_args={'search': identity.pubkey})
-        identity_data = requirements['identities'][0]
-        identity.uid = identity_data["uid"]
-        identity.blockstamp = identity["meta"]["timestamp"]
-        identity.member = identity["membershipExpiresIn"] > 0 and identity["outdistanced"] is False
-        median_time = self._blockchain_processor.time(self.currency)
-        expiration_time = self._blockchain_processor.parameters(self.currency).ms_validity
-        identity.membership_timestamp = median_time - (expiration_time - identity["membershipExpiresIn"])
-        self._identities_processor.commit_identity(identity)
+        try:
+            requirements = await self._bma_connector.get(self.currency, bma.wot.requirements,
+                                                         req_args={'search': identity.pubkey})
+            identity_data = requirements['identities'][0]
+            identity.uid = identity_data["uid"]
+            identity.blockstamp = identity["meta"]["timestamp"]
+            identity.member = identity["membershipExpiresIn"] > 0 and identity["outdistanced"] is False
+            median_time = self._blockchain_processor.time(self.currency)
+            expiration_time = self._blockchain_processor.parameters(self.currency).ms_validity
+            identity.membership_timestamp = median_time - (expiration_time - identity["membershipExpiresIn"])
+            self._identities_processor.commit_identity(identity)
+        except NoPeerAvailable as e:
+            self._logger.debug(str(e))
 
     def parse_block(self, block):
         """
@@ -277,3 +307,19 @@ class IdentitiesService(QObject):
         """
         validity = self._blockchain_processor.parameters(self.currency).ms_validity
         return identity.membership_timestamp + validity
+
+    def certifications_received(self, pubkey):
+        """
+        Get the list of certifications received by a given identity
+        :param str pubkey: the pubkey
+        :rtype: List[sakia.data.entities.Certifications]
+        """
+        return self._certs_processor.certifications_received(self.currency, pubkey)
+
+    def certifications_sent(self, pubkey):
+        """
+        Get the list of certifications received by a given identity
+        :param str pubkey: the pubkey
+        :rtype: List[sakia.data.entities.Certifications]
+        """
+        return self._certs_processor.certifications_sent(self.currency, pubkey)