diff --git a/res/icons/icons.qrc b/res/icons/icons.qrc
index bf77a31ec0b714976425bcd146d69ceeee7b4782..af660cdf8ad598e40f15df78567b8c1cbcc55d33 100644
--- a/res/icons/icons.qrc
+++ b/res/icons/icons.qrc
@@ -1,6 +1,7 @@
 <RCC>
   <qresource prefix="icons">
     <file alias="network_icon">noun_21549_cc.svg</file>
+    <file alias="member_icon">iconmonstr-user-icon.svg</file>
     <file alias="informations_icon">iconmonstr-info-2-icon.svg</file>
     <file alias="community_icon">noun_22441_cc.svg</file>
     <file alias="wot_icon">noun_2651_cc.svg</file>
diff --git a/src/cutecoin/core/account.py b/src/cutecoin/core/account.py
index bca78280b64d42b6a99e3f1da2ac55d83d6f59f0..504ae4afdee58460430664b9e27326525be505d8 100644
--- a/src/cutecoin/core/account.py
+++ b/src/cutecoin/core/account.py
@@ -275,3 +275,6 @@ class Account(QObject):
                 'wallets': data_wallets,
                 'contacts': data_contacts}
         return data
+
+    def get_person(self):
+        return Person(self.name, self.pubkey)
diff --git a/src/cutecoin/core/graph.py b/src/cutecoin/core/graph.py
new file mode 100644
index 0000000000000000000000000000000000000000..1dddf104fae5d65a37cf31fd7ffcd98476712949
--- /dev/null
+++ b/src/cutecoin/core/graph.py
@@ -0,0 +1,251 @@
+import logging
+import copy
+import time
+import datetime
+from cutecoin.core.person import Person
+from cutecoin.gui.views.wot import NODE_STATUS_HIGHLIGHTED, NODE_STATUS_OUT, ARC_STATUS_STRONG, ARC_STATUS_WEAK
+
+
+class Graph(dict):
+    def __init__(self, community):
+        """
+        Init Graph instance
+        :param cutecoin.core.community.Community community:
+        :return:
+        """
+        self.community = community
+        self.signature_validity = self.community.get_parameters()['sigValidity']
+        #  arc considered strong during 75% of signature validity time
+        self.ARC_STATUS_STRONG_time = int(self.signature_validity * 0.75)
+
+    def get_shortest_path_between_members(self, from_person, to_person):
+        """
+        Return path list of nodes from from_person to to_person
+        :param Person from_person:
+        :param Person to_person:
+        :return:
+        """
+        path = list()
+        graph_tmp = copy.deepcopy(self)
+
+        logging.debug("path between %s to %s..." % (from_person.name, to_person.name))
+        if from_person.pubkey not in graph_tmp.keys():
+            graph_tmp.add_person(from_person)
+            certifier_list = from_person.certifiers_of(self.community)
+            graph_tmp.add_certifier_list(certifier_list, from_person, to_person)
+            certified_list = from_person.certified_by(self.community)
+            graph_tmp.add_certified_list(certified_list, from_person, to_person)
+
+        if to_person.pubkey not in graph_tmp.keys():
+            # recursively feed graph searching for account node...
+            graph_tmp.explore_to_find_member(to_person, graph_tmp[from_person.pubkey]['connected'], list())
+        if len(graph_tmp[from_person.pubkey]['connected']) > 0:
+            # calculate path of nodes between person and to_person
+            path = graph_tmp.find_shortest_path(graph_tmp[from_person.pubkey], graph_tmp[to_person.pubkey])
+
+        if path:
+            logging.debug([node['text'] for node in path])
+        else:
+            logging.debug('no wot path')
+
+        return path
+
+    def explore_to_find_member(self, person, connected=None, done=None):
+        """
+        Scan graph recursively to find person
+        :param Person person:   Person instance to find
+        :param list connected:  Optional, default=None, Pubkey list of the connected nodes
+        around the current scanned node
+        :param list done:       Optional, default=None, List of node already scanned
+        :return:
+        """
+        # functions keywords args are persistent... Need to reset it with None trick
+        connected = connected or (list() and (connected is None))
+        done = done or (list() and (done is None))
+        logging.debug("search %s in " % person.name)
+        logging.debug([self[pubkey]['text'] for pubkey in connected])
+        # for each pubkey connected...
+        for pubkey in tuple(connected):
+            # capture node connected
+            node = self[pubkey]
+            if node['id'] in tuple(done):
+                continue
+            person_selected = Person(node['text'], node['id'])
+            certifier_list = person_selected.certifiers_of(self.community)
+            self.add_certifier_list(certifier_list, person_selected, person)
+            if person.pubkey in tuple(self.keys()):
+                return False
+            certified_list = person_selected.certified_by(self.community)
+            self.add_certified_list(certified_list, person_selected, person)
+            if person.pubkey in tuple(self.keys()):
+                return False
+            if node['id'] not in tuple(done):
+                done.append(node['id'])
+            if len(done) >= len(self):
+                return True
+            result = self.explore_to_find_member(person, self[person_selected.pubkey]['connected'], done)
+            if not result:
+                return False
+
+        return True
+
+    def find_shortest_path(self, start, end, path=None):
+        """
+        Find recursively the shortest path between two nodes
+        :param dict start:  Start node
+        :param dict end:    End node
+        :param list path:   Optional, default=None, List of nodes
+        :return:
+        """
+        path = path or (list() and (path is None))
+        path = path + [start]
+        if start['id'] == end['id']:
+            return path
+        if start['id'] not in self.keys():
+            return None
+        shortest = None
+        for pubkey in tuple(self[start['id']]['connected']):
+            node = self[pubkey]
+            if node not in path:
+                newpath = self.find_shortest_path(node, end, path)
+                if newpath:
+                    if not shortest or len(newpath) < len(shortest):
+                        shortest = newpath
+        return shortest
+
+    def add_certifier_list(self, certifier_list, person, person_account):
+        """
+        Add list of certifiers to graph
+        :param list certifier_list: List of certifiers from api
+        :param Person person:   Person instance which is certified
+        :param Person person_account:   Account person instance
+        :return:
+        """
+        #  add certifiers of uid
+        for certifier in tuple(certifier_list):
+            # add only valid certification...
+            if (time.time() - certifier['cert_time']['medianTime']) > self.signature_validity:
+                continue
+            # new node
+            if certifier['pubkey'] not in self.keys():
+                node_status = 0
+                if certifier['pubkey'] == person_account.pubkey:
+                    node_status += NODE_STATUS_HIGHLIGHTED
+                if certifier['isMember'] is False:
+                    node_status += NODE_STATUS_OUT
+                self[certifier['pubkey']] = {
+                    'id': certifier['pubkey'],
+                    'arcs': list(),
+                    'text': certifier['uid'],
+                    'tooltip': certifier['pubkey'],
+                    'status': node_status,
+                    'connected': [person.pubkey]
+                }
+
+            # keep only the latest certification
+            if self[certifier['pubkey']]['arcs']:
+                if certifier['cert_time']['medianTime'] < self[certifier['pubkey']]['arcs'][0]['cert_time']:
+                    continue
+            # display validity status
+            if (time.time() - certifier['cert_time']['medianTime']) > self.ARC_STATUS_STRONG_time:
+                arc_status = ARC_STATUS_WEAK
+            else:
+                arc_status = ARC_STATUS_STRONG
+            arc = {
+                'id': person.pubkey,
+                'status': arc_status,
+                'tooltip': datetime.datetime.fromtimestamp(
+                    certifier['cert_time']['medianTime'] + self.signature_validity
+                ).strftime("%d/%m/%Y"),
+                'cert_time': certifier['cert_time']['medianTime']
+            }
+            #  add arc to certifier
+            self[certifier['pubkey']]['arcs'].append(arc)
+            # if certifier node not in person nodes
+            if certifier['pubkey'] not in tuple(self[person.pubkey]['connected']):
+                # add certifier node to person node
+                self[person.pubkey]['connected'].append(certifier['pubkey'])
+
+    def add_certified_list(self, certified_list, person, person_account):
+        """
+        Add list of certified from api to graph
+        :param list certified_list: List of certified from api
+        :param Person person:   Person instance which is certifier
+        :param Person person_account:   Account person instance
+        :return:
+        """
+        # add certified by uid
+        for certified in tuple(certified_list):
+            # add only valid certification...
+            if (time.time() - certified['cert_time']['medianTime']) > self.signature_validity:
+                continue
+            if certified['pubkey'] not in self.keys():
+                node_status = 0
+                if certified['pubkey'] == person_account.pubkey:
+                    node_status += NODE_STATUS_HIGHLIGHTED
+                if certified['isMember'] is False:
+                    node_status += NODE_STATUS_OUT
+                self[certified['pubkey']] = {
+                    'id': certified['pubkey'],
+                    'arcs': list(),
+                    'text': certified['uid'],
+                    'tooltip': certified['pubkey'],
+                    'status': node_status,
+                    'connected': [person.pubkey]
+                }
+            # display validity status
+            if (time.time() - certified['cert_time']['medianTime']) > self.ARC_STATUS_STRONG_time:
+                arc_status = ARC_STATUS_WEAK
+            else:
+                arc_status = ARC_STATUS_STRONG
+            arc = {
+                'id': certified['pubkey'],
+                'status': arc_status,
+                'tooltip': datetime.datetime.fromtimestamp(
+                    certified['cert_time']['medianTime'] + self.signature_validity
+                ).strftime("%d/%m/%Y"),
+                'cert_time': certified['cert_time']['medianTime']
+            }
+
+            # replace old arc if this one is more recent
+            new_arc = True
+            index = 0
+            for a in self[person.pubkey]['arcs']:
+                # if same arc already exists...
+                if a['id'] == arc['id']:
+                    # if arc more recent, dont keep old one...
+                    if arc['cert_time'] >= a['cert_time']:
+                        self[person.pubkey]['arcs'][index] = arc
+                    new_arc = False
+                index += 1
+
+            #  if arc not in graph...
+            if new_arc:
+                # add arc in graph
+                self[person.pubkey]['arcs'].append(arc)
+            # if certified node not in person nodes
+            if certified['pubkey'] not in tuple(self[person.pubkey]['connected']):
+                # add certified node to person node
+                self[person.pubkey]['connected'].append(certified['pubkey'])
+
+    def add_person(self, person, status=None, arcs=None, connected=None):
+        """
+        Add person as a new node in graph
+        :param Person person: Person instance
+        :param int status:  Optional, default=None, Node status (see cutecoin.gui.views.wot)
+        :param list arcs:  Optional, default=None, List of arcs (certified by person)
+        :param list connected:  Optional, default=None, Public key list of the connected nodes around the person
+        :return:
+        """
+        # functions keywords args are persistent... Need to reset it with None trick
+        status = status or (0 and (status is None))
+        arcs = arcs or (list() and (arcs is None))
+        connected = connected or (list() and (connected is None))
+        self[person.pubkey] = {
+            'id': person.pubkey,
+            'arcs': arcs,
+            'text': person.name,
+            'tooltip': person.pubkey,
+            'status': status,
+            'connected': connected
+        }
diff --git a/src/cutecoin/core/person.py b/src/cutecoin/core/person.py
index 2b40cb4e931fceae08c9752a69a2d7a3eb87b43d..4548c0794ae49099de0351cb14ce6c706213d52a 100644
--- a/src/cutecoin/core/person.py
+++ b/src/cutecoin/core/person.py
@@ -6,6 +6,7 @@ Created on 11 févr. 2014
 
 import logging
 import functools
+import datetime
 from ucoinpy.api import bma
 from ucoinpy import PROTOCOL_VERSION
 from ucoinpy.documents.certification import SelfCertification
@@ -156,14 +157,28 @@ class Person(object):
                                              signature)
         raise PersonNotFoundError(self.pubkey, community.name())
 
+    def get_join_date(self, community):
+        try:
+            search = community.request(bma.blockchain.Membership, {'search': self.pubkey})
+            membership_data = None
+            if len(search['memberships']) > 0:
+                membership_data = search['memberships'][0]
+                return datetime.datetime.fromtimestamp(community.get_block(membership_data['blockNumber']).mediantime).strftime("%d/%m/%Y %I:%M")
+            else:
+                return None
+        except ValueError as e:
+            if '400' in str(e):
+                raise MembershipNotFoundError(self.pubkey, community.name())
+
     @cached
     def membership(self, community):
         try:
             search = community.request(bma.blockchain.Membership,
                                                {'search': self.pubkey})
-            block_number = 0
+            block_number = -1
             for ms in search['memberships']:
-                if ms['blockNumber'] >= block_number:
+                if ms['blockNumber'] > block_number:
+                    block_number = ms['blockNumber']
                     if 'type' in ms:
                         if ms['type'] is 'IN':
                             membership_data = ms
diff --git a/src/cutecoin/gui/community_tab.py b/src/cutecoin/gui/community_tab.py
index 69075a40d06bb8663de01e674853b5c9b8cf4be6..5d713e640adff57b8af9354ffc8473ecdd3341ac 100644
--- a/src/cutecoin/gui/community_tab.py
+++ b/src/cutecoin/gui/community_tab.py
@@ -12,6 +12,7 @@ from PyQt5.QtWidgets import QWidget, QMessageBox, QAction, QMenu, QDialog, \
 from ..models.members import MembersFilterProxyModel, MembersTableModel
 from ..gen_resources.community_tab_uic import Ui_CommunityTabWidget
 from cutecoin.gui.contact import ConfigureContactDialog
+from cutecoin.gui.member import MemberDialog
 from .wot_tab import WotTabWidget
 from .transfer import TransferMoneyDialog
 from .password_asker import PasswordAskerDialog
@@ -64,6 +65,10 @@ class CommunityTabWidget(QWidget, Ui_CommunityTabWidget):
             member = Person.lookup(pubkey, self.community)
             menu = QMenu(self)
 
+            informations = QAction("Informations", self)
+            informations.triggered.connect(self.menu_informations)
+            informations.setData(member)
+
             add_contact = QAction("Add as contact", self)
             add_contact.triggered.connect(self.menu_add_as_contact)
             add_contact.setData(member)
@@ -80,6 +85,7 @@ class CommunityTabWidget(QWidget, Ui_CommunityTabWidget):
             view_wot.triggered.connect(self.view_wot)
             view_wot.setData(member)
 
+            menu.addAction(informations)
             menu.addAction(add_contact)
             menu.addAction(send_money)
             menu.addAction(certify)
@@ -88,6 +94,10 @@ class CommunityTabWidget(QWidget, Ui_CommunityTabWidget):
             # Show the context menu.
             menu.exec_(QCursor.pos())
 
+    def menu_informations(self):
+        person = self.sender().data()
+        self.member_informations(person)
+
     def menu_add_as_contact(self):
         person = self.sender().data()
         self.add_member_as_contact(person)
@@ -100,6 +110,10 @@ class CommunityTabWidget(QWidget, Ui_CommunityTabWidget):
         person = self.sender().data()
         self.certify_member(person)
 
+    def member_informations(self, person):
+        dialog = MemberDialog(self.account, self.community, person)
+        dialog.exec_()
+
     def add_member_as_contact(self, person):
         dialog = ConfigureContactDialog(self.account, self.window(), person)
         result = dialog.exec_()
diff --git a/src/cutecoin/gui/member.py b/src/cutecoin/gui/member.py
new file mode 100644
index 0000000000000000000000000000000000000000..d961db04146f74fa9a3e22fe1ff2d6520cf36139
--- /dev/null
+++ b/src/cutecoin/gui/member.py
@@ -0,0 +1,63 @@
+from cutecoin.core.graph import Graph
+from PyQt5.QtWidgets import QDialog
+from ..gen_resources.member_uic import Ui_DialogMember
+
+
+class MemberDialog(QDialog, Ui_DialogMember):
+    """
+    classdocs
+    """
+
+    def __init__(self, account, community, person):
+        """
+        Constructor
+        """
+        super().__init__()
+        self.setupUi(self)
+        self.community = community
+        self.account = account
+        self.person = person
+        self.label_uid.setText(person.name)
+
+        join_date = self.person.get_join_date(self.community)
+        if join_date is None:
+            join_date = 'not a member'
+
+        # calculate path to account member
+        graph = Graph(self.community)
+        path = None
+        # if selected member is not the account member...
+        if person.pubkey != self.account.pubkey:
+            # add path from selected member to account member
+            path = graph.get_shortest_path_between_members(person, self.account.get_person())
+
+        text = """
+            <table cellpadding="5">
+            <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>
+            <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>
+            """.format(
+                'Public key',
+                self.person.pubkey,
+                'Join date',
+                join_date
+            )
+
+        if path:
+            distance = len(path) - 1
+            text += """<tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>""".format('Distance', distance)
+            if distance > 1:
+                index = 0
+                for node in path:
+                    if index == 0:
+                        text += """<tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>""".format('Path', node['text'])
+                    else:
+                        text += """<tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>""".format('', node['text'])
+                    if index == distance and node['id'] != self.account.pubkey:
+                        text += """<tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>""".format('', self.account.name)
+                    index += 1
+        # close html text
+        text += "</table>"
+
+        # set text in label
+        self.label_properties.setText(text)
+
diff --git a/src/cutecoin/gui/views/wot.py b/src/cutecoin/gui/views/wot.py
index ce64aca6aaca8d4dc87ef885a6a51e0f6f5fc020..812c9166fc626ec4d7191e615e10dab8df173a9d 100644
--- a/src/cutecoin/gui/views/wot.py
+++ b/src/cutecoin/gui/views/wot.py
@@ -1,11 +1,11 @@
 # -*- coding: utf-8 -*-
 
 import math
-from PyQt5.QtGui import QPainter, QBrush, QPen, QPolygonF, QColor, QRadialGradient,\
+from PyQt5.QtGui import QPainter, QBrush, QPen, QPolygonF, QColor, QRadialGradient, \
     QPainterPath, QMouseEvent, QWheelEvent, QTransform, QCursor
 from PyQt5.QtCore import Qt, QRectF, QLineF, QPoint, QPointF, QSizeF, qFuzzyCompare, pyqtSignal
-from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QGraphicsEllipseItem,\
-    QGraphicsSimpleTextItem, QGraphicsLineItem, QMenu, QAction, QGraphicsSceneHoverEvent,\
+from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QGraphicsEllipseItem, \
+    QGraphicsSimpleTextItem, QGraphicsLineItem, QMenu, QAction, QGraphicsSceneHoverEvent, \
     QGraphicsSceneContextMenuEvent
 
 NODE_STATUS_HIGHLIGHTED = 1
@@ -48,19 +48,19 @@ class WotView(QGraphicsView):
             self.scale(sc, sc)
             self.centerOn(self.mapToScene(event.pos()))
             event.accept()
-        # act normally on scrollbar
+        #  act normally on scrollbar
         else:
             # transmit event to parent class wheelevent
             super(QGraphicsView, self).wheelEvent(event)
 
 
 class Scene(QGraphicsScene):
-
     # This defines signals taking string arguments
     node_clicked = pyqtSignal(dict, name='nodeClicked')
     node_signed = pyqtSignal(dict, name='nodeSigned')
     node_transaction = pyqtSignal(dict, name='nodeTransaction')
     node_contact = pyqtSignal(dict, name='nodeContact')
+    node_member = pyqtSignal(dict, name='nodeMember')
 
     def __init__(self, parent=None):
         """
@@ -73,7 +73,9 @@ class Scene(QGraphicsScene):
         self.lastDragPos = QPoint()
         self.setItemIndexMethod(QGraphicsScene.NoIndex)
 
-        # axis of the scene for debug purpose
+        # 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)
 
@@ -88,6 +90,7 @@ class Scene(QGraphicsScene):
         """
         node = Node(metadata, pos)
         self.addItem(node)
+        self.nodes[node.id] = node
         return node
 
     def add_arc(self, source_node, destination_node, metadata):
@@ -108,9 +111,9 @@ class Scene(QGraphicsScene):
         """
         draw community graph
 
-        :param dict graph: graph to draw
+        :param cutecoin.core.graph.Graph graph: graph to draw
         """
-        # clear scene
+        #  clear scene
         self.clear()
 
         # capture selected node (to draw it in the center)
@@ -140,7 +143,8 @@ class Scene(QGraphicsScene):
         y = 0
         x = -200
         # sort by text
-        nodes = ((k, v) for (k, v) in sorted(graph.items(), key=lambda kv: kv[1]['text'].lower()) if selected_id in (arc['id'] for arc in v['arcs']))
+        nodes = ((k, v) for (k, v) in sorted(graph.items(), key=lambda kv: kv[1]['text'].lower()) if
+                 selected_id in (arc['id'] for arc in v['arcs']))
         # add nodes and arcs
         for _id, certifier_node in nodes:
             node = self.add_node(certifier_node, (x, y))
@@ -151,6 +155,31 @@ class Scene(QGraphicsScene):
 
         self.update()
 
+    def update_path(self, path):
+        x = 0
+        y = 0
+        for json_node in path:
+            if json_node['status'] & NODE_STATUS_SELECTED:
+                previous_node = json_node
+                y -= 100
+                continue
+            node = self.add_node(json_node, (x, y))
+            skip_reverse_arc = False
+            for arc in json_node['arcs']:
+                if arc['id'] == previous_node['id']:
+                    #print("arc from %s to %s" % (node.id, previous_node['id']))
+                    self.add_arc(node, self.nodes[previous_node['id']], arc)
+                    skip_reverse_arc = True
+                    break
+            if not skip_reverse_arc:
+                for arc in previous_node['arcs']:
+                    if arc['id'] == json_node['id']:
+                        #print("arc from %s to %s" % (previous_node['id'], node.id))
+                        self.add_arc(self.nodes[previous_node['id']], node, arc)
+
+            previous_node = json_node
+            y -= 100
+
 
 class Node(QGraphicsEllipseItem):
     def __init__(self, metadata, x_y):
@@ -166,6 +195,7 @@ class Node(QGraphicsEllipseItem):
         super(Node, self).__init__()
 
         self.metadata = metadata
+        self.id = metadata['id']
         self.status_wallet = self.metadata['status'] & NODE_STATUS_HIGHLIGHTED
         self.status_member = not self.metadata['status'] & NODE_STATUS_OUT
         self.text = self.metadata['text']
@@ -175,6 +205,7 @@ class Node(QGraphicsEllipseItem):
         self.action_sign = None
         self.action_transaction = None
         self.action_contact = None
+        self.action_show_member = None
 
         # color around ellipse
         outline_color = QColor('grey')
@@ -185,7 +216,7 @@ class Node(QGraphicsEllipseItem):
             outline_width = 2
         if not self.status_member:
             outline_color = QColor('red')
-            outline_style = Qt.DashLine
+            outline_style = Qt.SolidLine
         self.setPen(QPen(outline_color, outline_width, outline_style))
 
         # text inside ellipse
@@ -203,10 +234,10 @@ class Node(QGraphicsEllipseItem):
             self.text_item.boundingRect().height() * 2
         )
 
-        # set anchor to the center
-        self.setTransform(QTransform().translate(-self.boundingRect().width()/2.0, -self.boundingRect().height()/2.0))
+        #  set anchor to the center
+        self.setTransform(
+            QTransform().translate(-self.boundingRect().width() / 2.0, -self.boundingRect().height() / 2.0))
         self.setPos(x, y)
-        #print(x, y)
         # center text in ellipse
         self.text_item.setPos(self.boundingRect().width() / 4.0, self.boundingRect().height() / 4.0)
 
@@ -245,11 +276,15 @@ class Node(QGraphicsEllipseItem):
 
         :param event: scene context menu event
         """
-        # no menu on the wallet node
+        #  no menu on the wallet node
         if self.status_wallet:
             return None
         # create node context menus
         self.menu = QMenu()
+        # action show member
+        self.action_show_member = QAction('Informations', self.scene())
+        self.menu.addAction(self.action_show_member)
+        self.action_show_member.triggered.connect(self.member_action)
         # action add identity as contact
         self.action_contact = QAction('Add as contact', self.scene())
         self.menu.addAction(self.action_contact)
@@ -273,6 +308,20 @@ class Node(QGraphicsEllipseItem):
         """
         self.arcs.append(arc)
 
+    def member_action(self):
+        """
+        Transaction action to identity node
+        """
+        # trigger scene signal
+        self.scene().node_member.emit(self.metadata)
+
+    def contact_action(self):
+        """
+        Transaction action to identity node
+        """
+        # trigger scene signal
+        self.scene().node_contact.emit(self.metadata)
+
     def sign_action(self):
         """
         Sign identity node
@@ -287,12 +336,6 @@ class Node(QGraphicsEllipseItem):
         # trigger scene signal
         self.scene().node_transaction.emit(self.metadata)
 
-    def contact_action(self):
-        """
-        Transaction action to identity node
-        """
-        # trigger scene signal
-        self.scene().node_contact.emit(self.metadata)
 
 class Arc(QGraphicsLineItem):
     def __init__(self, source_node, destination_node, metadata):
@@ -319,7 +362,7 @@ class Arc(QGraphicsLineItem):
 
         self.setAcceptedMouseButtons(Qt.NoButton)
 
-        # cursor change on hover
+        #  cursor change on hover
         self.setAcceptHoverEvents(True)
         self.adjust()
         self.setZValue(0)
@@ -405,11 +448,9 @@ class Arc(QGraphicsLineItem):
         if line.dy() >= 0:
             angle = (2.0 * math.pi) - angle
 
-        # arrow in the middle of the arc
-        hpx = (line.p2().x() + line.p1().x()) / 2.0
-        hpy = (line.p2().y() - line.p1().y()) / 2.0
-        if line.dy() < 0:
-            hpy = -hpy
+        #  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))
@@ -440,17 +481,17 @@ class Arc(QGraphicsLineItem):
         # detection mouse hover on arc path
         path = QPainterPath()
         path.addPolygon(QPolygonF([self.line().p1(), self.line().p2()]))
-        # add handles at the start and end of arc
+        #  add handles at the start and end of arc
         path.addRect(QRectF(
-            self.line().p1().x()-5,
-            self.line().p1().y()-5,
-            self.line().p1().x()+5,
-            self.line().p1().y()+5
+            self.line().p1().x() - 5,
+            self.line().p1().y() - 5,
+            self.line().p1().x() + 5,
+            self.line().p1().y() + 5
         ))
         path.addRect(QRectF(
-            self.line().p2().x()-5,
-            self.line().p2().y()-5,
-            self.line().p2().x()+5,
-            self.line().p2().y()+5
+            self.line().p2().x() - 5,
+            self.line().p2().y() - 5,
+            self.line().p2().x() + 5,
+            self.line().p2().y() + 5
         ))
         return path
diff --git a/src/cutecoin/gui/wot_tab.py b/src/cutecoin/gui/wot_tab.py
index 71a96c8b553437556d8060f2d3cef97605646c5d..62efa0201ab96aa053272dbdc91db63e991fd5ab 100644
--- a/src/cutecoin/gui/wot_tab.py
+++ b/src/cutecoin/gui/wot_tab.py
@@ -1,18 +1,18 @@
 # -*- coding: utf-8 -*-
 
-import time
-import datetime
 import logging
-from PyQt5.QtWidgets import QWidget, QComboBox, QDialog
+from cutecoin.core.graph import Graph
+from PyQt5.QtWidgets import QWidget, QComboBox
 from ..gen_resources.wot_tab_uic import Ui_WotTabWidget
 from cutecoin.gui.views.wot import NODE_STATUS_HIGHLIGHTED, NODE_STATUS_SELECTED, NODE_STATUS_OUT, ARC_STATUS_STRONG, ARC_STATUS_WEAK
 from ucoinpy.api import bma
-from .certification import CertificationDialog
-from cutecoin.gui.contact import ConfigureContactDialog
-from .transfer import TransferMoneyDialog
 from cutecoin.core.person import Person
 
 
+def get_person_from_metadata(metadata):
+    return Person(metadata['text'], metadata['id'])
+
+
 class WotTabWidget(QWidget, Ui_WotTabWidget):
     def __init__(self, account, community, password_asker, parent=None):
         """
@@ -39,6 +39,7 @@ class WotTabWidget(QWidget, Ui_WotTabWidget):
         self.graphicsView.scene().node_signed.connect(self.sign_node)
         self.graphicsView.scene().node_transaction.connect(self.send_money_to_node)
         self.graphicsView.scene().node_contact.connect(self.add_node_as_contact)
+        self.graphicsView.scene().node_member.connect(self.member_informations)
 
         self.account = account
         self.community = community
@@ -46,9 +47,6 @@ class WotTabWidget(QWidget, Ui_WotTabWidget):
 
         # nodes list for menu from search
         self.nodes = list()
-        self.signature_validity = self.community.get_parameters()['sigValidity']
-        # arc considered strong during 75% of signature validity time
-        self.ARC_STATUS_STRONG_time = int(self.signature_validity * 0.75)
 
         # create node metadata from account
         metadata = {'text': self.account.name, 'id': self.account.pubkey}
@@ -60,121 +58,41 @@ class WotTabWidget(QWidget, Ui_WotTabWidget):
 
         :param dict metadata: Graph node metadata of the identity
         """
+        logging.debug("Draw graph - " + metadata['text'])
+
         # create Person from node metadata
-        person = self.get_person_from_metadata(metadata)
-        certifiers = person.certifiers_of(self.community)
+        person = get_person_from_metadata(metadata)
+        person_account = Person(self.account.name, self.account.pubkey)
+        certifier_list = person.certifiers_of(self.community)
+        certified_list = person.certified_by(self.community)
 
-        # reset graph
-        graph = dict()
+        # create empty graph instance
+        graph = Graph(self.community)
 
         # add wallet node
         node_status = 0
-        if person.pubkey == self.account.pubkey:
+        if person.pubkey == person_account.pubkey:
             node_status += NODE_STATUS_HIGHLIGHTED
         if person.is_member(self.community) is False:
             node_status += NODE_STATUS_OUT
         node_status += NODE_STATUS_SELECTED
+        graph.add_person(person, node_status)
 
-        # center node
-        graph[person.pubkey] = {
-            'id': person.pubkey,
-            'arcs': list(),
-            'text': person.name,
-            'tooltip':  person.pubkey,
-            'status': node_status
-        }
-
-        # add certifiers of uid
-        for certifier in certifiers:
-            # new node
-            if certifier['pubkey'] not in graph.keys():
-                node_status = 0
-                if certifier['pubkey'] == self.account.pubkey:
-                    node_status += NODE_STATUS_HIGHLIGHTED
-                if certifier['isMember'] is False:
-                    node_status += NODE_STATUS_OUT
-                graph[certifier['pubkey']] = {
-                    'id': certifier['pubkey'],
-                    'arcs': list(),
-                    'text': certifier['uid'],
-                    'tooltip': certifier['pubkey'],
-                    'status': node_status
-                }
-            # add only valid certification...
-            if (time.time() - certifier['cert_time']['medianTime']) > self.signature_validity:
-                continue
-            # keep only the latest certification
-            if graph[certifier['pubkey']]['arcs']:
-                if certifier['cert_time']['medianTime'] < graph[certifier['pubkey']]['arcs'][0]['cert_time']:
-                    continue
-                # display validity status
-            if (time.time() - certifier['cert_time']['medianTime']) > self.ARC_STATUS_STRONG_time:
-                arc_status = ARC_STATUS_WEAK
-            else:
-                arc_status = ARC_STATUS_STRONG
-            arc = {
-                'id': person.pubkey,
-                'status': arc_status,
-                'tooltip': datetime.datetime.fromtimestamp(
-                    certifier['cert_time']['medianTime'] + self.signature_validity
-                ).strftime("%d/%m/%Y"),
-                'cert_time': certifier['cert_time']['medianTime']
-            }
-            graph[certifier['pubkey']]['arcs'] = [arc]
-
-        # add certified by uid
-        for certified in person.certified_by(self.community):
-            if certified['pubkey'] not in graph.keys():
-                node_status = 0
-                if certified['pubkey'] == self.account.pubkey:
-                    node_status += NODE_STATUS_HIGHLIGHTED
-                if certified['isMember'] is False:
-                    node_status += NODE_STATUS_OUT
-
-                graph[certified['pubkey']] = {
-                    'id': certified['pubkey'],
-                    'arcs': list(),
-                    'text': certified['uid'],
-                    'tooltip': certified['pubkey'],
-                    'status': node_status
-                }
-            # add only valid certification...
-            if (time.time() - certified['cert_time']['medianTime']) > self.signature_validity:
-                continue
-            # display validity status
-            if (time.time() - certified['cert_time']['medianTime']) > self.ARC_STATUS_STRONG_time:
-                arc_status = ARC_STATUS_WEAK
-            else:
-                arc_status = ARC_STATUS_STRONG
-            arc = {
-                'id': certified['pubkey'],
-                'status': arc_status,
-                'tooltip': datetime.datetime.fromtimestamp(
-                    certified['cert_time']['medianTime'] + self.signature_validity
-                ).strftime("%d/%m/%Y"),
-                'cert_time': certified['cert_time']['medianTime']
-            }
-
-            # replace old arc if this one is more recent
-            new_arc = True
-            index = 0
-            for a in graph[person.pubkey]['arcs']:
-                # if same arc already exists...
-                if a['id'] == arc['id']:
-                    # if arc more recent, dont keep old one...
-                    if arc['cert_time'] >= a['cert_time']:
-                        graph[person.pubkey]['arcs'][index] = arc
-                    new_arc = False
-                index += 1
-
-            # if arc not in graph...
-            if new_arc:
-                # add arc in graph
-                graph[person.pubkey]['arcs'].append(arc)
+        # populate graph with certifiers-of
+        graph.add_certifier_list(certifier_list, person, person_account)
+        # populate graph with certified-by
+        graph.add_certified_list(certified_list, person, person_account)
 
         # draw graph in qt scene
         self.graphicsView.scene().update_wot(graph)
 
+        # if selected member is not the account member...
+        if person.pubkey != person_account.pubkey:
+            # add path from selected member to account member
+            path = graph.get_shortest_path_between_members(person, person_account)
+            if path:
+                self.graphicsView.scene().update_path(path)
+
     def reset(self):
         """
         Reset graph scene to wallet identity
@@ -211,13 +129,6 @@ class WotTabWidget(QWidget, Ui_WotTabWidget):
                 self.comboBoxSearch.addItem(uid)
             self.comboBoxSearch.showPopup()
 
-        if len(nodes) == 1:
-            node = self.nodes[0]
-            metadata = {'id': node['pubkey'], 'text': node['uid']}
-            self.draw_graph(
-                metadata
-            )
-
     def select_node(self, index):
         """
         Select node in graph when item is selected in combobox
@@ -230,19 +141,23 @@ class WotTabWidget(QWidget, Ui_WotTabWidget):
             metadata
         )
 
+    def member_informations(self, metadata):
+        person = get_person_from_metadata(metadata)
+        self.parent.member_informations(person)
+
     def sign_node(self, metadata):
-        person = self.get_person_from_metadata(metadata)
+        person = get_person_from_metadata(metadata)
         self.parent.certify_member(person)
 
     def send_money_to_node(self, metadata):
-        person = self.get_person_from_metadata(metadata)
+        person = get_person_from_metadata(metadata)
         self.parent.send_money_to_member(person)
 
     def add_node_as_contact(self, metadata):
         # check if contact already exists...
         if metadata['id'] == self.account.pubkey or metadata['id'] in [contact.pubkey for contact in self.account.contacts]:
             return False
-        person = self.get_person_from_metadata(metadata)
+        person = get_person_from_metadata(metadata)
         self.parent.add_member_as_contact(person)
 
     def get_block_mediantime(self, number):