diff --git a/.travis.yml b/.travis.yml
index bd2240cb66fa44c962abb3655e9858f7d39f2c6a..a744220be45cf198ae3d03d9706d9e922f32cdea 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,7 +10,7 @@ matrix:
     - os: osx
 
 env:
-- PYENV_PYTHON_VERSION=3.5.2
+- PYENV_PYTHON_VERSION=3.5.3
 
 before_install:
 - ci/travis/before_install.sh
diff --git a/ci/appveyor/sakia.iss b/ci/appveyor/sakia.iss
index a12e8760d0fb2a19fb8fbd7d6a6d8b23eeda2baf..3e4fbf4cc871dafee73a1d957a34bad873b63ee0 100644
--- a/ci/appveyor/sakia.iss
+++ b/ci/appveyor/sakia.iss
@@ -15,7 +15,7 @@
 #error "Unable to find MyAppExe"
 #endif
 
-#define MyAppVerStr "0.31.6"
+#define MyAppVerStr "0.32.0RC6"
 
 [Setup]
 AppName={#MyAppName}
diff --git a/ci/travis/before_deploy.sh b/ci/travis/before_deploy.sh
index b4fd6dbef45860e89130856e2b29eac175df6ad0..6d6e58b382a0331816567892e10e6abec96af9de 100755
--- a/ci/travis/before_deploy.sh
+++ b/ci/travis/before_deploy.sh
@@ -14,7 +14,7 @@ then
 
     cp sakia.png ci/travis/debian/opt/sakia/
     cp sakia-${TRAVIS_OS_NAME}.zip ci/travis/debian/opt/sakia/sakia.zip
-
+    cp -r res/linux/usr ci/travis/debian
     fakeroot dpkg-deb --build ci/travis/debian
     mv ci/travis/debian.deb sakia-${TRAVIS_OS_NAME}.deb
 fi
diff --git a/ci/travis/build.sh b/ci/travis/build.sh
index e519047a891ddbcd1357d99723b23169ded2d431..3d806dce0b15887b89c1060fe821f61232cf88b8 100755
--- a/ci/travis/build.sh
+++ b/ci/travis/build.sh
@@ -33,9 +33,9 @@ if [ $TRAVIS_OS_NAME == "osx" ]
 then
     pyinstaller sakia.spec
     cp -rv dist/sakia/* dist/sakia.app/Contents/MacOS
+    cp -v res/osx/Info.plist dist/sakia.app/Contents/
     rm -rfv dist/sakia
 elif [ $TRAVIS_OS_NAME == "linux" ]
 then
     pyinstaller sakia.spec
 fi
-
diff --git a/ci/travis/debian/DEBIAN/control b/ci/travis/debian/DEBIAN/control
index 3b3356c375b10e905a121b557876ddb5f47564ef..443fb0e702627ea249076b05e04f7d1a3953f8e1 100644
--- a/ci/travis/debian/DEBIAN/control
+++ b/ci/travis/debian/DEBIAN/control
@@ -1,5 +1,5 @@
 Package: sakia
-Version: 0.31.6
+Version: 0.32.0RC6
 Section: misc
 Priority: optional
 Architecture: all
diff --git a/doc/install_for_developpers.md b/doc/install_for_developers.md
similarity index 93%
rename from doc/install_for_developpers.md
rename to doc/install_for_developers.md
index 1fb9e0e3d825e11aaf97b822cbf3923eef506254..e740ae3b4b5c694422e07d91f057c0c705df165b 100644
--- a/doc/install_for_developpers.md
+++ b/doc/install_for_developers.md
@@ -94,15 +94,24 @@ If you are running El Capitan (MacOS 10.10), you'll need to run `xcode-select --
 
 #### Pyenv environment 
 
-##### Build python 3.5.0
+##### Build python 3.5.3
+
+Building python 3.5.3 requires libraries of `openssl` and `sqlite3`. On Ubuntu, install it using the following commands : 
+
+```
+apt-get update
+apt-get install libssl-dev
+apt-get install libsqlite3-dev
+```
+
 Restart your shell then prepare your virtualenv: 
 
-On GNU/Linux: `PYTHON_CONFIGURE_OPTS="--enable-shared" pyenv install 3.5.1`  
-On MacOS: `env PYTHON_CONFIGURE_OPTS="--enable-framework" pyenv install 3.5.1`
+On GNU/Linux: `PYTHON_CONFIGURE_OPTS="--enable-shared" pyenv install 3.5.3`  
+On MacOS: `env PYTHON_CONFIGURE_OPTS="--enable-framework" pyenv install 3.5.3`
 
 Run:
 ```bash
-pyenv shell 3.5.1
+pyenv shell 3.5.3
 pyenv virtualenv sakia-env
 ```
 
@@ -124,9 +133,8 @@ export PYTHONPATH=${PYTHONPATH}:/YOUR_SAKIA_INSTALL_PATH/src
 
 On Linux, you'll need buildable python-dbus and notify2 :  
 ```bash
-pyenv activate sakia-env
+pyenv local sakia-env
 pip install PyQt5
-rm ~/.pyenv/versions/sakia-env/bin/pyuic5 # Because of some bug in binary packages we need to remove this
 pip install -U git+https://github.com/posborne/dbus-python.git
 pip install notify2
 ```
diff --git a/doc/plugin_development.md b/doc/plugin_development.md
new file mode 100644
index 0000000000000000000000000000000000000000..8b1a388d898ef92e6df1a19f909b3e82a3fe7d6c
--- /dev/null
+++ b/doc/plugin_development.md
@@ -0,0 +1,88 @@
+# Developing a plugin for sakia
+
+## Prepare dev environment
+
+Follow the doc file [Install for developers](https://github.com/duniter/sakia/blob/dev/doc/install_for_developers.md).
+You can use the same pyenv environment to develop your plugin.
+
+## Plugin structure
+
+The plugin source code should follow the structure below :
+
+```
+/
+   [plugin_pkg_name]/
+      images/                # The directory containing images used in the widget
+         images.qrc          # The qt resources .qrc file describing available images
+         [image1.png]        # The list of images
+         [image2.png]
+      __init__.py            # The __init__ file of the plugin
+      [script_1.py]          # Some scripts imported in the __init__ file
+      [script_2.py]
+      [ui_file.ui]           # ui files designed using QtDesigner
+```
+
+The `__init__.py` file must set the following global constants :
+
+```python
+PLUGIN_NAME = "Title of the plugin"
+PLUGIN_DESCRIPTION = "Description of the plugin"
+PLUGIN_VERSION = "0.1"
+```
+
+The function below must be present in the `__init__.py` file to initialize the plugin on Sakia startup :
+
+```python
+
+def plugin_exec(app, main_window):
+    """
+    :param sakia.app.Application app:
+    :param sakia.gui.main_window.controller.MainWindowController main_window:
+    """
+    # Place your init code here
+    pass
+```
+
+## Building your plugin
+
+To build the plugin, you need :
+
+### To generate resources (images, qrc, ...)
+
+Generating resources uses [pyrcc5](http://pyqt.sourceforge.net/Docs/PyQt5/resources.html).
+Generating designer ui files uses [pyuic5](http://pyqt.sourceforge.net/Docs/PyQt5/designer.html).
+
+To help you generate your resources, you should copy the `gen_resources.py` file from sakia sources and configure the
+ variable `gen_resources`. Replace `'src'` by the name of your plugin package.
+
+### To import your resources in your code
+
+The generation of the resources builds the following python files :
+
+ - `filename.ui` -> `filename_uic.py`
+ - `filename.qrc` -> `filename_rc.py`
+
+The `filename_uic.py` file should be imported in the file using the designed widget. See the
+[dialog of the example plugin](https://github.com/Insoleet/sakia-plugin-example/blob/master/plugin_example/main_dialog.py)
+
+The `filename_rc.py` file should be imported in the `__init__.py` file, on the last line. See the
+[\__init__.py of the example plugin](https://github.com/Insoleet/sakia-plugin-example/blob/master/plugin_example/__init__.py#L28)
+
+### To generate your plugin
+
+To generate your plugin, you must zip everything (generated resources) in a zip file respecting the structure below :
+
+```
+[plugin_name].zip\
+    [plugin_name]\
+        __init__.py
+        [generated files...]
+```
+
+The [setup.py](https://github.com/Insoleet/sakia-plugin-example/blob/master/setup.py) file from the
+example plugin is available to help you generate correctly the plugin.
+
+### To test your plugin
+
+To test your plugin, you need to run sakia with the parameter `--withplugin [path to zip file]`. The plugin will
+be loaded automatically on startup but won't be installed to user profile directory.
\ No newline at end of file
diff --git a/gen_resources.py b/gen_resources.py
index b73cfa715e5bd3c4889ec59ed3c91df88195eaad..699fdd81cd5e52a4a01b53ace7ddbde12e265279 100644
--- a/gen_resources.py
+++ b/gen_resources.py
@@ -3,9 +3,8 @@
 import sys, os, multiprocessing, subprocess
 
 
-sakia = os.path.abspath(os.path.join(os.path.dirname(__file__)))
+root_path = os.path.abspath(os.path.join(os.path.dirname(__file__)))
 resources = os.path.abspath(os.path.join(os.path.dirname(__file__), 'res'))
-gen_ui = os.path.abspath(os.path.join(os.path.dirname(__file__), 'src', 'sakia', 'gen_resources'))
 gen_resources = os.path.abspath(os.path.join(os.path.dirname(__file__), 'src'))
 
 def convert_ui(args, **kwargs):
@@ -14,14 +13,11 @@ def convert_ui(args, **kwargs):
 def build_resources():
     try:
         to_process = []
-        for root, dirs, files in os.walk(sakia):
+        for root, dirs, files in os.walk(root_path):
             for f in files:
                 if f.endswith('.ui'):
                     source = os.path.join(root, f)
-                    if os.path.commonpath([resources, root]) == resources:
-                        dest = os.path.join(gen_ui, os.path.splitext(os.path.basename(source))[0]+'_uic.py')
-                    else:
-                        dest = os.path.join(root, os.path.splitext(os.path.basename(source))[0]+'_uic.py')
+                    dest = os.path.join(root, os.path.splitext(os.path.basename(source))[0]+'_uic.py')
 
                     exe = 'pyuic5'
                 elif f.endswith('.qrc'):
diff --git a/release.sh b/release.sh
index cdd8a84cfc664314526e5ef851c3777b473f8430..d783301cc7e5de895fa9d91733c9d5086e1f05ac 100755
--- a/release.sh
+++ b/release.sh
@@ -4,13 +4,13 @@
 current=`grep -P "__version_info__ = \(\'\d+\', \'\d+\', \'\d+(\w*)\'\)" src/sakia/__init__.py | grep -oP "\'\d+\', \'\d+\', \'\d+(\w*)\'"`
 echo "Current version: $current"
 
-if [[ $1 =~ ^[0-9]+.[0-9]+.[0-9]+[0-9a-z]*$ ]]; then
+if [[ $1 =~ ^[0-9]+.[0-9]+.[0-9]+[0-9A-Za-z]*$ ]]; then
   IFS='.' read -r -a array <<< "$1"
   sed -i "s/__version_info__\ = ($current)/__version_info__ = ('${array[0]}', '${array[1]}', '${array[2]}')/g" src/sakia/__init__.py
   sed -i "s/#define MyAppVerStr .*/#define MyAppVerStr \"$1\"/g" ci/appveyor/sakia.iss
   sed -i "s/Version: .*/Version: $1/g" ci/travis/debian/DEBIAN/control
-  sed -i "s/Version=.*/Version=$1/g" ci/travis/debian/usr/share/applications/sakia.desktop
-  git commit src/sakia/__init__.py ci/appveyor/sakia.iss ci/travis/debian/DEBIAN/control ci/travis/debian/usr/share/applications/sakia.desktop -m "$1"
+  sed -i "s/Version=.*/Version=$1/g" res/linux/usr/share/applications/sakia.desktop
+  git commit src/sakia/__init__.py ci/appveyor/sakia.iss ci/travis/debian/DEBIAN/control res/linux/usr/share/applications/sakia.desktop -m "$1"
   git tag "$1" -a -m "$1"
 else
   echo "Wrong version format"
diff --git a/requirements.txt b/requirements.txt
index 6a17e851d10711a877971bf5342b9fb66844bfe7..5e01047aa27a4aa3f33cce543b54db038ecd0f03 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -5,5 +5,5 @@ attrs
 duniter-mirage
 duniterpy>=0.40
 pytest
-pytest-asyncio
+pytest-asyncio<0.6
 pyyaml
\ No newline at end of file
diff --git a/res/icons/icons.qrc b/res/icons/icons.qrc
index d7193f256f84c7c5be21a3d9fd88e479e19e94f3..c8a8a8e959a10a3ef5326d9a07404aa8795fa7a7 100644
--- a/res/icons/icons.qrc
+++ b/res/icons/icons.qrc
@@ -1,5 +1,6 @@
 <RCC>
   <qresource prefix="icons">
+    <file alias="loader">loader.gif</file>
     <file alias="guest_icon">noun_178537_cc.svg</file>
     <file alias="menu_icon">noun_100552_cc.svg</file>
     <file alias="leave_icon">noun_155520_cc.svg</file>
diff --git a/res/icons/loader.gif b/res/icons/loader.gif
new file mode 100644
index 0000000000000000000000000000000000000000..6a4c333d919c7aa2802f921cf9c95126743c3654
Binary files /dev/null and b/res/icons/loader.gif differ
diff --git a/ci/travis/debian/usr/share/applications/sakia.desktop b/res/linux/usr/share/applications/sakia.desktop
similarity index 91%
rename from ci/travis/debian/usr/share/applications/sakia.desktop
rename to res/linux/usr/share/applications/sakia.desktop
index 72491b691c2a2a6dd77ea65e531fe4bcbbe25ddb..c4fc9bbec0c93bd7e6d13a3851a542f7a751c3d1 100644
--- a/ci/travis/debian/usr/share/applications/sakia.desktop
+++ b/res/linux/usr/share/applications/sakia.desktop
@@ -1,5 +1,5 @@
 [Desktop Entry]
-Version=0.31.6
+Version=0.32.0RC6
 Name=Sakia
 Comment=Duniter Qt Client
 Exec=sakia
diff --git a/res/osx/Info.plist b/res/osx/Info.plist
new file mode 100644
index 0000000000000000000000000000000000000000..5f927ac5967f33c3d7859f17962275137a6d0b31
--- /dev/null
+++ b/res/osx/Info.plist
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict><key>CFBundleIdentifier</key>
+<string>sakia</string>
+<key>CFBundlePackageType</key>
+<string>APPL</string>
+<key>CFBundleName</key>
+<string>sakia</string>
+<key>CFBundleExecutable</key>
+<string>MacOS/sakia.bin</string>
+<key>CFBundleInfoDictionaryVersion</key>
+<string>6.0</string>
+<key>CFBundleIconFile</key>
+<string>sakia.ico</string>
+<key>NSHighResolutionCapable</key>
+<string>True</string>
+<key>CFBundleDisplayName</key>
+<string>sakia</string>
+<key>CFBundleShortVersionString</key>
+<string>0.0.0</string>
+<key>LSBackgroundOnly</key>
+<string>False</string>
+<key>LSEnvironment</key>
+<dict>
+<key>LC_ALL</key>
+<string>UTF-8</string>
+</dict>
+</dict>
+</plist>
diff --git a/res/test_plugin/plugin/__init__.py b/res/test_plugin/plugin/__init__.py
deleted file mode 100644
index 2ed03dffc10489701fe7d86f740a787330d377fd..0000000000000000000000000000000000000000
--- a/res/test_plugin/plugin/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from PyQt5.QtWidgets import QMessageBox
-
-
-def display_messagebox():
-    QMessageBox.about(None, "About", "Sakia")
\ No newline at end of file
diff --git a/sakia.spec b/sakia.spec
index c036561a441b76ae38e5044dbf22271594766b93..0e86e2f24c97197dcca2c2c335eb76e6ff8f5fbf 100644
--- a/sakia.spec
+++ b/sakia.spec
@@ -29,6 +29,7 @@ if is_darwin:
                                       "libsodium.dylib")
         a.binaries = a.binaries + TOC([('lib/libsodium.dylib', libsodium_path, 'BINARY')])
     a.datas = a.datas + [('sakia/root_servers.yml', 'src/sakia/root_servers.yml', 'DATA')]
+    a.datas = a.datas + [('sakia/g1_licence.html', 'src/sakia/g1_licence.html', 'DATA')]
 
 if is_linux:
     libsodium_path = ctypes.util.find_library('libsodium.so')
@@ -40,10 +41,12 @@ if is_linux:
 
     a.binaries = a.binaries + TOC([('libsodium.so', libsodium_path, 'BINARY')])
     a.datas = a.datas + [('sakia/root_servers.yml', 'src/sakia/root_servers.yml', 'DATA')]
+    a.datas = a.datas + [('sakia/g1_licence.html', 'src/sakia/g1_licence.html', 'DATA')]
 
 if is_win:
     a.binaries = a.binaries + TOC([('libsodium.dll', ctypes.util.find_library('libsodium.dll'), 'BINARY')])
-    a.datas = a.datas + [('sakia\\root_servers.yml', 'src\\/sakia\\root_servers.yml', 'DATA')]
+    a.datas = a.datas + [('sakia\\root_servers.yml', 'src\\sakia\\root_servers.yml', 'DATA')]
+    a.datas = a.datas + [('sakia\\g1_licence.html', 'src\\sakia\\g1_licence.html', 'DATA')]
 
 for file in os.listdir(os.path.join("src", "sakia", "data", "repositories")):
     if file.endswith(".sql"):
@@ -94,10 +97,4 @@ if is_darwin:
     app = BUNDLE(exe,
          name='sakia.app',
          icon='sakia.ico',
-         bundle_identifier=None,
-         info_plist={
-        'NSHighResolutionCapable': 'True',
-        'LSBackgroundOnly': 'False'
-        },)
-
-
+         bundle_identifier=None,) # take care, info.plist will be overridden.
diff --git a/src/sakia/__init__.py b/src/sakia/__init__.py
index 11e27c30eb1af15b1556b3fa65b515b190e02efb..68c0a6457d27fb49ecfd8d8ba064611a9502d1ed 100644
--- a/src/sakia/__init__.py
+++ b/src/sakia/__init__.py
@@ -1,2 +1,2 @@
-__version_info__ = ('0', '31', '6')
+__version_info__ = ('0', '32', '0RC6')
 __version__ = '.'.join(__version_info__)
diff --git a/src/sakia/app.py b/src/sakia/app.py
index 0805c3609cfc76e116b4a5aff2e6c00f291229fc..c2c44e0411e6dd79f37ef8f4e8021c1e9c090a07 100644
--- a/src/sakia/app.py
+++ b/src/sakia/app.py
@@ -51,7 +51,9 @@ class Application(QObject):
     referential_changed = pyqtSignal()
     sources_refreshed = pyqtSignal()
     new_blocks_handled = pyqtSignal()
-    view_in_wot = pyqtSignal(Connection, Identity)
+    view_in_wot = pyqtSignal(Identity)
+    refresh_started = pyqtSignal()
+    refresh_finished = pyqtSignal()
 
     qapp = attr.ib()
     loop = attr.ib()
@@ -85,7 +87,7 @@ class Application(QObject):
         app = cls(qapp, loop, options, app_data, None, None, options.currency, None)
         #app.set_proxy()
         app.get_last_version()
-        app.load_profile(app_data.default)
+        app.load_profile(options.profile)
         app.start_coroutines()
         app.documents_service = DocumentsService.instanciate(app)
         app.switch_language()
@@ -97,7 +99,7 @@ class Application(QObject):
         :param profile_name:
         :return:
         """
-        self.plugins_dir = PluginsDirectory.in_config_path(self.options.config_path, profile_name).load_or_init()
+        self.plugins_dir = PluginsDirectory.in_config_path(self.options.config_path, profile_name).load_or_init(self.options.with_plugin)
         self.parameters = UserParametersFile.in_config_path(self.options.config_path, profile_name).load_or_init()
         self.db = SakiaDatabase.load_or_init(self.options, profile_name)
 
@@ -131,10 +133,11 @@ class Application(QObject):
                                                connections_processor, transactions_processor,
                                                blockchain_processor, bma_connector)
 
-        self.blockchain_service = BlockchainService(self, self.currency, blockchain_processor, bma_connector,
-                                                               self.identities_service,
-                                                               self.transactions_service,
-                                                               self.sources_service)
+        self.blockchain_service = BlockchainService(self, self.currency, blockchain_processor, connections_processor,
+                                                    bma_connector,
+                                                    self.identities_service,
+                                                    self.transactions_service,
+                                                    self.sources_service)
 
         self.network_service = NetworkService.load(self, self.currency, nodes_processor,
                                                     self.blockchain_service,
@@ -155,6 +158,10 @@ class Application(QObject):
 
         self.db.commit()
 
+    async def initialize_blockchain(self):
+        await asyncio.sleep(2) # Give time for the network to connect to nodes
+        await BlockchainProcessor.instanciate(self).initialize_blockchain(self.currency)
+
     def switch_language(self):
         logging.debug("Loading translations")
         locale = self.parameters.lang
@@ -207,7 +214,7 @@ class Application(QObject):
                         logging.debug("Found version : {0}".format(latest_version))
                         logging.debug("Current version : {0}".format(__version__))
                         self.available_version = version
-        except (aiohttp.ClientError, asyncio.TimeoutError) as e:
+        except (aiohttp.errors.ClientError, aiohttp.errors.ServerDisconnectedError, asyncio.TimeoutError) as e:
             self._logger.debug("Could not connect to github : {0}".format(str(e)))
 
     def save_parameters(self, parameters):
diff --git a/src/sakia/constants.py b/src/sakia/constants.py
index 6daa2dd68856eb25e50a7aaf29b21f3570b99ba2..c1ad2befb4a8f09d84f1644608f495c4ad9ac098 100644
--- a/src/sakia/constants.py
+++ b/src/sakia/constants.py
@@ -5,3 +5,6 @@ MAX_CONFIRMATIONS = 6
 
 with open(os.path.join(os.path.dirname(__file__), "root_servers.yml"), 'r') as stream:
     ROOT_SERVERS = yaml.load(stream)
+
+with open(os.path.join(os.path.dirname(__file__), "g1_licence.html"), 'r') as stream:
+    G1_LICENCE = stream.read()
diff --git a/src/sakia/data/connectors/node.py b/src/sakia/data/connectors/node.py
index b191be7ebbf96c1fb14ab5554df9d39d369c6385..a139436953811b07ae3c0cb773282a574be45cca 100644
--- a/src/sakia/data/connectors/node.py
+++ b/src/sakia/data/connectors/node.py
@@ -17,6 +17,15 @@ from sakia.errors import InvalidNodeCurrency
 from ..entities.node import Node
 
 
+class NodeConnectorLoggerAdapter(logging.LoggerAdapter):
+    """
+    This example adapter expects the passed in dict-like object to have a
+    'connid' key, whose value in brackets is prepended to the log message.
+    """
+    def process(self, msg, kwargs):
+        return '[%s] %s' % (self.extra['pubkey'][:5], msg), kwargs
+
+
 class NodeConnector(QObject):
     """
     A node is a peer send from the client point of view.
@@ -38,7 +47,8 @@ class NodeConnector(QObject):
                     'peer': False}
         self._user_parameters = user_parameters
         self.session = session
-        self._logger = logging.getLogger('sakia')
+        self._raw_logger = logging.getLogger('sakia')
+        self._logger = NodeConnectorLoggerAdapter(self._raw_logger, {'pubkey': self.node.pubkey})
 
     def __del__(self):
         for ws in self._ws_tasks.values():
@@ -69,7 +79,7 @@ class NodeConnector(QObject):
         if currency and peer.currency != currency:
             raise InvalidNodeCurrency(currency, peer.currency)
 
-        node = Node(peer.currency, peer.pubkey, peer.endpoints, peer.blockUID)
+        node = Node(peer.currency, peer.pubkey, peer.endpoints, peer.blockUID, last_state_change=time.time())
         logging.getLogger('sakia').debug("Node from address : {:}".format(str(node)))
 
         return cls(node, user_parameters, session=session)
@@ -87,7 +97,7 @@ class NodeConnector(QObject):
         if currency and peer.currency != currency:
             raise InvalidNodeCurrency(currency, peer.currency)
 
-        node = Node(peer.currency, peer.pubkey, peer.endpoints, peer.blockUID)
+        node = Node(peer.currency, peer.pubkey, peer.endpoints, peer.blockUID, last_state_change=time.time())
         logging.getLogger('sakia').debug("Node from peer : {:}".format(str(node)))
 
         return cls(node, user_parameters, session=None)
@@ -97,12 +107,16 @@ class NodeConnector(QObject):
             conn_handler = next(endpoint.conn_handler(self.session, proxy=proxy))
             data = await request(conn_handler, **req_args)
             return data
+        except errors.DuniterError as e:
+            if e.ucode == 1006:
+                self._logger.debug("{0}".format(str(e)))
+            else:
+                raise
         except (ClientError, gaierror, TimeoutError, ConnectionRefusedError, ValueError) as e:
-            self._logger.debug("{0} : {1}".format(str(e), self.node.pubkey[:5]))
+            self._logger.debug("{0}".format(str(e)))
             self.change_state_and_emit(Node.OFFLINE)
         except jsonschema.ValidationError as e:
             self._logger.debug(str(e))
-            self._logger.debug("Validation error : {0}".format(self.node.pubkey[:5]))
             self.change_state_and_emit(Node.CORRUPTED)
 
     async def init_session(self):
@@ -151,11 +165,10 @@ class NodeConnector(QObject):
                     ws_connection = bma.ws.block(conn_handler)
                     async with ws_connection as ws:
                         self._connected['block'] = True
-                        self._logger.debug("Connected successfully to block ws : {0}"
-                                           .format(self.node.pubkey[:5]))
+                        self._logger.debug("Connected successfully to block ws")
                         async for msg in ws:
                             if msg.tp == aiohttp.WSMsgType.TEXT:
-                                self._logger.debug("Received a block : {0}".format(self.node.pubkey[:5]))
+                                self._logger.debug("Received a block")
                                 block_data = bma.parse_text(msg.data, bma.ws.WS_BLOCk_SCHEMA)
                                 await self.refresh_block(block_data)
                             elif msg.tp == aiohttp.WSMsgType.CLOSED:
@@ -163,15 +176,14 @@ class NodeConnector(QObject):
                             elif msg.tp == aiohttp.WSMsgType.ERROR:
                                 break
                 except (aiohttp.WSServerHandshakeError, ValueError) as e:
-                    self._logger.debug("Websocket block {0} : {1} - {2}"
-                                        .format(type(e).__name__, str(e), self.node.pubkey[:5]))
+                    self._logger.debug("Websocket block {0} : {1}".format(type(e).__name__, str(e)))
                     await self.request_current_block()
                 except (ClientError, gaierror, TimeoutError) as e:
                     self._logger.debug("{0} : {1}".format(str(e), self.node.pubkey[:5]))
                     self.change_state_and_emit(Node.OFFLINE)
                 except jsonschema.ValidationError as e:
                     self._logger.debug(str(e))
-                    self._logger.debug("Validation error : {0}".format(self.node.pubkey[:5]))
+                    self._logger.debug("Validation error")
                     self.change_state_and_emit(Node.CORRUPTED)
                 finally:
                     self._connected['block'] = False
@@ -196,9 +208,9 @@ class NodeConnector(QObject):
                     self.change_state_and_emit(Node.ONLINE)
                 else:
                     self.change_state_and_emit(Node.CORRUPTED)
-                    self._logger.debug("Error in block reply of {0} : {1}}".format(self.node.pubkey[:5], str(e)))
+                    self._logger.debug("Error in block reply :  {0}".format(str(e)))
         else:
-            self._logger.debug("Could not connect to any BMA endpoint : {0}".format(self.node.pubkey[:5]))
+            self._logger.debug("Could not connect to any BMA endpoint")
             self.change_state_and_emit(Node.OFFLINE)
 
     async def refresh_block(self, block_data):
@@ -228,7 +240,6 @@ class NodeConnector(QObject):
                         self.change_state_and_emit(Node.CORRUPTED)
                         break
 
-                    self._logger.debug("Error in previous block reply of {0} : {1}".format(self.node.pubkey[:5], str(e)))
                 finally:
                     if self.node.current_buid != BlockUID(block_data['number'], block_data['hash']):
                         self.node.current_buid = BlockUID(block_data['number'], block_data['hash'])
@@ -237,7 +248,7 @@ class NodeConnector(QObject):
                                                                         block_data['number']))
                         self.changed.emit()
             else:
-                self._logger.debug("Could not connect to any BMA endpoint : {0}".format(self.node.pubkey[:5]))
+                self._logger.debug("Could not connect to any BMA endpoint")
                 self.change_state_and_emit(Node.OFFLINE)
         else:
             self.change_state_and_emit(Node.ONLINE)
@@ -259,10 +270,10 @@ class NodeConnector(QObject):
                 self.identity_changed.emit()
                 return  # Break endpoints loop
             except errors.DuniterError as e:
-                self._logger.debug("Error in summary of {0} : {1}".format(self.node.pubkey[:5], str(e)))
+                self._logger.debug("Error in summary : {:}".format(str(e)))
                 self.change_state_and_emit(Node.OFFLINE)
         else:
-            self._logger.debug("Could not connect to any BMA endpoint : {0}".format(self.node.pubkey[:5]))
+            self._logger.debug("Could not connect to any BMA endpoint")
             self.change_state_and_emit(Node.OFFLINE)
 
     async def connect_peers(self):
@@ -278,10 +289,10 @@ class NodeConnector(QObject):
                     ws_connection = bma.ws.peer(conn_handler)
                     async with ws_connection as ws:
                         self._connected['peer'] = True
-                        self._logger.debug("Connected successfully to peer ws : {0}".format(self.node.pubkey[:5]))
+                        self._logger.debug("Connected successfully to peer ws")
                         async for msg in ws:
                             if msg.tp == aiohttp.WSMsgType.TEXT:
-                                self._logger.debug("Received a peer : {0}".format(self.node.pubkey[:5]))
+                                self._logger.debug("Received a peer")
                                 peer_data = bma.parse_text(msg.data, bma.ws.WS_PEER_SCHEMA)
                                 self.refresh_peer_data(peer_data)
                             elif msg.tp == aiohttp.WSMsgType.CLOSED:
@@ -289,15 +300,14 @@ class NodeConnector(QObject):
                             elif msg.tp == aiohttp.WSMsgType.ERROR:
                                 break
                 except (aiohttp.WSServerHandshakeError, ValueError) as e:
-                    self._logger.debug("Websocket peer {0} : {1} - {2}"
-                                       .format(type(e).__name__, str(e), self.node.pubkey[:5]))
+                    self._logger.debug("Websocket peer {0} : {1}"
+                                       .format(type(e).__name__, str(e)))
                     await self.request_peers()
                 except (ClientError, gaierror, TimeoutError) as e:
-                    self._logger.debug("{0} : {1}".format(str(e), self.node.pubkey[:5]))
+                    self._logger.debug("{0}".format(str(e)))
                     self.change_state_and_emit(Node.OFFLINE)
                 except jsonschema.ValidationError as e:
                     self._logger.debug(str(e))
-                    self._logger.debug("Validation error : {0}".format(self.node.pubkey[:5]))
                     self.change_state_and_emit(Node.CORRUPTED)
                 finally:
                     self._connected['peer'] = False
@@ -328,9 +338,7 @@ class NodeConnector(QObject):
                                 break
                             self.refresh_peer_data(leaf_data['leaf']['value'])
                         except (AttributeError, ValueError, errors.DuniterError) as e:
-                            self._logger.debug("{pubkey} : Incorrect peer data in {leaf}"
-                                          .format(pubkey=self.node.pubkey[:5],
-                                                  leaf=leaf_hash))
+                            self._logger.debug("Incorrect peer data in {leaf} : {err}".format(leaf=leaf_hash, err=str(e)))
                             self.change_state_and_emit(Node.OFFLINE)
                     else:
                         self.node.merkle_peers_root = peers_data['root']
@@ -340,7 +348,7 @@ class NodeConnector(QObject):
                 self._logger.debug("Error in peers reply : {0}".format(str(e)))
                 self.change_state_and_emit(Node.OFFLINE)
         else:
-            self._logger.debug("Could not connect to any BMA endpoint : {0}".format(self.node.pubkey[:5]))
+            self._logger.debug("Could not connect to any BMA endpoint")
             self.change_state_and_emit(Node.OFFLINE)
 
     def refresh_peer_data(self, peer_data):
@@ -356,9 +364,6 @@ class NodeConnector(QObject):
             self._logger.debug("Incorrect leaf reply")
 
     def change_state_and_emit(self, new_state):
-        if self.node.state in (Node.CORRUPTED, Node.OFFLINE):
-            self.error.emit()
-
         if self.node.state != new_state:
             self.node.last_state_change = time.time()
             self.node.state = new_state
diff --git a/src/sakia/data/entities/app_data.py b/src/sakia/data/entities/app_data.py
index a3ed41ad1bac72fabd2dc19b3813addaac5b6127..c96f6478e62182e77c1c3659207ca2bc49c2be3c 100644
--- a/src/sakia/data/entities/app_data.py
+++ b/src/sakia/data/entities/app_data.py
@@ -3,5 +3,4 @@ import attr
 
 @attr.s()
 class AppData:
-    profiles = attr.ib(default=attr.Factory(list))
-    default = attr.ib(convert=str, default="Default Profile")
+    pass
diff --git a/src/sakia/data/entities/blockchain.py b/src/sakia/data/entities/blockchain.py
index 887cb6f917ac1deb5a3cfe7d78b18f7dd12f201c..b1f34c0f4f624e706c647ede6a57bbe208ce8b0b 100644
--- a/src/sakia/data/entities/blockchain.py
+++ b/src/sakia/data/entities/blockchain.py
@@ -2,7 +2,7 @@ import attr
 from duniterpy.documents import block_uid, BlockUID
 
 
-@attr.s()
+@attr.s(hash=False)
 class BlockchainParameters:
     # The decimal percent growth of the UD every [dt] period
     c = attr.ib(convert=float, default=0, cmp=False, hash=False)
@@ -45,10 +45,11 @@ class BlockchainParameters:
     # The dt recomputation of the ud
     dt_reeval = attr.ib(convert=int, default=0, cmp=False, hash=False)
 
-@attr.s()
+
+@attr.s(hash=True)
 class Blockchain:
     # Parameters in block 0
-    parameters = attr.ib(default=BlockchainParameters())
+    parameters = attr.ib(default=BlockchainParameters(), cmp=False, hash=False)
     # block number and hash
     current_buid = attr.ib(convert=block_uid, default=BlockUID.empty())
     # Number of members
diff --git a/src/sakia/data/entities/certification.py b/src/sakia/data/entities/certification.py
index 0b915289ba03930f33e92908a626293d3cf927cf..3e7c7d9a9b7dece178faf4a9f74629b037d33d96 100644
--- a/src/sakia/data/entities/certification.py
+++ b/src/sakia/data/entities/certification.py
@@ -2,7 +2,7 @@ import attr
 from duniterpy.documents import block_uid, BlockUID
 
 
-@attr.s()
+@attr.s(hash=True)
 class Certification:
     currency = attr.ib(convert=str)
     certifier = attr.ib(convert=str)
diff --git a/src/sakia/data/entities/connection.py b/src/sakia/data/entities/connection.py
index 6e4b43ac2d5d5af4751cb7c7778e2def8c98cd16..6b3136913748d4d6cf4ea3395c796a99ae0c9a30 100644
--- a/src/sakia/data/entities/connection.py
+++ b/src/sakia/data/entities/connection.py
@@ -3,7 +3,7 @@ from duniterpy.documents import block_uid, BlockUID
 from duniterpy.key import ScryptParams
 
 
-@attr.s()
+@attr.s(hash=True)
 class Connection:
     """
     A connection represents a connection to a currency's network
diff --git a/src/sakia/data/entities/contact.py b/src/sakia/data/entities/contact.py
index 6fd2cbdf561736691aae8eb4c313c1fed735562d..989958fd99d3c45ae30abefe01954a95fbc3b0ca 100644
--- a/src/sakia/data/entities/contact.py
+++ b/src/sakia/data/entities/contact.py
@@ -3,7 +3,7 @@ import re
 from sakia.helpers import attrs_tuple_of_str
 
 
-@attr.s()
+@attr.s(hash=True)
 class Contact:
     """
     A contact in the network currency
diff --git a/src/sakia/data/entities/dividend.py b/src/sakia/data/entities/dividend.py
index 75c70b4e8721643b7924c05a3298b5c5f04164a8..9aa7f6d43d238af61bd0c0c6567dc8e5f3d006f7 100644
--- a/src/sakia/data/entities/dividend.py
+++ b/src/sakia/data/entities/dividend.py
@@ -1,11 +1,11 @@
 import attr
 
 
-@attr.s()
+@attr.s(hash=True)
 class Dividend:
-    currency = attr.ib(convert=str)
-    pubkey = attr.ib(convert=str)
-    block_number = attr.ib(convert=int)
+    currency = attr.ib(convert=str, cmp=True, hash=True)
+    pubkey = attr.ib(convert=str, cmp=True, hash=True)
+    block_number = attr.ib(convert=int, cmp=True, hash=True)
     timestamp = attr.ib(convert=int)
     amount = attr.ib(convert=int, cmp=False, hash=False)
     base = attr.ib(convert=int, cmp=False, hash=False)
diff --git a/src/sakia/data/entities/identity.py b/src/sakia/data/entities/identity.py
index 9b9e5ac9d38bb2088c2f69635bfcae4ea5ef39a0..64510ed076f5c61f6436fa1a47d8dd2232853fc3 100644
--- a/src/sakia/data/entities/identity.py
+++ b/src/sakia/data/entities/identity.py
@@ -3,7 +3,7 @@ from duniterpy.documents import block_uid, BlockUID
 from duniterpy.documents import Identity as IdentityDoc
 
 
-@attr.s()
+@attr.s(hash=True)
 class Identity:
     currency = attr.ib(convert=str)
     pubkey = attr.ib(convert=str)
diff --git a/src/sakia/data/entities/node.py b/src/sakia/data/entities/node.py
index 999d2e322e4bf21630a8976caccf3d0690b566e5..6c7bb24cff1d5d1c1bd66e0facb1248034bfbfb7 100644
--- a/src/sakia/data/entities/node.py
+++ b/src/sakia/data/entities/node.py
@@ -19,7 +19,7 @@ def _tuple_of_endpoints(value):
         raise TypeError("Can't convert {0} to list of endpoints".format(value))
 
 
-@attr.s()
+@attr.s(hash=True)
 class Node:
     """
 
diff --git a/src/sakia/data/entities/plugin.py b/src/sakia/data/entities/plugin.py
index 973139c1749b96bd5e78efc5cb26410b754ff664..36d190e3f4b472ab97f425f0b6698048f9f36c55 100644
--- a/src/sakia/data/entities/plugin.py
+++ b/src/sakia/data/entities/plugin.py
@@ -1,7 +1,7 @@
 import attr
 
 
-@attr.s(frozen=True)
+@attr.s(frozen=True, hash=True)
 class Plugin:
     name = attr.ib()
     description = attr.ib(cmp=False, hash=False)
diff --git a/src/sakia/data/entities/source.py b/src/sakia/data/entities/source.py
index 870340ad7fd18495e375224a0af0793a193838bd..be93c5a9cc272a79e38168414a9c7939e9d03811 100644
--- a/src/sakia/data/entities/source.py
+++ b/src/sakia/data/entities/source.py
@@ -1,7 +1,7 @@
 import attr
 
 
-@attr.s()
+@attr.s(hash=True)
 class Source:
     currency = attr.ib(convert=str)
     pubkey = attr.ib(convert=str)
diff --git a/src/sakia/data/entities/transaction.py b/src/sakia/data/entities/transaction.py
index e321d013423f73a2f9f8c32396d34549bfab8119..332ae3ae6c487cd7f0c820927c86f54689eccf8e 100644
--- a/src/sakia/data/entities/transaction.py
+++ b/src/sakia/data/entities/transaction.py
@@ -21,10 +21,11 @@ def parse_transaction_doc(tx_doc, pubkey, block_number, mediantime, txid):
 
     in_issuers = len([i for i in tx_doc.issuers
                       if i == pubkey]) > 0
+
     in_outputs = len([o for o in tx_doc.outputs
                       if o.conditions.left.pubkey == pubkey]) > 0
 
-    if len(receivers) == 0:
+    if len(receivers) == 0 and in_issuers:
         receivers = [tx_doc.issuers[0]]
         # Transaction to self
         outputs = [o for o in tx_doc.outputs]
@@ -70,7 +71,7 @@ def parse_transaction_doc(tx_doc, pubkey, block_number, mediantime, txid):
     return transaction
 
 
-@attr.s()
+@attr.s(hash=True)
 class Transaction:
     """
     Transaction entity
@@ -95,9 +96,9 @@ class Transaction:
     REFUSED = 8
     DROPPED = 16
 
-    currency      = attr.ib(convert=str)
-    pubkey        = attr.ib(convert=str)
-    sha_hash      = attr.ib(convert=str)
+    currency      = attr.ib(convert=str, cmp=True, hash=True)
+    pubkey        = attr.ib(convert=str, cmp=True, hash=True)
+    sha_hash      = attr.ib(convert=str, cmp=True, hash=True)
     written_block = attr.ib(convert=int, cmp=False)
     blockstamp    = attr.ib(convert=block_uid, cmp=False)
     timestamp     = attr.ib(convert=int, cmp=False)
diff --git a/src/sakia/data/files/plugins.py b/src/sakia/data/files/plugins.py
index 14ae702cc1ab289cd60fbec0ab117ba4de5d8474..e4c914458f56ff4aa4e0aa20f4bf5ed219fa1057 100644
--- a/src/sakia/data/files/plugins.py
+++ b/src/sakia/data/files/plugins.py
@@ -7,13 +7,14 @@ import importlib
 from ..entities import Plugin
 
 
-@attr.s(frozen=True)
+@attr.s()
 class PluginsDirectory:
     """
     The repository for UserParameters
     """
     _path = attr.ib()
     plugins = attr.ib(default=[])
+    with_plugin = attr.ib(default=None)
     _logger = attr.ib(default=attr.Factory(lambda: logging.getLogger('sakia')))
 
     @classmethod
@@ -23,7 +24,7 @@ class PluginsDirectory:
             os.makedirs(plugins_path)
         return cls(plugins_path)
 
-    def load_or_init(self):
+    def load_or_init(self, with_plugin=""):
         """
         Init plugins
         """
@@ -44,6 +45,20 @@ class PluginsDirectory:
                         self.plugins.append(Plugin(module_name, "", "",
                                                    False, None, file))
                         self._logger.debug(str(e) + " with sys.path " + str(sys.path))
+            if with_plugin:
+                sys.path.append(with_plugin)
+                module_name = os.path.splitext(os.path.basename(with_plugin))[0]
+                try:
+                    plugin_module = importlib.import_module(module_name)
+                    self.with_plugin = Plugin(plugin_module.PLUGIN_NAME,
+                                              plugin_module.PLUGIN_DESCRIPTION,
+                                              plugin_module.PLUGIN_VERSION,
+                                              True,
+                                              plugin_module,
+                                              with_plugin)
+                except ImportError as e:
+                    self.with_plugin = Plugin(module_name, "", "", False, None, with_plugin)
+                    self._logger.debug(str(e) + " with sys.path " + str(sys.path))
         except OSError as e:
             self._logger.debug(str(e))
         return self
diff --git a/src/sakia/data/graphs/base_graph.py b/src/sakia/data/graphs/base_graph.py
index 05d64ac49946e4ef92dfe04456cc54df3a7a70b0..602d72e0aae712e6181a681ae4aad6168fb57063 100644
--- a/src/sakia/data/graphs/base_graph.py
+++ b/src/sakia/data/graphs/base_graph.py
@@ -1,6 +1,7 @@
 import logging
 import time
 import networkx
+from sakia.data.processors import ConnectionsProcessor
 from PyQt5.QtCore import QLocale, QDateTime, QObject, QT_TRANSLATE_NOOP
 from sakia.errors import NoPeerAvailable
 from .constants import EdgeStatus, NodeStatus
@@ -30,6 +31,7 @@ class BaseGraph(QObject):
         self.app = app
         self.identities_service = identities_service
         self.blockchain_service = blockchain_service
+        self._connections_processor = ConnectionsProcessor.instanciate(app)
         # graph empty if None parameter
         self.nx_graph = nx_graph if nx_graph else networkx.DiGraph()
 
@@ -48,24 +50,23 @@ class BaseGraph(QObject):
         else:
             return EdgeStatus.STRONG
 
-    async def node_status(self, node_identity, account_identity):
+    async def node_status(self, node_identity):
         """
         Return the status of the node depending
         :param sakia.core.registry.Identity node_identity: The identity of the node
-        :param sakia.core.registry.Identity account_identity: The identity of the account displayed
         :return: HIGHLIGHTED if node_identity is account_identity and OUT if the node_identity is not a member
         :rtype: sakia.core.graph.constants.NodeStatus
         """
         # new node
         node_status = NodeStatus.NEUTRAL
         node_identity = await self.identities_service.load_requirements(node_identity)
-        if node_identity.pubkey == account_identity.pubkey:
+        if node_identity.pubkey in self._connections_processor.pubkeys():
             node_status += NodeStatus.HIGHLIGHTED
         if node_identity.member is False:
             node_status += NodeStatus.OUT
         return node_status
 
-    def offline_node_status(self, node_identity, account_identity):
+    def offline_node_status(self, node_identity):
         """
         Return the status of the node depending on its requirements. No network request.
         :param sakia.core.registry.Identity node_identity: The identity of the node
@@ -75,7 +76,7 @@ class BaseGraph(QObject):
         """
         # new node
         node_status = NodeStatus.NEUTRAL
-        if node_identity.pubkey == account_identity.pubkey:
+        if node_identity.pubkey in self._connections_processor.pubkeys():
             node_status += NodeStatus.HIGHLIGHTED
         if node_identity.member is False:
             node_status += NodeStatus.OUT
@@ -114,13 +115,14 @@ class BaseGraph(QObject):
 
         arc_status = self.arc_status(certification.timestamp)
         sig_validity = self.blockchain_service.parameters().sig_validity
+        expiration = self.blockchain_service.adjusted_ts(certification.timestamp + sig_validity)
         arc = {
             'status': arc_status,
             'tooltip': QLocale.toString(
                 QLocale(),
-                QDateTime.fromTime_t(certification.timestamp + sig_validity).date(),
+                QDateTime.fromTime_t(expiration).date(),
                 QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
-            ),
+            ) + " BAT",
             'cert_time': certification.timestamp,
             'confirmation_text': self.confirmation_text(certification.written_on)
         }
@@ -139,55 +141,53 @@ class BaseGraph(QObject):
 
         arc_status = self.arc_status(certification.timestamp)
         sig_validity = self.blockchain_service.parameters().sig_validity
+        expiration = self.blockchain_service.adjusted_ts(certification.timestamp + sig_validity)
         arc = {
             'status': arc_status,
             'tooltip': QLocale.toString(
                 QLocale(),
-                QDateTime.fromTime_t(certification.timestamp + sig_validity).date(),
+                QDateTime.fromTime_t(expiration).date(),
                 QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
-            ),
+            ) + " BAT",
             'cert_time': certification.timestamp,
             'confirmation_text': self.confirmation_text(certification.written_on)
         }
 
         self.nx_graph.add_edge(identity.pubkey, certified.pubkey, attr_dict=arc)
 
-    def add_offline_certifier_list(self, certifier_list, identity, account_identity):
+    def add_offline_certifier_list(self, certifier_list, identity):
         """
         Add list of certifiers to graph
         :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:
         """
         #  add certifiers of uid
         for certification in tuple(certifier_list):
             certifier = self.identities_service.get_identity(certification.certifier)
             if certifier:
-                node_status = self.offline_node_status(certifier, account_identity)
+                node_status = self.offline_node_status(certifier)
                 self.add_certifier_node(certifier, identity, certification, node_status)
 
-    def add_offline_certified_list(self, certified_list, identity, account_identity):
+    def add_offline_certified_list(self, certified_list, identity):
         """
         Add list of certified from api to graph
         :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:
         """
         # add certified by uid
         for certification in tuple(certified_list):
             certified = self.identities_service.get_identity(certification.certified)
             if certified:
-                node_status = self.offline_node_status(certified, account_identity)
+                node_status = self.offline_node_status(certified)
                 self.add_certified_node(identity, certified, certification, node_status)
 
-    async def add_certifier_list(self, certifier_list, identity, account_identity):
+    async def add_certifier_list(self, certifier_list, identity):
         """
         Add list of certifiers to graph
         :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:
         """
         try:
@@ -197,17 +197,16 @@ class BaseGraph(QObject):
                 if not certifier:
                     certifier = await self.identities_service.find_from_pubkey(certification.certifier)
                     self.identities_service.insert_or_update_identity(certifier)
-                node_status = await self.node_status(certifier, account_identity)
+                node_status = await self.node_status(certifier)
                 self.add_certifier_node(certifier, identity, certification, node_status)
         except NoPeerAvailable as e:
             logging.debug(str(e))
 
-    async def add_certified_list(self, certified_list, identity, account_identity):
+    async def add_certified_list(self, certified_list, identity):
         """
         Add list of certified from api to graph
         :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:
         """
         try:
@@ -217,7 +216,7 @@ class BaseGraph(QObject):
                 if not certified:
                     certified = await self.identities_service.find_from_pubkey(certification.certified)
                     self.identities_service.insert_or_update_identity(certified)
-                node_status = await self.node_status(certified, account_identity)
+                node_status = await self.node_status(certified)
                 self.add_certified_node(identity, certified, certification, node_status)
 
         except NoPeerAvailable as e:
diff --git a/src/sakia/data/graphs/wot_graph.py b/src/sakia/data/graphs/wot_graph.py
index 7d143e82c7b62e763414ec895554160be3cb3350..58f9b81c5768409cb1db1cd57aa1edbe64bf2d91 100644
--- a/src/sakia/data/graphs/wot_graph.py
+++ b/src/sakia/data/graphs/wot_graph.py
@@ -16,9 +16,9 @@ class WoTGraph(BaseGraph):
         """
         super().__init__(app, blockchain_service, identities_service, nx_graph)
 
-    async def initialize(self, center_identity, connection_identity):
+    async def initialize(self, center_identity):
         self.nx_graph.clear()
-        node_status = await self.node_status(center_identity, connection_identity)
+        node_status = await self.node_status(center_identity)
 
         self.add_identity(center_identity, node_status)
 
@@ -33,23 +33,21 @@ class WoTGraph(BaseGraph):
                                                                                             certified_list)
 
         # populate graph with certifiers-of
-        certifier_coro = asyncio.ensure_future(self.add_certifier_list(certifier_list,
-                                                                       center_identity, connection_identity))
+        certifier_coro = asyncio.ensure_future(self.add_certifier_list(certifier_list, center_identity))
         # populate graph with certified-by
-        certified_coro = asyncio.ensure_future(self.add_certified_list(certified_list,
-                                                                       center_identity, connection_identity))
+        certified_coro = asyncio.ensure_future(self.add_certified_list(certified_list, center_identity))
 
         await asyncio.gather(*[certifier_coro, certified_coro], return_exceptions=True)
         await asyncio.sleep(0)
 
-    def offline_init(self, center_identity, connection_identity):
-        node_status = self.offline_node_status(center_identity, connection_identity)
+    def offline_init(self, center_identity):
+        node_status = self.offline_node_status(center_identity)
 
         self.add_identity(center_identity, node_status)
 
         # populate graph with certifiers-of
         certifier_list = self.identities_service.certifications_received(center_identity.pubkey)
-        self.add_offline_certifier_list(certifier_list, center_identity, connection_identity)
+        self.add_offline_certifier_list(certifier_list, center_identity)
         # populate graph with certified-by
         certified_list = self.identities_service.certifications_sent(center_identity.pubkey)
-        self.add_offline_certified_list(certified_list, center_identity, connection_identity)
+        self.add_offline_certified_list(certified_list, center_identity)
diff --git a/src/sakia/data/processors/blockchain.py b/src/sakia/data/processors/blockchain.py
index 25b02eff0278de19d28628dd014b562348e3bf22..e1879e4fdaca78847db9cf6fe3057fc01e965bd2 100644
--- a/src/sakia/data/processors/blockchain.py
+++ b/src/sakia/data/processors/blockchain.py
@@ -223,14 +223,14 @@ class BlockchainProcessor:
 
         return blocks
 
-    async def initialize_blockchain(self, currency, log_stream):
+    async def initialize_blockchain(self, currency):
         """
         Initialize blockchain for a given currency if no source exists locally
         """
         blockchain = self._repo.get_one(currency=currency)
         if not blockchain:
             blockchain = Blockchain(currency=currency)
-            log_stream("Requesting blockchain parameters")
+            self._logger.debug("Requesting blockchain parameters")
             try:
                 parameters = await self._bma_connector.get(currency, bma.blockchain.parameters)
                 blockchain.parameters.ms_validity = parameters['msValidity']
@@ -256,7 +256,7 @@ class BlockchainProcessor:
             except errors.DuniterError as e:
                 raise
 
-        log_stream("Requesting current block")
+        self._logger.debug("Requesting current block")
         try:
             current_block = await self._bma_connector.get(currency, bma.blockchain.current)
             signed_raw = "{0}{1}\n".format(current_block['raw'], current_block['signature'])
@@ -268,12 +268,12 @@ class BlockchainProcessor:
             if e.ucode != errors.NO_CURRENT_BLOCK:
                 raise
 
-        log_stream("Requesting blocks with dividend")
+        self._logger.debug("Requesting blocks with dividend")
         with_ud = await self._bma_connector.get(currency, bma.blockchain.ud)
         blocks_with_ud = with_ud['result']['blocks']
 
         if len(blocks_with_ud) > 0:
-            log_stream("Requesting last block with dividend")
+            self._logger.debug("Requesting last block with dividend")
             try:
                 index = max(len(blocks_with_ud) - 1, 0)
                 block_number = blocks_with_ud[index]
@@ -289,7 +289,7 @@ class BlockchainProcessor:
                 if e.ucode != errors.NO_CURRENT_BLOCK:
                     raise
 
-            log_stream("Requesting previous block with dividend")
+            self._logger.debug("Requesting previous block with dividend")
             try:
                 index = max(len(blocks_with_ud) - 2, 0)
                 block_number = blocks_with_ud[index]
diff --git a/src/sakia/data/processors/transactions.py b/src/sakia/data/processors/transactions.py
index e13542bbce6e3c2bbc15acccd4715b4d47612758..d090642c69d3a941253146396f1f4cd10c784fd4 100644
--- a/src/sakia/data/processors/transactions.py
+++ b/src/sakia/data/processors/transactions.py
@@ -143,8 +143,11 @@ class TransactionsProcessor:
             try:
                 tx = parse_transaction_doc(sent, connection.pubkey, sent_data["block_number"],
                                            sent_data["time"], txid)
-                transactions.append(tx)
-                self._repo.insert(tx)
+                if tx:
+                    transactions.append(tx)
+                    self._repo.insert(tx)
+                else:
+                    log_stream("ERROR : Could not parse transaction")
             except sqlite3.IntegrityError:
                 log_stream("Transaction already registered in database")
             await asyncio.sleep(0)
diff --git a/src/sakia/data/repositories/certifications.py b/src/sakia/data/repositories/certifications.py
index ad571c4acc88bc35ef521b2eb2752299f5185fa4..2ae935801a543d7cc325b35b087d1ca255608c59 100644
--- a/src/sakia/data/repositories/certifications.py
+++ b/src/sakia/data/repositories/certifications.py
@@ -90,7 +90,7 @@ class CertificationsRepo:
         """
         request = """SELECT * FROM certifications
                   WHERE currency=? AND (certifier=? or certified=?)
-                  AND ((ts + ? < ?) or (written_on == 0 and ts + ? < ?))
+                  AND ((ts + ? < ?) or (written_on == -1 and ts + ? < ?))
                   """
         c = self._conn.execute(request, (currency, pubkey, pubkey,
                                          sig_validity, current_ts,
diff --git a/src/sakia/data/repositories/meta.py b/src/sakia/data/repositories/meta.py
index 3b1fb7c3634347cde24b78f09767dfc7d71e8e13..bd08ef3d504a8092c58e3f4a16d6b40e2a6b7f19 100644
--- a/src/sakia/data/repositories/meta.py
+++ b/src/sakia/data/repositories/meta.py
@@ -36,8 +36,13 @@ class SakiaDatabase:
         sqlite3.register_adapter(BlockUID, str)
         sqlite3.register_adapter(bool, int)
         sqlite3.register_converter("BOOLEAN", lambda v: bool(int(v)))
+
+        def total_amount(amount, amount_base):
+            return amount * 10 ** amount_base
+
         db_path = os.path.join(options.config_path, profile_name, options.currency + ".db")
         con = sqlite3.connect(db_path, detect_types=sqlite3.PARSE_DECLTYPES)
+        con.create_function("total_amount", 2, total_amount)
         meta = SakiaDatabase(con, ConnectionsRepo(con), IdentitiesRepo(con),
                              BlockchainsRepo(con), CertificationsRepo(con), TransactionsRepo(con),
                              NodesRepo(con), SourcesRepo(con), DividendsRepo(con), ContactsRepo(con))
diff --git a/src/sakia/data/repositories/transactions.py b/src/sakia/data/repositories/transactions.py
index 0a9a771785cdbefdfe7e9cdbd7dfcab34b402291..4a657a61b9c5fb433567cd0c1c08a8bd8aa6c958 100644
--- a/src/sakia/data/repositories/transactions.py
+++ b/src/sakia/data/repositories/transactions.py
@@ -1,6 +1,6 @@
 import attr
 
-from ..entities import Transaction
+from ..entities import Transaction, Dividend
 
 
 @attr.s(frozen=True)
diff --git a/src/sakia/g1_licence.html b/src/sakia/g1_licence.html
new file mode 100644
index 0000000000000000000000000000000000000000..4cedfcbfe0ea3c7a1e182a3fbf6c1a650d7225a5
--- /dev/null
+++ b/src/sakia/g1_licence.html
@@ -0,0 +1,105 @@
+<H1> License Äž1 - v0.2 </H1>
+<H2> Money licensing and liability commitment. </H2>
+
+<P>Any certification operation of a new member of Äž1
+must first be accompanied by the transmission of this
+ license of the currency Äž1 whose certifier must ensure
+ that it has been studied, understood and accepted by the
+ person who will be certified.
+</P>
+<H4> Production of Units Äž1 </h4>
+<P> Äž1 occurs via a Universal Dividend (DU) for any human member, which is of the form: </ p>
+<Ul>
+<Li> 1 DU per person per day </ li>
+</Ul>
+<div>
+<P> The amount of DU is identical each day until the next equinox,
+where the DU will then be reevaluated according to the formula: </p>
+</div>
+<div>
+<ul>
+<li> DU <sub> day </sub> (the following equinox) = DU <day> (equinox) + c² (M / N) (equinox) / (15778800 seconds)
+</Ul>
+</div>
+<div>
+<P> With as parameters: </p>
+</div>
+<div>
+<Ul>
+<Li> c = 4.88% / equinox </li>
+<Li> UD (0) = 10.00 Äž1 </li>
+</Ul>
+</div>
+<div>
+<P> And as variables: </p>
+</div>
+<div>
+<Ul>
+<Li> <em> M </em> the total monetary mass at the equinox </li>
+<Li> <em> N </em> the number of members at the equinox </li>
+</Ul>
+<div>
+<H4>Web of Trust</H4>
+</div>
+<div>
+<P> <strong> Warning: </strong> Certifying is not just about making sure you've met the person,
+it's ensuring that the community Äž1 knows the certified person well enough and Duplicate account
+made by a person certified by you, or other types of problems (disappearance ...),
+by cross-checking that will reveal the problem if necessary. </P>
+</div>
+<div>
+<P> When you are a member of Äž1 and you are about to certify a new account: </p>
+</div>
+<div>
+<P> <strong> You are assured: </strong> </p>
+</div>
+<div>
+<P> 1 °) The person who declares to manage this public key (new account) and to
+have personally checked with him that this is the public key is sufficiently well known
+ (not only to know this person visually) that you are about to certify.
+ </P>
+<P> 2a °) To meet her physically to make sure that it is this person you know who manages this public key. </P>
+<P> 2b °) Remotely verify the public person / key link by contacting the person via several different means of communication,
+such as social network + forum + mail + video conference + phone (acknowledge voice). </P>
+<P> Because if you can hack an email account or a forum account, it will be much harder to imagine hacking four distinct
+ means of communication, and mimic the appearance (video) as well as the voice of the person . </P>
+<P> However, the 2 °) is preferable to 3 °, whereas the 1 °) is always indispensable in all cases. </P>
+<p> 3 °) To have verified with the person concerned that he has indeed generated his Duniter account revocation document,
+which will enable him, if necessary, to cancel his account (in case of account theft,
+ID, an incorrectly created account, etc.).</p>
+</div>
+<h4>Abbreviated Web of Trust rules</h4>
+<div><p>
+Each member has a stock of 100 possible certifications,
+which can only be issued at the rate of 1 certification / 5 days.</p>
+
+<p>Valid for 2 months, certification for a new member is definitively adopted only if the certified has
+ at least 4 other certifications after these 2 months, otherwise the entry process will have to be relaunched.
+</p>
+
+<p>To become a new member of TOC Äž1 therefore 5 certifications
+must be obtained at a distance> 5 of 80% of the TOC sentinels.</p>
+
+<p>A member of the TdC Äž1 is sentinel when he has received and issued at least Y [N] certifications
+where N is the number of members of the TdC and Y [N] = ceiling N ^ (1/5). Examples:</p>
+
+<ul>
+<li>For 1024 &lt; N ≤ 3125 we have Y [N] = 5</li>
+<li>For 7776 &lt; N ≤ 16807 we have Y [N] = 7</li>
+<li>For 59049 &lt; N ≤ 100 000 we have Y [N] = 10</li>
+</ul>
+
+<p>Once the new member is part of the TOC Äž1 his certifications remain valid for 2 years.</p>
+
+<p>To remain a member, you must renew your agreement regularly with your private key (every 12 months)
+and make sure you have at least 5 certifications valid after 2 years.</p>
+
+<h4>Software Äž1 and license Äž1</h4>
+
+<p>The software Äž1 allowing users to manage their use of Äž1 must transmit this license with the software
+and all the technical parameters of the currency Äž1 and TdC Äž1 which are entered in block 0 of Äž1.</p>
+
+<p>For more details in the technical details it is possible to consult directly the code of Duniter
+which is a free software and also the data of the blockchain Äž1 by retrieving it via a Duniter instance or node Äž1.</p>
+
+More information on the Duniter Team website <a href="https://www.duniter.org">https://www.duniter.org</a>
\ No newline at end of file
diff --git a/src/sakia/gui/dialogs/certification/certification.ui b/src/sakia/gui/dialogs/certification/certification.ui
deleted file mode 100644
index dc03f7bcc9728695cbfcbb86321d40d8f6fbfc71..0000000000000000000000000000000000000000
--- a/src/sakia/gui/dialogs/certification/certification.ui
+++ /dev/null
@@ -1,135 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>CertificationDialog</class>
- <widget class="QDialog" name="CertificationDialog">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>517</width>
-    <height>441</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Certification</string>
-  </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
-   <item>
-    <widget class="QGroupBox" name="groupBox_2">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="title">
-      <string>Select your identity</string>
-     </property>
-     <layout class="QVBoxLayout" name="verticalLayout_2">
-      <item>
-       <widget class="QComboBox" name="combo_connection"/>
-      </item>
-      <item>
-       <widget class="QGroupBox" name="groupBox_3">
-        <property name="title">
-         <string>Certifications stock</string>
-        </property>
-        <layout class="QVBoxLayout" name="verticalLayout_4">
-         <item>
-          <widget class="QLabel" name="label_cert_stock">
-           <property name="text">
-            <string/>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <widget class="QGroupBox" name="groupbox_certified">
-     <property name="title">
-      <string>Certify user</string>
-     </property>
-     <layout class="QVBoxLayout" name="verticalLayout_3">
-      <item>
-       <layout class="QHBoxLayout" name="horizontalLayout">
-        <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="QPushButton" name="button_import_identity">
-          <property name="text">
-           <string>Import identity document</string>
-          </property>
-         </widget>
-        </item>
-       </layout>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <widget class="QLabel" name="label_confirm">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="text">
-      <string>label_confirm</string>
-     </property>
-    </widget>
-   </item>
-   <item>
-    <widget class="QGroupBox" name="group_box_password">
-     <property name="title">
-      <string>Secret Key / Password</string>
-     </property>
-     <layout class="QVBoxLayout" name="verticalLayout_6">
-      <item>
-       <layout class="QVBoxLayout" name="layout_password_input"/>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <widget class="QDialogButtonBox" name="button_box">
-     <property name="enabled">
-      <bool>true</bool>
-     </property>
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="standardButtons">
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
-     </property>
-    </widget>
-   </item>
-  </layout>
- </widget>
- <resources/>
- <connections/>
- <slots>
-  <slot>open_manage_wallet_coins()</slot>
-  <slot>change_displayed_wallet(int)</slot>
-  <slot>transfer_mode_changed(bool)</slot>
-  <slot>recipient_mode_changed(bool)</slot>
-  <slot>change_current_community(int)</slot>
-  <slot>amount_changed()</slot>
-  <slot>relative_amount_changed()</slot>
- </slots>
-</ui>
diff --git a/src/sakia/gui/dialogs/connection_cfg/connection_cfg.ui b/src/sakia/gui/dialogs/connection_cfg/connection_cfg.ui
index 5aee15280722fb175ea2c3d5556121a56f54a3e9..35ae6e71aeb365b2578b5ac2e3a981fb80325aa9 100644
--- a/src/sakia/gui/dialogs/connection_cfg/connection_cfg.ui
+++ b/src/sakia/gui/dialogs/connection_cfg/connection_cfg.ui
@@ -433,7 +433,7 @@ p, li { white-space: pre-wrap; }
             <item>
              <widget class="QPushButton" name="button_next">
               <property name="text">
-               <string>Next</string>
+               <string>Export revocation document to continue</string>
               </property>
              </widget>
             </item>
diff --git a/src/sakia/gui/dialogs/connection_cfg/controller.py b/src/sakia/gui/dialogs/connection_cfg/controller.py
index 8c11b6bccaf611581cfe6c68d2e0c1c0cbb76991..3026b48d9858e5c3ed879a45a0dff2d325ff0b6f 100644
--- a/src/sakia/gui/dialogs/connection_cfg/controller.py
+++ b/src/sakia/gui/dialogs/connection_cfg/controller.py
@@ -144,12 +144,14 @@ class ConnectionConfigController(QObject):
             connection_identity = await self.step_key
         elif self.mode == ConnectionConfigController.CONNECT:
             self._logger.debug("Connect mode")
+            self.view.button_next.setText(self.tr("Next"))
             self.view.groupbox_pubkey.hide()
             self.view.button_next.clicked.connect(self.check_connect)
             self.view.stacked_pages.setCurrentWidget(self.view.page_connection)
             connection_identity = await self.step_key
         elif self.mode == ConnectionConfigController.WALLET:
             self._logger.debug("Wallet mode")
+            self.view.button_next.setText(self.tr("Next"))
             self.view.button_next.clicked.connect(self.check_wallet)
             self.view.edit_uid.hide()
             self.view.label_action.hide()
@@ -158,6 +160,7 @@ class ConnectionConfigController(QObject):
             connection_identity = await self.step_key
         elif self.mode == ConnectionConfigController.PUBKEY:
             self._logger.debug("Pubkey mode")
+            self.view.button_next.setText(self.tr("Next"))
             self.view.button_next.clicked.connect(self.check_pubkey)
             if not self.view.label_action.text().endswith(self.tr(" (Optional)")):
                 self.view.label_action.setText(self.view.label_action.text() + self.tr(" (Optional)"))
@@ -169,19 +172,18 @@ class ConnectionConfigController(QObject):
         self.view.progress_bar.setValue(0)
         self.view.progress_bar.setMaximum(3)
         try:
-            await self.model.initialize_blockchain(self.view.stream_log)
-            self.view.progress_bar.setValue(1)
+            self.view.progress_bar.setValue(0)
             if self.mode == ConnectionConfigController.REGISTER:
                 self.view.display_info(self.tr("Broadcasting identity..."))
                 self.view.stream_log("Broadcasting identity...")
-                result, connection_identity = await self.model.publish_selfcert()
+                result = await self.model.publish_selfcert(connection_identity)
                 if result[0]:
                     await self.view.show_success(self.model.notification())
                 else:
                     self.view.show_error(self.model.notification(), result[1])
                     raise StopIteration()
 
-            self.view.progress_bar.setValue(2)
+            self.view.progress_bar.setValue(1)
 
             if self.mode in (ConnectionConfigController.REGISTER,
                         ConnectionConfigController.CONNECT,
@@ -195,6 +197,7 @@ class ConnectionConfigController(QObject):
                 self.view.stream_log("Initializing certifications informations...")
                 await self.model.initialize_certifications(connection_identity, log_stream=self.view.stream_log)
 
+            self.view.progress_bar.setValue(2)
             self.view.stream_log("Initializing transactions history...")
             transactions = await self.model.initialize_transactions(self.model.connection,
                                                                     log_stream=self.view.stream_log)
@@ -211,8 +214,6 @@ class ConnectionConfigController(QObject):
 
             if self.mode == ConnectionConfigController.REGISTER:
                 await self.view.show_register_message(self.model.blockchain_parameters())
-                await self.export_identity_document()
-                await self.action_save_revokation()
         except (NoPeerAvailable, DuniterError, StopIteration) as e:
             if not isinstance(e, StopIteration):
                 self.view.show_error(self.model.notification(), str(e))
@@ -269,10 +270,10 @@ class ConnectionConfigController(QObject):
         self.view.label_info.setText("")
         return True
 
-    async def action_save_revokation(self):
-        raw_document = self.model.generate_revokation()
+    async def action_save_revocation(self):
+        raw_document, identity = self.model.generate_revocation()
         # Testable way of using a QFileDialog
-        selected_files = await QAsyncFileDialog.get_save_filename(self.view, self.tr("Save a revokation document"),
+        selected_files = await QAsyncFileDialog.get_save_filename(self.view, self.tr("Save a revocation document"),
                                                                   "", self.tr("All text files (*.txt)"))
         if selected_files:
             path = selected_files[0]
@@ -282,28 +283,12 @@ class ConnectionConfigController(QObject):
                 save_file.write(raw_document)
 
             dialog = QMessageBox(QMessageBox.Information, self.tr("Revokation file"),
-                                 self.tr("""<div>Your revokation document has been saved.</div>
+                                 self.tr("""<div>Your revocation document has been saved.</div>
 <div><b>Please keep it in a safe place.</b></div>
 The publication of this document will remove your identity from the network.</p>"""), QMessageBox.Ok)
             dialog.setTextFormat(Qt.RichText)
-            await dialog_async_exec(dialog)
-
-    async def export_identity_document(self):
-        identity, identity_doc = self.model.generate_identity()
-        selected_files = await QAsyncFileDialog.get_save_filename(self.view, self.tr("Save an identity document"),
-                                                                  "", self.tr("All text files (*.txt)"))
-        if selected_files:
-            path = selected_files[0]
-            if not path.endswith('.txt'):
-                path = "{0}.txt".format(path)
-            with open(path, 'w') as save_file:
-                save_file.write(identity_doc.signed_raw())
-
-            dialog = QMessageBox(QMessageBox.Information, self.tr("Identity file"),
-                                 self.tr("""<div>Your identity document has been saved.</div>
-Share this document to your friends for them to certify you.</p>"""), QMessageBox.Ok)
-            dialog.setTextFormat(Qt.RichText)
-            await dialog_async_exec(dialog)
+            return True, identity
+        return False, identity
 
     @asyncify
     async def check_pubkey(self, checked=False):
@@ -326,11 +311,7 @@ Yours : {0}, the network : {1}""".format(registered[1], registered[2])))
                         else:
                             self.step_key.set_result(found_identity)
                     else:
-                        if registered[0] is False and registered[2] is None:
-                            self.step_key.set_result(None)
-                        elif registered[2]:
-                            self.view.display_info(self.tr("""Your pubkey is associated to an identity.<br/>
-Yours : {0}, the network : {1}""".format(registered[1], registered[2])))
+                        self.step_key.set_result(None)
 
                 except DuniterError as e:
                     self.view.display_info(e.message)
@@ -415,7 +396,11 @@ Yours : {0}, the network : {1}""".format(registered[1], registered[2])))
                 try:
                     registered, found_identity = await self.model.check_registered()
                     if registered[0] is False and registered[2] is None:
-                        self.step_key.set_result(None)
+                        result, identity = await self.action_save_revocation()
+                        if result:
+                            self.step_key.set_result(identity)
+                        else:
+                            self.view.display_info("Saving your revocation document on your disk is mandatory.")
                     elif registered[0] is False and registered[2]:
                         self.view.display_info(self.tr("""Your pubkey or UID was already found on the network.
         Yours : {0}, the network : {1}""".format(registered[1], registered[2])))
diff --git a/src/sakia/gui/dialogs/connection_cfg/model.py b/src/sakia/gui/dialogs/connection_cfg/model.py
index 4f8567f443d5c678ab1db1c0923f04d4f2fbd09d..bbba9ed3ff85c6618c312d87fdd38ef1e02dbc94 100644
--- a/src/sakia/gui/dialogs/connection_cfg/model.py
+++ b/src/sakia/gui/dialogs/connection_cfg/model.py
@@ -56,8 +56,8 @@ class ConnectionConfigModel(QObject):
     def insert_or_update_identity(self, identity):
         self.identities_processor.insert_or_update_identity(identity)
 
-    def generate_revokation(self):
-        return self.app.documents_service.generate_revokation(self.connection,
+    def generate_revocation(self):
+        return self.app.documents_service.generate_revocation(self.connection,
                                                               self.connection.salt,
                                                               self.connection.password)
 
@@ -71,7 +71,7 @@ class ConnectionConfigModel(QObject):
         :return:
         """
         blockchain_processor = BlockchainProcessor.instanciate(self.app)
-        await blockchain_processor.initialize_blockchain(self.app.currency, log_stream)
+        await blockchain_processor.initialize_blockchain(self.app.currency)
 
     async def initialize_sources(self, transactions, dividends, log_stream):
         """
@@ -123,17 +123,12 @@ class ConnectionConfigModel(QObject):
         dividends_processor = DividendsProcessor.instanciate(self.app)
         return await dividends_processor.initialize_dividends(identity, transactions, log_stream)
 
-    async def publish_selfcert(self):
+    async def publish_selfcert(self, identity):
         """"
         Publish the self certification of the connection identity
         """
-        identity, identity_doc = self.app.documents_service.generate_identity(self.connection)
-        key = SigningKey(self.connection.salt, self.connection.password, self.connection.scrypt_params)
-        identity_doc.sign([key])
-        identity.signature = identity_doc.signatures[0]
-        self.identities_processor.insert_or_update_identity(identity)
-        result = await self.app.documents_service.broadcast_identity(self.connection, identity_doc)
-        return result, identity
+        result = await self.app.documents_service.broadcast_identity(self.connection, identity.document())
+        return result
 
     async def check_registered(self):
         identities_processor = IdentitiesProcessor.instanciate(self.app)
diff --git a/src/sakia/gui/dialogs/connection_cfg/view.py b/src/sakia/gui/dialogs/connection_cfg/view.py
index 9f9ba0f5369005a7a66cfceec6eb806b7d843f3b..3961ea3a9fecce8e6196c9a0a02041acb3a0d3df 100644
--- a/src/sakia/gui/dialogs/connection_cfg/view.py
+++ b/src/sakia/gui/dialogs/connection_cfg/view.py
@@ -7,7 +7,7 @@ from math import ceil, log
 from sakia.gui.widgets import toast
 from sakia.helpers import timestamp_to_dhms
 from sakia.gui.widgets.dialogs import dialog_async_exec, QAsyncMessageBox
-from sakia.constants import ROOT_SERVERS
+from sakia.constants import ROOT_SERVERS, G1_LICENCE
 
 
 class ConnectionConfigView(QDialog, Ui_ConnectionConfigurationDialog):
@@ -60,113 +60,7 @@ class ConnectionConfigView(QDialog, Ui_ConnectionConfigurationDialog):
         self.spin_p.blockSignals(False)
 
     def set_license(self, currency):
-        license_text = self.tr("""
-<H1> License Äž1 - v0.2 </H1>
-<H2> Money licensing and liability commitment. </H2>
-
-<P>Any certification operation of a new member of Äž1
-must first be accompanied by the transmission of this
- license of the currency Äž1 whose certifier must ensure
- that it has been studied, understood and accepted by the
- person who will be certified.
-</P>
-<H4> Production of Units Äž1 </h4>
-<P> Äž1 occurs via a Universal Dividend (DU) for any human member, which is of the form: </ p>
-<Ul>
-<Li> 1 DU per person per day </ li>
-</Ul>
-<div>
-<P> The amount of DU is identical each day until the next equinox,
-where the DU will then be reevaluated according to the formula: </p>
-</div>
-<div>
-<ul>
-<li> DU <sub> day </sub> (the following equinox) = DU <day> (equinox) + c² (M / N) (equinox) / (15778800 seconds)
-</Ul>
-</div>
-<div>
-<P> With as parameters: </p>
-</div>
-<div>
-<Ul>
-<Li> c = 4.88% / equinox </li>
-<Li> UD (0) = 10.00 Äž1 </li>
-</Ul>
-</div>
-<div>
-<P> And as variables: </p>
-</div>
-<div>
-<Ul>
-<Li> <em> M </em> the total monetary mass at the equinox </li>
-<Li> <em> N </em> the number of members at the equinox </li>
-</Ul>
-<div>
-<H4>Web of Trust</H4>
-</div>
-<div>
-<P> <strong> Warning: </strong> Certifying is not just about making sure you've met the person,
-it's ensuring that the community Äž1 knows the certified person well enough and Duplicate account
-made by a person certified by you, or other types of problems (disappearance ...),
-by cross-checking that will reveal the problem if necessary. </P>
-</div>
-<div>
-<P> When you are a member of Äž1 and you are about to certify a new account: </p>
-</div>
-<div>
-<P> <strong> You are assured: </strong> </p>
-</div>
-<div>
-<P> 1 °) The person who declares to manage this public key (new account) and to
-have personally checked with him that this is the public key is sufficiently well known
- (not only to know this person visually) that you are about to certify.
- </P>
-<P> 2a °) To meet her physically to make sure that it is this person you know who manages this public key. </P>
-<P> 2b °) Remotely verify the public person / key link by contacting the person via several different means of communication,
-such as social network + forum + mail + video conference + phone (acknowledge voice). </P>
-<P> Because if you can hack an email account or a forum account, it will be much harder to imagine hacking four distinct
- means of communication, and mimic the appearance (video) as well as the voice of the person . </P>
-<P> However, the 2 °) is preferable to 3 °, whereas the 1 °) is always indispensable in all cases. </P>
-<p> 3 °) To have verified with the person concerned that he has indeed generated his Duniter account revocation document,
-which will enable him, if necessary, to cancel his account (in case of account theft,
-ID, an incorrectly created account, etc.).</p>
-</div>
-<h4>Abbreviated Web of Trust rules</h4>
-<div><p>
-Each member has a stock of 100 possible certifications,
-which can only be issued at the rate of 1 certification / 5 days.</p>
-
-<p>Valid for 2 months, certification for a new member is definitively adopted only if the certified has
- at least 4 other certifications after these 2 months, otherwise the entry process will have to be relaunched.
-</p>
-
-<p>To become a new member of TOC Äž1 therefore 5 certifications
-must be obtained at a distance> 5 of 80% of the TOC sentinels.</p>
-
-<p>A member of the TdC Äž1 is sentinel when he has received and issued at least Y [N] certifications
-where N is the number of members of the TdC and Y [N] = ceiling N ^ (1/5). Examples:</p>
-
-<ul>
-<li>For 1024 &lt; N ≤ 3125 we have Y [N] = 5</li>
-<li>For 7776 &lt; N ≤ 16807 we have Y [N] = 7</li>
-<li>For 59049 &lt; N ≤ 100 000 we have Y [N] = 10</li>
-</ul>
-
-<p>Once the new member is part of the TOC Äž1 his certifications remain valid for 2 years.</p>
-
-<p>To remain a member, you must renew your agreement regularly with your private key (every 12 months)
-and make sure you have at least 5 certifications valid after 2 years.</p>
-
-<h4>Software Äž1 and license Äž1</h4>
-
-<p>The software Äž1 allowing users to manage their use of Äž1 must transmit this license with the software
-and all the technical parameters of the currency Äž1 and TdC Äž1 which are entered in block 0 of Äž1.</p>
-
-<p>For more details in the technical details it is possible to consult directly the code of Duniter
-which is a free software and also the data of the blockchain Äž1 by retrieving it via a Duniter instance or node Äž1.</p>
-
-More information on the Duniter Team website <a href="https://www.duniter.org">https://www.duniter.org</a>
-""")
+        license_text = self.tr(G1_LICENCE)
         self.text_license.setText(license_text)
 
     def handle_n_change(self, value):
diff --git a/src/sakia/gui/main_window/controller.py b/src/sakia/gui/main_window/controller.py
index b53ab1704e89bfdc9f471d03842b20b95c4df2f2..b9848b110f6fbf6605eab03a54683196fef7f6c8 100644
--- a/src/sakia/gui/main_window/controller.py
+++ b/src/sakia/gui/main_window/controller.py
@@ -76,6 +76,10 @@ class MainWindowController(QObject):
                                  navigation=navigation,
                                  toolbar=toolbar
                                  )
+        toolbar.view.button_network.clicked.connect(navigation.open_network_view)
+        toolbar.view.button_identity.clicked.connect(navigation.open_identities_view)
+        toolbar.view.button_explore.clicked.connect(navigation.open_wot_view)
+        toolbar.exit_triggered.connect(main_window.view.close)
         #app.version_requested.connect(main_window.latest_version_requested)
         #app.account_imported.connect(main_window.import_account_accepted)
         #app.account_changed.connect(main_window.change_account)
@@ -83,6 +87,8 @@ class MainWindowController(QObject):
             main_window.view.showMaximized()
         else:
             main_window.view.show()
+        app.refresh_started.connect(main_window.status_bar.start_loading)
+        app.refresh_finished.connect(main_window.status_bar.stop_loading)
         main_window.model.load_plugins(main_window)
         main_window.refresh(app.currency)
         return main_window
@@ -118,7 +124,6 @@ class MainWindowController(QObject):
         in the window have to be refreshed
         """
         self.status_bar.refresh()
-        self.toolbar.enable_actions(len(self.navigation.model.navigation[0]['children']) > 0)
         display_name = ROOT_SERVERS[currency]["display"]
         self.view.setWindowTitle(self.tr("sakia {0} - {1}").format(__version__, display_name))
 
diff --git a/src/sakia/gui/main_window/model.py b/src/sakia/gui/main_window/model.py
index fa6f19a799bc5768961aeaf90280163e4cf36710..adb5736e7c6dbea7cf9bffd3ca141bc0e01a9ca3 100644
--- a/src/sakia/gui/main_window/model.py
+++ b/src/sakia/gui/main_window/model.py
@@ -14,3 +14,5 @@ class MainWindowModel(QObject):
         for plugin in self.app.plugins_dir.plugins:
             if plugin.imported:
                 plugin.module.plugin_exec(self.app, main_window)
+        if self.app.plugins_dir.with_plugin and self.app.plugins_dir.with_plugin.module:
+            self.app.plugins_dir.with_plugin.module.plugin_exec(self.app, main_window)
diff --git a/src/sakia/gui/main_window/status_bar/controller.py b/src/sakia/gui/main_window/status_bar/controller.py
index e438150172eb9927728b01faf8ca5c455ee47b83..ffd20c19d3a867e0b16388d01d528eea539d9be0 100644
--- a/src/sakia/gui/main_window/status_bar/controller.py
+++ b/src/sakia/gui/main_window/status_bar/controller.py
@@ -14,8 +14,8 @@ class StatusBarController(QObject):
         """
         Constructor of the navigation component
 
-        :param sakia.gui.status_bar.view.StatusBarView view: the presentation
-        :param sakia.core.status_bar.model.StatusBarModel model: the model
+        :param sakia.gui.main_window.status_bar.view.StatusBarView view: the presentation
+        :param sakia.gui.main_window.status_bar.model.StatusBarModel model: the model
         """
         super().__init__()
         self.view = view
@@ -53,6 +53,12 @@ class StatusBarController(QObject):
         timer.timeout.connect(self.update_time)
         timer.start(1000)
 
+    def start_loading(self):
+        self.view.start_loading()
+
+    def stop_loading(self):
+        self.view.stop_loading()
+
     def new_blocks_handled(self):
         current_block = self.model.current_block()
         current_time = self.model.current_time()
@@ -61,7 +67,7 @@ class StatusBarController(QObject):
                         QDateTime.fromTime_t(current_time),
                         QLocale.dateTimeFormat(QLocale(), QLocale.NarrowFormat)
                     )
-        self.view.status_label.setText(self.tr("Blockchain sync : {0} ({1})").format(str_time, str(current_block)[:15]))
+        self.view.status_label.setText(self.tr("Blockchain sync : {0} BAT ({1})").format(str_time, str(current_block)[:15]))
 
     def refresh(self):
         """
diff --git a/src/sakia/gui/main_window/status_bar/model.py b/src/sakia/gui/main_window/status_bar/model.py
index cdaef8be805787d52c80ddebbdf53876b66775de..4e3b4f82d7d596b9caaf9cdff2f5fe5cfadd2fc8 100644
--- a/src/sakia/gui/main_window/status_bar/model.py
+++ b/src/sakia/gui/main_window/status_bar/model.py
@@ -28,5 +28,6 @@ class StatusBarModel(QObject):
         return self.blockchain_processor.current_buid(self.app.currency)
 
     def current_time(self):
-        return self.blockchain_processor.time(self.app.currency)
+        time = self.blockchain_processor.time(self.app.currency)
+        return self.blockchain_processor.adjusted_ts(self.app.currency, time)
 
diff --git a/src/sakia/gui/main_window/status_bar/view.py b/src/sakia/gui/main_window/status_bar/view.py
index 14ade070b7cb5a7ecbf5bee5081d3235fe8d433f..ef8721b4fbf08fd1136409310ad02aa80333dd6d 100644
--- a/src/sakia/gui/main_window/status_bar/view.py
+++ b/src/sakia/gui/main_window/status_bar/view.py
@@ -1,6 +1,7 @@
 from PyQt5.QtWidgets import QStatusBar
-from PyQt5.QtWidgets import QLabel, QComboBox
-from PyQt5.QtCore import Qt
+from PyQt5.QtWidgets import QLabel, QComboBox, QSpacerItem, QSizePolicy
+from PyQt5.QtGui import QMovie
+from PyQt5.QtCore import Qt, QSize
 
 
 class StatusBarView(QStatusBar):
@@ -10,7 +11,6 @@ class StatusBarView(QStatusBar):
 
     def __init__(self, parent):
         super().__init__(parent)
-        self.label_icon = QLabel("", parent)
 
         self.status_label = QLabel("", parent)
         self.status_label.setTextFormat(Qt.RichText)
@@ -18,8 +18,20 @@ class StatusBarView(QStatusBar):
         self.label_time = QLabel("", parent)
 
         self.combo_referential = QComboBox(parent)
-
-        self.addPermanentWidget(self.label_icon, 1)
+        self.movie_loader = QMovie(":/icons/loader")
+        self.label_loading = QLabel(parent)
+        self.label_loading.setMovie(self.movie_loader)
+        self.label_loading.setMaximumHeight(self.height())
+        self.movie_loader.setScaledSize(QSize(16, 16))
+        self.movie_loader.start()
+        self.movie_loader.setPaused(True)
+        self.addPermanentWidget(self.label_loading)
         self.addPermanentWidget(self.status_label, 2)
         self.addPermanentWidget(self.label_time)
         self.addPermanentWidget(self.combo_referential)
+
+    def start_loading(self):
+        self.movie_loader.setPaused(False)
+
+    def stop_loading(self):
+        self.movie_loader.setPaused(True)
diff --git a/src/sakia/gui/main_window/toolbar/about_money.ui b/src/sakia/gui/main_window/toolbar/about_money.ui
new file mode 100644
index 0000000000000000000000000000000000000000..d4e6cc90d7c056b5da8e6027d065960baeade415
--- /dev/null
+++ b/src/sakia/gui/main_window/toolbar/about_money.ui
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AboutMoney</class>
+ <widget class="QWidget" name="AboutMoney">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>509</width>
+    <height>406</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QGroupBox" name="group_general">
+     <property name="styleSheet">
+      <string notr="true"/>
+     </property>
+     <property name="title">
+      <string>General</string>
+     </property>
+     <property name="flat">
+      <bool>false</bool>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_2">
+      <item>
+       <widget class="QLabel" name="label_general">
+        <property name="text">
+         <string/>
+        </property>
+        <property name="scaledContents">
+         <bool>false</bool>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="group_rules">
+     <property name="title">
+      <string>Rules</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_6">
+      <item>
+       <widget class="QLabel" name="label_rules">
+        <property name="text">
+         <string/>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="group_money">
+     <property name="title">
+      <string>Money</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_3">
+      <item>
+       <widget class="QLabel" name="label_money">
+        <property name="text">
+         <string/>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/sakia/gui/main_window/toolbar/about_wot.ui b/src/sakia/gui/main_window/toolbar/about_wot.ui
new file mode 100644
index 0000000000000000000000000000000000000000..24e061aee9f17e0dd7b0ba039e3382b103cc58ae
--- /dev/null
+++ b/src/sakia/gui/main_window/toolbar/about_wot.ui
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AboutWot</class>
+ <widget class="QWidget" name="AboutWot">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>509</width>
+    <height>406</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QGroupBox" name="group_wot">
+     <property name="title">
+      <string>WoT</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_4">
+      <item>
+       <widget class="QLabel" name="label_wot">
+        <property name="text">
+         <string/>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/sakia/gui/main_window/toolbar/controller.py b/src/sakia/gui/main_window/toolbar/controller.py
index 5cb8a8f6b38661284851c1660a84fcedd0849347..6ed122225fba8ad6c63ff68e735b689656f87cdb 100644
--- a/src/sakia/gui/main_window/toolbar/controller.py
+++ b/src/sakia/gui/main_window/toolbar/controller.py
@@ -1,14 +1,13 @@
-from PyQt5.QtCore import QObject
+from PyQt5.QtCore import QObject, pyqtSignal
 from PyQt5.QtWidgets import QDialog
-from sakia.gui.dialogs.certification.controller import CertificationController
 from sakia.gui.dialogs.connection_cfg.controller import ConnectionConfigController
 from sakia.gui.dialogs.revocation.controller import RevocationController
-from sakia.gui.dialogs.transfer.controller import TransferController
 from sakia.gui.dialogs.contact.controller import ContactController
 from sakia.gui.dialogs.plugins_manager.controller import PluginsManagerController
 from sakia.gui.preferences import PreferencesDialog
 from .model import ToolbarModel
 from .view import ToolbarView
+from sakia.data.processors import BlockchainProcessor
 import sys
 
 
@@ -17,6 +16,8 @@ class ToolbarController(QObject):
     The navigation panel
     """
 
+    exit_triggered = pyqtSignal()
+
     def __init__(self, view, model):
         """
         :param sakia.gui.component.controller.ComponentController parent: the parent
@@ -26,14 +27,16 @@ class ToolbarController(QObject):
         super().__init__()
         self.view = view
         self.model = model
-        self.view.button_certification.clicked.connect(self.open_certification_dialog)
-        self.view.button_send_money.clicked.connect(self.open_transfer_money_dialog)
         self.view.action_add_connection.triggered.connect(self.open_add_connection_dialog)
         self.view.action_parameters.triggered.connect(self.open_settings_dialog)
         self.view.action_plugins.triggered.connect(self.open_plugins_manager_dialog)
         self.view.action_about.triggered.connect(self.open_about_dialog)
+        self.view.action_about_wot.triggered.connect(self.open_about_wot_dialog)
+        self.view.action_about_money.triggered.connect(self.open_about_money_dialog)
+        self.view.action_about_referentials.triggered.connect(self.open_about_referentials_dialog)
         self.view.action_revoke_uid.triggered.connect(self.open_revocation_dialog)
         self.view.button_contacts.clicked.connect(self.open_contacts_dialog)
+        self.view.action_exit.triggered.connect(self.exit_triggered)
 
     @classmethod
     def create(cls, app, navigation):
@@ -45,27 +48,16 @@ class ToolbarController(QObject):
         :rtype: NavigationController
         """
         view = ToolbarView(None)
-        model = ToolbarModel(app, navigation.model)
+        model = ToolbarModel(app, navigation.model, app.blockchain_service, BlockchainProcessor.instanciate(app))
         toolbar = cls(view, model)
         return toolbar
 
-    def enable_actions(self, enabled):
-        self.view.button_certification.setEnabled(enabled)
-        self.view.button_send_money.setEnabled(enabled)
-
-    def open_certification_dialog(self):
-        CertificationController.open_dialog(self, self.model.app,
-                                            self.model.navigation_model.current_connection())
-
     def open_contacts_dialog(self):
         ContactController.open_dialog(self, self.model.app)
 
     def open_revocation_dialog(self):
         RevocationController.open_dialog(self, self.model.app, self.model.navigation_model.current_connection())
 
-    def open_transfer_money_dialog(self):
-        TransferController.open_dialog(self, self.model.app, self.model.navigation_model.current_connection())
-
     def open_settings_dialog(self):
         PreferencesDialog(self.model.app).exec()
 
@@ -79,12 +71,26 @@ class ToolbarController(QObject):
             self.model.app.instanciate_services()
             self.model.app.start_coroutines()
             self.model.app.new_connection.emit(connection_config.model.connection)
-            self.enable_actions(True)
 
     def open_about_dialog(self):
         text = self.model.about_text()
         self.view.show_about(text)
 
+    def open_about_wot_dialog(self):
+        params = self.model.parameters()
+        self.view.show_about_wot(params)
+
+    def open_about_money_dialog(self):
+        params = self.model.parameters()
+        currency = self.model.app.currency
+        localized_data = self.model.get_localized_data()
+        referentials = self.model.referentials()
+        self.view.show_about_money(params, currency, localized_data)
+
+    def open_about_referentials_dialog(self):
+        referentials = self.model.referentials()
+        self.view.show_about_referentials(referentials)
+
     def retranslateUi(self, widget):
         """
         Method to complete translations missing from generated code
diff --git a/src/sakia/gui/main_window/toolbar/model.py b/src/sakia/gui/main_window/toolbar/model.py
index 5e312cdb4227b8142e8fd639ffa0f28fd8e7852f..ffa438ef972444024dd172ee147f648747ce63b7 100644
--- a/src/sakia/gui/main_window/toolbar/model.py
+++ b/src/sakia/gui/main_window/toolbar/model.py
@@ -1,7 +1,11 @@
-from PyQt5.QtCore import QObject
+from PyQt5.QtCore import QObject, QLocale, QDateTime
 from sakia.data.processors import ConnectionsProcessor
 import attr
+import math
 from sakia import __version__
+from sakia.constants import ROOT_SERVERS
+from duniterpy.api import errors
+from sakia.money import Referentials
 
 
 @attr.s()
@@ -15,13 +19,12 @@ class ToolbarModel(QObject):
 
     app = attr.ib()
     navigation_model = attr.ib()
+    blockchain_service = attr.ib()
+    blockchain_processor = attr.ib()
 
     def __attrs_post_init__(self):
         super().__init__()
 
-    async def send_join(self, connection, secret_key, password):
-        return await self.app.documents_service.send_membership(connection, secret_key, password, "IN")
-
     def notifications(self):
         return self.app.parameters.notifications
 
@@ -62,4 +65,110 @@ class ToolbarModel(QObject):
         <p>canercandan</p>
         <p>Moul</p>
         """.format(__version__,
-                   new_version_text=new_version_text)
\ No newline at end of file
+                   new_version_text=new_version_text)
+
+    def get_localized_data(self):
+        localized_data = {}
+        #  try to request money parameters
+        params = self.blockchain_service.parameters()
+
+        localized_data['currency'] = ROOT_SERVERS[self.app.currency]["display"]
+        localized_data['growth'] = params.c
+        localized_data['days_per_dividend'] = QLocale().toString(params.dt / 86400, 'f', 2)
+
+        last_ud, last_ud_base = self.blockchain_service.last_ud()
+        members_count = self.blockchain_service.last_members_count()
+        previous_ud, previous_ud_base = self.blockchain_service.previous_ud()
+        previous_ud_time = self.blockchain_service.previous_ud_time()
+        previous_monetary_mass = self.blockchain_service.previous_monetary_mass()
+        previous_members_count = self.blockchain_service.previous_members_count()
+
+        localized_data['units'] = self.app.current_ref.instance(0,
+                                                                self.app.currency,
+                                                                self.app, None).units
+        localized_data['diff_units'] = self.app.current_ref.instance(0,
+                                                                     self.app.currency,
+                                                                     self.app, None).diff_units
+
+        if last_ud:
+            # display float values
+            localized_data['ud'] = self.app.current_ref.instance(last_ud * math.pow(10, last_ud_base),
+                                              self.app.currency,
+                                              self.app).diff_localized(False, True)
+
+            localized_data['members_count'] = self.blockchain_service.current_members_count()
+
+            computed_dividend = self.blockchain_service.computed_dividend()
+            # display float values
+            localized_data['ud_plus_1'] = self.app.current_ref.instance(computed_dividend,
+                                              self.app.currency, self.app).diff_localized(False, True)
+
+            localized_data['mass'] = self.app.current_ref.instance(self.blockchain_service.current_mass(),
+                                              self.app.currency, self.app).localized(False, True)
+
+            ud_median_time = self.blockchain_service.last_ud_time()
+            ud_median_time = self.blockchain_processor.adjusted_ts(self.app.currency, ud_median_time)
+
+            localized_data['ud_median_time'] = QLocale.toString(
+                QLocale(),
+                QDateTime.fromTime_t(ud_median_time),
+                QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
+            )
+
+            next_ud_median_time = self.blockchain_service.last_ud_time() + params.dt
+            next_ud_median_time = self.blockchain_processor.adjusted_ts(self.app.currency, next_ud_median_time)
+
+            localized_data['next_ud_median_time'] = QLocale.toString(
+                QLocale(),
+                QDateTime.fromTime_t(next_ud_median_time),
+                QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
+            )
+
+            next_ud_reeval = self.blockchain_service.next_ud_reeval()
+            next_ud_reeval = self.blockchain_processor.adjusted_ts(self.app.currency, next_ud_reeval)
+            localized_data['next_ud_reeval'] = QLocale.toString(
+                QLocale(),
+                QDateTime.fromTime_t(next_ud_reeval),
+                QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
+            )
+
+            if previous_ud:
+                mass_minus_1_per_member = (float(0) if previous_ud == 0 or previous_members_count == 0 else
+                                           previous_monetary_mass / previous_members_count)
+                localized_data['mass_minus_1_per_member'] = self.app.current_ref.instance(mass_minus_1_per_member,
+                                                  self.app.currency, self.app) \
+                                                  .localized(False, True)
+                localized_data['mass_minus_1'] = self.app.current_ref.instance(previous_monetary_mass,
+                                                  self.app.currency, self.app) \
+                                                  .localized(False, True)
+                # avoid divide by zero !
+                if members_count == 0 or previous_members_count == 0:
+                    localized_data['actual_growth'] = float(0)
+                else:
+                    localized_data['actual_growth'] = (last_ud * math.pow(10, last_ud_base)) / (
+                    previous_monetary_mass / members_count)
+
+                previous_ud_time = self.blockchain_processor.adjusted_ts(self.app.currency, previous_ud_time)
+                localized_data['ud_median_time_minus_1'] = QLocale.toString(
+                    QLocale(),
+                    QDateTime.fromTime_t(previous_ud_time),
+                    QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
+                )
+        return localized_data
+
+    def parameters(self):
+        """
+        Get community parameters
+        """
+        return self.blockchain_service.parameters()
+
+    def referentials(self):
+        """
+        Get referentials
+        :return: The list of instances of all referentials
+        :rtype: list
+        """
+        refs_instances = []
+        for ref_class in Referentials:
+             refs_instances.append(ref_class(0, self.app.currency, self.app, None))
+        return refs_instances
\ No newline at end of file
diff --git a/src/sakia/gui/main_window/toolbar/toolbar.ui b/src/sakia/gui/main_window/toolbar/toolbar.ui
index d202ca7c07d74a760ed6b1678cce917341c12be4..330986d4df5ca7caa96165a8001a141f1ffd0e6a 100644
--- a/src/sakia/gui/main_window/toolbar/toolbar.ui
+++ b/src/sakia/gui/main_window/toolbar/toolbar.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>4095</width>
-    <height>4000</height>
+    <width>1000</width>
+    <height>237</height>
    </rect>
   </property>
   <property name="sizePolicy">
@@ -16,6 +16,12 @@
     <verstretch>0</verstretch>
    </sizepolicy>
   </property>
+  <property name="maximumSize">
+   <size>
+    <width>1000</width>
+    <height>16777215</height>
+   </size>
+  </property>
   <property name="windowTitle">
    <string>Frame</string>
   </property>
@@ -27,13 +33,30 @@
   </property>
   <layout class="QHBoxLayout" name="horizontalLayout">
    <item>
-    <widget class="QPushButton" name="button_send_money">
+    <widget class="QPushButton" name="button_network">
+     <property name="text">
+      <string>Network</string>
+     </property>
+     <property name="icon">
+      <iconset resource="../../../../../res/icons/icons.qrc">
+       <normaloff>:/icons/wot_icon</normaloff>:/icons/wot_icon</iconset>
+     </property>
+     <property name="iconSize">
+      <size>
+       <width>32</width>
+       <height>32</height>
+      </size>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QPushButton" name="button_identity">
      <property name="text">
-      <string>Send money</string>
+      <string>Search an identity</string>
      </property>
      <property name="icon">
       <iconset resource="../../../../../res/icons/icons.qrc">
-       <normaloff>:/icons/payment_icon</normaloff>:/icons/payment_icon</iconset>
+       <normaloff>:/icons/explorer_icon</normaloff>:/icons/explorer_icon</iconset>
      </property>
      <property name="iconSize">
       <size>
@@ -44,13 +67,13 @@
     </widget>
    </item>
    <item>
-    <widget class="QPushButton" name="button_certification">
+    <widget class="QPushButton" name="button_explore">
      <property name="text">
-      <string>Certification</string>
+      <string>Explore</string>
      </property>
      <property name="icon">
       <iconset resource="../../../../../res/icons/icons.qrc">
-       <normaloff>:/icons/certification_icon</normaloff>:/icons/certification_icon</iconset>
+       <normaloff>:/icons/add_community</normaloff>:/icons/add_community</iconset>
      </property>
      <property name="iconSize">
       <size>
@@ -67,7 +90,7 @@
      </property>
      <property name="sizeHint" stdset="0">
       <size>
-       <width>999999999</width>
+       <width>200</width>
        <height>221</height>
       </size>
      </property>
diff --git a/src/sakia/gui/main_window/toolbar/view.py b/src/sakia/gui/main_window/toolbar/view.py
index df886770090fa6fdc02232e79a1790560b570365..361d514cacd6e889ceb86a32bab094140d7886f7 100644
--- a/src/sakia/gui/main_window/toolbar/view.py
+++ b/src/sakia/gui/main_window/toolbar/view.py
@@ -1,8 +1,12 @@
-from PyQt5.QtWidgets import QFrame, QAction, QMenu, QSizePolicy, QInputDialog, QDialog
+from PyQt5.QtWidgets import QFrame, QAction, QMenu, QSizePolicy, QInputDialog, QDialog, \
+    QVBoxLayout, QTabWidget, QWidget, QLabel
 from sakia.gui.widgets.dialogs import dialog_async_exec
-from PyQt5.QtCore import QObject, QT_TRANSLATE_NOOP, Qt
+from PyQt5.QtCore import QObject, QT_TRANSLATE_NOOP, Qt, QLocale
 from .toolbar_uic import Ui_SakiaToolbar
 from .about_uic import Ui_AboutPopup
+from .about_money_uic import Ui_AboutMoney
+from .about_wot_uic import Ui_AboutWot
+from sakia.helpers import timestamp_to_dhms, dpi_ratio
 
 
 class ToolbarView(QFrame, Ui_SakiaToolbar):
@@ -30,11 +34,38 @@ class ToolbarView(QFrame, Ui_SakiaToolbar):
         self.action_plugins = QAction(self.tr("Plugins manager"), tool_menu)
         tool_menu.addAction(self.action_plugins)
 
-        self.action_about = QAction(self.tr("About"), tool_menu)
-        tool_menu.addAction(self.action_about)
+        tool_menu.addSeparator()
+
+        about_menu = QMenu(self.tr("About"), tool_menu)
+        tool_menu.addMenu(about_menu)
+
+        self.action_about_money = QAction(self.tr("About Money"), about_menu)
+        about_menu.addAction(self.action_about_money)
+
+        self.action_about_referentials = QAction(self.tr("About Referentials"), about_menu)
+        about_menu.addAction(self.action_about_referentials)
+
+        self.action_about_wot = QAction(self.tr("About Web of Trust"), about_menu)
+        about_menu.addAction(self.action_about_wot)
+
+        self.action_about = QAction(self.tr("About Sakia"), about_menu)
+        about_menu.addAction(self.action_about)
+
+        self.action_exit = QAction(self.tr("Exit"), tool_menu)
+        tool_menu.addAction(self.action_exit)
 
         self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Minimum)
         self.setMaximumHeight(60)
+        self.button_network.setIconSize(self.button_network.iconSize()*dpi_ratio())
+        self.button_contacts.setIconSize(self.button_contacts.iconSize()*dpi_ratio())
+        self.button_identity.setIconSize(self.button_identity.iconSize()*dpi_ratio())
+        self.button_explore.setIconSize(self.button_explore.iconSize()*dpi_ratio())
+        self.toolbutton_menu.setIconSize(self.toolbutton_menu.iconSize()*dpi_ratio())
+        self.button_network.setFixedHeight(self.button_network.height()*dpi_ratio()+5*dpi_ratio())
+        self.button_contacts.setFixedHeight(self.button_contacts.height()*dpi_ratio()+5*dpi_ratio())
+        self.button_identity.setFixedHeight(self.button_identity.height()*dpi_ratio()+5*dpi_ratio())
+        self.button_explore.setFixedHeight(self.button_explore.height()*dpi_ratio()+5*dpi_ratio())
+        self.toolbutton_menu.setFixedHeight(self.toolbutton_menu.height()*dpi_ratio()+5*dpi_ratio())
 
     async def ask_for_connection(self, connections):
         connections_titles = [c.title() for c in connections]
@@ -50,6 +81,216 @@ class ToolbarView(QFrame, Ui_SakiaToolbar):
                 if c.title() == result:
                     return c
 
+    def show_about_wot(self, params):
+        """
+        Set wot text from currency parameters
+        :param sakia.data.entities.BlockchainParameters params: Parameters of the currency
+        :return:
+        """
+        dialog = QDialog(self)
+        about_dialog = Ui_AboutWot()
+        about_dialog.setupUi(dialog)
+
+        # set infos in label
+        about_dialog.label_wot.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>
+<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>
+<tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
+<tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
+</table>
+""").format(
+                QLocale().toString(params.sig_period / 86400, 'f', 2),
+                self.tr('Minimum delay between 2 certifications (in days)'),
+                QLocale().toString(params.sig_validity / 86400, 'f', 2),
+                self.tr('Maximum age of a valid signature (in days)'),
+                params.sig_qty,
+                self.tr('Minimum quantity of signatures to be part of the WoT'),
+                params.sig_stock,
+                self.tr('Maximum quantity of active certifications made by member.'),
+                params.sig_window,
+                self.tr('Maximum delay a certification can wait before being expired for non-writing.'),
+                params.xpercent,
+                self.tr('Minimum percent of sentries to reach to match the distance rule'),
+                params.ms_validity / 86400,
+                self.tr('Maximum age of a valid membership (in days)'),
+                params.step_max,
+                self.tr('Maximum distance between each WoT member and a newcomer'),
+            )
+        )
+        dialog.setWindowTitle(self.tr("Web of Trust rules"))
+        dialog.exec()
+
+    def show_about_money(self, params, currency, localized_data):
+        dialog = QDialog(self)
+        about_dialog = Ui_AboutMoney()
+        about_dialog.setupUi(dialog)
+        about_dialog.label_general.setText(self.general_text(localized_data))
+        about_dialog.label_rules.setText(self.rules_text(localized_data))
+        about_dialog.label_money.setText(self.money_text(params, currency))
+        dialog.setWindowTitle(self.tr("Money rules"))
+        dialog.exec()
+
+    def show_about_referentials(self, referentials):
+        dialog = QDialog(self)
+        layout = QVBoxLayout(dialog)
+        tabwidget = QTabWidget(dialog)
+        layout.addWidget(tabwidget)
+        for ref in referentials:
+            widget = QWidget()
+            layout = QVBoxLayout(widget)
+            label = QLabel()
+            label.setText(self.text_referential(ref))
+            layout.addWidget(label)
+            tabwidget.addTab(widget, ref.translated_name())
+        dialog.setWindowTitle(self.tr("Referentials"))
+        dialog.exec()
+
+    def general_text(self, localized_data):
+        """
+        Fill the general text with given informations
+        :return:
+        """
+        # set infos in label
+        return self.tr("""
+            <table cellpadding="5">
+            <tr><td align="right"><b>{:}</b></div></td><td>{:} {:}</td></tr>
+            <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>
+            <tr><td align="right"><b>{:2.2%} / {:} days</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>
+            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
+            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
+            </table>
+            """).format(
+                localized_data.get('ud', '####'),
+                self.tr('Universal Dividend UD(t) in'),
+                localized_data['diff_units'],
+                localized_data.get('mass_minus_1', "###"),
+                self.tr('Monetary Mass M(t-1) in'),
+                localized_data['units'],
+                localized_data.get('members_count', '####'),
+                self.tr('Members N(t)'),
+                localized_data.get('mass_minus_1_per_member', '####'),
+                self.tr('Monetary Mass per member M(t-1)/N(t) in'),
+                localized_data['diff_units'],
+                localized_data.get('actual_growth', 0),
+                localized_data.get('days_per_dividend', '####'),
+                self.tr('Actual growth c = UD(t)/[M(t-1)/N(t)]'),
+                localized_data.get('ud_median_time_minus_1', '####'),
+                self.tr('Penultimate UD date and time (t-1)'),
+                localized_data.get('ud_median_time', '####') + " BAT",
+                self.tr('Last UD date and time (t)'),
+                localized_data.get('next_ud_median_time', '####') + " BAT",
+                self.tr('Next UD date and time (t+1)'),
+                localized_data.get('next_ud_reeaval', '####') + " BAT",
+                self.tr('Next UD reevaluation (t+1)')
+            )
+
+    def rules_text(self, localized_data):
+        """
+        Set text in rules
+        :param dict localized_data:
+        :return:
+        """
+        # set infos in label
+        return 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.tr('{:2.0%} / {:} days').format(localized_data['growth'], localized_data['days_per_dividend']),
+                self.tr('Fundamental growth (c) / Delta time (dt)'),
+                self.tr('UDĞ(t) = UDĞ(t-1) + c²*M(t-1)/N(t-1)'),
+                self.tr('Universal Dividend (formula)'),
+                self.tr('{:} = {:} + {:2.0%}²* {:} / {:}').format(
+                    localized_data.get('ud_plus_1', '####'),
+                    localized_data.get('ud', '####'),
+                    localized_data.get('growth', '####'),
+                    localized_data.get('mass', '####'),
+                    localized_data.get('members_count', '####')
+                ),
+                self.tr('Universal Dividend (computed)')
+            )
+
+    def text_referential(self, ref):
+        """
+        Set text from referentials
+        """
+        # set infos in label
+        ref_template = """
+                <table cellpadding="5">
+                <tr><th>{:}</th><td>{:}</td></tr>
+                <tr><th>{:}</th><td>{:}</td></tr>
+                <tr><th>{:}</th><td>{:}</td></tr>
+                <tr><th>{:}</th><td>{:}</td></tr>
+                </table>
+                """
+        return ref_template.format(self.tr('Name'), ref.translated_name(),
+                                                 self.tr('Units'), ref.units,
+                                                 self.tr('Formula'), ref.formula,
+                                                 self.tr('Description'), ref.description
+                                                 )
+
+    def money_text(self, params, currency):
+        """
+        Set text from money parameters
+        :param sakia.data.entities.BlockchainParameters params: Parameters of the currency
+        :param str currency: The currency
+        """
+
+        dt_dhms = timestamp_to_dhms(params.dt)
+        if dt_dhms[0] > 0:
+            dt_as_str = self.tr("{:} day(s) {:} hour(s)").format(*dt_dhms)
+        else:
+            dt_as_str = self.tr("{:} hour(s)").format(dt_dhms[1])
+        if dt_dhms[2] > 0 or dt_dhms[3] > 0:
+            dt_dhms += ", {:} minute(s) and {:} second(s)".format(*dt_dhms[1:])
+        dt_reeval_dhms = timestamp_to_dhms(params.dt_reeval)
+        dt_reeval_as_str = self.tr("{:} day(s) {:} hour(s)").format(*dt_reeval_dhms)
+
+        # set infos in label
+        return self.tr("""
+            <table cellpadding="5">
+            <tr><td align="right"><b>{:2.0%} / {:} days</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>
+            <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>
+            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
+            <tr><td align="right"><b>{:2.0%}</b></td><td>{:}</td></tr>
+            </table>
+            """).format(
+                params.c,
+                QLocale().toString(params.dt / 86400, 'f', 2),
+                self.tr('Fundamental growth (c)'),
+                params.ud0,
+                self.tr('Initial Universal Dividend UD(0) in'),
+                currency,
+                dt_as_str,
+                self.tr('Time period between two UD'),
+                dt_reeval_as_str,
+                self.tr('Time period between two UD reevaluation'),
+                params.median_time_blocks,
+                self.tr('Number of blocks used for calculating median time'),
+                params.avg_gen_time,
+                self.tr('The average time in seconds for writing 1 block (wished time)'),
+                params.dt_diff_eval,
+                self.tr('The number of blocks required to evaluate again PoWMin value'),
+                params.percent_rot,
+                self.tr('The percent of previous issuers to reach for personalized difficulty')
+            )
+
     def show_about(self, text):
         dialog = QDialog(self)
         about_dialog = Ui_AboutPopup()
diff --git a/src/sakia/gui/navigation/controller.py b/src/sakia/gui/navigation/controller.py
index 0a91640ca5ac711765c64da82e14b4a5e0807590..e36fc549fcbdbe402a7d07e98a2abdc4996eab2c 100644
--- a/src/sakia/gui/navigation/controller.py
+++ b/src/sakia/gui/navigation/controller.py
@@ -12,7 +12,7 @@ from sakia.models.generic_tree import GenericTreeModel
 from .graphs.wot.controller import WotController
 from .homescreen.controller import HomeScreenController
 from .identities.controller import IdentitiesController
-from .informations.controller import InformationsController
+from .identity.controller import IdentityController
 from .model import NavigationModel
 from .network.controller import NetworkController
 from .txhistory.controller import TxHistoryController
@@ -41,7 +41,7 @@ class NavigationController(QObject):
             'HomeScreen': HomeScreenController,
             'Network': NetworkController,
             'Identities': IdentitiesController,
-            'Informations': InformationsController,
+            'Informations': IdentityController,
             'Wot': WotController
         }
         self.view.current_view_changed.connect(self.handle_view_change)
@@ -63,11 +63,29 @@ class NavigationController(QObject):
         model.setParent(navigation)
         navigation.init_navigation()
         app.new_connection.connect(navigation.add_connection)
-        app.view_in_wot.connect(navigation.view_in_wot)
+        app.view_in_wot.connect(navigation.open_wot_view)
         return navigation
 
-    def view_in_wot(self, connection, _):
-        raw_data = self.model.get_raw_data('Wot', connection=connection)
+    def open_network_view(self, _):
+        raw_data = self.model.get_raw_data('Network')
+        if raw_data:
+            widget = raw_data['widget']
+            if self.view.stacked_widget.indexOf(widget) != -1:
+                self.view.stacked_widget.setCurrentWidget(widget)
+                self.view.current_view_changed.emit(raw_data)
+                return
+
+    def open_wot_view(self, _):
+        raw_data = self.model.get_raw_data('Wot')
+        if raw_data:
+            widget = raw_data['widget']
+            if self.view.stacked_widget.indexOf(widget) != -1:
+                self.view.stacked_widget.setCurrentWidget(widget)
+                self.view.current_view_changed.emit(raw_data)
+                return
+
+    def open_identities_view(self, _):
+        raw_data = self.model.get_raw_data('Identities')
         if raw_data:
             widget = raw_data['widget']
             if self.view.stacked_widget.indexOf(widget) != -1:
@@ -117,9 +135,14 @@ class NavigationController(QObject):
         mapped = self.view.splitter.mapFromParent(point)
         index = self.view.tree_view.indexAt(mapped)
         raw_data = self.view.tree_view.model().data(index, GenericTreeModel.ROLE_RAW_DATA)
-        if raw_data and raw_data["component"] == "Informations":
+        if raw_data:
             menu = QMenu(self.view)
             if raw_data['misc']['connection'].uid:
+                action_view_in_wot = QAction(self.tr("View in Web of Trust"), menu)
+                menu.addAction(action_view_in_wot)
+                action_view_in_wot.triggered.connect(lambda c:
+                                                        self.model.view_in_wot(raw_data['misc']['connection']))
+
                 action_gen_revokation = QAction(self.tr("Save revokation document"), menu)
                 menu.addAction(action_gen_revokation)
                 action_gen_revokation.triggered.connect(lambda c:
@@ -157,7 +180,8 @@ class NavigationController(QObject):
 
     @asyncify
     async def publish_uid(self, connection):
-        identity, identity_doc = self.model.generate_identity(connection)
+        identity = self.model.generate_identity(connection)
+        identity_doc = identity.document()
         if not identity_doc.signatures[0]:
             secret_key, password = await PasswordInputController.open_dialog(self, connection)
             if not password or not secret_key:
@@ -169,13 +193,13 @@ class NavigationController(QObject):
 
         result = await self.model.send_identity(connection, identity_doc)
         if result[0]:
-            if self.app.preferences['notifications']:
+            if self.model.notifications():
                 toast.display(self.tr("UID"), self.tr("Success publishing your UID"))
             else:
                 await QAsyncMessageBox.information(self.view, self.tr("UID"),
                                                         self.tr("Success publishing your UID"))
         else:
-            if self.app.preferences['notifications']:
+            if not self.model.notifications():
                 toast.display(self.tr("UID"), result[1])
             else:
                 await QAsyncMessageBox.critical(self.view, self.tr("UID"),
@@ -222,7 +246,7 @@ neither your identity from the network."""), QMessageBox.Ok | QMessageBox.Cancel
         if not password or not secret_key:
             return
 
-        raw_document = self.model.generate_revokation(connection, secret_key, password)
+        raw_document, _ = self.model.generate_revocation(connection, secret_key, password)
         # Testable way of using a QFileDialog
         selected_files = await QAsyncFileDialog.get_save_filename(self.view, self.tr("Save a revokation document"),
                                                                   "", self.tr("All text files (*.txt)"))
@@ -242,7 +266,8 @@ The publication of this document will remove your identity from the network.</p>
 
     @asyncify
     async def export_identity_document(self, connection):
-        identity, identity_doc = self.model.generate_identity(connection)
+        identity = self.model.generate_identity(connection)
+        identity_doc = identity.document()
         if not identity_doc.signatures[0]:
             secret_key, password = await PasswordInputController.open_dialog(self, connection)
             if not password or not secret_key:
diff --git a/src/sakia/gui/navigation/graphs/base/controller.py b/src/sakia/gui/navigation/graphs/base/controller.py
index e1af19acbd1f9485bd71ac5a975fb3a8d638bfc0..7c3c818623a8395347f4fb61d3a780f519286135 100644
--- a/src/sakia/gui/navigation/graphs/base/controller.py
+++ b/src/sakia/gui/navigation/graphs/base/controller.py
@@ -67,7 +67,7 @@ class BaseGraphController(QObject):
         Open the node context menu
         :param sakia.data.entities.Identity identity: the identity of the node to open
         """
-        menu = ContextMenu.from_data(self.view, self.model.app, self.model.connection, (identity,))
+        menu = ContextMenu.from_data(self.view, self.model.app, None, (identity,))
         menu.view_identity_in_wot.connect(self.draw_graph)
 
         # Show the context menu.
diff --git a/src/sakia/gui/navigation/graphs/base/model.py b/src/sakia/gui/navigation/graphs/base/model.py
index 12771e47fd8bdae35bc5b993a4a66d0638f699b8..fbc41f13c765788c7cdc1856111fcf831604de62 100644
--- a/src/sakia/gui/navigation/graphs/base/model.py
+++ b/src/sakia/gui/navigation/graphs/base/model.py
@@ -5,19 +5,17 @@ class BaseGraphModel(QObject):
     The model of Navigation component
     """
 
-    def __init__(self, parent, app, connection, blockchain_service, identities_service):
+    def __init__(self, parent, app, 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.connection = connection
         self.blockchain_service = blockchain_service
         self.identities_service = identities_service
 
@@ -27,4 +25,4 @@ class BaseGraphModel(QObject):
         :param str pubkey: Identity pubkey
         :rtype: sakia.core.registry.Identity
         """
-        return self.identities_service.get_identity(pubkey, self.connection.currency)
+        return self.identities_service.get_identity(pubkey, self.app.currency)
diff --git a/src/sakia/gui/navigation/graphs/wot/controller.py b/src/sakia/gui/navigation/graphs/wot/controller.py
index 5053bc569e3f1b91156b053f88b4e9d8f503d6d0..362f8f38915cd15af60968d3a92a8b803bdd9e4e 100644
--- a/src/sakia/gui/navigation/graphs/wot/controller.py
+++ b/src/sakia/gui/navigation/graphs/wot/controller.py
@@ -24,7 +24,7 @@ class WotController(BaseGraphController):
         self.reset()
 
     @classmethod
-    def create(cls, parent, app, connection, blockchain_service, identities_service):
+    def create(cls, parent, app, blockchain_service, identities_service):
         """
         :param sakia.app.Application app:
         :param sakia.data.entities.Connection connection:
@@ -33,11 +33,11 @@ class WotController(BaseGraphController):
         :return:
         """
         view = WotView(parent.view)
-        model = WotModel(None, app, connection, blockchain_service, identities_service)
+        model = WotModel(None, app, blockchain_service, identities_service)
         wot = cls(parent, view, model)
         model.setParent(wot)
         app.identity_changed.connect(wot.handle_identity_change)
-        app.view_in_wot.connect(lambda c, i: wot.center_on_identity(i) if c == connection else None)
+        app.view_in_wot.connect(wot.center_on_identity)
         return wot
 
     def center_on_identity(self, identity):
diff --git a/src/sakia/gui/navigation/graphs/wot/model.py b/src/sakia/gui/navigation/graphs/wot/model.py
index 3a5f789e03d99dafdba272f7a6b613e6bca42883..92e567c12c6d8be1286705140501e5d87ad4ac49 100644
--- a/src/sakia/gui/navigation/graphs/wot/model.py
+++ b/src/sakia/gui/navigation/graphs/wot/model.py
@@ -1,5 +1,6 @@
 from sakia.data.graphs import WoTGraph
 from ..base.model import BaseGraphModel
+from sakia.data.processors import ConnectionsProcessor
 
 
 class WotModel(BaseGraphModel):
@@ -7,19 +8,18 @@ class WotModel(BaseGraphModel):
     The model of Navigation component
     """
 
-    def __init__(self, parent, app, connection, blockchain_service, identities_service):
+    def __init__(self, parent, app, 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)
+        super().__init__(parent, app, blockchain_service, identities_service)
         self.app = app
-        self.connection = connection
+        self._connections_processor = ConnectionsProcessor.instanciate(self.app)
         self.blockchain_service = blockchain_service
         self.identities_service = identities_service
         self.wot_graph = WoTGraph(self.app, self.blockchain_service, self.identities_service)
@@ -32,21 +32,28 @@ class WotModel(BaseGraphModel):
         :param sakia.core.registry.Identity identity: the new identity to show
         :return:
         """
-        connection_identity = self.identities_service.get_identity(self.connection.pubkey)
-        # create empty graph instance
-        if identity:
-            self.identity = identity
-            await self.wot_graph.initialize(self.identity, connection_identity)
+        for pubkey in self._connections_processor.pubkeys():
+            if identity:
+                if identity.pubkey == pubkey:
+                    self.identity = identity
+                    self.wot_graph.offline_init(identity)
+                    break
+            else:
+                connection_identity = self.identities_service.get_identity(pubkey)
+                if connection_identity:
+                    self.identity = connection_identity
+                    self.wot_graph.offline_init(connection_identity)
+                    break
         else:
-            self.identity = connection_identity
             # create empty graph instance
-            self.wot_graph.offline_init(connection_identity, connection_identity)
+            if identity:
+                self.identity = identity
+                await self.wot_graph.initialize(self.identity)
 
     def refresh(self, identity):
-        connection_identity = self.identities_service.get_identity(self.connection.pubkey)
-        if self.identity == connection_identity == identity:
+        if self.identity == identity:
             # create empty graph instance
-            self.wot_graph.offline_init(connection_identity, connection_identity)
+            self.wot_graph.offline_init(identity)
             return True
         return False
 
diff --git a/src/sakia/gui/navigation/graphs/wot/scene.py b/src/sakia/gui/navigation/graphs/wot/scene.py
index d8c67d4597faa3254d86a5b3b810104131627e28..59d672257418c6ff562e77410651cf908fe45f66 100644
--- a/src/sakia/gui/navigation/graphs/wot/scene.py
+++ b/src/sakia/gui/navigation/graphs/wot/scene.py
@@ -4,6 +4,7 @@ from PyQt5.QtWidgets import QGraphicsScene
 
 from .edge import WotEdge
 from .node import WotNode
+from sakia.helpers import dpi_ratio
 
 from ..base.scene import BaseScene
 
@@ -138,30 +139,32 @@ class WotScene(BaseScene):
         :param networkx.MultiDiGraph nx_graph: graph to draw
         :param sakia.core.registry.Identity identity: the wot of the identity
         """
-        #  clear scene
-        self.clear()
-        certifiers_graph_pos = WotScene.certifiers_partial_layout(nx_graph, identity.pubkey, scale=200)
-        certified_graph_pos = WotScene.certified_partial_layout(nx_graph, identity.pubkey, scale=200)
-
-        # create networkx graph
-        for node in nx_graph.nodes(data=True):
-            if node[0] in certifiers_graph_pos:
-                v = WotNode(node, certifiers_graph_pos)
-                self.addItem(v)
-            if node[0] in certified_graph_pos:
-                v = WotNode(node, certified_graph_pos)
-                self.addItem(v)
-
-        for edge in nx_graph.edges(data=True):
-            if edge[0] in certifiers_graph_pos and edge[1] == identity.pubkey:
-                self.addItem(WotEdge(edge[0], edge[1], edge[2], certifiers_graph_pos))
-            if edge[0] == identity.pubkey and edge[1] in certified_graph_pos:
-                self.addItem(WotEdge(edge[0], edge[1], edge[2], certified_graph_pos))
-
-        self.update()
+        if identity:
+            #  clear scene
+            self.clear()
+
+            certifiers_graph_pos = WotScene.certifiers_partial_layout(nx_graph, identity.pubkey, scale=200*dpi_ratio())
+            certified_graph_pos = WotScene.certified_partial_layout(nx_graph, identity.pubkey, scale=200*dpi_ratio())
+
+            # create networkx graph
+            for node in nx_graph.nodes(data=True):
+                if node[0] in certifiers_graph_pos:
+                    v = WotNode(node, certifiers_graph_pos)
+                    self.addItem(v)
+                if node[0] in certified_graph_pos:
+                    v = WotNode(node, certified_graph_pos)
+                    self.addItem(v)
+
+            for edge in nx_graph.edges(data=True):
+                if edge[0] in certifiers_graph_pos and edge[1] == identity.pubkey:
+                    self.addItem(WotEdge(edge[0], edge[1], edge[2], certifiers_graph_pos))
+                if edge[0] == identity.pubkey and edge[1] in certified_graph_pos:
+                    self.addItem(WotEdge(edge[0], edge[1], edge[2], certified_graph_pos))
+
+            self.update()
 
     def update_path(self, nx_graph, path):
-        path_graph_pos = WotScene.path_partial_layout(nx_graph, path, scale=200)
+        path_graph_pos = WotScene.path_partial_layout(nx_graph, path, scale=200*dpi_ratio())
         nodes_path = [n for n in nx_graph.nodes(data=True) if n[0] in path[1:]]
         for node in nodes_path:
             v = WotNode(node, path_graph_pos)
diff --git a/src/sakia/gui/navigation/identities/controller.py b/src/sakia/gui/navigation/identities/controller.py
index 7af12b6cc1fc510decc34788dfc2bf88ee69e39d..f45d05bb82875ace7dd3e016d876f66f71ca798e 100644
--- a/src/sakia/gui/navigation/identities/controller.py
+++ b/src/sakia/gui/navigation/identities/controller.py
@@ -36,19 +36,19 @@ class IdentitiesController(QObject):
         self.view.set_table_identities_model(table_model)
 
     @classmethod
-    def create(cls, parent, app, connection, blockchain_service, identities_service):
+    def create(cls, parent, app, blockchain_service, identities_service):
         view = IdentitiesView(parent.view)
-        model = IdentitiesModel(None, app, connection, blockchain_service, identities_service)
+        model = IdentitiesModel(None, app, blockchain_service, identities_service)
         identities = cls(parent, view, model)
         model.setParent(identities)
-        identities.view_in_wot.connect(lambda i: app.view_in_wot.emit(connection, i))
+        identities.view_in_wot.connect(app.view_in_wot)
         return identities
 
     def identity_context_menu(self, point):
         index = self.view.table_identities.indexAt(point)
         valid, identities = self.model.table_data(index)
         if valid:
-            menu = ContextMenu.from_data(self.view, self.model.app, self.model.connection, (identities,))
+            menu = ContextMenu.from_data(self.view, self.model.app, None, (identities,))
             menu.view_identity_in_wot.connect(self.view_in_wot)
             menu.identity_information_loaded.connect(self.model.table_model.sourceModel().identity_loaded)
 
diff --git a/src/sakia/gui/navigation/identities/model.py b/src/sakia/gui/navigation/identities/model.py
index 8f35b8d8d2b1b2cf4152297d69bc11c8ec0fc6c9..203c768b40006f1be9b7e4e8308eb0d66c6546d5 100644
--- a/src/sakia/gui/navigation/identities/model.py
+++ b/src/sakia/gui/navigation/identities/model.py
@@ -8,19 +8,17 @@ class IdentitiesModel(QObject):
     The model of the identities component
     """
 
-    def __init__(self, parent, app, connection, blockchain_service, identities_service):
+    def __init__(self, parent, app, blockchain_service, identities_service):
         """
         Constructor of a model of Identities 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.connection = connection
         self.blockchain_service = blockchain_service
         self.identities_service = identities_service
 
diff --git a/src/sakia/gui/navigation/identities/table_model.py b/src/sakia/gui/navigation/identities/table_model.py
index de482f274099251c496cccc55dbb0adbbfcd5a96..9aea3a8deef26b609a23474965e4abb2724f7885 100644
--- a/src/sakia/gui/navigation/identities/table_model.py
+++ b/src/sakia/gui/navigation/identities/table_model.py
@@ -63,7 +63,7 @@ class IdentitiesFilterProxyModel(QSortFilterProxyModel):
                             QLocale(),
                             QDateTime.fromTime_t(ts).date(),
                             QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
-                        )
+                        ) + " BAT"
                     else:
                         return ""
                 if source_index.column() == IdentitiesTableModel.columns_ids.index('publication'):
@@ -73,7 +73,7 @@ class IdentitiesFilterProxyModel(QSortFilterProxyModel):
                             QLocale(),
                             QDateTime.fromTime_t(ts),
                             QLocale.dateTimeFormat(QLocale(), QLocale.LongFormat)
-                        )
+                        ) + " BAT"
                     else:
                         return ""
                 if source_index.column() == IdentitiesTableModel.columns_ids.index('pubkey'):
@@ -173,12 +173,8 @@ class IdentitiesTableModel(QAbstractTableModel):
             identities_data.append(self.identity_data(identity))
 
         if len(identities) > 0:
-            try:
-                parameters = self.blockchain_service.parameters()
-                self._sig_validity = parameters.sig_validity
-            except NoPeerAvailable as e:
-                logging.debug(str(e))
-                self._sig_validity = 0
+            parameters = self.blockchain_service.parameters()
+            self._sig_validity = parameters.sig_validity
         self.identities_data = identities_data
         self.endResetModel()
 
diff --git a/src/sakia/gui/dialogs/certification/__init__.py b/src/sakia/gui/navigation/identity/__init__.py
similarity index 100%
rename from src/sakia/gui/dialogs/certification/__init__.py
rename to src/sakia/gui/navigation/identity/__init__.py
diff --git a/src/sakia/gui/navigation/informations/controller.py b/src/sakia/gui/navigation/identity/controller.py
similarity index 58%
rename from src/sakia/gui/navigation/informations/controller.py
rename to src/sakia/gui/navigation/identity/controller.py
index 402c9618127ad704b31091959c9a22b7df5945f3..cc796ac000486a033fb5f4ff7e467083dca304fa 100644
--- a/src/sakia/gui/navigation/informations/controller.py
+++ b/src/sakia/gui/navigation/identity/controller.py
@@ -1,24 +1,30 @@
 import logging
 
-from PyQt5.QtCore import QObject
+from PyQt5.QtGui import QCursor
+from PyQt5.QtWidgets import QAction
+from PyQt5.QtCore import QObject, pyqtSignal
 from sakia.errors import NoPeerAvailable
 from sakia.constants import ROOT_SERVERS
+from sakia.data.entities import Identity
 from duniterpy.api import errors
-from .model import InformationsModel
-from .view import InformationsView
+from .model import IdentityModel
+from .view import IdentityView
 
-from sakia.decorators import asyncify
+from sakia.decorators import asyncify, once_at_a_time
+from sakia.gui.sub.certification.controller import CertificationController
 from sakia.gui.sub.password_input import PasswordInputController
 from sakia.gui.widgets import toast
+from sakia.gui.widgets.context_menu import ContextMenu
 from sakia.gui.widgets.dialogs import QAsyncMessageBox, QMessageBox
 
 
-class InformationsController(QObject):
+class IdentityController(QObject):
     """
     The informations component
     """
+    view_in_wot = pyqtSignal(Identity)
 
-    def __init__(self, parent, view, model):
+    def __init__(self, parent, view, model, certification):
         """
         Constructor of the informations component
 
@@ -28,15 +34,10 @@ class InformationsController(QObject):
         super().__init__(parent)
         self.view = view
         self.model = model
+        self.certification = certification
         self._logger = logging.getLogger('sakia')
         self.view.button_membership.clicked.connect(self.send_join_demand)
-
-    @property
-    def informations_view(self):
-        """
-        :rtype: sakia.gui.informations.view.InformationsView
-        """
-        return self.view
+        self.view.button_refresh.clicked.connect(self.refresh_certs)
 
     @classmethod
     def create(cls, parent, app, connection, blockchain_service, identities_service, sources_service):
@@ -50,38 +51,52 @@ class InformationsController(QObject):
         :param sources_service:
         :return:
         """
-        view = InformationsView(parent.view)
-        model = InformationsModel(None, app, connection, blockchain_service, identities_service, sources_service)
-        informations = cls(parent, view, model)
-        model.setParent(informations)
-        informations.init_view_text()
-        view.retranslate_required.connect(informations.refresh_localized_data)
-        app.identity_changed.connect(informations.handle_identity_change)
-        app.new_transfer.connect(informations.refresh_localized_data)
-        app.new_dividend.connect(informations.refresh_localized_data)
-        app.referential_changed.connect(informations.refresh_localized_data)
-        app.sources_refreshed.connect(informations.refresh_localized_data)
-        return informations
+        certification = CertificationController.integrate_to_main_view(None, app, connection)
+        view = IdentityView(parent.view, certification.view)
+        model = IdentityModel(None, app, connection, blockchain_service, identities_service, sources_service)
+        identity = cls(parent, view, model, certification)
+        certification.accepted.connect(view.clear)
+        certification.rejected.connect(view.clear)
+        identity.refresh_localized_data()
+        table_model = model.init_table_model()
+        view.set_table_identities_model(table_model)
+        view.table_certifiers.customContextMenuRequested['QPoint'].connect(identity.identity_context_menu)
+        identity.view_in_wot.connect(app.view_in_wot)
+        return identity
+
+    def identity_context_menu(self, point):
+        index = self.view.table_certifiers.indexAt(point)
+        valid, identity = self.model.table_data(index)
+        if valid:
+            menu = ContextMenu.from_data(self.view, self.model.app, None, (identity,))
+            menu.view_identity_in_wot.connect(self.view_in_wot)
+            menu.identity_information_loaded.connect(self.model.table_model.certifier_loaded)
+
+            # Show the context menu.
+            menu.qmenu.popup(QCursor.pos())
 
     @asyncify
     async def init_view_text(self):
         """
         Initialization of text in informations view
         """
-        referentials = self.model.referentials()
-        self.view.set_rules_text_no_dividend()
-        self.view.set_general_text_no_dividend()
-        self.view.set_text_referentials(referentials)
         params = self.model.parameters()
         if params:
             self.view.set_money_text(params, ROOT_SERVERS[self.model.connection.currency]["display"])
-            self.view.set_wot_text(params)
             self.refresh_localized_data()
 
     def handle_identity_change(self, identity):
         if identity.pubkey == self.model.connection.pubkey and identity.uid == self.model.connection.uid:
             self.refresh_localized_data()
 
+    @once_at_a_time
+    @asyncify
+    async def refresh_certs(self, checked=False):
+        self.view.table_certifiers.setEnabled(False)
+        await self.model.refresh_identity_data()
+        self.refresh_localized_data()
+        self.view.table_certifiers.setEnabled(True)
+
     def refresh_localized_data(self):
         """
         Refresh localized data in view
@@ -90,19 +105,16 @@ class InformationsController(QObject):
         try:
             simple_data = self.model.get_identity_data()
             all_data = {**simple_data, **localized_data}
-            self.view.set_simple_informations(all_data, InformationsView.CommunityState.READY)
+            self.view.set_simple_informations(all_data, IdentityView.CommunityState.READY)
         except NoPeerAvailable as e:
             self._logger.debug(str(e))
-            self.view.set_simple_informations(all_data, InformationsView.CommunityState.OFFLINE)
+            self.view.set_simple_informations(all_data, IdentityView.CommunityState.OFFLINE)
         except errors.DuniterError as e:
             if e.ucode == errors.BLOCK_NOT_FOUND:
-                self.view.set_simple_informations(all_data, InformationsView.CommunityState.NOT_INIT)
+                self.view.set_simple_informations(all_data, IdentityView.CommunityState.NOT_INIT)
             else:
                 self._logger.debug(str(e))
 
-        self.view.set_general_text(localized_data)
-        self.view.set_rules_text(localized_data)
-
     @asyncify
     async def send_join_demand(self, checked=False):
         if not self.model.connection:
diff --git a/src/sakia/gui/navigation/identity/identity.ui b/src/sakia/gui/navigation/identity/identity.ui
new file mode 100644
index 0000000000000000000000000000000000000000..1c3fd32caa5fe4f7a21a69f28a80602242518f34
--- /dev/null
+++ b/src/sakia/gui/navigation/identity/identity.ui
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>IdentityWidget</class>
+ <widget class="QWidget" name="IdentityWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>538</width>
+    <height>737</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <property name="styleSheet">
+   <string notr="true">QGroupBox {
+    border: 1px solid gray;
+    border-radius: 9px;
+    margin-top: 0.5em;
+}
+
+QGroupBox::title {
+    subcontrol-origin: margin;
+    left: 10px;
+    padding: 0 3px 0 3px;
+	font-weight: bold;
+}</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="2" column="0">
+    <widget class="QStackedWidget" name="stacked_widget">
+     <property name="currentIndex">
+      <number>0</number>
+     </property>
+     <widget class="QWidget" name="page_empty">
+      <layout class="QVBoxLayout" name="verticalLayout_3">
+       <item>
+        <widget class="QTableView" name="table_certifiers">
+         <attribute name="horizontalHeaderShowSortIndicator" stdset="0">
+          <bool>true</bool>
+         </attribute>
+         <attribute name="horizontalHeaderStretchLastSection">
+          <bool>true</bool>
+         </attribute>
+         <attribute name="verticalHeaderVisible">
+          <bool>false</bool>
+         </attribute>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+    </widget>
+   </item>
+   <item row="1" column="0">
+    <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="QPushButton" name="button_certify">
+       <property name="text">
+        <string>Certify an identity</string>
+       </property>
+       <property name="icon">
+        <iconset resource="../../../../../res/icons/icons.qrc">
+         <normaloff>:/icons/certification_icon</normaloff>:/icons/certification_icon</iconset>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item row="0" column="0">
+    <widget class="QGroupBox" name="group_uid_state">
+     <property name="title">
+      <string>Membership status</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout">
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout_3">
+        <item>
+         <widget class="QLabel" name="label_written">
+          <property name="text">
+           <string/>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_3">
+          <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="QPushButton" name="button_refresh">
+          <property name="text">
+           <string/>
+          </property>
+          <property name="icon">
+           <iconset resource="../../../../../res/icons/icons.qrc">
+            <normaloff>:/icons/refresh_icon</normaloff>:/icons/refresh_icon</iconset>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <widget class="QLabel" name="label_identity">
+        <property name="text">
+         <string/>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout_2">
+        <property name="topMargin">
+         <number>6</number>
+        </property>
+        <item>
+         <widget class="QLabel" name="label_membership">
+          <property name="text">
+           <string/>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="button_membership">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="text">
+           <string>Renew membership</string>
+          </property>
+          <property name="icon">
+           <iconset resource="../../../../../res/icons/icons.qrc">
+            <normaloff>:/icons/renew_membership</normaloff>:/icons/renew_membership</iconset>
+          </property>
+          <property name="iconSize">
+           <size>
+            <width>20</width>
+            <height>20</height>
+           </size>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_2">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources>
+  <include location="../../../../../res/icons/icons.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/src/sakia/gui/navigation/informations/model.py b/src/sakia/gui/navigation/identity/model.py
similarity index 76%
rename from src/sakia/gui/navigation/informations/model.py
rename to src/sakia/gui/navigation/identity/model.py
index 2ba9cd9083be6ae926e11c878b3644fb624016a2..589e957673ab5456fbddb6e3fe30f1e7fa177b8e 100644
--- a/src/sakia/gui/navigation/informations/model.py
+++ b/src/sakia/gui/navigation/identity/model.py
@@ -1,15 +1,15 @@
 import logging
 import math
 
-from PyQt5.QtCore import QLocale, QDateTime, pyqtSignal, QObject
+from PyQt5.QtCore import QLocale, QDateTime, pyqtSignal, QObject, QModelIndex, Qt
 from sakia.errors import NoPeerAvailable
 from sakia.constants import ROOT_SERVERS
-from sakia.money import Referentials
+from .table_model import CertifiersTableModel, CertifiersFilterProxyModel
 from sakia.data.processors import BlockchainProcessor
 from duniterpy.api import errors
 
 
-class InformationsModel(QObject):
+class IdentityModel(QObject):
     """
     An component
     """
@@ -19,7 +19,7 @@ class InformationsModel(QObject):
         """
         Constructor of an component
 
-        :param sakia.gui.informations.controller.InformationsController parent: the controller
+        :param sakia.gui.identity.controller.IdentityController parent: the controller
         :param sakia.app.Application app: the app
         :param sakia.data.entities.Connection connection: the user connection of this node
         :param sakia.services.BlockchainService blockchain_service: the service watching the blockchain state
@@ -33,8 +33,40 @@ class InformationsModel(QObject):
         self.blockchain_service = blockchain_service
         self.identities_service = identities_service
         self.sources_service = sources_service
+        self.table_model = None
+        self.proxy_model = None
         self._logger = logging.getLogger('sakia')
 
+    def init_table_model(self):
+        """
+        Instanciate the table model of the view
+        """
+        certifiers_model = CertifiersTableModel(self, self.connection, self.blockchain_service, self.identities_service)
+        proxy = CertifiersFilterProxyModel(self.app)
+        proxy.setSourceModel(certifiers_model)
+
+        self.table_model = certifiers_model
+        self.proxy_model = proxy
+        self.table_model.init_certifiers()
+        return self.proxy_model
+
+    async def refresh_identity_data(self):
+        identity = self.identities_service.get_identity(self.connection.pubkey, self.connection.uid)
+        identity = await self.identities_service.load_requirements(identity)
+        certifiers = await self.identities_service.load_certifiers_of(identity)
+        certified = await self.identities_service.load_certified_by(identity)
+        await self.identities_service.load_certs_in_lookup(identity, certifiers, certified)
+        self.table_model.init_certifiers()
+
+    def table_data(self, index):
+        if index.isValid() and index.row() < self.table_model.rowCount(QModelIndex()):
+            source_index = self.proxy_model.mapToSource(index)
+            identity_col = self.table_model.columns_ids.index('identity')
+            identity_index = self.table_model.index(source_index.row(), identity_col)
+            identity = self.table_model.data(identity_index, Qt.DisplayRole)
+            return True, identity
+        return False, None
+
     def get_localized_data(self):
         localized_data = {}
         #  try to request money parameters
@@ -135,9 +167,13 @@ class InformationsModel(QObject):
                                                          self.app).localized(False, True)
         outdistanced_text = self.tr("Outdistanced")
         is_identity = False
+        written = False
         is_member = False
         nb_certs = 0
         mstime_remaining = 0
+        identity_expiration = 0
+        identity_expired = False
+        outdistanced = False
         nb_certs_required = self.blockchain_service.parameters().sig_qty
 
         if self.connection.uid:
@@ -147,6 +183,13 @@ class InformationsModel(QObject):
                 if identity:
                     mstime_remaining = self.identities_service.ms_time_remaining(identity)
                     is_member = identity.member
+                    outdistanced = identity.outdistanced
+                    written = identity.written
+                    if not written:
+                        identity_expiration = identity.timestamp + self.parameters().sig_window
+                        identity_expired = identity_expiration < self.blockchain_processor.time(self.connection.currency)
+                        identity_expiration = self.blockchain_processor.adjusted_ts(self.app.currency,
+                                                                                    identity_expiration)
                     nb_certs = len(self.identities_service.certifications_received(identity.pubkey))
                     if not identity.outdistanced:
                         outdistanced_text = self.tr("In WoT range")
@@ -157,7 +200,11 @@ class InformationsModel(QObject):
                     self._logger.error(str(e))
 
         return {
+            'written': written,
+            'idty_expired': identity_expired,
+            'idty_expiration': identity_expiration,
             'amount': localized_amount,
+            'is_outdistanced': outdistanced,
             'outdistanced': outdistanced_text,
             'nb_certs': nb_certs,
             'nb_certs_required': nb_certs_required,
@@ -172,17 +219,6 @@ class InformationsModel(QObject):
         """
         return self.blockchain_service.parameters()
 
-    def referentials(self):
-        """
-        Get referentials
-        :return: The list of instances of all referentials
-        :rtype: list
-        """
-        refs_instances = []
-        for ref_class in Referentials:
-             refs_instances.append(ref_class(0, self.connection.currency, self.app, None))
-        return refs_instances
-
     def notifications(self):
         return self.app.parameters.notifications
 
diff --git a/src/sakia/gui/navigation/identity/table_model.py b/src/sakia/gui/navigation/identity/table_model.py
new file mode 100644
index 0000000000000000000000000000000000000000..3297642c8ee55e259341569461f61c72071ec559
--- /dev/null
+++ b/src/sakia/gui/navigation/identity/table_model.py
@@ -0,0 +1,172 @@
+from sakia.errors import NoPeerAvailable
+from sakia.data.entities import Identity
+from sakia.data.processors import BlockchainProcessor
+from PyQt5.QtCore import QAbstractTableModel, QSortFilterProxyModel, Qt, \
+                        QDateTime, QModelIndex, QLocale, QT_TRANSLATE_NOOP
+from PyQt5.QtGui import QColor, QIcon, QFont
+import logging
+import asyncio
+
+
+class CertifiersFilterProxyModel(QSortFilterProxyModel):
+    def __init__(self, app, parent=None):
+        super().__init__(parent)
+        self.app = app
+        self.blockchain_processor = BlockchainProcessor.instanciate(app)
+
+    def columnCount(self, parent):
+        return len(CertifiersTableModel.columns_ids) - 2
+    
+    def lessThan(self, left, right):
+        """
+        Sort table by given column number.
+        """
+        source_model = self.sourceModel()
+        left_data = source_model.data(left, Qt.DisplayRole)
+        right_data = source_model.data(right, Qt.DisplayRole)
+        left_data = 0 if left_data is None else left_data
+        right_data = 0 if right_data is None else right_data
+        return left_data < right_data
+
+    def data(self, index, role):
+        source_index = self.mapToSource(index)
+        if source_index.isValid():
+            source_data = self.sourceModel().data(source_index, role)
+            publication_col = CertifiersTableModel.columns_ids.index('publication')
+            publication_index = self.sourceModel().index(source_index.row(), publication_col)
+            expiration_col = CertifiersTableModel.columns_ids.index('expiration')
+            expiration_index = self.sourceModel().index(source_index.row(), expiration_col)
+            written_col = CertifiersTableModel.columns_ids.index('written')
+            written_index = self.sourceModel().index(source_index.row(), written_col)
+
+            publication_data = self.sourceModel().data(publication_index, Qt.DisplayRole)
+            expiration_data = self.sourceModel().data(expiration_index, Qt.DisplayRole)
+            written_data = self.sourceModel().data(written_index, Qt.DisplayRole)
+            current_time = QDateTime().currentDateTime().toMSecsSinceEpoch()
+            warning_expiration_time = int((expiration_data - publication_data) / 3)
+            #logging.debug("{0} > {1}".format(current_time, expiration_data))
+
+            if role == Qt.DisplayRole:
+                if source_index.column() == CertifiersTableModel.columns_ids.index('expiration'):
+                    if source_data:
+                        ts = self.blockchain_processor.adjusted_ts(self.app.currency, source_data)
+                        return QLocale.toString(
+                            QLocale(),
+                            QDateTime.fromTime_t(ts),
+                            QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
+                        ) + " BAT"
+                    else:
+                        return ""
+                if source_index.column() == CertifiersTableModel.columns_ids.index('publication'):
+                    if source_data:
+                        ts = self.blockchain_processor.adjusted_ts(self.app.currency, source_data)
+                        return QLocale.toString(
+                            QLocale(),
+                            QDateTime.fromTime_t(ts),
+                            QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
+                        ) + " BAT"
+                    else:
+                        return ""
+                if source_index.column() == CertifiersTableModel.columns_ids.index('pubkey'):
+                    return source_data
+
+            if role == Qt.FontRole:
+                font = QFont()
+                if not written_data:
+                    font.setItalic(True)
+                return font
+
+            if role == Qt.ForegroundRole:
+                if current_time > ((expiration_data*1000) - (warning_expiration_time*1000)):
+                    return QColor("darkorange").darker(120)
+
+            return source_data
+
+
+class CertifiersTableModel(QAbstractTableModel):
+
+    """
+    A Qt abstract item model to display communities in a tree
+    """
+
+    columns_titles = {'uid': lambda: QT_TRANSLATE_NOOP("CertifiersTableModel", 'UID'),
+                           'pubkey': lambda: QT_TRANSLATE_NOOP("CertifiersTableModel", 'Pubkey'),
+                           'publication': lambda: QT_TRANSLATE_NOOP("CertifiersTableModel", 'Publication Date'),
+                           'expiration': lambda: QT_TRANSLATE_NOOP("CertifiersTableModel", 'Expiration'),
+                           'available': lambda: QT_TRANSLATE_NOOP("CertifiersTableModel"), }
+    columns_ids = ('uid', 'pubkey', 'publication', 'expiration', 'written', 'identity')
+
+    def __init__(self, parent, connection, blockchain_service, identities_service):
+        """
+        Constructor
+        :param parent:
+        :param sakia.data.entities.Connection connection:
+        :param sakia.services.BlockchainService blockchain_service: the blockchain service
+        :param sakia.services.IdentitiesService identities_service: the identities service
+        """
+        super().__init__(parent)
+        self.connection = connection
+        self.blockchain_service = blockchain_service
+        self.identities_service = identities_service
+        self._certifiers_data = []
+
+    def certifier_data(self, certification):
+        """
+        Return the identity in the form a tuple to display
+        :param sakia.data.entities.Certification certification: The certification to get data from
+        :return: The certification data in the form of a tuple
+        :rtype: tuple
+        """
+        parameters = self.blockchain_service.parameters()
+        publication_date = certification.timestamp
+        identity = self.identities_service.get_identity(certification.certifier)
+        if not identity:
+            identity = Identity(currency=certification.currency, pubkey=certification.certifier, uid="")
+        written = certification.written_on >= 0
+        if written:
+            expiration_date = publication_date + parameters.sig_validity
+        else:
+            expiration_date = publication_date + parameters.sig_window
+        return identity.uid, identity.pubkey, publication_date, expiration_date, written, identity
+
+    def certifier_loaded(self, identity):
+        for i, idty in enumerate(self.identities_data):
+            if idty[CertifiersTableModel.columns_ids.index('identity')] == identity:
+                self._certifiers_data[i] = self._certifiers_data(identity)
+                self.dataChanged.emit(self.index(i, 0), self.index(i, len(CertifiersTableModel.columns_ids)))
+                return
+
+    def init_certifiers(self):
+        """
+        Change the identities to display
+        """
+        self.beginResetModel()
+        certifications = self.identities_service.certifications_received(self.connection.pubkey)
+        logging.debug("Refresh {0} certifiers".format(len(certifications)))
+        certifiers_data = []
+        for certifier in certifications:
+            certifiers_data.append(self.certifier_data(certifier))
+
+        self._certifiers_data = certifiers_data
+        self.endResetModel()
+
+    def rowCount(self, parent):
+        return len(self._certifiers_data)
+
+    def columnCount(self, parent):
+        return len(CertifiersTableModel.columns_ids)
+
+    def headerData(self, section, orientation, role):
+        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
+            col_id = CertifiersTableModel.columns_ids[section]
+            return CertifiersTableModel.columns_titles[col_id]()
+
+    def data(self, index, role):
+        if index.isValid() and role == Qt.DisplayRole:
+            row = index.row()
+            col = index.column()
+            identity_data = self._certifiers_data[row]
+            return identity_data[col]
+
+    def flags(self, index):
+        return Qt.ItemIsSelectable | Qt.ItemIsEnabled
diff --git a/src/sakia/gui/navigation/identity/view.py b/src/sakia/gui/navigation/identity/view.py
new file mode 100644
index 0000000000000000000000000000000000000000..3dd0c6d09df24b9fe6c526baacaebbc67c1d1102
--- /dev/null
+++ b/src/sakia/gui/navigation/identity/view.py
@@ -0,0 +1,233 @@
+from PyQt5.QtWidgets import QWidget, QMessageBox, QAbstractItemView, QHeaderView
+from PyQt5.QtCore import QEvent, QLocale, pyqtSignal, Qt, QDateTime
+from .identity_uic import Ui_IdentityWidget
+from enum import Enum
+from sakia.helpers import timestamp_to_dhms
+from sakia.constants import ROOT_SERVERS
+from sakia.gui.widgets.dialogs import dialog_async_exec
+
+
+class IdentityView(QWidget, Ui_IdentityWidget):
+    """
+    The view of navigation panel
+    """
+    retranslate_required = pyqtSignal()
+
+    class CommunityState(Enum):
+        NOT_INIT = 0
+        OFFLINE = 1
+        READY = 2
+
+    def __init__(self, parent, certification_view):
+        super().__init__(parent)
+        self.certification_view = certification_view
+        self.setupUi(self)
+        self.stacked_widget.insertWidget(1, certification_view)
+        self.button_certify.clicked.connect(lambda c: self.stacked_widget.setCurrentWidget(self.certification_view))
+
+    def set_table_identities_model(self, model):
+        """
+        Set the model of the table view
+        :param PyQt5.QtCore.QAbstractItemModel model: the model of the table view
+        """
+        self.table_certifiers.setModel(model)
+        self.table_certifiers.setSelectionBehavior(QAbstractItemView.SelectRows)
+        self.table_certifiers.setSortingEnabled(True)
+        self.table_certifiers.horizontalHeader().setSectionResizeMode(QHeaderView.Interactive)
+        self.table_certifiers.resizeRowsToContents()
+        self.table_certifiers.verticalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
+        self.table_certifiers.setContextMenuPolicy(Qt.CustomContextMenu)
+
+    def clear(self):
+        self.stacked_widget.setCurrentWidget(self.page_empty)
+
+    def set_simple_informations(self, data, state):
+        if state in (IdentityView.CommunityState.NOT_INIT, IdentityView.CommunityState.OFFLINE):
+            self.label_currency.setText("""<html>
+                <body>
+                <p>
+                <span style=" font-size:16pt; font-weight:600;">{currency}</span>
+                </p>
+                <p>{message}</p>
+                </body>
+                </html>""".format(currency=data['currency'],
+                                  message=IdentityView.simple_message[state]))
+            self.button_membership.hide()
+        else:
+            if data['written']:
+                written_value = self.tr("Identity written in blockchain")
+            else:
+                expiration_text = QLocale.toString(
+                    QLocale(),
+                    QDateTime.fromTime_t(data['idty_expiration']),
+                    QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
+                )
+                written_value = self.tr("Identity not written in blockchain") + \
+                                " (" + self.tr("Expires on : {0}").format(expiration_text) + " BAT)"
+
+            status_value = self.tr("Member") if data['membership_state'] else self.tr("Non-Member")
+            if data['mstime'] > 0:
+                membership_action_value = self.tr("Renew membership")
+                status_info = ""
+                membership_action_enabled = True
+            elif data['membership_state']:
+                membership_action_value = self.tr("Renew membership")
+                status_info = "Your membership expired"
+                membership_action_enabled = True
+            else:
+                membership_action_value = self.tr("Request membership")
+                if data['nb_certs'] > data['nb_certs_required']:
+                    status_info = self.tr("Registration ready")
+                    membership_action_enabled = True
+                else:
+                    status_info = self.tr("{0} more certifications required")\
+                        .format(data['nb_certs_required'] - data['nb_certs'])
+                    membership_action_enabled = True
+
+            if data['mstime'] > 0:
+                days, hours, minutes, seconds = timestamp_to_dhms(data['mstime'])
+                mstime_remaining_text = self.tr("Expires in ")
+                if days > 0:
+                    mstime_remaining_text += "{days} days".format(days=days)
+                else:
+                    mstime_remaining_text += "{hours} hours and {min} min.".format(hours=hours,
+                                                                                   min=minutes)
+            else:
+                mstime_remaining_text = self.tr("Expired or never published")
+
+            ms_status_color = '#00AA00' if data['membership_state'] else '#FF0000'
+            outdistanced_status_color = '#FF0000' if data['is_outdistanced'] else '#00AA00'
+            if data['written']:
+                written_status_color = "#00AA00"
+            elif data['idty_expired']:
+                written_status_color = "#FF0000"
+            else:
+                written_status_color = '#FF6347'
+
+            description_membership = """<html>
+<body>
+    <p><span style="font-weight:600;">{status_label}</span>
+     : <span style="color:{ms_status_color};">{status}</span>
+     - <span>{status_info}</span></p>
+</body>
+</html>""".format(ms_status_color=ms_status_color,
+                  status_label=self.tr("Status"),
+                  status=status_value,
+                  status_info=status_info)
+            description_identity = """<html>
+<body>
+    <p><span style="font-weight:600;">{nb_certs_label}</span> : {nb_certs} <span style="color:{outdistanced_status_color};">({outdistanced_text})</span></p>
+    <p><span style="font-weight:600;">{mstime_remaining_label}</span> : {mstime_remaining}</p>
+</body>
+</html>""".format(nb_certs_label=self.tr("Certs. received"),
+                  nb_certs=data['nb_certs'],
+                  outdistanced_text=data['outdistanced'],
+                  outdistanced_status_color=outdistanced_status_color,
+                  mstime_remaining_label=self.tr("Membership"),
+                  mstime_remaining=mstime_remaining_text)
+
+            self.label_written.setText("""
+<html>
+<body>
+    <p><span style="font-weight:450; color:{written_status_color};">{written_label}</span></p>
+</body>
+</html>
+""".format(written_label=written_value,
+           written_status_color=written_status_color))
+
+            if data['is_identity']:
+                self.label_membership.setText(description_membership)
+                self.label_identity.setText(description_identity)
+                self.button_membership.setText(membership_action_value)
+                self.button_membership.setEnabled(membership_action_enabled)
+            else:
+                self.label_membership.hide()
+                self.label_identity.hide()
+                self.button_membership.hide()
+
+    async def licence_dialog(self, currency, params):
+        dt_dhms = timestamp_to_dhms(params.dt)
+        if dt_dhms[0] > 0:
+            dt_as_str = self.tr("{:} day(s) {:} hour(s)").format(*dt_dhms)
+        else:
+            dt_as_str = self.tr("{:} hour(s)").format(dt_dhms[1])
+        if dt_dhms[2] > 0 or dt_dhms[3] > 0:
+            dt_dhms += ", {:} minute(s) and {:} second(s)".format(*dt_dhms[1:])
+        dt_reeval_dhms = timestamp_to_dhms(params.dt_reeval)
+        dt_reeval_as_str = self.tr("{:} day(s) {:} hour(s)").format(*dt_reeval_dhms)
+
+        message_box = QMessageBox(self)
+
+        message_box.setText("Do you recognize the terms of the following licence :")
+        message_box.setInformativeText("""
+{:} is being produced by a Universal Dividend (UD) for any human member, which is :<br/>
+<br/>
+<table cellpadding="5">
+ <tr><td align="right"><b>{:2.0%} / {:} days</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>
+ <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
+</table>
+<br/>
+<br/>
+
+The parameters of the Web of Trust of {:} are :<br/>
+<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>
+ <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>
+ <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
+ <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
+</table>
+<br/>
+<br/>
+
+<b>By asking to join as member, you recognize that this is your unique account,
+and that you will only certify persons that you know well enough.</b>
+ """.format(
+            ROOT_SERVERS[currency]["display"],
+            params.c,
+            QLocale().toString(params.dt / 86400, 'f', 2),
+            self.tr('Fundamental growth (c)'),
+            params.ud0,
+            self.tr('Initial Universal Dividend UD(0) in'),
+            ROOT_SERVERS[currency]["display"],
+            dt_as_str,
+            self.tr('Time period between two UD'),
+            dt_reeval_as_str,
+            self.tr('Time period between two UD reevaluation'),
+            ROOT_SERVERS[currency]["display"],
+            QLocale().toString(params.sig_period / 86400, 'f', 2),
+            self.tr('Minimum delay between 2 certifications (in days)'),
+            QLocale().toString(params.sig_validity / 86400, 'f', 2),
+            self.tr('Maximum age of a valid signature (in days)'),
+            params.sig_qty,
+            self.tr('Minimum quantity of signatures to be part of the WoT'),
+            params.sig_stock,
+            self.tr('Maximum quantity of active certifications made by member.'),
+            params.sig_window,
+            self.tr('Maximum delay a certification can wait before being expired for non-writing.'),
+            params.xpercent,
+            self.tr('Minimum percent of sentries to reach to match the distance rule'),
+            params.ms_validity / 86400,
+            self.tr('Maximum age of a valid membership (in days)'),
+            params.step_max,
+            self.tr('Maximum distance between each WoT member and a newcomer'),
+        )
+    )
+        message_box.setStandardButtons(QMessageBox.Yes | QMessageBox.No )
+        message_box.setDefaultButton(QMessageBox.No)
+        return await dialog_async_exec(message_box)
+
+    def changeEvent(self, event):
+        """
+        Intercepte LanguageChange event to translate UI
+        :param QEvent QEvent: Event
+        :return:
+        """
+        if event.type() == QEvent.LanguageChange:
+            self.retranslateUi(self)
+        return super().changeEvent(event)
diff --git a/src/sakia/gui/navigation/informations/informations.ui b/src/sakia/gui/navigation/informations/informations.ui
deleted file mode 100644
index ba3f34f1c501d941bd96cea513d764b5fefd5d5a..0000000000000000000000000000000000000000
--- a/src/sakia/gui/navigation/informations/informations.ui
+++ /dev/null
@@ -1,276 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>InformationsWidget</class>
- <widget class="QWidget" name="InformationsWidget">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>538</width>
-    <height>737</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Form</string>
-  </property>
-  <property name="styleSheet">
-   <string notr="true">QGroupBox {
-    border: 1px solid gray;
-    border-radius: 9px;
-    margin-top: 0.5em;
-}
-
-QGroupBox::title {
-    subcontrol-origin: margin;
-    left: 10px;
-    padding: 0 3px 0 3px;
-	font-weight: bold;
-}</string>
-  </property>
-  <layout class="QGridLayout" name="gridLayout">
-   <item row="3" column="0">
-    <widget class="QScrollArea" name="scrollarea">
-     <property name="styleSheet">
-      <string notr="true"/>
-     </property>
-     <property name="widgetResizable">
-      <bool>true</bool>
-     </property>
-     <widget class="QWidget" name="scrollAreaWidgetContents">
-      <property name="geometry">
-       <rect>
-        <x>0</x>
-        <y>0</y>
-        <width>522</width>
-        <height>272</height>
-       </rect>
-      </property>
-      <layout class="QVBoxLayout" name="verticalLayout_5">
-       <item>
-        <widget class="QGroupBox" name="group_general">
-         <property name="styleSheet">
-          <string notr="true"/>
-         </property>
-         <property name="title">
-          <string>General</string>
-         </property>
-         <property name="flat">
-          <bool>false</bool>
-         </property>
-         <layout class="QVBoxLayout" name="verticalLayout_2">
-          <item>
-           <widget class="QLabel" name="label_general">
-            <property name="text">
-             <string/>
-            </property>
-            <property name="scaledContents">
-             <bool>false</bool>
-            </property>
-            <property name="alignment">
-             <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
-            </property>
-           </widget>
-          </item>
-         </layout>
-        </widget>
-       </item>
-       <item>
-        <widget class="QGroupBox" name="group_rules">
-         <property name="title">
-          <string>Rules</string>
-         </property>
-         <layout class="QVBoxLayout" name="verticalLayout_6">
-          <item>
-           <widget class="QLabel" name="label_rules">
-            <property name="text">
-             <string/>
-            </property>
-            <property name="alignment">
-             <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
-            </property>
-           </widget>
-          </item>
-         </layout>
-        </widget>
-       </item>
-       <item>
-        <widget class="QGroupBox" name="group_referentials">
-         <property name="title">
-          <string>Referentials</string>
-         </property>
-         <layout class="QGridLayout" name="gridLayout_2">
-          <item row="0" column="0">
-           <widget class="QLabel" name="label_referentials">
-            <property name="text">
-             <string/>
-            </property>
-           </widget>
-          </item>
-         </layout>
-        </widget>
-       </item>
-       <item>
-        <widget class="QGroupBox" name="group_money">
-         <property name="title">
-          <string>Money</string>
-         </property>
-         <layout class="QVBoxLayout" name="verticalLayout_3">
-          <item>
-           <widget class="QLabel" name="label_money">
-            <property name="text">
-             <string/>
-            </property>
-            <property name="alignment">
-             <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
-            </property>
-           </widget>
-          </item>
-         </layout>
-        </widget>
-       </item>
-       <item>
-        <widget class="QGroupBox" name="group_wot">
-         <property name="title">
-          <string>WoT</string>
-         </property>
-         <layout class="QVBoxLayout" name="verticalLayout_4">
-          <item>
-           <widget class="QLabel" name="label_wot">
-            <property name="text">
-             <string/>
-            </property>
-            <property name="alignment">
-             <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
-            </property>
-           </widget>
-          </item>
-         </layout>
-        </widget>
-       </item>
-      </layout>
-     </widget>
-    </widget>
-   </item>
-   <item row="1" column="0">
-    <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="QPushButton" name="button_details">
-       <property name="text">
-        <string>Details</string>
-       </property>
-       <property name="checkable">
-        <bool>true</bool>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-   <item row="0" column="0">
-    <widget class="QGroupBox" name="group_uid_state">
-     <property name="title">
-      <string>UID</string>
-     </property>
-     <layout class="QVBoxLayout" name="verticalLayout">
-      <item>
-       <widget class="QLabel" name="label_currency">
-        <property name="text">
-         <string/>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <widget class="QLabel" name="label_identity">
-        <property name="text">
-         <string/>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <layout class="QHBoxLayout" name="horizontalLayout_2">
-        <property name="topMargin">
-         <number>6</number>
-        </property>
-        <item>
-         <widget class="QLabel" name="label_membership">
-          <property name="text">
-           <string/>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QPushButton" name="button_membership">
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="text">
-           <string>Renew membership</string>
-          </property>
-          <property name="icon">
-           <iconset resource="../../../../../res/icons/icons.qrc">
-            <normaloff>:/icons/renew_membership</normaloff>:/icons/renew_membership</iconset>
-          </property>
-          <property name="iconSize">
-           <size>
-            <width>20</width>
-            <height>20</height>
-           </size>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <spacer name="horizontalSpacer_2">
-          <property name="orientation">
-           <enum>Qt::Horizontal</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>40</width>
-            <height>20</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-       </layout>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item row="2" column="0">
-    <spacer name="verticalSpacer">
-     <property name="orientation">
-      <enum>Qt::Vertical</enum>
-     </property>
-     <property name="sizeHint" stdset="0">
-      <size>
-       <width>20</width>
-       <height>40</height>
-      </size>
-     </property>
-    </spacer>
-   </item>
-  </layout>
- </widget>
- <resources>
-  <include location="../../../../../res/icons/icons.qrc"/>
- </resources>
- <connections/>
-</ui>
diff --git a/src/sakia/gui/navigation/informations/view.py b/src/sakia/gui/navigation/informations/view.py
deleted file mode 100644
index f5d3988b54dc5d0bd68a8d3185a5ae355d846544..0000000000000000000000000000000000000000
--- a/src/sakia/gui/navigation/informations/view.py
+++ /dev/null
@@ -1,420 +0,0 @@
-from PyQt5.QtWidgets import QWidget, QMessageBox
-from PyQt5.QtCore import QEvent, QLocale, pyqtSignal
-from .informations_uic import Ui_InformationsWidget
-from enum import Enum
-from sakia.helpers import timestamp_to_dhms
-from sakia.constants import ROOT_SERVERS
-from sakia.gui.widgets.dialogs import dialog_async_exec
-
-
-class InformationsView(QWidget, Ui_InformationsWidget):
-    """
-    The view of navigation panel
-    """
-    retranslate_required = pyqtSignal()
-
-    class CommunityState(Enum):
-        NOT_INIT = 0
-        OFFLINE = 1
-        READY = 2
-
-    def __init__(self, parent):
-        super().__init__(parent)
-        self.setupUi(self)
-        self.scrollarea.hide()
-        self.button_details.clicked.connect(self.handle_details_click)
-
-    def handle_details_click(self):
-        if self.button_details.isChecked():
-            self.scrollarea.show()
-        else:
-            self.scrollarea.hide()
-
-    def set_simple_informations(self, data, state):
-        if state in (InformationsView.CommunityState.NOT_INIT, InformationsView.CommunityState.OFFLINE):
-            self.label_currency.setText("""<html>
-                <body>
-                <p>
-                <span style=" font-size:16pt; font-weight:600;">{currency}</span>
-                </p>
-                <p>{message}</p>
-                </body>
-                </html>""".format(currency=data['currency'],
-                                  message=InformationsView.simple_message[state]))
-            self.button_membership.hide()
-        else:
-            status_value = self.tr("Member") if data['membership_state'] else self.tr("Non-Member")
-            if data['mstime'] > 0:
-                membership_action_value = self.tr("Renew membership")
-                status_info = ""
-                membership_action_enabled = True
-            elif data['membership_state']:
-                membership_action_value = self.tr("Renew membership")
-                status_info = "Your membership expired"
-                membership_action_enabled = True
-            else:
-                membership_action_value = self.tr("Request membership")
-                if data['nb_certs'] > data['nb_certs_required']:
-                    status_info = self.tr("Registration ready")
-                    membership_action_enabled = True
-                else:
-                    status_info = self.tr("{0} more certifications required")\
-                        .format(data['nb_certs_required'] - data['nb_certs'])
-                    membership_action_enabled = True
-
-            if data['mstime'] > 0:
-                days, hours, minutes, seconds = timestamp_to_dhms(data['mstime'])
-                mstime_remaining_text = self.tr("Expires in ")
-                if days > 0:
-                    mstime_remaining_text += "{days} days".format(days=days)
-                else:
-                    mstime_remaining_text += "{hours} hours and {min} min.".format(hours=hours,
-                                                                                   min=minutes)
-            else:
-                mstime_remaining_text = self.tr("Expired or never published")
-
-            status_color = '#00AA00' if data['membership_state'] else self.tr('#FF0000')
-            description_currency = """<html>
-<body>
-    <p>
-        <span style=" font-size:16pt; font-weight:600;">{currency}</span>
-    </p>
-    <p>{nb_members} {members_label}</p>
-    <p><span style="font-weight:600;">{monetary_mass_label}</span> : {monetary_mass}</p>
-    <p><span style="font-weight:600;">{balance_label}</span> : {balance}</p>
-</body>
-</html>""".format(currency=data['currency'],
-                  nb_members=data['members_count'],
-                  members_label=self.tr("members"),
-                  monetary_mass_label=self.tr("Monetary mass"),
-                  monetary_mass=data['mass'],
-                  balance_label=self.tr("Balance"),
-                  balance=data['amount'])
-
-            description_membership = """<html>
-<body>
-    <p><span style="font-weight:600;">{status_label}</span>
-     : <span style="color:{status_color};">{status}</span>
-     - <span>{status_info}</span></p>
-</body>
-</html>""".format(status_color=status_color,
-                  status_label=self.tr("Status"),
-                  status=status_value,
-                  status_info=status_info)
-            description_identity = """<html>
-<body>
-    <p><span style="font-weight:600;">{nb_certs_label}</span> : {nb_certs} ({outdistanced_text})</p>
-    <p><span style="font-weight:600;">{mstime_remaining_label}</span> : {mstime_remaining}</p>
-</body>
-</html>""".format(nb_certs_label=self.tr("Certs. received"),
-                  nb_certs=data['nb_certs'],
-                  outdistanced_text=data['outdistanced'],
-                  mstime_remaining_label=self.tr("Membership"),
-                  mstime_remaining=mstime_remaining_text)
-
-            self.label_currency.setText(description_currency)
-
-            if data['is_identity']:
-                self.label_membership.setText(description_membership)
-                self.label_identity.setText(description_identity)
-                self.button_membership.setText(membership_action_value)
-                self.button_membership.setEnabled(membership_action_enabled)
-            else:
-                self.label_membership.hide()
-                self.label_identity.hide()
-                self.button_membership.hide()
-
-    def set_general_text_no_dividend(self):
-        """
-        Set the general text when there is no dividend
-        """
-        self.label_general.setText(self.tr('No Universal Dividend created yet.'))
-
-    def set_general_text(self, localized_data):
-        """
-        Fill the general text with given informations
-        :return:
-        """
-        # set infos in label
-        self.label_general.setText(
-            self.tr("""
-            <table cellpadding="5">
-            <tr><td align="right"><b>{:}</b></div></td><td>{:} {:}</td></tr>
-            <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>
-            <tr><td align="right"><b>{:2.2%} / {:} days</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>
-            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
-            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
-            </table>
-            """).format(
-                localized_data.get('ud', '####'),
-                self.tr('Universal Dividend UD(t) in'),
-                localized_data['diff_units'],
-                localized_data.get('mass_minus_1', "###"),
-                self.tr('Monetary Mass M(t-1) in'),
-                localized_data['units'],
-                localized_data.get('members_count', '####'),
-                self.tr('Members N(t)'),
-                localized_data.get('mass_minus_1_per_member', '####'),
-                self.tr('Monetary Mass per member M(t-1)/N(t) in'),
-                localized_data['diff_units'],
-                localized_data.get('actual_growth', 0),
-                localized_data.get('days_per_dividend', '####'),
-                self.tr('Actual growth c = UD(t)/[M(t-1)/N(t)]'),
-                localized_data.get('ud_median_time_minus_1', '####'),
-                self.tr('Penultimate UD date and time (t-1)'),
-                localized_data.get('ud_median_time', '####'),
-                self.tr('Last UD date and time (t)'),
-                localized_data.get('next_ud_median_time', '####'),
-                self.tr('Next UD date and time (t+1)'),
-                localized_data.get('next_ud_reeaval', '####'),
-                self.tr('Next UD reevaluation (t+1)')
-            )
-        )
-
-    def set_rules_text_no_dividend(self):
-        """
-        Set text when no dividends was generated yet
-        """
-        self.label_rules.setText(self.tr('No Universal Dividend created yet.'))
-
-    def set_rules_text(self, localized_data):
-        """
-        Set text in rules
-        :param dict localized_data:
-        :return:
-        """
-        # set infos in label
-        self.label_rules.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.tr('{:2.0%} / {:} days').format(localized_data['growth'], localized_data['days_per_dividend']),
-                self.tr('Fundamental growth (c) / Delta time (dt)'),
-                self.tr('UDĞ(t) = UDĞ(t-1) + c²*M(t-1)/N(t-1)'),
-                self.tr('Universal Dividend (formula)'),
-                self.tr('{:} = {:} + {:2.0%}²* {:} / {:}').format(
-                    localized_data.get('ud_plus_1', '####'),
-                    localized_data.get('ud', '####'),
-                    localized_data.get('growth', '####'),
-                    localized_data.get('mass', '####'),
-                    localized_data.get('members_count', '####')
-                ),
-                self.tr('Universal Dividend (computed)')
-            )
-        )
-
-    def set_text_referentials(self, referentials):
-        """
-        Set text from referentials
-        :param list referentials: list of referentials
-        """
-        # set infos in label
-        ref_template = """
-                <table cellpadding="5">
-                <tr><th>{:}</th><td>{:}</td></tr>
-                <tr><th>{:}</th><td>{:}</td></tr>
-                <tr><th>{:}</th><td>{:}</td></tr>
-                <tr><th>{:}</th><td>{:}</td></tr>
-                </table>
-                """
-        templates = []
-        for ref in referentials:
-            # print(ref_class.__class__.__name__)
-            # if ref_class.__class__.__name__ == 'RelativeToPast':
-            #     continue
-            templates.append(ref_template.format(self.tr('Name'), ref.translated_name(),
-                                                 self.tr('Units'), ref.units,
-                                                 self.tr('Formula'), ref.formula,
-                                                 self.tr('Description'), ref.description
-                                                 )
-                             )
-
-        self.label_referentials.setText('<hr>'.join(templates))
-
-    def set_money_text(self, params, currency):
-        """
-        Set text from money parameters
-        :param sakia.data.entities.BlockchainParameters params: Parameters of the currency
-        :param str currency: The currency
-        """
-
-        dt_dhms = timestamp_to_dhms(params.dt)
-        if dt_dhms[0] > 0:
-            dt_as_str = self.tr("{:} day(s) {:} hour(s)").format(*dt_dhms)
-        else:
-            dt_as_str = self.tr("{:} hour(s)").format(dt_dhms[1])
-        if dt_dhms[2] > 0 or dt_dhms[3] > 0:
-            dt_dhms += ", {:} minute(s) and {:} second(s)".format(*dt_dhms[1:])
-        dt_reeval_dhms = timestamp_to_dhms(params.dt_reeval)
-        dt_reeval_as_str = self.tr("{:} day(s) {:} hour(s)").format(*dt_reeval_dhms)
-
-
-        # set infos in label
-        self.label_money.setText(
-                self.tr("""
-            <table cellpadding="5">
-            <tr><td align="right"><b>{:2.0%} / {:} days</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>
-            <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>
-            <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
-            <tr><td align="right"><b>{:2.0%}</b></td><td>{:}</td></tr>
-            </table>
-            """).format(
-                        params.c,
-                        QLocale().toString(params.dt / 86400, 'f', 2),
-                        self.tr('Fundamental growth (c)'),
-                        params.ud0,
-                        self.tr('Initial Universal Dividend UD(0) in'),
-                        currency,
-                        dt_as_str,
-                        self.tr('Time period between two UD'),
-                        dt_reeval_as_str,
-                        self.tr('Time period between two UD reevaluation'),
-                        params.median_time_blocks,
-                        self.tr('Number of blocks used for calculating median time'),
-                        params.avg_gen_time,
-                        self.tr('The average time in seconds for writing 1 block (wished time)'),
-                        params.dt_diff_eval,
-                        self.tr('The number of blocks required to evaluate again PoWMin value'),
-                        params.percent_rot,
-                        self.tr('The percent of previous issuers to reach for personalized difficulty')
-                )
-        )
-
-    def set_wot_text(self, params):
-        """
-        Set wot text from currency parameters
-        :param sakia.data.entities.BlockchainParameters params: Parameters of the currency
-        :return:
-        """
-
-        # set infos in label
-        self.label_wot.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>
-<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>
-<tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
-<tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
-</table>
-""").format(
-            QLocale().toString(params.sig_period / 86400, 'f', 2),
-            self.tr('Minimum delay between 2 certifications (in days)'),
-            QLocale().toString(params.sig_validity / 86400, 'f', 2),
-            self.tr('Maximum age of a valid signature (in days)'),
-            params.sig_qty,
-            self.tr('Minimum quantity of signatures to be part of the WoT'),
-            params.sig_stock,
-            self.tr('Maximum quantity of active certifications made by member.'),
-            params.sig_window,
-            self.tr('Maximum delay a certification can wait before being expired for non-writing.'),
-            params.xpercent,
-            self.tr('Minimum percent of sentries to reach to match the distance rule'),
-            params.ms_validity / 86400,
-            self.tr('Maximum age of a valid membership (in days)'),
-            params.step_max,
-            self.tr('Maximum distance between each WoT member and a newcomer'),
-                )
-        )
-
-    async def licence_dialog(self, currency, params):
-        dt_dhms = timestamp_to_dhms(params.dt)
-        if dt_dhms[0] > 0:
-            dt_as_str = self.tr("{:} day(s) {:} hour(s)").format(*dt_dhms)
-        else:
-            dt_as_str = self.tr("{:} hour(s)").format(dt_dhms[1])
-        if dt_dhms[2] > 0 or dt_dhms[3] > 0:
-            dt_dhms += ", {:} minute(s) and {:} second(s)".format(*dt_dhms[1:])
-        dt_reeval_dhms = timestamp_to_dhms(params.dt_reeval)
-        dt_reeval_as_str = self.tr("{:} day(s) {:} hour(s)").format(*dt_reeval_dhms)
-
-        message_box = QMessageBox(self)
-
-        message_box.setText("Do you recognize the terms of the following licence :")
-        message_box.setInformativeText("""
-{:} is being produced by a Universal Dividend (UD) for any human member, which is :<br/>
-<br/>
-<table cellpadding="5">
- <tr><td align="right"><b>{:2.0%} / {:} days</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>
- <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
-</table>
-<br/>
-<br/>
-
-The parameters of the Web of Trust of {:} are :<br/>
-<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>
- <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>
- <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
- <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
-</table>
-<br/>
-<br/>
-
-<b>By asking to join as member, you recognize that this is your unique account,
-and that you will only certify persons that you know well enough.</b>
- """.format(
-            ROOT_SERVERS[currency]["display"],
-            params.c,
-            QLocale().toString(params.dt / 86400, 'f', 2),
-            self.tr('Fundamental growth (c)'),
-            params.ud0,
-            self.tr('Initial Universal Dividend UD(0) in'),
-            ROOT_SERVERS[currency]["display"],
-            dt_as_str,
-            self.tr('Time period between two UD'),
-            dt_reeval_as_str,
-            self.tr('Time period between two UD reevaluation'),
-            ROOT_SERVERS[currency]["display"],
-            QLocale().toString(params.sig_period / 86400, 'f', 2),
-            self.tr('Minimum delay between 2 certifications (in days)'),
-            QLocale().toString(params.sig_validity / 86400, 'f', 2),
-            self.tr('Maximum age of a valid signature (in days)'),
-            params.sig_qty,
-            self.tr('Minimum quantity of signatures to be part of the WoT'),
-            params.sig_stock,
-            self.tr('Maximum quantity of active certifications made by member.'),
-            params.sig_window,
-            self.tr('Maximum delay a certification can wait before being expired for non-writing.'),
-            params.xpercent,
-            self.tr('Minimum percent of sentries to reach to match the distance rule'),
-            params.ms_validity / 86400,
-            self.tr('Maximum age of a valid membership (in days)'),
-            params.step_max,
-            self.tr('Maximum distance between each WoT member and a newcomer'),
-        )
-    )
-        message_box.setStandardButtons(QMessageBox.Yes | QMessageBox.No )
-        message_box.setDefaultButton(QMessageBox.No)
-        return await dialog_async_exec(message_box)
-
-    def changeEvent(self, event):
-        """
-        Intercepte LanguageChange event to translate UI
-        :param QEvent QEvent: Event
-        :return:
-        """
-        if event.type() == QEvent.LanguageChange:
-            self.retranslateUi(self)
-        return super().changeEvent(event)
diff --git a/src/sakia/gui/navigation/model.py b/src/sakia/gui/navigation/model.py
index d8bf13d5f484c452d7636f04bb662ef784721cae..d3bbc97c4a4ea7738a3a65523b7ddd1a3389c879 100644
--- a/src/sakia/gui/navigation/model.py
+++ b/src/sakia/gui/navigation/model.py
@@ -34,12 +34,42 @@ class NavigationModel(QObject):
                 'misc': {
                 },
                 'children': []
+            },
+            {
+                'title': self.tr('Identities'),
+                'icon': ':/icons/members_icon',
+                'component': "Identities",
+                'dependencies': {
+                    'blockchain_service': self.app.blockchain_service,
+                    'identities_service': self.app.identities_service,
+                },
+                'misc': {
+                }
+            },
+            {
+                'title': self.tr('Web of Trust'),
+                'icon': ':/icons/wot_icon',
+                'component': "Wot",
+                'dependencies': {
+                    'blockchain_service': self.app.blockchain_service,
+                    'identities_service': self.app.identities_service,
+                },
+                'misc': {
+                }
+            },
+            {
+                'title': self.tr('Personal accounts'),
+                'children': []
             }
         ]
 
         self._current_data = self.navigation[0]
         for connection in self.app.db.connections_repo.get_all():
-            self.navigation[0]['children'].append(self.create_node(connection))
+            self.navigation[3]['children'].append(self.create_node(connection))
+        try:
+            self._current_data = self.navigation[0]
+        except IndexError:
+            self._current_data = None
         return self.navigation
 
     def create_node(self, connection):
@@ -48,71 +78,72 @@ class NavigationModel(QObject):
             title = matching_contact.displayed_text()
         else:
             title = connection.title()
-        node = {
-            'title': title,
-            'component': "Informations",
-            'dependencies': {
-                'blockchain_service': self.app.blockchain_service,
-                'identities_service': self.app.identities_service,
-                'sources_service': self.app.sources_service,
-                'connection': connection,
-            },
-            'misc': {
-                'connection': connection
-            },
-            'children': [
-                {
-                    'title': self.tr('Transfers'),
-                    'icon': ':/icons/tx_icon',
-                    'component': "TxHistory",
-                    'dependencies': {
-                        'connection': connection,
-                        'identities_service': self.app.identities_service,
-                        'blockchain_service': self.app.blockchain_service,
-                        'transactions_service': self.app.transactions_service,
-                        "sources_service": self.app.sources_service
-                    },
-                    'misc': {
-                        'connection': connection
-                    }
-                }
-            ]
-        }
         if connection.uid:
-            node["children"] += [{
-                'title': self.tr('Identities'),
-                'icon': ':/icons/members_icon',
-                'component': "Identities",
+            if self.identity_is_member(connection):
+                icon = ':/icons/member'
+            else:
+                icon = ':/icons/not_member'
+            node = {
+                'title': title,
+                'component': "Informations",
+                'icon': icon,
                 'dependencies': {
-                    'connection': connection,
                     'blockchain_service': self.app.blockchain_service,
                     'identities_service': self.app.identities_service,
+                    'sources_service': self.app.sources_service,
+                    'connection': connection,
                 },
                 'misc': {
                     'connection': connection
-                }
-            },
-            {
-                'title': self.tr('Web of Trust'),
-                'icon': ':/icons/wot_icon',
-                'component': "Wot",
+                },
+                'children': [
+                    {
+                        'title': self.tr('Transfers'),
+                        'icon': ':/icons/tx_icon',
+                        'component': "TxHistory",
+                        'dependencies': {
+                            'connection': connection,
+                            'identities_service': self.app.identities_service,
+                            'blockchain_service': self.app.blockchain_service,
+                            'transactions_service': self.app.transactions_service,
+                            "sources_service": self.app.sources_service
+                        },
+                        'misc': {
+                            'connection': connection
+                        }
+                    }
+                ]
+            }
+        else:
+            node = {
+                'title': title,
+                'component': "TxHistory",
+                'icon': ':/icons/tx_icon',
                 'dependencies': {
                     'connection': connection,
-                    'blockchain_service': self.app.blockchain_service,
                     'identities_service': self.app.identities_service,
+                    'blockchain_service': self.app.blockchain_service,
+                    'transactions_service': self.app.transactions_service,
+                    "sources_service": self.app.sources_service
                 },
                 'misc': {
                     'connection': connection
-                }
-            }]
+                },
+                'children': []
+            }
+
         return node
 
+    def view_in_wot(self, connection):
+        identity = self.app.identities_service.get_identity(connection.pubkey, connection.uid)
+        self.app.view_in_wot.emit(identity)
+
     def generic_tree(self):
-        return GenericTreeModel.create("Navigation", self.navigation)
+        return GenericTreeModel.create("Navigation", self.navigation[3]['children'])
 
     def add_connection(self, connection):
         raw_node = self.create_node(connection)
-        self.navigation[0]["children"].append(raw_node)
+        self.navigation[3]["children"].append(raw_node)
         return raw_node
 
     def set_current_data(self, raw_data):
@@ -123,9 +154,12 @@ class NavigationModel(QObject):
 
     def _lookup_raw_data(self, raw_data, component, **kwargs):
         if raw_data['component'] == component:
-            for k in kwargs:
-                if raw_data['misc'].get(k, None) == kwargs[k]:
-                    return raw_data
+            if kwargs:
+                for k in kwargs:
+                    if raw_data['misc'].get(k, None) == kwargs[k]:
+                        return raw_data
+            else:
+                return raw_data
         for c in raw_data.get('children', []):
             children_data = self._lookup_raw_data(c, component, **kwargs)
             if children_data:
@@ -133,7 +167,9 @@ class NavigationModel(QObject):
 
     def get_raw_data(self, component, **kwargs):
         for data in self.navigation:
-            return self._lookup_raw_data(data, component, **kwargs)
+            raw_data = self._lookup_raw_data(data, component, **kwargs)
+            if raw_data:
+                return raw_data
 
     def current_connection(self):
         if self._current_data:
@@ -141,20 +177,34 @@ class NavigationModel(QObject):
         else:
             return None
 
-    def generate_revokation(self, connection, secret_key, password):
-        return self.app.documents_service.generate_revokation(connection, secret_key, password)
+    def generate_revocation(self, connection, secret_key, password):
+        return self.app.documents_service.generate_revocation(connection, secret_key, password)
 
     def identity_published(self, connection):
-        return self.app.identities_service.get_identity(connection.pubkey, connection.uid).written
+        identity = self.app.identities_service.get_identity(connection.pubkey, connection.uid)
+        if identity:
+            return identity.written
+        else:
+            return False
 
     def identity_is_member(self, connection):
-        return self.app.identities_service.get_identity(connection.pubkey, connection.uid).member
+        identity = self.app.identities_service.get_identity(connection.pubkey, connection.uid)
+        if identity:
+            return identity.member
+        else:
+            return False
 
     async def remove_connection(self, connection):
         for data in self.navigation:
             connected_to = self._current_data['misc'].get('connection', None)
             if connected_to == connection:
-                self._current_data['widget'].disconnect()
+                try:
+                    self._current_data['widget'].disconnect()
+                except TypeError as e:
+                    if "disconnect()" in str(e):
+                        pass
+                    else:
+                        raise
         await self.app.remove_connection(connection)
 
     async def send_leave(self, connection, secret_key, password):
@@ -169,6 +219,9 @@ class NavigationModel(QObject):
     def update_identity(self, identity):
         self.app.identities_service.insert_or_update_identity(identity)
 
+    def notifications(self):
+        return self.app.parameters.notifications
+
     @staticmethod
     def copy_pubkey_to_clipboard(connection):
         clipboard = QApplication.clipboard()
diff --git a/src/sakia/gui/navigation/network/model.py b/src/sakia/gui/navigation/network/model.py
index 669fae3f6f953fe8e9e040e68802cf228e581557..f6b7f5a1cc8bda00f0c3dffb37b2e8dccf70c007 100644
--- a/src/sakia/gui/navigation/network/model.py
+++ b/src/sakia/gui/navigation/network/model.py
@@ -43,6 +43,8 @@ class NetworkModel(QObject):
         """
         if index.isValid() and index.row() < self.table_model.rowCount(QModelIndex()):
             source_index = self.table_model.mapToSource(index)
-            node = self.network_service.nodes()[source_index.row()]
-            return True, node
+            node_col = NetworkTableModel.columns_types.index('node')
+            node_index = self.table_model.sourceModel().index(source_index.row(), node_col)
+            source_data = self.table_model.sourceModel().data(node_index, Qt.DisplayRole)
+            return True, source_data
         return False, None
diff --git a/src/sakia/gui/navigation/network/table_model.py b/src/sakia/gui/navigation/network/table_model.py
index 77c3c2a4143ed89e1855531dcb1979b8a83d98d9..fff9b5d2c8fbb99fb1af051897755b82f9a5b7f0 100644
--- a/src/sakia/gui/navigation/network/table_model.py
+++ b/src/sakia/gui/navigation/network/table_model.py
@@ -67,7 +67,9 @@ class NetworkFilterProxyModel(QSortFilterProxyModel):
 
         if role == Qt.DisplayRole:
             if index.column() == NetworkTableModel.columns_types.index('is_member'):
-                value = {True: QT_TRANSLATE_NOOP("NetworkTableModel", 'yes'), False: QT_TRANSLATE_NOOP("NetworkTableModel", 'no'), None: QT_TRANSLATE_NOOP("NetworkTableModel", 'offline')}
+                value = {True: QT_TRANSLATE_NOOP("NetworkTableModel", 'yes'),
+                         False: QT_TRANSLATE_NOOP("NetworkTableModel", 'no'),
+                         None: QT_TRANSLATE_NOOP("NetworkTableModel", 'offline')}
                 return value[source_data]
 
             if index.column() == NetworkTableModel.columns_types.index('pubkey'):
@@ -92,7 +94,7 @@ class NetworkFilterProxyModel(QSortFilterProxyModel):
                             QLocale(),
                             QDateTime.fromTime_t(ts),
                             QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
-                        )
+                        ) + " BAT"
 
         if role == Qt.TextAlignmentRole:
             if source_index.column() == NetworkTableModel.columns_types.index('address') or source_index.column() == self.sourceModel().columns_types.index('current_block'):
@@ -140,7 +142,8 @@ class NetworkTableModel(QAbstractTableModel):
         'software',
         'version',
         'is_root',
-        'state'
+        'state',
+        'node'
     )
 
     DESYNCED = 3
@@ -213,7 +216,8 @@ class NetworkTableModel(QAbstractTableModel):
             state = NetworkTableModel.DESYNCED
 
         return (address, port, number, block_hash, block_time, node.uid,
-                node.member, node.pubkey, node.software, node.version, node.root, state)
+                node.member, node.pubkey, node.software, node.version, node.root, state,
+                node)
 
     def init_nodes(self, current_buid=None):
         self._logger.debug("Init nodes table")
diff --git a/src/sakia/gui/navigation/txhistory/controller.py b/src/sakia/gui/navigation/txhistory/controller.py
index 965c21a16a5d04a447bc7afcff6c020594067fb3..80d8496e702a1ecd79f61da385624b6d3d8004ed 100644
--- a/src/sakia/gui/navigation/txhistory/controller.py
+++ b/src/sakia/gui/navigation/txhistory/controller.py
@@ -6,7 +6,7 @@ from PyQt5.QtGui import QCursor
 from sakia.decorators import asyncify
 from sakia.gui.widgets import toast
 from sakia.gui.widgets.context_menu import ContextMenu
-from sakia.data.entities import Identity, Transaction
+from sakia.gui.sub.transfer.controller import TransferController
 from .model import TxHistoryModel
 from .view import TxHistoryView
 
@@ -17,10 +17,17 @@ class TxHistoryController(QObject):
     """
     view_in_wot = pyqtSignal(object)
 
-    def __init__(self, view, model):
+    def __init__(self, view, model, transfer):
+        """
+
+        :param TxHistoryView view:
+        :param TxHistoryModel model:
+        :param sakia.gui.sub.transfer.controller.TransferController transfer:
+        """
         super().__init__()
         self.view = view
         self.model = model
+        self.transfer = transfer
         self._logger = logging.getLogger('sakia')
         ts_from, ts_to = self.view.get_time_frame()
         model = self.model.init_history_table_model(ts_from, ts_to)
@@ -35,14 +42,18 @@ class TxHistoryController(QObject):
     def create(cls, parent, app, connection,
                identities_service, blockchain_service, transactions_service, sources_service):
 
-        view = TxHistoryView(parent.view)
+        transfer = TransferController.integrate_to_main_view(None, app, connection)
+        view = TxHistoryView(parent.view, transfer.view)
         model = TxHistoryModel(None, app, connection, blockchain_service, identities_service,
                                transactions_service, sources_service)
-        txhistory = cls(view, model)
+        txhistory = cls(view, model, transfer)
         model.setParent(txhistory)
         app.referential_changed.connect(txhistory.refresh_balance)
         app.sources_refreshed.connect(txhistory.refresh_balance)
-        txhistory.view_in_wot.connect(lambda i: app.view_in_wot.emit(connection, i))
+        txhistory.view_in_wot.connect(app.view_in_wot)
+        txhistory.view.spin_page.valueChanged.connect(model.change_page)
+        transfer.accepted.connect(view.clear)
+        transfer.rejected.connect(view.clear)
         return txhistory
 
     def refresh_minimum_maximum(self):
@@ -55,13 +66,14 @@ class TxHistoryController(QObject):
     def refresh(self):
         self.refresh_minimum_maximum()
         self.refresh_balance()
+        self.refresh_pages()
 
     @asyncify
     async def notification_reception(self, received_list):
         if len(received_list) > 0:
             localized_amount = await self.model.received_amount(received_list)
             text = self.tr("Received {amount} from {number} transfers").format(amount=localized_amount,
-                                                                           number=len(received_list))
+                                                                               number=len(received_list))
             if self.model.notifications():
                 toast.display(self.tr("New transactions received"), text)
 
@@ -69,6 +81,10 @@ class TxHistoryController(QObject):
         localized_amount = self.model.localized_balance()
         self.view.set_balance(localized_amount)
 
+    def refresh_pages(self):
+        pages = self.model.max_pages()
+        self.view.set_max_pages(pages)
+
     def history_context_menu(self, point):
         index = self.view.table_history.indexAt(point)
         valid, identities, transfer = self.model.table_data(index)
@@ -92,3 +108,5 @@ class TxHistoryController(QObject):
             self.view.table_history.model().set_period(ts_from, ts_to)
 
             self.refresh_balance()
+            self.refresh_pages()
+
diff --git a/src/sakia/gui/navigation/txhistory/delegate.py b/src/sakia/gui/navigation/txhistory/delegate.py
index 80779be0c1389e935acd68dd43506ffc68ce37bd..4c28df7dd587a51b8679940a999c8b08baf13ecf 100644
--- a/src/sakia/gui/navigation/txhistory/delegate.py
+++ b/src/sakia/gui/navigation/txhistory/delegate.py
@@ -13,7 +13,7 @@ class TxHistoryDelegate(QStyledItemDelegate):
         style = QApplication.style()
 
         doc = QTextDocument()
-        if index.column() == HistoryTableModel.columns_types.index('uid'):
+        if index.column() == HistoryTableModel.columns_types.index('pubkey'):
             doc.setHtml(option.text)
         else:
             doc.setPlainText(option.text)
@@ -39,7 +39,7 @@ class TxHistoryDelegate(QStyledItemDelegate):
         self.initStyleOption(option, index)
 
         doc = QTextDocument()
-        if index.column() == HistoryTableModel.columns_types.index('uid'):
+        if index.column() == HistoryTableModel.columns_types.index('pubkey'):
             doc.setHtml(option.text)
         else:
             doc.setPlainText("")
diff --git a/src/sakia/gui/navigation/txhistory/model.py b/src/sakia/gui/navigation/txhistory/model.py
index 5fea05231bcb7a163092caf66bb5a3fff910df79..4a0b674c8dc9ff0fe5d52a64a4a445498f6f0572 100644
--- a/src/sakia/gui/navigation/txhistory/model.py
+++ b/src/sakia/gui/navigation/txhistory/model.py
@@ -1,8 +1,9 @@
 from PyQt5.QtCore import QObject
-from .table_model import HistoryTableModel, TxFilterProxyModel
+from .table_model import HistoryTableModel
 from PyQt5.QtCore import Qt, QDateTime, QTime, pyqtSignal, QModelIndex
 from sakia.errors import NoPeerAvailable
 from duniterpy.api import errors
+from sakia.data.entities import Identity
 
 import logging
 
@@ -31,7 +32,6 @@ class TxHistoryModel(QObject):
         self.transactions_service = transactions_service
         self.sources_service = sources_service
         self._model = None
-        self._proxy = None
 
     def init_history_table_model(self, ts_from, ts_to):
         """
@@ -40,19 +40,21 @@ class TxHistoryModel(QObject):
         :param int ts_to: date to where to filter tx
         :return:
         """
-        self._model = HistoryTableModel(self, self.app, self.connection,
+        self._model = HistoryTableModel(self, self.app, self.connection, ts_from, ts_to,
                                         self.identities_service, self.transactions_service)
-        self._proxy = TxFilterProxyModel(self, ts_from, ts_to, self.blockchain_service)
-        self._proxy.setSourceModel(self._model)
-        self._proxy.setDynamicSortFilter(True)
-        self._proxy.setSortRole(Qt.DisplayRole)
         self._model.init_transfers()
-        self.app.new_transfer.connect(self._model.add_transfer)
-        self.app.new_dividend.connect(self._model.add_dividend)
+        self.app.new_transfer.connect(self._model.init_transfers)
+        self.app.new_dividend.connect(self._model.init_transfers)
         self.app.transaction_state_changed.connect(self._model.change_transfer)
         self.app.referential_changed.connect(self._model.modelReset)
 
-        return self._proxy
+        return self._model
+
+    def change_page(self, page):
+        self._model.set_current_page(page)
+
+    def max_pages(self):
+        return self._model.pages()
 
     def table_data(self, index):
         """
@@ -61,16 +63,18 @@ class TxHistoryModel(QObject):
         :return: tuple containing (Identity, Transfer)
         """
         if index.isValid() and index.row() < self.table_model.rowCount(QModelIndex()):
-            source_index = self.table_model.mapToSource(index)
-
-            pubkey_col = self.table_model.sourceModel().columns_types.index('pubkey')
-            pubkey_index = self.table_model.sourceModel().index(source_index.row(), pubkey_col)
-            pubkeys = self.table_model.sourceModel().data(pubkey_index, Qt.DisplayRole)
-            identities = []
+            pubkey_col = self._model.columns_types.index('pubkey')
+            pubkey_index = self._model.index(index.row(), pubkey_col)
+            pubkeys = self._model.data(pubkey_index, Qt.DisplayRole)
+            identities_or_pubkeys = []
             for pubkey in pubkeys:
-                identities.append(self.identities_service.get_identity(pubkey))
-            transfer = self._model.transfers_data[source_index.row()][self._model.columns_types.index('raw_data')]
-            return True, identities, transfer
+                identity = self.identities_service.get_identity(pubkey)
+                if identity:
+                    identities_or_pubkeys.append(identity)
+                else:
+                    identities_or_pubkeys.append(pubkey)
+            transfer = self._model.transfers_data[index.row()][self._model.columns_types.index('raw_data')]
+            return True,  identities_or_pubkeys, transfer
         return False, [], None
 
     def minimum_maximum_datetime(self):
@@ -80,7 +84,7 @@ class TxHistoryModel(QObject):
         :return: minimum and maximum datetime
         """
         minimum_datetime = QDateTime()
-        minimum_datetime.setTime_t(0)
+        minimum_datetime.setTime_t(1488322800) # First of may 2017
         tomorrow_datetime = QDateTime().currentDateTime().addDays(1)
         return minimum_datetime, tomorrow_datetime
 
@@ -118,7 +122,7 @@ class TxHistoryModel(QObject):
 
     @property
     def table_model(self):
-        return self._proxy
+        return self._model
 
     def notifications(self):
         return self.app.parameters.notifications
diff --git a/src/sakia/gui/navigation/txhistory/sql_adapter.py b/src/sakia/gui/navigation/txhistory/sql_adapter.py
new file mode 100644
index 0000000000000000000000000000000000000000..5bcfbd11bb49cca2d03e6f4bc341e95644f78dfe
--- /dev/null
+++ b/src/sakia/gui/navigation/txhistory/sql_adapter.py
@@ -0,0 +1,137 @@
+import math
+import attr
+
+
+TX_HISTORY_REQUEST = """
+SELECT 
+      transactions.ts,
+      transactions.pubkey,
+      total_amount((amount * -1), amountbase) as amount,
+      transactions.comment ,
+      transactions.sha_hash,
+      transactions.written_on,
+      transactions.txid
+    FROM 
+      transactions
+    WHERE 
+      transactions.currency = ? 
+      and transactions.pubkey = ? 
+      AND transactions.ts >= ? 
+      and transactions.ts <= ? 
+      AND transactions.issuers LIKE "%{pubkey}%"
+UNION ALL
+SELECT 
+      transactions.ts,
+      transactions.pubkey,
+      total_amount(amount, amountbase) as amount,
+      transactions.comment ,
+      transactions.sha_hash,
+      transactions.written_on,
+      transactions.txid
+    FROM 
+      transactions
+    WHERE 
+      transactions.currency = ? 
+      and transactions.pubkey = ? 
+      AND transactions.ts >= ? 
+      and transactions.ts <= ? 
+      AND transactions.receivers LIKE "%{pubkey}%"
+UNION ALL
+SELECT 
+      dividends.timestamp as ts,
+      dividends.pubkey ,
+      total_amount(amount, base) as amount,
+      NULL as comment,
+      NULL as sha_hash,
+      dividends.block_number AS written_on,
+      0 as txid
+    FROM 
+      dividends
+    WHERE 
+      dividends.currency = ? 
+      and dividends.pubkey =? 
+      AND dividends.timestamp >= ? 
+      and dividends.timestamp <= ?
+"""
+
+PAGE_LENGTH = 50
+
+
+@attr.s(frozen=True)
+class TxHistorySqlAdapter:
+    _conn = attr.ib()  # :type sqlite3.Connection
+
+    def _transfers_and_dividends(self, currency, pubkey, ts_from, ts_to, offset=0, limit=1000,
+                                    sort_by="currency", sort_order="ASC"):
+        """
+        Get all transfers in the database on a given currency from or to a pubkey
+
+        :param str pubkey: the criterions of the lookup
+        :rtype: List[sakia.data.entities.Transaction]
+        """
+        request = (TX_HISTORY_REQUEST + """
+ORDER BY {sort_by} {sort_order}, txid {sort_order}
+LIMIT {limit} OFFSET {offset}""").format(offset=offset,
+                                         limit=limit,
+                                         sort_by=sort_by,
+                                         sort_order=sort_order,
+                                         pubkey=pubkey
+                                         )
+        c = self._conn.execute(request, (currency, pubkey, ts_from, ts_to,
+                                         currency, pubkey, ts_from, ts_to,
+                                         currency, pubkey, ts_from, ts_to))
+        datas = c.fetchall()
+        if datas:
+            return datas
+        return []
+
+    def _transfers_and_dividends_count(self, currency, pubkey, ts_from, ts_to):
+        """
+        Get all transfers in the database on a given currency from or to a pubkey
+
+        :param str pubkey: the criterions of the lookup
+        :rtype: List[sakia.data.entities.Transaction]
+        """
+        request = ("""
+SELECT COUNT(*)
+FROM (
+""" + TX_HISTORY_REQUEST + ")").format(pubkey=pubkey)
+        c = self._conn.execute(request, (currency, pubkey, ts_from, ts_to,
+                                                    currency, pubkey, ts_from, ts_to,
+                                                    currency, pubkey, ts_from, ts_to))
+        datas = c.fetchone()
+        if datas:
+            return datas[0]
+        return 0
+
+    def transfers_and_dividends(self, currency, pubkey, page, ts_from, ts_to, sort_by, sort_order):
+        """
+        Get all transfers and dividends from or to a given pubkey
+        :param str currency:
+        :param str pubkey:
+        :param int page:
+        :param int ts_from:
+        :param int ts_to:
+        :return: the list of Transaction entities
+        :rtype: List[sakia.data.entities.Transaction]
+        """
+        return self._transfers_and_dividends(currency, pubkey, ts_from, ts_to,
+                                                      offset=page*PAGE_LENGTH,
+                                                      limit=PAGE_LENGTH,
+                                                      sort_by=sort_by, sort_order=sort_order)
+
+    def pages(self, currency, pubkey, ts_from, ts_to):
+        """
+        Get all transfers and dividends from or to a given pubkey
+        :param str currency:
+        :param str pubkey:
+        :param int page:
+        :param int ts_from:
+        :param int ts_to:
+        :return: the list of Transaction entities
+        :rtype: List[sakia.data.entities.Transaction]
+        """
+        count = self._transfers_and_dividends_count(currency, pubkey, ts_from, ts_to)
+        return int(count / PAGE_LENGTH)
+
+
diff --git a/src/sakia/gui/navigation/txhistory/table_model.py b/src/sakia/gui/navigation/txhistory/table_model.py
index a50b238162ee31123cac826b7bf317830f67eab1..0952ba79377df41a0a8a9f51acbb14f943542b84 100644
--- a/src/sakia/gui/navigation/txhistory/table_model.py
+++ b/src/sakia/gui/navigation/txhistory/table_model.py
@@ -7,154 +7,8 @@ from PyQt5.QtGui import QFont, QColor
 from sakia.data.entities import Transaction
 from sakia.constants import MAX_CONFIRMATIONS
 from sakia.data.processors import BlockchainProcessor
-
-
-class TxFilterProxyModel(QSortFilterProxyModel):
-    def __init__(self, parent, ts_from, ts_to, blockchain_service):
-        """
-        History of all transactions
-        :param PyQt5.QtWidgets.QWidget parent: parent widget
-        :param int ts_from: the min timestamp of latest tx
-        :param in ts_to: the max timestamp of most recent tx
-        :param sakia.services.BlockchainService blockchain_service: the blockchain service
-        """
-        super().__init__(parent)
-        self.app = None
-        self.ts_from = ts_from
-        self.ts_to = ts_to
-        self.blockchain_service = blockchain_service
-        self.blockchain_processor = BlockchainProcessor.instanciate(blockchain_service.app)
-
-    def set_period(self, ts_from, ts_to):
-        """
-        Filter table by given timestamps
-        """
-        logging.debug("Filtering from {0} to {1}".format(
-            datetime.datetime.fromtimestamp(ts_from).isoformat(' '),
-            datetime.datetime.fromtimestamp(ts_to).isoformat(' '))
-        )
-        self.beginResetModel()
-        self.ts_from = ts_from
-        self.ts_to = ts_to
-        self.endResetModel()
-
-    def filterAcceptsRow(self, sourceRow, sourceParent):
-        def in_period(date_ts):
-            return date_ts in range(self.ts_from, self.ts_to)
-
-        source_model = self.sourceModel()
-        date_col = source_model.columns_types.index('date')
-        source_index = source_model.index(sourceRow, date_col)
-        date = source_model.data(source_index, Qt.DisplayRole)
-
-        return in_period(date)
-
-    def columnCount(self, parent):
-        return self.sourceModel().columnCount(None) - 6
-
-    def setSourceModel(self, source_model):
-        self.app = source_model.app
-        super().setSourceModel(source_model)
-
-    def lessThan(self, left, right):
-        """
-        Sort table by given column number.
-        """
-        source_model = self.sourceModel()
-        left_data = source_model.data(left, Qt.DisplayRole)
-        right_data = source_model.data(right, Qt.DisplayRole)
-        if left_data == "":
-            return self.sortOrder() == Qt.DescendingOrder
-        elif right_data == "":
-            return self.sortOrder() == Qt.AscendingOrder
-        if left_data == right_data:
-            txid_col = source_model.columns_types.index('txid')
-            txid_left = source_model.index(left.row(), txid_col)
-            txid_right = source_model.index(right.row(), txid_col)
-            return txid_left < txid_right
-
-        return left_data < right_data
-
-    def data(self, index, role):
-        source_index = self.mapToSource(index)
-        model = self.sourceModel()
-        source_data = model.data(source_index, role)
-        state_col = model.columns_types.index('state')
-        state_index = model.index(source_index.row(), state_col)
-        state_data = model.data(state_index, Qt.DisplayRole)
-
-        block_col = model.columns_types.index('block_number')
-        block_index = model.index(source_index.row(), block_col)
-        block_data = model.data(block_index, Qt.DisplayRole)
-
-        if state_data == Transaction.VALIDATED and block_data:
-            current_confirmations = self.blockchain_service.current_buid().number - block_data
-        else:
-            current_confirmations = 0
-
-        if role == Qt.DisplayRole:
-            if source_index.column() == model.columns_types.index('uid'):
-                return "<p>" + source_data.replace('\n', "<br>") + "</p>"
-            if source_index.column() == model.columns_types.index('date'):
-                ts = self.blockchain_processor.adjusted_ts(model.connection.currency, source_data)
-                return QLocale.toString(
-                    QLocale(),
-                    QDateTime.fromTime_t(ts).date(),
-                    QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
-                )
-            if source_index.column() == model.columns_types.index('amount'):
-                amount = self.app.current_ref.instance(source_data, model.connection.currency,
-                                                       self.app, block_data).diff_localized(False, False)
-                return amount
-            return source_data
-
-        if role == Qt.FontRole:
-            font = QFont()
-            if state_data == Transaction.AWAITING or \
-                    (state_data == Transaction.VALIDATED and current_confirmations < MAX_CONFIRMATIONS):
-                font.setItalic(True)
-            elif state_data == Transaction.REFUSED:
-                font.setItalic(True)
-            elif state_data == Transaction.TO_SEND:
-                font.setBold(True)
-            else:
-                font.setItalic(False)
-            return font
-
-        if role == Qt.ForegroundRole:
-            if state_data == Transaction.REFUSED:
-                return QColor(Qt.darkGray)
-            elif state_data == Transaction.TO_SEND:
-                return QColor(Qt.blue)
-            if source_index.column() == model.columns_types.index('amount'):
-                if source_data < 0:
-                    return QColor(Qt.darkRed)
-                elif state_data == HistoryTableModel.DIVIDEND:
-                    return QColor(Qt.darkBlue)
-            if state_data == Transaction.AWAITING or \
-                    (state_data == Transaction.VALIDATED and current_confirmations == 0):
-                return QColor("#ffb000")
-
-        if role == Qt.TextAlignmentRole:
-            if self.sourceModel().columns_types.index('amount'):
-                return Qt.AlignRight | Qt.AlignVCenter
-            if source_index.column() == model.columns_types.index('date'):
-                return Qt.AlignCenter
-
-        if role == Qt.ToolTipRole:
-            if source_index.column() == model.columns_types.index('date'):
-                ts = self.blockchain_processor.adjusted_ts(model.connection.currency, source_data)
-                return QDateTime.fromTime_t(ts).toString(Qt.SystemLocaleLongDate)
-
-            if state_data == Transaction.VALIDATED or state_data == Transaction.AWAITING:
-                if current_confirmations >= MAX_CONFIRMATIONS:
-                    return None
-                elif self.app.parameters.expert_mode:
-                    return self.tr("{0} / {1} confirmations").format(current_confirmations, MAX_CONFIRMATIONS)
-                else:
-                    confirmation = current_confirmations / MAX_CONFIRMATIONS * 100
-                    confirmation = 100 if confirmation > 100 else confirmation
-                    return self.tr("Confirming... {0} %").format(QLocale().toString(float(confirmation), 'f', 0))
+from .sql_adapter import TxHistorySqlAdapter
+from sakia.data.repositories import TransactionsRepo, DividendsRepo
 
 
 class HistoryTableModel(QAbstractTableModel):
@@ -166,7 +20,7 @@ class HistoryTableModel(QAbstractTableModel):
 
     columns_types = (
         'date',
-        'uid',
+        'pubkey',
         'amount',
         'comment',
         'state',
@@ -177,14 +31,21 @@ class HistoryTableModel(QAbstractTableModel):
         'raw_data'
     )
 
+    columns_to_sql = {
+        'date': "ts",
+        "pubkey": "pubkey",
+        "amount": "amount",
+        "comment": "comment"
+    }
+
     columns_headers = (
         QT_TRANSLATE_NOOP("HistoryTableModel", 'Date'),
-        QT_TRANSLATE_NOOP("HistoryTableModel", 'UID/Public key'),
+        QT_TRANSLATE_NOOP("HistoryTableModel", 'Public key'),
         QT_TRANSLATE_NOOP("HistoryTableModel", 'Amount'),
         QT_TRANSLATE_NOOP("HistoryTableModel", 'Comment')
     )
 
-    def __init__(self, parent, app, connection, identities_service, transactions_service):
+    def __init__(self, parent, app, connection, ts_from, ts_to,  identities_service, transactions_service):
         """
         History of all transactions
         :param PyQt5.QtWidgets.QWidget parent: parent widget
@@ -198,37 +59,50 @@ class HistoryTableModel(QAbstractTableModel):
         self.connection = connection
         self.blockchain_processor = BlockchainProcessor.instanciate(app)
         self.identities_service = identities_service
-        self.transactions_service = transactions_service
+        self.sql_adapter = TxHistorySqlAdapter(self.app.db.conn)
+        self.transactions_repo = TransactionsRepo(self.app.db.conn)
+        self.dividends_repo = DividendsRepo(self.app.db.conn)
+        self.current_page = 0
+        self.ts_from = ts_from
+        self.ts_to = ts_to
+        self.main_column_id = HistoryTableModel.columns_types[0]
+        self.order = Qt.AscendingOrder
         self.transfers_data = []
 
-    def transfers(self):
+    def set_period(self, ts_from, ts_to):
         """
-        Transfer
-        :rtype: List[sakia.data.entities.Transfer]
+        Filter table by given timestamps
         """
-        return self.transactions_service.transfers(self.connection.pubkey)
+        logging.debug("Filtering from {0} to {1}".format(
+            datetime.datetime.fromtimestamp(ts_from).isoformat(' '),
+            datetime.datetime.fromtimestamp(ts_to).isoformat(' '))
+        )
+        self.ts_from = ts_from
+        self.ts_to = ts_to
+        self.init_transfers()
 
-    def dividends(self):
+    def set_current_page(self, page):
+        self.current_page = page - 1
+        self.init_transfers()
+
+    def pages(self):
+        return self.sql_adapter.pages(self.app.currency,
+                                      self.connection.pubkey,
+                                      ts_from=self.ts_from,
+                                      ts_to=self.ts_to)
+
+    def transfers_and_dividends(self):
         """
         Transfer
-        :rtype: List[sakia.data.entities.Dividend]
+        :rtype: List[sakia.data.entities.Transfer]
         """
-        return self.transactions_service.dividends(self.connection.pubkey)
-
-    def add_transfer(self, connection, transfer):
-        if self.connection == connection:
-            self.beginInsertRows(QModelIndex(), len(self.transfers_data), len(self.transfers_data))
-            if self.connection.pubkey in transfer.issuers:
-                self.transfers_data.append(self.data_sent(transfer))
-            if self.connection.pubkey in transfer.receivers:
-                self.transfers_data.append(self.data_received(transfer))
-            self.endInsertRows()
-
-    def add_dividend(self, connection, dividend):
-        if self.connection == connection:
-            self.beginInsertRows(QModelIndex(), len(self.transfers_data), len(self.transfers_data))
-            self.transfers_data.append(self.data_dividend(dividend))
-            self.endInsertRows()
+        return self.sql_adapter.transfers_and_dividends(self.app.currency,
+                                                        self.connection.pubkey,
+                                                        page=self.current_page,
+                                                        ts_from=self.ts_from,
+                                                        ts_to=self.ts_to,
+                                                        sort_by=HistoryTableModel.columns_to_sql[self.main_column_id],
+                                                        sort_order= "ASC" if Qt.AscendingOrder else "DESC")
 
     def change_transfer(self, transfer):
         for i, data in enumerate(self.transfers_data):
@@ -244,7 +118,6 @@ class HistoryTableModel(QAbstractTableModel):
                     if self.connection.pubkey in transfer.receivers:
                         self.transfers_data[i] = self.data_received(transfer)
                         self.dataChanged.emit(self.index(i, 0), self.index(i, len(HistoryTableModel.columns_types)))
-                return
 
     def data_received(self, transfer):
         """
@@ -260,7 +133,7 @@ class HistoryTableModel(QAbstractTableModel):
         for issuer in transfer.issuers:
             identity = self.identities_service.get_identity(issuer)
             if identity:
-                senders.append(identity.uid)
+                senders.append(issuer + " (" + identity.uid + ")")
             else:
                 senders.append(issuer)
 
@@ -284,7 +157,7 @@ class HistoryTableModel(QAbstractTableModel):
         for receiver in transfer.receivers:
             identity = self.identities_service.get_identity(receiver)
             if identity:
-                receivers.append(identity.uid)
+                receivers.append(receiver + " (" + identity.uid + ")")
             else:
                 receivers.append(receiver)
 
@@ -304,7 +177,7 @@ class HistoryTableModel(QAbstractTableModel):
         amount = dividend.amount * 10**dividend.base
         identity = self.identities_service.get_identity(dividend.pubkey)
         if identity:
-            receiver = identity.uid
+            receiver = dividend.pubkey + " (" + identity.uid + ")"
         else:
             receiver = dividend.pubkey
 
@@ -315,28 +188,41 @@ class HistoryTableModel(QAbstractTableModel):
     def init_transfers(self):
         self.beginResetModel()
         self.transfers_data = []
-        transfers = self.transfers()
-        for transfer in transfers:
-            if transfer.state != Transaction.DROPPED:
-                if self.connection.pubkey in transfer.issuers:
-                    self.transfers_data.append(self.data_sent(transfer))
-                if self.connection.pubkey in transfer.receivers:
-                    self.transfers_data.append(self.data_received(transfer))
-        dividends = self.dividends()
-        for dividend in dividends:
-            self.transfers_data.append(self.data_dividend(dividend))
+        transfers_and_dividends = self.transfers_and_dividends()
+        for data in transfers_and_dividends:
+            if data[4]: # If data is transfer, it has a sha_hash column
+                transfer = self.transactions_repo.get_one(currency=self.app.currency,
+                                                          pubkey=self.connection.pubkey,
+                                                          sha_hash=data[4])
+
+                if transfer.state != Transaction.DROPPED:
+                    if data[2] < 0:
+                        self.transfers_data.append(self.data_sent(transfer))
+                    else:
+                        self.transfers_data.append(self.data_received(transfer))
+            else:
+                # else we get the dividend depending on the block number
+                dividend = self.dividends_repo.get_one(currency=self.app.currency,
+                                                       pubkey=self.connection.pubkey,
+                                                       block_number=data[5])
+                self.transfers_data.append(self.data_dividend(dividend))
         self.endResetModel()
 
     def rowCount(self, parent):
         return len(self.transfers_data)
 
     def columnCount(self, parent):
-        return len(HistoryTableModel.columns_types)
+        return len(HistoryTableModel.columns_types) - 6
+
+    def sort(self, main_column, order):
+        self.main_column_id = self.columns_types[main_column]
+        self.order = order
+        self.init_transfers()
 
     def headerData(self, section, orientation, role):
         if orientation == Qt.Horizontal and role == Qt.DisplayRole:
             if HistoryTableModel.columns_types[section] == 'amount':
-                dividend, base = self.blockchain_processor.last_ud(self.transactions_service.currency)
+                dividend, base = self.blockchain_processor.last_ud(self.app.currency)
                 header = '{:}'.format(HistoryTableModel.columns_headers[section])
                 if self.app.current_ref.base_str(base):
                     header += " ({:})".format(self.app.current_ref.base_str(base))
@@ -350,8 +236,78 @@ class HistoryTableModel(QAbstractTableModel):
         if not index.isValid():
             return QVariant()
 
-        if role in (Qt.DisplayRole, Qt.ForegroundRole, Qt.ToolTipRole):
-            return self.transfers_data[row][col]
+        source_data = self.transfers_data[row][col]
+        state_data = self.transfers_data[row][HistoryTableModel.columns_types.index('state')]
+        block_data = self.transfers_data[row][HistoryTableModel.columns_types.index('block_number')]
+
+        if state_data == Transaction.VALIDATED and block_data:
+            current_confirmations = self.blockchain_processor.current_buid(self.app.currency).number - block_data
+        else:
+            current_confirmations = 0
+
+        if role == Qt.DisplayRole:
+            if col == HistoryTableModel.columns_types.index('pubkey'):
+                return "<p>" + source_data.replace('\n', "<br>") + "</p>"
+            if col == HistoryTableModel.columns_types.index('date'):
+                ts = self.blockchain_processor.adjusted_ts(self.connection.currency, source_data)
+                return QLocale.toString(
+                    QLocale(),
+                    QDateTime.fromTime_t(ts).date(),
+                    QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
+                ) + " BAT"
+            if col == HistoryTableModel.columns_types.index('amount'):
+                amount = self.app.current_ref.instance(source_data, self.connection.currency,
+                                                       self.app, block_data).diff_localized(False, False)
+                return amount
+            return source_data
+
+        if role == Qt.FontRole:
+            font = QFont()
+            if state_data == Transaction.AWAITING or \
+                    (state_data == Transaction.VALIDATED and current_confirmations < MAX_CONFIRMATIONS):
+                font.setItalic(True)
+            elif state_data == Transaction.REFUSED:
+                font.setItalic(True)
+            elif state_data == Transaction.TO_SEND:
+                font.setBold(True)
+            else:
+                font.setItalic(False)
+            return font
+
+        if role == Qt.ForegroundRole:
+            if state_data == Transaction.REFUSED:
+                return QColor(Qt.darkGray)
+            elif state_data == Transaction.TO_SEND:
+                return QColor(Qt.blue)
+            if col == HistoryTableModel.columns_types.index('amount'):
+                if source_data < 0:
+                    return QColor(Qt.darkRed)
+                elif state_data == HistoryTableModel.DIVIDEND:
+                    return QColor(Qt.darkBlue)
+            if state_data == Transaction.AWAITING or \
+                    (state_data == Transaction.VALIDATED and current_confirmations == 0):
+                return QColor("#ffb000")
+
+        if role == Qt.TextAlignmentRole:
+            if HistoryTableModel.columns_types.index('amount'):
+                return Qt.AlignRight | Qt.AlignVCenter
+            if col == HistoryTableModel.columns_types.index('date'):
+                return Qt.AlignCenter
+
+        if role == Qt.ToolTipRole:
+            if col == HistoryTableModel.columns_types.index('date'):
+                ts = self.blockchain_processor.adjusted_ts(self.connection.currency, source_data)
+                return QDateTime.fromTime_t(ts).toString(Qt.SystemLocaleLongDate)
+
+            if state_data == Transaction.VALIDATED or state_data == Transaction.AWAITING:
+                if current_confirmations >= MAX_CONFIRMATIONS:
+                    return None
+                elif self.app.parameters.expert_mode:
+                    return self.tr("{0} / {1} confirmations").format(current_confirmations, MAX_CONFIRMATIONS)
+                else:
+                    confirmation = current_confirmations / MAX_CONFIRMATIONS * 100
+                    confirmation = 100 if confirmation > 100 else confirmation
+                    return self.tr("Confirming... {0} %").format(QLocale().toString(float(confirmation), 'f', 0))
 
     def flags(self, index):
         return Qt.ItemIsSelectable | Qt.ItemIsEnabled
diff --git a/src/sakia/gui/navigation/txhistory/txhistory.ui b/src/sakia/gui/navigation/txhistory/txhistory.ui
index 838345c54cfeb45b29caea9b3b1dc9f9d1f905d1..a903b359cc826053cc55efdc8a587d73183111d5 100644
--- a/src/sakia/gui/navigation/txhistory/txhistory.ui
+++ b/src/sakia/gui/navigation/txhistory/txhistory.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>481</width>
-    <height>456</height>
+    <width>656</width>
+    <height>635</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -21,21 +21,87 @@
      </property>
      <layout class="QVBoxLayout" name="verticalLayout_4">
       <item>
-       <widget class="QLabel" name="label_balance">
-        <property name="font">
-         <font>
-          <pointsize>22</pointsize>
-          <weight>75</weight>
-          <bold>true</bold>
-         </font>
+       <layout class="QHBoxLayout" name="horizontalLayout">
+        <property name="topMargin">
+         <number>6</number>
         </property>
-        <property name="text">
-         <string>loading...</string>
-        </property>
-        <property name="alignment">
-         <set>Qt::AlignHCenter|Qt::AlignTop</set>
-        </property>
-       </widget>
+        <item>
+         <spacer name="horizontalSpacer_3">
+          <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>
+         <spacer name="horizontalSpacer_2">
+          <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_balance">
+          <property name="font">
+           <font>
+            <pointsize>22</pointsize>
+            <weight>75</weight>
+            <bold>true</bold>
+           </font>
+          </property>
+          <property name="text">
+           <string>loading...</string>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignHCenter|Qt::AlignTop</set>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeType">
+           <enum>QSizePolicy::Expanding</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <widget class="QPushButton" name="button_send">
+          <property name="text">
+           <string>Send money</string>
+          </property>
+          <property name="icon">
+           <iconset resource="../../../../../res/icons/icons.qrc">
+            <normaloff>:/icons/payment_icon</normaloff>:/icons/payment_icon</iconset>
+          </property>
+          <property name="iconSize">
+           <size>
+            <width>24</width>
+            <height>16</height>
+           </size>
+          </property>
+         </widget>
+        </item>
+       </layout>
       </item>
       <item>
        <widget class="Busy" name="busy_balance" native="true"/>
@@ -44,57 +110,91 @@
     </widget>
    </item>
    <item>
-    <layout class="QVBoxLayout" name="verticalLayout_3">
-     <item>
-      <layout class="QHBoxLayout" name="horizontalLayout_2">
-       <property name="topMargin">
-        <number>5</number>
-       </property>
+    <widget class="QStackedWidget" name="stacked_widget">
+     <property name="currentIndex">
+      <number>0</number>
+     </property>
+     <widget class="QWidget" name="page_history">
+      <layout class="QVBoxLayout" name="verticalLayout_2">
        <item>
-        <widget class="QDateTimeEdit" name="date_from">
-         <property name="displayFormat">
-          <string>dd/MM/yyyy</string>
-         </property>
-         <property name="calendarPopup">
-          <bool>true</bool>
-         </property>
-        </widget>
+        <layout class="QVBoxLayout" name="verticalLayout_3">
+         <item>
+          <layout class="QHBoxLayout" name="horizontalLayout_2">
+           <property name="topMargin">
+            <number>5</number>
+           </property>
+           <item>
+            <widget class="QDateTimeEdit" name="date_from">
+             <property name="displayFormat">
+              <string>dd/MM/yyyy</string>
+             </property>
+             <property name="calendarPopup">
+              <bool>true</bool>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="QDateTimeEdit" name="date_to">
+             <property name="displayFormat">
+              <string>dd/MM/yyyy</string>
+             </property>
+             <property name="calendarPopup">
+              <bool>true</bool>
+             </property>
+            </widget>
+           </item>
+          </layout>
+         </item>
+         <item>
+          <widget class="QTableView" name="table_history">
+           <property name="contextMenuPolicy">
+            <enum>Qt::CustomContextMenu</enum>
+           </property>
+           <property name="alternatingRowColors">
+            <bool>true</bool>
+           </property>
+           <property name="showGrid">
+            <bool>true</bool>
+           </property>
+           <attribute name="horizontalHeaderShowSortIndicator" stdset="0">
+            <bool>true</bool>
+           </attribute>
+           <attribute name="horizontalHeaderStretchLastSection">
+            <bool>true</bool>
+           </attribute>
+           <attribute name="verticalHeaderVisible">
+            <bool>false</bool>
+           </attribute>
+          </widget>
+         </item>
+        </layout>
        </item>
        <item>
-        <widget class="QDateTimeEdit" name="date_to">
-         <property name="displayFormat">
-          <string>dd/MM/yyyy</string>
-         </property>
-         <property name="calendarPopup">
-          <bool>true</bool>
+        <layout class="QHBoxLayout" name="horizontalLayout_3">
+         <property name="topMargin">
+          <number>6</number>
          </property>
-        </widget>
+         <item>
+          <spacer name="horizontalSpacer_4">
+           <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="QSpinBox" name="spin_page"/>
+         </item>
+        </layout>
        </item>
       </layout>
-     </item>
-     <item>
-      <widget class="QTableView" name="table_history">
-       <property name="contextMenuPolicy">
-        <enum>Qt::CustomContextMenu</enum>
-       </property>
-       <property name="alternatingRowColors">
-        <bool>true</bool>
-       </property>
-       <property name="showGrid">
-        <bool>true</bool>
-       </property>
-       <attribute name="horizontalHeaderShowSortIndicator" stdset="0">
-        <bool>true</bool>
-       </attribute>
-       <attribute name="horizontalHeaderStretchLastSection">
-        <bool>true</bool>
-       </attribute>
-       <attribute name="verticalHeaderVisible">
-        <bool>false</bool>
-       </attribute>
-      </widget>
-     </item>
-    </layout>
+     </widget>
+    </widget>
    </item>
   </layout>
  </widget>
diff --git a/src/sakia/gui/navigation/txhistory/view.py b/src/sakia/gui/navigation/txhistory/view.py
index abdec7816a66d3a36fc1c3633e414effc23b3f99..eae64a5961fbaf0ae04889ebea8567ab20cfe957 100644
--- a/src/sakia/gui/navigation/txhistory/view.py
+++ b/src/sakia/gui/navigation/txhistory/view.py
@@ -10,9 +10,13 @@ class TxHistoryView(QWidget, Ui_TxHistoryWidget):
     The view of TxHistory component
     """
 
-    def __init__(self, parent):
+    def __init__(self, parent, transfer_view):
         super().__init__(parent)
+        self.transfer_view = transfer_view
         self.setupUi(self)
+        self.stacked_widget.insertWidget(1, transfer_view)
+        self.button_send.clicked.connect(lambda c: self.stacked_widget.setCurrentWidget(self.transfer_view))
+        self.spin_page.setMinimum(1)
 
     def get_time_frame(self):
         """
@@ -49,6 +53,10 @@ class TxHistoryView(QWidget, Ui_TxHistoryWidget):
         self.date_to.setDateTime(maximum)
         self.date_to.setMaximumDateTime(maximum)
 
+    def set_max_pages(self, pages):
+        self.spin_page.setSuffix(self.tr(" / {:} pages").format(pages + 1))
+        self.spin_page.setMaximum(pages + 1)
+
     def set_balance(self, balance):
         """
         Display given balance
@@ -60,6 +68,9 @@ class TxHistoryView(QWidget, Ui_TxHistoryWidget):
             "{:}".format(balance)
         )
 
+    def clear(self):
+        self.stacked_widget.setCurrentWidget(self.page_history)
+
     def changeEvent(self, event):
         """
         Intercepte LanguageChange event to translate UI
diff --git a/src/sakia/gui/dialogs/transfer/__init__.py b/src/sakia/gui/sub/certification/__init__.py
similarity index 100%
rename from src/sakia/gui/dialogs/transfer/__init__.py
rename to src/sakia/gui/sub/certification/__init__.py
diff --git a/src/sakia/gui/sub/certification/certification.ui b/src/sakia/gui/sub/certification/certification.ui
new file mode 100644
index 0000000000000000000000000000000000000000..a027ab10f3915f8544de845013ec63f49ba1b27c
--- /dev/null
+++ b/src/sakia/gui/sub/certification/certification.ui
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>CertificationWidget</class>
+ <widget class="QWidget" name="CertificationWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>629</width>
+    <height>620</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QStackedWidget" name="stackedWidget">
+     <property name="currentIndex">
+      <number>0</number>
+     </property>
+     <widget class="QWidget" name="page">
+      <layout class="QVBoxLayout" name="verticalLayout_7">
+       <item>
+        <widget class="QGroupBox" name="groupbox_identity">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="title">
+          <string>Select your identity</string>
+         </property>
+         <layout class="QVBoxLayout" name="verticalLayout_2">
+          <item>
+           <widget class="QComboBox" name="combo_connections"/>
+          </item>
+          <item>
+           <widget class="QGroupBox" name="groupBox_3">
+            <property name="title">
+             <string>Certifications stock</string>
+            </property>
+            <layout class="QVBoxLayout" name="verticalLayout_4">
+             <item>
+              <widget class="QLabel" name="label_cert_stock">
+               <property name="text">
+                <string/>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+       <item>
+        <widget class="QGroupBox" name="groupbox_certified">
+         <property name="title">
+          <string>Certify user</string>
+         </property>
+         <layout class="QVBoxLayout" name="verticalLayout_3">
+          <item>
+           <layout class="QHBoxLayout" name="identity_select_layout">
+            <item>
+             <widget class="QPushButton" name="button_import_identity">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="text">
+               <string>Import identity document</string>
+              </property>
+             </widget>
+            </item>
+           </layout>
+          </item>
+         </layout>
+        </widget>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout">
+         <item>
+          <spacer name="horizontalSpacer_2">
+           <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="QPushButton" name="button_process">
+           <property name="text">
+            <string>Process certification</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QPushButton" name="button_cancel">
+           <property name="text">
+            <string>Cancel</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <widget class="QFrame" name="frame">
+         <property name="frameShape">
+          <enum>QFrame::StyledPanel</enum>
+         </property>
+         <property name="frameShadow">
+          <enum>QFrame::Raised</enum>
+         </property>
+         <layout class="QHBoxLayout" name="horizontalLayout_4">
+          <item>
+           <widget class="QLabel" name="label">
+            <property name="frameShadow">
+             <enum>QFrame::Raised</enum>
+            </property>
+            <property name="text">
+             <string>Step 1. Check the key/user / Step 2. Accept the money licence / Step 3. Sign to confirm certification</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="page_2">
+      <layout class="QVBoxLayout" name="verticalLayout_8">
+       <item>
+        <widget class="QGroupBox" name="groupBox">
+         <property name="title">
+          <string>Licence</string>
+         </property>
+         <layout class="QVBoxLayout" name="verticalLayout_5">
+          <item>
+           <widget class="QTextEdit" name="text_licence">
+            <property name="readOnly">
+             <bool>true</bool>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QLabel" name="label_confirm">
+            <property name="text">
+             <string>By going throught the process of creating a wallet, you accept the license above.</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <layout class="QHBoxLayout" name="horizontalLayout_2">
+            <item>
+             <spacer name="horizontalSpacer_3">
+              <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="QPushButton" name="button_accept">
+              <property name="text">
+               <string>I accept the above licence</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QPushButton" name="button_cancel_licence">
+              <property name="text">
+               <string>Cancel</string>
+              </property>
+             </widget>
+            </item>
+           </layout>
+          </item>
+         </layout>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="page_3">
+      <layout class="QVBoxLayout" name="verticalLayout_9">
+       <item>
+        <widget class="QGroupBox" name="group_box_password">
+         <property name="title">
+          <string>Secret Key / Password</string>
+         </property>
+         <layout class="QVBoxLayout" name="verticalLayout_6">
+          <item>
+           <layout class="QVBoxLayout" name="layout_password_input"/>
+          </item>
+         </layout>
+        </widget>
+       </item>
+       <item>
+        <widget class="QDialogButtonBox" name="button_box">
+         <property name="enabled">
+          <bool>true</bool>
+         </property>
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="standardButtons">
+          <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/sakia/gui/dialogs/certification/controller.py b/src/sakia/gui/sub/certification/controller.py
similarity index 68%
rename from src/sakia/gui/dialogs/certification/controller.py
rename to src/sakia/gui/sub/certification/controller.py
index 84bbd89703c2fcb154f3c7bfa17b597944bef45c..4d1600f4f428149b405d04275d368a0a1aea1ae2 100644
--- a/src/sakia/gui/dialogs/certification/controller.py
+++ b/src/sakia/gui/sub/certification/controller.py
@@ -1,7 +1,5 @@
-import asyncio
-
-from PyQt5.QtCore import Qt, QObject
-from PyQt5.QtWidgets import QApplication
+from PyQt5.QtCore import Qt, QObject, pyqtSignal
+from PyQt5.QtWidgets import QApplication, QDialog, QVBoxLayout
 
 from sakia.constants import ROOT_SERVERS
 from sakia.decorators import asyncify
@@ -20,6 +18,8 @@ class CertificationController(QObject):
     """
     The Certification view
     """
+    accepted = pyqtSignal()
+    rejected = pyqtSignal()
 
     view = attr.ib()
     model = attr.ib()
@@ -31,7 +31,9 @@ class CertificationController(QObject):
         super().__init__()
         self.view.button_box.accepted.connect(self.accept)
         self.view.button_box.rejected.connect(self.reject)
-        self.view.combo_connection.currentIndexChanged.connect(self.change_connection)
+        self.view.button_cancel.clicked.connect(self.reject)
+        self.view.button_cancel_licence.clicked.connect(self.reject)
+        self.view.combo_connections.currentIndexChanged.connect(self.change_connection)
 
     @classmethod
     def create(cls, parent, app):
@@ -61,6 +63,13 @@ class CertificationController(QObject):
         view.identity_document_imported.connect(certification.load_identity_document)
         return certification
 
+    @classmethod
+    def integrate_to_main_view(cls, parent, app, connection):
+        certification = cls.create(parent, app)
+        certification.view.combo_connections.setCurrentText(connection.title())
+        certification.view.groupbox_identity.hide()
+        return certification
+
     @classmethod
     def open_dialog(cls, parent, app, connection):
         """
@@ -71,13 +80,20 @@ class CertificationController(QObject):
         :param sakia.core.Community community: the community
         :return:
         """
-        dialog = cls.create(parent, app)
-        dialog.set_connection(connection)
-        dialog.refresh()
+
+        dialog = QDialog(parent)
+        dialog.setWindowTitle(dialog.tr("Certification"))
+        dialog.setLayout(QVBoxLayout(dialog))
+        certification = cls.create(parent, app)
+        certification.set_connection(connection)
+        certification.refresh()
+        dialog.layout().addWidget(certification.view)
+        certification.accepted.connect(dialog.accept)
+        certification.rejected.connect(dialog.reject)
         return dialog.exec()
 
     @classmethod
-    async def certify_identity(cls, parent, app, connection, identity):
+    def certify_identity(cls, parent, app, connection, identity):
         """
         Certify and identity
         :param sakia.gui.component.controller.ComponentController parent: the parent
@@ -86,11 +102,18 @@ class CertificationController(QObject):
         :param sakia.data.entities.Identity identity: the identity certified
         :return:
         """
-        dialog = cls.create(parent, app)
-        dialog.view.combo_connection.setCurrentText(connection.title())
-        dialog.user_information.change_identity(identity)
-        dialog.refresh()
-        return await dialog.async_exec()
+        dialog = QDialog(parent)
+        dialog.setWindowTitle(dialog.tr("Certification"))
+        dialog.setLayout(QVBoxLayout(dialog))
+        certification = cls.create(parent, app)
+        if connection:
+            certification.view.combo_connections.setCurrentText(connection.title())
+        certification.user_information.change_identity(identity)
+        certification.refresh()
+        dialog.layout().addWidget(certification.view)
+        certification.accepted.connect(dialog.accept)
+        certification.rejected.connect(dialog.reject)
+        return dialog.exec()
 
     def change_connection(self, index):
         self.model.set_connection(index)
@@ -99,7 +122,7 @@ class CertificationController(QObject):
 
     def set_connection(self, connection):
         if connection:
-            self.view.combo_connection.setCurrentText(connection.title())
+            self.view.combo_connections.setCurrentText(connection.title())
             self.password_input.set_connection(connection)
 
     @asyncify
@@ -138,15 +161,20 @@ using cross checking which will help to reveal the problem if needs to be.</br>"
         if result[0]:
             QApplication.restoreOverrideCursor()
             await self.view.show_success(self.model.notification())
-            self.view.accept()
+            self.search_user.clear()
+            self.user_information.clear()
+            self.view.clear()
+            self.accepted.emit()
         else:
             await self.view.show_error(self.model.notification(), result[1])
             QApplication.restoreOverrideCursor()
             self.view.button_box.setEnabled(True)
 
-    @asyncify
-    async def reject(self):
-        self.view.reject()
+    def reject(self):
+        self.search_user.clear()
+        self.user_information.clear()
+        self.view.clear()
+        self.rejected.emit()
 
     def refresh(self):
         stock = self.model.get_cert_stock()
@@ -156,24 +184,25 @@ using cross checking which will help to reveal the problem if needs to be.</br>"
 
         if self.model.could_certify():
             if written < stock or stock == 0:
-                if self.password_input.valid():
-                    if not self.user_information.model.identity:
-                        self.view.set_button_box(CertificationView.ButtonBoxState.SELECT_IDENTITY)
-                    elif days+hours+minutes > 0:
-                        if days > 0:
-                            remaining_localized = self.tr("{days} days").format(days=days)
-                        else:
-                            remaining_localized = self.tr("{hours}h {min}min").format(hours=hours, min=minutes)
-                        self.view.set_button_box(CertificationView.ButtonBoxState.REMAINING_TIME_BEFORE_VALIDATION,
-                                                 remaining=remaining_localized)
+                if not self.user_information.model.identity:
+                    self.view.set_button_process(CertificationView.ButtonsState.SELECT_IDENTITY)
+                elif days+hours+minutes > 0:
+                    if days > 0:
+                        remaining_localized = self.tr("{days} days").format(days=days)
                     else:
-                        self.view.set_button_box(CertificationView.ButtonBoxState.OK)
+                        remaining_localized = self.tr("{hours}h {min}min").format(hours=hours, min=minutes)
+                    self.view.set_button_process(CertificationView.ButtonsState.REMAINING_TIME_BEFORE_VALIDATION,
+                                                 remaining=remaining_localized)
                 else:
-                    self.view.set_button_box(CertificationView.ButtonBoxState.WRONG_PASSWORD)
+                    self.view.set_button_process(CertificationView.ButtonsState.OK)
+                    if self.password_input.valid():
+                        self.view.set_button_box(CertificationView.ButtonsState.OK)
+                    else:
+                        self.view.set_button_box(CertificationView.ButtonsState.WRONG_PASSWORD)
             else:
-                self.view.set_button_box(CertificationView.ButtonBoxState.NO_MORE_CERTIFICATION)
+                self.view.set_button_process(CertificationView.ButtonsState.NO_MORE_CERTIFICATION)
         else:
-            self.view.set_button_box(CertificationView.ButtonBoxState.NOT_A_MEMBER)
+            self.view.set_button_process(CertificationView.ButtonsState.NOT_A_MEMBER)
 
     def load_identity_document(self, identity_doc):
         """
@@ -192,14 +221,3 @@ using cross checking which will help to reveal the problem if needs to be.</br>"
         Refresh user information
         """
         self.user_information.search_identity(self.search_user.model.identity())
-
-    def async_exec(self):
-        future = asyncio.Future()
-        self.view.finished.connect(lambda r: future.set_result(r))
-        self.view.open()
-        self.refresh()
-        return future
-
-    def exec(self):
-        self.refresh()
-        self.view.exec()
diff --git a/src/sakia/gui/dialogs/certification/model.py b/src/sakia/gui/sub/certification/model.py
similarity index 100%
rename from src/sakia/gui/dialogs/certification/model.py
rename to src/sakia/gui/sub/certification/model.py
diff --git a/src/sakia/gui/dialogs/certification/view.py b/src/sakia/gui/sub/certification/view.py
similarity index 68%
rename from src/sakia/gui/dialogs/certification/view.py
rename to src/sakia/gui/sub/certification/view.py
index b5bd687b877146286832568bdfbb95f4d4bf8918..b2234edeb94d6cad591f01cb2de755b73c0020a7 100644
--- a/src/sakia/gui/dialogs/certification/view.py
+++ b/src/sakia/gui/sub/certification/view.py
@@ -1,19 +1,19 @@
-from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QFileDialog, QMessageBox
+from PyQt5.QtWidgets import QWidget, QDialogButtonBox, QFileDialog, QMessageBox
 from PyQt5.QtCore import QT_TRANSLATE_NOOP, Qt, pyqtSignal
-from .certification_uic import Ui_CertificationDialog
+from .certification_uic import Ui_CertificationWidget
 from sakia.gui.widgets import toast
 from sakia.gui.widgets.dialogs import QAsyncMessageBox
-from sakia.constants import ROOT_SERVERS
+from sakia.constants import ROOT_SERVERS, G1_LICENCE
 from duniterpy.documents import Identity, MalformedDocumentError
 from enum import Enum
 
 
-class CertificationView(QDialog, Ui_CertificationDialog):
+class CertificationView(QWidget, Ui_CertificationWidget):
     """
     The view of the certification component
     """
 
-    class ButtonBoxState(Enum):
+    class ButtonsState(Enum):
         NO_MORE_CERTIFICATION = 0
         NOT_A_MEMBER = 1
         REMAINING_TIME_BEFORE_VALIDATION = 2
@@ -21,16 +21,20 @@ class CertificationView(QDialog, Ui_CertificationDialog):
         SELECT_IDENTITY = 4
         WRONG_PASSWORD = 5
 
-    _button_box_values = {
-        ButtonBoxState.NO_MORE_CERTIFICATION: (False,
-                                               QT_TRANSLATE_NOOP("CertificationView", "No more certifications")),
-        ButtonBoxState.NOT_A_MEMBER: (False, QT_TRANSLATE_NOOP("CertificationView", "Not a member")),
-        ButtonBoxState.SELECT_IDENTITY: (False, QT_TRANSLATE_NOOP("CertificationView", "Please select an identity")),
-        ButtonBoxState.REMAINING_TIME_BEFORE_VALIDATION: (True,
-                                                          QT_TRANSLATE_NOOP("CertificationView",
+    _button_process_values = {
+        ButtonsState.NO_MORE_CERTIFICATION: (False,
+                                             QT_TRANSLATE_NOOP("CertificationView", "No more certifications")),
+        ButtonsState.NOT_A_MEMBER: (False, QT_TRANSLATE_NOOP("CertificationView", "Not a member")),
+        ButtonsState.SELECT_IDENTITY: (False, QT_TRANSLATE_NOOP("CertificationView", "Please select an identity")),
+        ButtonsState.REMAINING_TIME_BEFORE_VALIDATION: (True,
+                                                        QT_TRANSLATE_NOOP("CertificationView",
                                                                             "&Ok (Not validated before {remaining})")),
-        ButtonBoxState.OK: (True, QT_TRANSLATE_NOOP("CertificationView", "&Ok")),
-        ButtonBoxState.WRONG_PASSWORD: (False, QT_TRANSLATE_NOOP("CertificationView", "Please enter correct password"))
+        ButtonsState.OK: (True, QT_TRANSLATE_NOOP("CertificationView", "&Process Certification")),
+    }
+
+    _button_box_values = {
+        ButtonsState.OK: (True, QT_TRANSLATE_NOOP("CertificationView", "&Ok")),
+        ButtonsState.WRONG_PASSWORD: (False, QT_TRANSLATE_NOOP("CertificationView", "Please enter correct password"))
     }
 
     identity_document_imported = pyqtSignal(Identity)
@@ -49,22 +53,34 @@ class CertificationView(QDialog, Ui_CertificationDialog):
         self.search_user_view = search_user_view
         self.user_information_view = user_information_view
         self.password_input_view = password_input_view
-        self.groupbox_certified.layout().addWidget(search_user_view)
+        self.identity_select_layout.insertWidget(0, search_user_view)
         self.search_user_view.button_reset.hide()
         self.layout_password_input.addWidget(password_input_view)
         self.groupbox_certified.layout().addWidget(user_information_view)
         self.button_import_identity.clicked.connect(self.import_identity_document)
+        self.button_process.clicked.connect(lambda c: self.stackedWidget.setCurrentIndex(1))
+        self.button_accept.clicked.connect(lambda c: self.stackedWidget.setCurrentIndex(2))
+
+        licence_text = self.tr(G1_LICENCE)
+        self.text_licence.setText(licence_text)
+
+    def clear(self):
+        self.stackedWidget.setCurrentIndex(0)
+        self.set_button_process(CertificationView.ButtonsState.SELECT_IDENTITY)
+        self.password_input_view.clear()
+        self.search_user_view.clear()
+        self.user_information_view.clear()
 
     def set_keys(self, connections):
-        self.combo_connection.clear()
+        self.combo_connections.clear()
         for c in connections:
-            self.combo_connection.addItem(c.title())
+            self.combo_connections.addItem(c.title())
 
     def set_selected_key(self, connection):
         """
         :param sakia.data.entities.Connection connection:
         """
-        self.combo_connection.setCurrentText(connection.title())
+        self.combo_connections.setCurrentText(connection.title())
 
     def pubkey_value(self):
         return self.edit_pubkey.text()
@@ -73,7 +89,7 @@ class CertificationView(QDialog, Ui_CertificationDialog):
         file_name = QFileDialog.getOpenFileName(self,
                                                 self.tr("Open identity document"), "",
                                                 self.tr("Duniter documents (*.txt)"))
-        if file_name:
+        if file_name and file_name[0]:
             with open(file_name[0], 'r') as open_file:
                 raw_text = open_file.read()
                 try:
@@ -87,8 +103,7 @@ class CertificationView(QDialog, Ui_CertificationDialog):
     def set_label_confirm(self, currency):
         self.label_confirm.setTextFormat(Qt.RichText)
         self.label_confirm.setText("""<b>Vous confirmez engager votre responsabilité envers la communauté Duniter {:}
-    et acceptez de certifier le compte Duniter {:} ci-dessus.<br/><br/>
-Pour confirmer votre certification veuillez confirmer votre signature :</b>""".format(ROOT_SERVERS[currency]["display"],
+    et acceptez de certifier le compte Duniter {:} sélectionné.<br/><br/>""".format(ROOT_SERVERS[currency]["display"],
                                                                                      ROOT_SERVERS[currency]["display"]))
 
     async def show_success(self, notification):
@@ -145,3 +160,14 @@ Pour confirmer votre certification veuillez confirmer votre signature :</b>""".f
         button_box_state = CertificationView._button_box_values[state]
         self.button_box.button(QDialogButtonBox.Ok).setEnabled(button_box_state[0])
         self.button_box.button(QDialogButtonBox.Ok).setText(button_box_state[1].format(**kwargs))
+
+    def set_button_process(self, state, **kwargs):
+        """
+        Set button box state
+        :param sakia.gui.certification.view.CertificationView.ButtonBoxState state: the state of te button box
+        :param dict kwargs: the values to replace from the text in the state
+        :return:
+        """
+        button_process_state = CertificationView._button_process_values[state]
+        self.button_process.setEnabled(button_process_state[0])
+        self.button_process.setText(button_process_state[1].format(**kwargs))
diff --git a/src/sakia/gui/sub/password_input/view.py b/src/sakia/gui/sub/password_input/view.py
index 2de53dd8380fc0a12c0293699fb8d3646761fa6a..51a32a20c6a6fc787719860b997b7f662506c394 100644
--- a/src/sakia/gui/sub/password_input/view.py
+++ b/src/sakia/gui/sub/password_input/view.py
@@ -22,6 +22,10 @@ class PasswordInputView(QWidget, Ui_PasswordInputWidget):
         self.label_info.setText(text)
         self.button_box.button(QDialogButtonBox.Ok).setEnabled(False)
 
+    def clear(self):
+        self.edit_password.clear()
+        self.edit_secret_key.clear()
+
     def valid(self):
         self.label_info.setText(self.tr("Password is valid"))
         self.button_box.button(QDialogButtonBox.Ok).setEnabled(True)
diff --git a/src/sakia/gui/sub/search_user/controller.py b/src/sakia/gui/sub/search_user/controller.py
index 666769b874db83d28c00902dbbf4f7c7995f5e85..7973c67607e85ec7fe5a0733b6eed33f7444d103 100644
--- a/src/sakia/gui/sub/search_user/controller.py
+++ b/src/sakia/gui/sub/search_user/controller.py
@@ -1,7 +1,6 @@
 from PyQt5.QtCore import pyqtSignal, QObject
 from sakia.data.entities import Identity
 from sakia.decorators import asyncify
-import re
 from .model import SearchUserModel
 from .view import SearchUserView
 
@@ -60,3 +59,6 @@ class SearchUserController(QObject):
         if self.model.select_identity(index):
             self.identity_selected.emit(self.model.identity())
 
+    def clear(self):
+        self.model.clear()
+        self.view.clear()
\ No newline at end of file
diff --git a/src/sakia/gui/sub/search_user/model.py b/src/sakia/gui/sub/search_user/model.py
index 8839788c3d2fcd81db68ca02b0b77ebd291af558..2afcabe9bf9865f7e9439bdf60bebc083fca113e 100644
--- a/src/sakia/gui/sub/search_user/model.py
+++ b/src/sakia/gui/sub/search_user/model.py
@@ -69,4 +69,8 @@ class SearchUserModel(QObject):
             self._current_identity = None
             return False
         self._current_identity = self._nodes[index]
-        return True
\ No newline at end of file
+        return True
+
+    def clear(self):
+        self._current_identity = None
+        self._nodes = list()
\ No newline at end of file
diff --git a/src/sakia/gui/sub/search_user/view.py b/src/sakia/gui/sub/search_user/view.py
index f84085e8ba6f8e467a9fc09d354f5f2bceba55a5..58636e22fc725f5b34b6057de4518c682b98a793 100644
--- a/src/sakia/gui/sub/search_user/view.py
+++ b/src/sakia/gui/sub/search_user/view.py
@@ -3,6 +3,7 @@ from PyQt5.QtCore import QT_TRANSLATE_NOOP, pyqtSignal, Qt, QStringListModel
 from sakia.data.entities import Contact
 from .search_user_uic import Ui_SearchUserWidget
 import re
+import asyncio
 
 
 class SearchUserView(QWidget, Ui_SearchUserWidget):
@@ -28,6 +29,10 @@ class SearchUserView(QWidget, Ui_SearchUserWidget):
         self.combobox_search.setInsertPolicy(QComboBox.NoInsert)
         self.combobox_search.activated.connect(self.node_selected)
 
+    def clear(self):
+        self.combobox_search.clear()
+        self.combobox_search.lineEdit().setPlaceholderText(self.tr(SearchUserView._search_placeholder))
+
     def search(self, text=""):
         """
         Search nodes when return is pressed in combobox lineEdit
@@ -71,9 +76,3 @@ class SearchUserView(QWidget, Ui_SearchUserWidget):
         completer.setModel(model)
         completer.activated.connect(self.search, type=Qt.QueuedConnection)
         self.combobox_search.setCompleter(completer)
-
-    def keyPressEvent(self, event):
-        if event.key() == Qt.Key_Return:
-            return
-
-        super().keyPressEvent(event)
diff --git a/src/sakia/gui/navigation/informations/__init__.py b/src/sakia/gui/sub/transfer/__init__.py
similarity index 100%
rename from src/sakia/gui/navigation/informations/__init__.py
rename to src/sakia/gui/sub/transfer/__init__.py
diff --git a/src/sakia/gui/dialogs/transfer/controller.py b/src/sakia/gui/sub/transfer/controller.py
similarity index 67%
rename from src/sakia/gui/dialogs/transfer/controller.py
rename to src/sakia/gui/sub/transfer/controller.py
index 5a92cbcac43a470bedf10d2a9ac08781ef38e28d..3a65ec40e0249721cd8891d7e558f25acd5cc593 100644
--- a/src/sakia/gui/dialogs/transfer/controller.py
+++ b/src/sakia/gui/sub/transfer/controller.py
@@ -1,8 +1,8 @@
 import asyncio
 import logging
 
-from PyQt5.QtCore import Qt, QObject
-from PyQt5.QtWidgets import QApplication
+from PyQt5.QtCore import Qt, QObject, pyqtSignal
+from PyQt5.QtWidgets import QApplication, QDialog, QVBoxLayout
 
 from sakia.data.processors import ConnectionsProcessor
 from sakia.decorators import asyncify
@@ -10,6 +10,7 @@ from sakia.gui.sub.password_input import PasswordInputController
 from sakia.gui.sub.search_user.controller import SearchUserController
 from sakia.gui.sub.user_information.controller import UserInformationController
 from sakia.money import Quantitative
+from sakia.gui.widgets.dialogs import dialog_async_exec
 from .model import TransferModel
 from .view import TransferView
 
@@ -19,6 +20,9 @@ class TransferController(QObject):
     The transfer component controller
     """
 
+    accepted = pyqtSignal()
+    rejected = pyqtSignal()
+
     def __init__(self, view, model, search_user, user_information, password_input):
         """
         Constructor of the transfer component
@@ -68,48 +72,81 @@ class TransferController(QObject):
         return transfer
 
     @classmethod
-    def open_dialog(cls, parent, app, connection):
-        dialog = cls.create(parent, app)
-        if connection:
-            dialog.view.combo_connections.setCurrentText(connection.title())
-        dialog.refresh()
-        return dialog.exec()
+    def integrate_to_main_view(cls, parent, app, connection):
+        transfer = cls.create(parent, app)
+        transfer.view.combo_connections.setCurrentText(connection.title())
+        transfer.view.groupbox_connection.hide()
+        transfer.view.label_total.hide()
+        return transfer
 
     @classmethod
-    async def send_money_to_identity(cls, parent, app, connection, identity):
-        dialog = cls.create(parent, app)
-        dialog.view.combo_connections.setCurrentText(connection.title())
-        dialog.user_information.change_identity(identity)
-        dialog.view.edit_pubkey.setText(identity.pubkey)
-        dialog.view.radio_pubkey.setChecked(True)
+    def open_transfer_with_pubkey(cls, parent, app, connection, pubkey):
+        transfer = cls.create(parent, app)
+        transfer.view.groupbox_connection.show()
+        if connection:
+            transfer.view.combo_connections.setCurrentText(connection.title())
+        transfer.view.edit_pubkey.setText(pubkey)
+        transfer.view.radio_pubkey.setChecked(True)
 
-        dialog.refresh()
-        return await dialog.async_exec()
+        transfer.refresh()
+        return transfer
 
     @classmethod
-    def send_transfer_again(cls, parent, app, connection, resent_transfer):
-        dialog = cls.create(parent, app)
-        dialog.view.combo_connections.setCurrentText(connection.title())
-        dialog.view.edit_pubkey.setText(resent_transfer.receivers[0])
-        dialog.view.radio_pubkey.setChecked(True)
+    def send_money_to_pubkey(cls, parent, app, connection, pubkey):
+        dialog = QDialog(parent)
+        dialog.setWindowTitle(dialog.tr("Transfer"))
+        dialog.setLayout(QVBoxLayout(dialog))
+        transfer = cls.open_transfer_with_pubkey(parent, app, connection, pubkey)
+
+        dialog.layout().addWidget(transfer.view)
+        transfer.accepted.connect(dialog.accept)
+        transfer.rejected.connect(dialog.reject)
+        return dialog.exec()
 
-        dialog.refresh()
+    @classmethod
+    def send_money_to_identity(cls, parent, app, connection, identity):
+        dialog = QDialog(parent)
+        dialog.setWindowTitle(dialog.tr("Transfer"))
+        dialog.setLayout(QVBoxLayout(dialog))
+        transfer = cls.open_transfer_with_pubkey(parent, app, connection, identity.pubkey)
+
+        transfer.user_information.change_identity(identity)
+        dialog.layout().addWidget(transfer.view)
+        transfer.accepted.connect(dialog.accept)
+        transfer.rejected.connect(dialog.reject)
+        return dialog.exec()
 
-        current_base = dialog.model.current_base()
+    @classmethod
+    def send_transfer_again(cls, parent, app, connection, resent_transfer):
+        dialog = QDialog(parent)
+        dialog.setWindowTitle(dialog.tr("Transfer"))
+        dialog.setLayout(QVBoxLayout(dialog))
+        transfer = cls.create(parent, app)
+        transfer.view.groupbox_connection.show()
+        transfer.view.label_total.show()
+        transfer.view.combo_connections.setCurrentText(connection.title())
+        transfer.view.edit_pubkey.setText(resent_transfer.receivers[0])
+        transfer.view.radio_pubkey.setChecked(True)
+
+        transfer.refresh()
+
+        current_base = transfer.model.current_base()
         current_base_amount = resent_transfer.amount / pow(10, resent_transfer.amount_base - current_base)
 
-        relative = dialog.model.quant_to_rel(current_base_amount / 100)
-        dialog.view.set_spinboxes_parameters(current_base_amount / 100, relative)
-        dialog.view.change_relative_amount(relative)
-        dialog.view.change_quantitative_amount(current_base_amount / 100)
+        relative = transfer.model.quant_to_rel(current_base_amount / 100)
+        transfer.view.set_spinboxes_parameters(current_base_amount / 100, relative)
+        transfer.view.change_relative_amount(relative)
+        transfer.view.change_quantitative_amount(current_base_amount / 100)
 
         connections_processor = ConnectionsProcessor.instanciate(app)
         wallet_index = connections_processor.connections().index(connection)
-        dialog.view.combo_connections.setCurrentIndex(wallet_index)
-        dialog.view.edit_pubkey.setText(resent_transfer.receivers[0])
-        dialog.view.radio_pubkey.setChecked(True)
-        dialog.view.edit_message.setText(resent_transfer.comment)
-
+        transfer.view.combo_connections.setCurrentIndex(wallet_index)
+        transfer.view.edit_pubkey.setText(resent_transfer.receivers[0])
+        transfer.view.radio_pubkey.setChecked(True)
+        transfer.view.edit_message.setText(resent_transfer.comment)
+        dialog.layout().addWidget(transfer.view)
+        transfer.accepted.connect(dialog.accept)
+        transfer.rejected.connect(dialog.reject)
         return dialog.exec()
 
     def selected_pubkey(self):
@@ -156,12 +193,14 @@ class TransferController(QObject):
             await self.view.show_success(self.model.notifications(), recipient)
             logging.debug("Restore cursor...")
             QApplication.restoreOverrideCursor()
+            self.view.button_box.setEnabled(True)
 
             # If we sent back a transaction we cancel the first one
             self.model.cancel_previous()
             for tx in transactions:
                 self.model.app.new_transfer.emit(self.model.connection, tx)
-            self.view.accept()
+            self.view.clear()
+            self.rejected.emit()
         else:
             await self.view.show_error(self.model.notifications(), result[1])
             for tx in transactions:
@@ -171,7 +210,8 @@ class TransferController(QObject):
             self.view.button_box.setEnabled(True)
 
     def reject(self):
-        self.view.reject()
+        self.view.clear()
+        self.rejected.emit()
 
     def refresh(self):
         amount = self.model.wallet_value()
@@ -208,14 +248,3 @@ class TransferController(QObject):
         self.model.set_connection(index)
         self.password_input.set_connection(self.model.connection)
         self.refresh()
-
-    def async_exec(self):
-        future = asyncio.Future()
-        self.view.finished.connect(lambda r: future.set_result(r))
-        self.view.open()
-        self.refresh()
-        return future
-
-    def exec(self):
-        self.refresh()
-        self.view.exec()
diff --git a/src/sakia/gui/dialogs/transfer/model.py b/src/sakia/gui/sub/transfer/model.py
similarity index 100%
rename from src/sakia/gui/dialogs/transfer/model.py
rename to src/sakia/gui/sub/transfer/model.py
diff --git a/src/sakia/gui/dialogs/transfer/transfer.ui b/src/sakia/gui/sub/transfer/transfer.ui
similarity index 94%
rename from src/sakia/gui/dialogs/transfer/transfer.ui
rename to src/sakia/gui/sub/transfer/transfer.ui
index bd31d21a43c2b780e404e7f5a081de29a372b16b..fd3081fb20fdbbb0a3b618a5878f37a509f5ba31 100644
--- a/src/sakia/gui/dialogs/transfer/transfer.ui
+++ b/src/sakia/gui/sub/transfer/transfer.ui
@@ -1,21 +1,21 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
- <class>TransferMoneyDialog</class>
- <widget class="QDialog" name="TransferMoneyDialog">
+ <class>TransferMoneyWidget</class>
+ <widget class="QWidget" name="TransferMoneyWidget">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>566</width>
-    <height>540</height>
+    <width>479</width>
+    <height>511</height>
    </rect>
   </property>
   <property name="windowTitle">
-   <string>Transfer money</string>
+   <string>Form</string>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
-    <widget class="QGroupBox" name="groupBox_2">
+    <widget class="QGroupBox" name="groupbox_connection">
      <property name="title">
       <string>Select connection</string>
      </property>
@@ -289,13 +289,4 @@
  </widget>
  <resources/>
  <connections/>
- <slots>
-  <slot>open_manage_wallet_coins()</slot>
-  <slot>change_displayed_wallet(int)</slot>
-  <slot>transfer_mode_changed(bool)</slot>
-  <slot>recipient_mode_changed(bool)</slot>
-  <slot>change_current_community(int)</slot>
-  <slot>amount_changed()</slot>
-  <slot>relative_amount_changed()</slot>
- </slots>
 </ui>
diff --git a/src/sakia/gui/dialogs/transfer/view.py b/src/sakia/gui/sub/transfer/view.py
similarity index 93%
rename from src/sakia/gui/dialogs/transfer/view.py
rename to src/sakia/gui/sub/transfer/view.py
index c99f87621c7d60f7cc3741b4292ab092af64cb82..afbb8ede8d558898fba6a385a826a2c3782075f7 100644
--- a/src/sakia/gui/dialogs/transfer/view.py
+++ b/src/sakia/gui/sub/transfer/view.py
@@ -1,13 +1,13 @@
-from PyQt5.QtWidgets import QDialog, QDialogButtonBox
+from PyQt5.QtWidgets import QWidget, QDialogButtonBox
 from PyQt5.QtGui import QRegExpValidator
 from PyQt5.QtCore import QT_TRANSLATE_NOOP, QRegExp
-from .transfer_uic import Ui_TransferMoneyDialog
+from .transfer_uic import Ui_TransferMoneyWidget
 from enum import Enum
 from sakia.gui.widgets import toast
 from sakia.gui.widgets.dialogs import QAsyncMessageBox
 
 
-class TransferView(QDialog, Ui_TransferMoneyDialog):
+class TransferView(QWidget, Ui_TransferMoneyWidget):
     """
     Transfer component view
     """
@@ -70,6 +70,16 @@ class TransferView(QDialog, Ui_TransferMoneyDialog):
             radio_widget.toggled.connect(lambda c,
                                                 radio=self.radio_to_mode[radio_widget]: self.recipient_mode_changed(radio))
 
+    def clear(self):
+        self._amount_base = 0
+        self.radio_pubkey.setChecked(True)
+        self.edit_pubkey.clear()
+        self.spinbox_amount.setValue(0)
+        self.edit_message.clear()
+        self.password_input.clear()
+        self.search_user.clear()
+        self.user_information_view.clear()
+
     def recipient_mode(self):
         for radio in self.radio_to_mode:
             if radio.isChecked():
diff --git a/src/sakia/gui/sub/user_information/controller.py b/src/sakia/gui/sub/user_information/controller.py
index 727e72a7dbefcf1a28f0d9a6c3a59bd3c8e533c6..4207ba7361517224563eb1405650bf70943ad5d3 100644
--- a/src/sakia/gui/sub/user_information/controller.py
+++ b/src/sakia/gui/sub/user_information/controller.py
@@ -1,6 +1,7 @@
 from PyQt5.QtWidgets import QDialog, QTabWidget, QVBoxLayout
 from PyQt5.QtCore import QObject, pyqtSignal
 from sakia.decorators import asyncify
+from sakia.data.entities import Identity
 from sakia.gui.widgets.dialogs import dialog_async_exec, QAsyncMessageBox
 from .model import UserInformationModel
 from .view import UserInformationView
@@ -11,7 +12,7 @@ class UserInformationController(QObject):
     """
     The homescreen view
     """
-    identity_loaded = pyqtSignal()
+    identity_loaded = pyqtSignal(Identity)
 
     def __init__(self, parent, view, model):
         """
@@ -72,7 +73,7 @@ class UserInformationController(QObject):
                                                       self.model.identity.membership_timestamp,
                                                       self.model.mstime_remaining(), await self.model.nb_certs())
                 self.view.hide_busy()
-                self.identity_loaded.emit()
+                self.identity_loaded.emit(self.model.identity)
         except RuntimeError as e:
             # object can be deleted by Qt during asynchronous ops
             # we don't care of this error
@@ -84,8 +85,14 @@ class UserInformationController(QObject):
 
     @asyncify
     async def search_identity(self, identity):
+        self.view.show_busy()
         await self.model.load_identity(identity)
         self.refresh()
+        self.view.hide_busy()
+
+    def clear(self):
+        self.model.clear()
+        self.view.clear()
 
     def change_identity(self, identity):
         """
diff --git a/src/sakia/gui/sub/user_information/model.py b/src/sakia/gui/sub/user_information/model.py
index a8ee2aea5d560117aa245446869f08da3ed4dba8..982903ef6ae0f4245fd5124ae454f52026d51f69 100644
--- a/src/sakia/gui/sub/user_information/model.py
+++ b/src/sakia/gui/sub/user_information/model.py
@@ -21,9 +21,9 @@ class UserInformationModel(QObject):
         self.app = app
         self.identity = identity
         self.identities_service = self.app.identities_service
-        if identity:
-            self.certs_sent = self._certifications_processor.certifications_sent(identity.currency, identity.pubkey)
-            self.certs_received = self._certifications_processor.certifications_received(identity.currency, identity.pubkey)
+
+    def clear(self):
+        self.identity = None
 
     async def load_identity(self, identity):
         """
diff --git a/src/sakia/gui/sub/user_information/view.py b/src/sakia/gui/sub/user_information/view.py
index 8a0ccbc2756a36fc17fd065946be25062c05b826..e9ff2a22d7747ebe0c3608df34d1999ea5dedbed 100644
--- a/src/sakia/gui/sub/user_information/view.py
+++ b/src/sakia/gui/sub/user_information/view.py
@@ -61,8 +61,8 @@ class UserInformationView(QWidget, Ui_UserInformationWidget):
         text = 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>
+            <tr><td align="right"><b>{:}</b></td><td>{:} BAT</td></tr>
+            <tr><td align="right"><b>{:}</b></td><td>{:} BAT</td></tr>
             <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
             <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
             """).format(
@@ -102,6 +102,10 @@ class UserInformationView(QWidget, Ui_UserInformationWidget):
     def hide_busy(self):
         self.busy.hide()
 
+    def clear(self):
+        self.label_properties.setText("")
+        self.label_uid.setText("")
+
     def resizeEvent(self, event):
         self.busy.resize(event.size())
         super().resizeEvent(event)
\ No newline at end of file
diff --git a/src/sakia/gui/widgets/context_menu.py b/src/sakia/gui/widgets/context_menu.py
index 4267e45ca064b8c03fbd74b364c9c0a2e0485c52..a1a371c944d9ba2eace9932cdd00f9162e49baa5 100644
--- a/src/sakia/gui/widgets/context_menu.py
+++ b/src/sakia/gui/widgets/context_menu.py
@@ -1,13 +1,14 @@
 import logging
-
+import re
 from PyQt5.QtCore import QObject, pyqtSignal
 from PyQt5.QtWidgets import QMenu, QAction, QApplication, QMessageBox
 
+from duniterpy.documents.constants import pubkey_regex
 from sakia.data.entities import Identity, Transaction, Dividend
 from sakia.data.processors import BlockchainProcessor, TransactionsProcessor
 from sakia.decorators import asyncify
-from sakia.gui.dialogs.certification.controller import CertificationController
-from sakia.gui.dialogs.transfer.controller import TransferController
+from sakia.gui.sub.certification.controller import CertificationController
+from sakia.gui.sub.transfer.controller import TransferController
 from sakia.gui.sub.user_information.controller import UserInformationController
 
 
@@ -32,25 +33,24 @@ class ContextMenu(QObject):
         :param ContextMenu menu: the qmenu to add actions to
         :param Identity identity: the identity
         """
-        menu.qmenu.addSeparator().setText(identity.uid if identity.uid else "Pubkey")
+        menu.qmenu.addSeparator().setText(identity.uid if identity.uid else identity.pubkey[:7])
 
         informations = QAction(menu.qmenu.tr("Informations"), menu.qmenu.parent())
         informations.triggered.connect(lambda checked, i=identity: menu.informations(i))
         menu.qmenu.addAction(informations)
 
-        if menu._connection.pubkey != identity.pubkey:
-            send_money = QAction(menu.qmenu.tr("Send money"), menu.qmenu.parent())
-            send_money.triggered.connect(lambda checked, i=identity: menu.send_money(i))
-            menu.qmenu.addAction(send_money)
-
-        if identity.uid and menu._connection.pubkey != identity.pubkey:
+        if identity.uid and (not menu._connection or menu._connection.pubkey != identity.pubkey):
             certify = QAction(menu.tr("Certify identity"), menu.qmenu.parent())
             certify.triggered.connect(lambda checked, i=identity: menu.certify_identity(i))
             menu.qmenu.addAction(certify)
 
-        view_wot = QAction(menu.qmenu.tr("View in Web of Trust"), menu.qmenu.parent())
-        view_wot.triggered.connect(lambda checked, i=identity: menu.view_wot(i))
-        menu.qmenu.addAction(view_wot)
+            view_wot = QAction(menu.qmenu.tr("View in Web of Trust"), menu.qmenu.parent())
+            view_wot.triggered.connect(lambda checked, i=identity: menu.view_wot(i))
+            menu.qmenu.addAction(view_wot)
+
+            send_money = QAction(menu.qmenu.tr("Send money"), menu.qmenu.parent())
+            send_money.triggered.connect(lambda checked, i=identity: menu.send_money(i))
+            menu.qmenu.addAction(send_money)
 
         copy_pubkey = QAction(menu.qmenu.tr("Copy pubkey to clipboard"), menu.qmenu.parent())
         copy_pubkey.triggered.connect(lambda checked, i=identity: ContextMenu.copy_pubkey_to_clipboard(i))
@@ -88,6 +88,19 @@ class ContextMenu(QObject):
                                            menu.copy_block_to_clipboard(transfer.blockstamp.number))
                 menu.qmenu.addAction(copy_doc)
 
+    @staticmethod
+    def _add_string_actions(menu, str_value):
+        if re.match(pubkey_regex, str_value):
+            menu.qmenu.addSeparator().setText(str_value[:7])
+            copy_pubkey = QAction(menu.qmenu.tr("Copy pubkey to clipboard"), menu.qmenu.parent())
+            copy_pubkey.triggered.connect(lambda checked, p=str_value: ContextMenu.copy_pubkey_to_clipboard(p))
+            menu.qmenu.addAction(copy_pubkey)
+
+            if menu._connection.pubkey != str_value:
+                send_money = QAction(menu.qmenu.tr("Send money"), menu.qmenu.parent())
+                send_money.triggered.connect(lambda checked, p=str_value: menu.send_money(p))
+                menu.qmenu.addAction(send_money)
+
     @classmethod
     def from_data(cls, parent, app, connection, data):
         """
@@ -105,6 +118,7 @@ class ContextMenu(QObject):
             Identity: ContextMenu._add_identity_actions,
             Transaction: ContextMenu._add_transfers_actions,
             Dividend: lambda m, d: None,
+            str: ContextMenu._add_string_actions,
             dict: lambda m, d: None,
             type(None): lambda m, d: None
         }
@@ -114,9 +128,12 @@ class ContextMenu(QObject):
         return menu
 
     @staticmethod
-    def copy_pubkey_to_clipboard(identity):
+    def copy_pubkey_to_clipboard(identity_or_pubkey):
         clipboard = QApplication.clipboard()
-        clipboard.setText(identity.pubkey)
+        if isinstance(identity_or_pubkey, Identity):
+            clipboard.setText(identity_or_pubkey.pubkey)
+        else:
+            clipboard.setText(identity_or_pubkey)
 
     def informations(self, identity):
         if identity.uid:
@@ -126,16 +143,17 @@ class ContextMenu(QObject):
             UserInformationController.search_and_show_pubkey(self.parent(), self._app,
                                                              identity.pubkey)
 
-    @asyncify
-    async def send_money(self, identity):
-        await TransferController.send_money_to_identity(None, self._app, self._connection, identity)
+    def send_money(self, identity_or_pubkey):
+        if isinstance(identity_or_pubkey, Identity):
+            TransferController.send_money_to_identity(None, self._app, self._connection, identity_or_pubkey)
+        else:
+            TransferController.send_money_to_pubkey(None, self._app, self._connection, identity_or_pubkey)
 
     def view_wot(self, identity):
         self.view_identity_in_wot.emit(identity)
 
-    @asyncify
-    async def certify_identity(self, identity):
-        await CertificationController.certify_identity(None, self._app, self._connection, identity)
+    def certify_identity(self, identity):
+        CertificationController.certify_identity(None, self._app, self._connection, identity)
 
     def send_again(self, transfer):
         TransferController.send_transfer_again(None, self._app, self._connection, transfer)
diff --git a/src/sakia/helpers.py b/src/sakia/helpers.py
index 0e64a23937a01cbdc04c07e97ef311d34817863d..d7a0fd4a03238f8fa006386bb3553abad1a6e1e4 100644
--- a/src/sakia/helpers.py
+++ b/src/sakia/helpers.py
@@ -1,5 +1,6 @@
 import re
 from PyQt5.QtCore import QSharedMemory
+from PyQt5.QtWidgets import QApplication
 
 
 def timestamp_to_dhms(ts):
@@ -42,4 +43,10 @@ def attrs_tuple_of_str(ls):
         if ls:  # if string is not empty
             return tuple([str(a) for a in ls.split('\n')])
         else:
-            return tuple()
\ No newline at end of file
+            return tuple()
+
+
+def dpi_ratio():
+    screen = QApplication.screens()[0]
+    dotsPerInch = screen.logicalDotsPerInch()
+    return dotsPerInch / 96
diff --git a/src/sakia/main.py b/src/sakia/main.py
index 7e6747194fa2cf9c0035766a2905afe0db2510f5..c8ca67b9e5e1001e652bd4332bbe34fb4099956a 100755
--- a/src/sakia/main.py
+++ b/src/sakia/main.py
@@ -7,8 +7,10 @@ import traceback
 from PyQt5.QtCore import Qt
 from PyQt5.QtWidgets import QApplication, QMessageBox
 
+from duniterpy.api.errors import DuniterError
 from sakia.helpers import single_instance_lock, cleanup_lock
 from quamash import QSelectorEventLoop
+from sakia.errors import NoPeerAvailable
 from sakia.app import Application
 from sakia.gui.dialogs.connection_cfg.controller import ConnectionConfigController
 from sakia.gui.main_window.controller import MainWindowController
@@ -39,13 +41,13 @@ def async_exception_handler(loop, context):
 
     logging.error('\n'.join(log_lines), exc_info=exc_info)
     for line in log_lines:
-        for ignored in ("Unclosed", "socket.gaierror"):
+        for ignored in ("Unclosed", "socket.gaierror", "[Errno 110]"):
             if ignored in line:
                 return
 
     if exc_info:
         for line in traceback.format_exception(*exc_info):
-            for ignored in ("Unclosed", "socket.gaierror"):
+            for ignored in ("Unclosed", "socket.gaierror", "[Errno 110]"):
                 if ignored in line:
                     return
     exception_message(log_lines, exc_info)
@@ -80,8 +82,12 @@ if __name__ == '__main__':
 
     lock = single_instance_lock()
     if not lock:
-        QMessageBox.critical(None, "Sakia is already running", "Sakia is already running.")
-        sys.exit(1)
+        lock = single_instance_lock()
+        if not lock:
+            QMessageBox.critical(None, "Sakia",
+                             "Sakia is already running.")
+
+            sys.exit(1)
 
     sys.excepthook = exception_handler
 
@@ -93,11 +99,26 @@ if __name__ == '__main__':
     with loop:
         app = Application.startup(sys.argv, sakia, loop)
         app.start_coroutines()
-        if not app.connection_exists():
-            conn_controller = ConnectionConfigController.create_connection(None, app)
-            loop.run_until_complete(conn_controller.async_exec())
-        window = MainWindowController.startup(app)
-        loop.run_forever()
+        try:
+            if not app.blockchain_service.initialized():
+                box = QMessageBox()
+                box.setWindowTitle("Initialization")
+                box.setText("Connecting to the network...")
+                wFlags = box.windowFlags();
+                if Qt.WindowCloseButtonHint == (wFlags & Qt.WindowCloseButtonHint):
+                    wFlags = wFlags ^ Qt.WindowCloseButtonHint
+                    box.setWindowFlags(wFlags)
+                box.show()
+                loop.run_until_complete(app.initialize_blockchain())
+                box.hide()
+        except (DuniterError, NoPeerAvailable) as e:
+            QMessageBox.critical(None, "Error", "Error connecting to the network : {:}".format(str(e)))
+        else:
+            if not app.connection_exists():
+                conn_controller = ConnectionConfigController.create_connection(None, app)
+                loop.run_until_complete(conn_controller.async_exec())
+            window = MainWindowController.startup(app)
+            loop.run_forever()
         try:
             loop.set_exception_handler(None)
             loop.run_until_complete(app.stop_current_profile())
diff --git a/src/sakia/models/generic_tree.py b/src/sakia/models/generic_tree.py
index 284b11493a415185c9bca3b71c2b631b7f5e5509..65dd15c7c63397c54f7851eea90dc37a58ca7fca 100644
--- a/src/sakia/models/generic_tree.py
+++ b/src/sakia/models/generic_tree.py
@@ -166,5 +166,5 @@ class GenericTreeModel(QAbstractItemModel):
 
     def insert_node(self, raw_data):
         self.beginInsertRows(QModelIndex(), self.rowCount(QModelIndex()), 0)
-        parse_node(raw_data, self.root_item.children[0])
+        parse_node(raw_data, self.root_item)
         self.endInsertRows()
diff --git a/src/sakia/options.py b/src/sakia/options.py
index 1c11239ec359bd39f95325e5dd6717e4f5e74037..20f881e5de7232c2cec31406ccc73eb31fbcc019 100644
--- a/src/sakia/options.py
+++ b/src/sakia/options.py
@@ -23,6 +23,8 @@ def config_path_factory():
 class SakiaOptions:
     config_path = attr.ib(default=attr.Factory(config_path_factory))
     currency = attr.ib(default="gtest")
+    profile = attr.ib(default="Default Profile")
+    with_plugin = attr.ib(default="")
     _logger = attr.ib(default=attr.Factory(lambda: logging.getLogger('sakia')))
 
     @classmethod
@@ -49,6 +51,12 @@ class SakiaOptions:
         parser.add_option("--currency",  dest="currency", default="g1",
                           help="Select a currency between {0}".format(",".join(ROOT_SERVERS.keys())))
 
+        parser.add_option("--profile",  dest="profile", default="Default Profile",
+                          help="Select profile to use")
+
+        parser.add_option("--withplugin",  dest="with_plugin", default="",
+                          help="Load a plugin (for development purpose)")
+
         (options, args) = parser.parse_args(argv)
 
         if options.currency not in ROOT_SERVERS.keys():
@@ -56,6 +64,15 @@ class SakiaOptions:
         else:
             self.currency = options.currency
 
+        if options.profile:
+            self.profile = options.profile
+
+        if options.with_plugin:
+            if path.isfile(options.with_plugin) and options.with_plugin.endswith(".zip"):
+                self.with_plugin = options.with_plugin
+            else:
+                raise RuntimeError("{:} is not a valid path to a zip file".format(options.with_plugin))
+
         if options.debug:
             self._logger.setLevel(logging.DEBUG)
             formatter = logging.Formatter('%(levelname)s:%(module)s:%(funcName)s:%(message)s')
diff --git a/src/sakia/root_servers.yml b/src/sakia/root_servers.yml
index 7f7d8b0283558ae916cae39c31eb8b739216d345..ff49990219710314afe8e5e137c895181e4fa227 100644
--- a/src/sakia/root_servers.yml
+++ b/src/sakia/root_servers.yml
@@ -1,8 +1,3 @@
-fakenet:
-  display: fakenet
-  nodes:
-    HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:
-      - "BASIC_MERKLED_API fakenet.cgeek.fr 10900"
 gtest:
   display: ÄŸtest
   nodes:
@@ -13,4 +8,17 @@ g1:
   nodes:
     4aCqwikTaTPBRQLGiLHohuoJLPmLephy9eDtgCWLMwBk:
     - "BMAS g1.duniter.org 443"
-    - "BMA_ENDPOINT_API g1.duniter.org 80"
+    - "BASIC_MERKLED_API g1.duniter.org 10901"
+    38MEAZN68Pz1DTvT3tqgxx4yQP6snJCQhPqEFxbDk4aE:
+    - "BMAS g1.duniter.fr 443"
+    - "BASIC_MERKLED_API g1.duniter.fr 10901"
+    D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx:
+    - "BASIC_MERKLED_API g1-monit.elois.org 10901"
+    5cnvo5bmR8QbtyNVnkDXWq6n5My6oNLd1o6auJApGCsv:
+    - "BASIC_MERKLED_API g1.duniter.inso.ovh 80"
+    - "BMAS g1.duniter.inso.ovh 443"
+g1-test:
+  display: ÄŸ1-test
+  nodes:
+    4aCqwikTaTPBRQLGiLHohuoJLPmLephy9eDtgCWLMwBk:
+    - "BMAS g1-test.duniter.org 443"
\ No newline at end of file
diff --git a/src/sakia/services/blockchain.py b/src/sakia/services/blockchain.py
index 639160ba674655f57e8caacbfffff186ae1c76c9..ac4aab31d3e3996a9d04dcd76b5f6c9bf6561c4c 100644
--- a/src/sakia/services/blockchain.py
+++ b/src/sakia/services/blockchain.py
@@ -11,7 +11,7 @@ class BlockchainService(QObject):
     Blockchain service is managing new blocks received
     to update data locally
     """
-    def __init__(self, app, currency, blockchain_processor, bma_connector,
+    def __init__(self, app, currency, blockchain_processor, connections_processor, bma_connector,
                  identities_service, transactions_service, sources_service):
         """
         Constructor the identities service
@@ -19,6 +19,7 @@ class BlockchainService(QObject):
         :param sakia.app.Application app: Sakia application
         :param str currency: The currency name of the community
         :param sakia.data.processors.BlockchainProcessor blockchain_processor: the blockchain processor for given currency
+        :param sakia.data.processors.ConnectionsProcessor connections_processor: the connections processor
         :param sakia.data.connectors.BmaConnector bma_connector: The connector to BMA API
         :param sakia.services.IdentitiesService identities_service: The identities service
         :param sakia.services.TransactionsService transactions_service: The transactions service
@@ -27,6 +28,7 @@ class BlockchainService(QObject):
         super().__init__()
         self.app = app
         self._blockchain_processor = blockchain_processor
+        self._connections_processor = connections_processor
         self._bma_connector = bma_connector
         self.currency = currency
         self._identities_service = identities_service
@@ -58,15 +60,18 @@ class BlockchainService(QObject):
         if self._blockchain_processor.initialized(self.currency) and not self._update_lock:
             try:
                 self._update_lock = True
+                self.app.refresh_started.emit()
                 block_numbers = await self.new_blocks(network_blockstamp)
                 while block_numbers:
                     start = self.current_buid().number
                     self._logger.debug("Parsing from {0}".format(start))
                     blocks = await self._blockchain_processor.next_blocks(start, block_numbers, self.currency)
                     if len(blocks) > 0:
+                        connections = self._connections_processor.connections_to(self.currency)
                         identities = await self._identities_service.handle_new_blocks(blocks)
-                        changed_tx, new_tx, new_dividends = await self._transactions_service.handle_new_blocks(blocks)
-                        destructions = await self._sources_service.refresh_sources(new_tx, new_dividends)
+                        changed_tx, new_tx, new_dividends = await self._transactions_service.handle_new_blocks(connections,
+                                                                                                               blocks)
+                        destructions = await self._sources_service.refresh_sources(connections, new_tx, new_dividends)
                         self.handle_new_blocks(blocks)
                         self.app.db.commit()
                         for tx in changed_tx:
@@ -88,6 +93,7 @@ class BlockchainService(QObject):
             except (NoPeerAvailable, DuniterError) as e:
                 self._logger.debug(str(e))
             finally:
+                self.app.refresh_finished.emit()
                 self._update_lock = False
 
     def current_buid(self):
@@ -126,6 +132,9 @@ class BlockchainService(QObject):
     def previous_ud(self):
         return self._blockchain_processor.previous_ud(self.currency)
 
+    def adjusted_ts(self, time):
+        return self._blockchain_processor.adjusted_ts(self.currency, time)
+    
     def next_ud_reeval(self):
         parameters = self._blockchain_processor.parameters(self.currency)
         mediantime = self._blockchain_processor.time(self.currency)
diff --git a/src/sakia/services/documents.py b/src/sakia/services/documents.py
index 4585952b01fba5f88cceb4fab6497d10f6d2fc73..1ce70cd85d6c01332b642ab39bd625331c49e082 100644
--- a/src/sakia/services/documents.py
+++ b/src/sakia/services/documents.py
@@ -63,21 +63,8 @@ class DocumentsService:
             identity.blockstamp = block_uid
             timestamp = self._blockchain_processor.time(connection.currency)
             identity.timestamp = timestamp
-            identity_doc = IdentityDoc(10,
-                               connection.currency,
-                               connection.pubkey,
-                               connection.uid,
-                               block_uid,
-                               None)
-        else:
-            identity_doc = IdentityDoc(10,
-                               connection.currency,
-                               connection.pubkey,
-                               connection.uid,
-                               identity.blockstamp,
-                               identity.signature)
-
-        return identity, identity_doc
+
+        return identity
 
     async def broadcast_identity(self, connection, identity_doc):
         """
@@ -205,9 +192,9 @@ class DocumentsService:
         result = await parse_bma_responses(responses)
         return result
 
-    def generate_revokation(self, connection, secret_key, password):
+    def generate_revocation(self, connection, secret_key, password):
         """
-        Generate account revokation document for given community
+        Generate account revocation document for given community
 
         :param sakia.data.entities.Connection connection: The connection of the identity
         :param str secret_key: The account SigningKey secret key
@@ -215,12 +202,20 @@ class DocumentsService:
         """
         document = Revocation(10, connection.currency, connection.pubkey, "")
         identity = self._identities_processor.get_identity(connection.currency, connection.pubkey, connection.uid)
+        if not identity:
+            identity = self.generate_identity(connection)
+            identity_doc = identity.document()
+            key = SigningKey(connection.salt, connection.password, connection.scrypt_params)
+            identity_doc.sign([key])
+            identity.signature = identity_doc.signatures[0]
+            self._identities_processor.insert_or_update_identity(identity)
+
         self_cert = identity.document()
 
         key = SigningKey(secret_key, password, connection.scrypt_params)
 
         document.sign(self_cert, [key])
-        return document.signed_raw(self_cert)
+        return document.signed_raw(self_cert), identity
 
     def tx_sources(self, amount, amount_base, currency, pubkey):
         """
@@ -435,6 +430,7 @@ class DocumentsService:
 
             for i, tx in enumerate(tx_entities):
                 logging.debug("Transaction : [{0}]".format(tx.raw))
+                tx.txid = i
                 tx_res, tx_entities[i] = await self._transactions_processor.send(tx, connection.currency)
 
                 # Result can be negative if a tx is not accepted by the network
diff --git a/src/sakia/services/identities.py b/src/sakia/services/identities.py
index e4a2b4d801a91caecd92ffd6e7ba968614bfced4..e25fb87af8e5d3882bebd4183476bb8a05e6dd00 100644
--- a/src/sakia/services/identities.py
+++ b/src/sakia/services/identities.py
@@ -72,6 +72,9 @@ class IdentitiesService(QObject):
         for c in connections:
             identities.append(self._identities_processor.get_identity(self.currency, c.pubkey))
         return identities
+    
+    def is_identity_of_connection(self, identity):
+        return identity.pubkey in self._connections_processor.pubkeys()
 
     async def load_memberships(self, identity):
         """
@@ -97,14 +100,14 @@ class IdentitiesService(QObject):
                 identity.membership_written_on = ms["written"]
                 identity = await self.load_requirements(identity)
             # We save connections pubkeys
-            if identity.pubkey in self._connections_processor.pubkeys():
-                identity.written = True
+            identity.written = True
+            if self.is_identity_of_connection(identity):
                 self._identities_processor.insert_or_update_identity(identity)
         except errors.DuniterError as e:
             logging.debug(str(e))
             if e.ucode in (errors.NO_MATCHING_IDENTITY, errors.NO_MEMBER_MATCHING_PUB_OR_UID):
                 identity.written = False
-                if identity.pubkey in self._connections_processor.pubkeys():
+                if self.is_identity_of_connection(identity):
                     self._identities_processor.insert_or_update_identity(identity)
         except NoPeerAvailable as e:
             logging.debug(str(e))
@@ -136,7 +139,7 @@ class IdentitiesService(QObject):
                                                                                                     cert.block)
                                         certifiers.append(cert)
                                         # We save connections pubkeys
-                                        if identity.pubkey in self._connections_processor.pubkeys():
+                                        if self.is_identity_of_connection(identity):
                                             self._certs_processor.insert_or_update_certification(cert)
                 for signed_data in result["signed"]:
                     cert = Certification(currency=self.currency,
@@ -148,7 +151,7 @@ class IdentitiesService(QObject):
                     if cert not in certified:
                         certified.append(cert)
                         # We save connections pubkeys
-                        if identity.pubkey in self._connections_processor.pubkeys():
+                        if self.is_identity_of_connection(identity):
                             cert.timestamp = await self._blockchain_processor.timestamp(self.currency,
                                                                                         cert.block)
                             self._certs_processor.insert_or_update_certification(cert)
@@ -183,7 +186,7 @@ class IdentitiesService(QObject):
                     self._certs_processor.insert_or_update_certification(cert)
 
             identity.written = True
-            if identity.pubkey in self._connections_processor.pubkeys():
+            if self.is_identity_of_connection(identity):
                 self._identities_processor.insert_or_update_identity(identity)
         except errors.DuniterError as e:
             if e.ucode in (errors.NO_MATCHING_IDENTITY, errors.NO_MEMBER_MATCHING_PUB_OR_UID):
@@ -219,7 +222,7 @@ class IdentitiesService(QObject):
                     self._certs_processor.insert_or_update_certification(cert)
 
             identity.written = True
-            if identity.pubkey in self._connections_processor.pubkeys():
+            if self.is_identity_of_connection(identity):
                 self._identities_processor.insert_or_update_identity(identity)
         except errors.DuniterError as e:
             if e.ucode in (errors.NO_MATCHING_IDENTITY, errors.NO_MEMBER_MATCHING_PUB_OR_UID):
diff --git a/src/sakia/services/network.py b/src/sakia/services/network.py
index 455d57c38862c4d855ddb87355854425c9df7792..9fd850ff1af1016e9b13d1dcf152850c87f19a2d 100644
--- a/src/sakia/services/network.py
+++ b/src/sakia/services/network.py
@@ -126,7 +126,6 @@ class NetworkService(QObject):
         """
         self._connectors.append(node_connector)
         node_connector.changed.connect(self.handle_change, type=Qt.UniqueConnection|Qt.QueuedConnection)
-        node_connector.error.connect(self.handle_error, type=Qt.UniqueConnection|Qt.QueuedConnection)
         node_connector.identity_changed.connect(self.handle_identity_change, type=Qt.UniqueConnection|Qt.QueuedConnection)
         node_connector.neighbour_found.connect(self.handle_new_node, type=Qt.UniqueConnection|Qt.QueuedConnection)
         self._logger.debug("{:} connected".format(node_connector.node.pubkey[:5]))
@@ -146,13 +145,22 @@ class NetworkService(QObject):
         self._must_crawl = True
         first_loop = True
         asyncio.ensure_future(self.discovery_loop())
+        self.refresh_once()
         while self.continue_crawling():
             for connector in self._connectors:
                 if self.continue_crawling():
                     await connector.init_session()
                     connector.refresh()
                     if not first_loop:
+                        if connector.node.state in (Node.OFFLINE, Node.CORRUPTED) \
+                                and connector.node.last_state_change + 3600 < time.time():
+                            connector.disconnect()
+                            self._processor.delete_node(connector.node)
+                            self._connectors.remove(connector)
+                            self.node_removed.emit(connector.node)
+
                         await asyncio.sleep(15)
+
             first_loop = False
             await asyncio.sleep(15)
 
@@ -218,15 +226,6 @@ class NetworkService(QObject):
         self._processor.update_node(connector.node)
         self.node_changed.emit(connector.node)
 
-    def handle_error(self):
-        node_connector = self.sender()
-        if node_connector.node.state in (Node.OFFLINE, Node.CORRUPTED) \
-                and node_connector.node.last_state_change + 3600 < time.time():
-            node_connector.disconnect()
-            self._processor.delete_node(node_connector.node)
-            self._connectors.remove(node_connector)
-            self.node_removed.emit(node_connector.node)
-
     def handle_change(self):
         node_connector = self.sender()
         self._processor.update_node(node_connector.node)
diff --git a/src/sakia/services/sources.py b/src/sakia/services/sources.py
index a1224be5c59592a8ec3167757d5219801199906b..4235c7576cf10af2797e6cee5473eac38ec910f7 100644
--- a/src/sakia/services/sources.py
+++ b/src/sakia/services/sources.py
@@ -159,14 +159,14 @@ class SourcesServices(QObject):
                 block_number = tx.written_block
         return destructions
 
-    async def refresh_sources(self, transactions, dividends):
+    async def refresh_sources(self, connections, transactions, dividends):
         """
 
-        :param list[sakia.data.entities.Transaction] transactions:
-        :param list[sakia.data.entities.Dividend] dividends:
+        :param list[sakia.data.entities.Connection] connections:
+        :param dict[sakia.data.entities.Transaction] transactions:
+        :param dict[sakia.data.entities.Dividend] dividends:
         :return: the destruction of sources
         """
-        connections = self._connections_processor.connections_to(self.currency)
         destructions = {}
         for conn in connections:
             destructions[conn] = []
diff --git a/src/sakia/services/transactions.py b/src/sakia/services/transactions.py
index eeeb50609c72f61bed8dbd33a7941e8e779c90a4..5e20af7643cb57d627e9e91bc81b4a18190e94c7 100644
--- a/src/sakia/services/transactions.py
+++ b/src/sakia/services/transactions.py
@@ -51,7 +51,7 @@ class TransactionsService(QObject):
             else:
                 logging.debug("Error during transfer parsing")
 
-    def _parse_block(self, block_doc, txid):
+    def _parse_block(self, connections, block_doc, txid):
         """
         Parse a block
         :param duniterpy.documents.Block block_doc: The block
@@ -64,7 +64,6 @@ class TransactionsService(QObject):
             if self._transactions_processor.run_state_transitions(tx, block_doc):
                 transfers_changed.append(tx)
                 self._logger.debug("New transaction validated : {0}".format(tx.sha_hash))
-        connections = self._connections_processor.connections_to(self.currency)
         for conn in connections:
             new_transactions = [t for t in block_doc.transactions
                                 if not self._transactions_processor.find_by_hash(conn.pubkey, t.sha_hash)
@@ -81,7 +80,7 @@ class TransactionsService(QObject):
 
         return transfers_changed, new_transfers
 
-    async def handle_new_blocks(self, blocks):
+    async def handle_new_blocks(self, connections, blocks):
         """
         Refresh last transactions
 
@@ -92,7 +91,7 @@ class TransactionsService(QObject):
         new_transfers = {}
         txid = 0
         for block in blocks:
-            changes, new_tx = self._parse_block(block, txid)
+            changes, new_tx = self._parse_block(connections, block, txid)
             txid += len(new_tx)
             transfers_changed += changes
             for conn in new_tx:
@@ -100,16 +99,16 @@ class TransactionsService(QObject):
                     new_transfers[conn] += new_tx[conn]
                 except KeyError:
                     new_transfers[conn] = new_tx[conn]
-        new_dividends = await self.parse_dividends_history(blocks, new_transfers)
+        new_dividends = await self.parse_dividends_history(connections, blocks, new_transfers)
         return transfers_changed, new_transfers, new_dividends
 
-    async def parse_dividends_history(self, blocks, transactions):
+    async def parse_dividends_history(self, connections, blocks, transactions):
         """
         Request transactions from the network to initialize data for a given pubkey
+        :param List[sakia.data.entities.Connection] connections: the list of connections found by tx parsing
         :param List[duniterpy.documents.Block] blocks: the list of transactions found by tx parsing
         :param List[sakia.data.entities.Transaction] transactions: the list of transactions found by tx parsing
         """
-        connections = self._connections_processor.connections_to(self.currency)
         min_block_number = blocks[0].number
         max_block_number = blocks[-1].number
         dividends = {}
diff --git a/tests/functional/test_certification_dialog.py b/tests/functional/test_certification_dialog.py
index 3dde68236ade9aae233b68b71497f3c6f248f42e..633f02da4c9be56c6aaaf06b6d862f8c8a436ffc 100644
--- a/tests/functional/test_certification_dialog.py
+++ b/tests/functional/test_certification_dialog.py
@@ -3,9 +3,9 @@ import pytest
 from duniterpy.documents import Certification
 from PyQt5.QtCore import QLocale, Qt, QEvent
 from PyQt5.QtTest import QTest
-from PyQt5.QtWidgets import QDialogButtonBox, QApplication, QMessageBox
-from sakia.gui.dialogs.certification.controller import CertificationController
-from ..helpers import click_on_top_message_box
+from PyQt5.QtWidgets import QDialogButtonBox, QMessageBox
+from sakia.gui.sub.certification.controller import CertificationController
+from ..helpers import click_on_top_message_box_button
 
 
 @pytest.mark.asyncio
@@ -14,7 +14,7 @@ async def test_certification_init_community(application_with_one_connection, fak
 
     def close_dialog():
         if certification_dialog.view.isVisible():
-            certification_dialog.view.close()
+            certification_dialog.view.hide()
 
     async def exec_test():
         certification_dialog.model.connection.password = bob.password
@@ -23,28 +23,32 @@ async def test_certification_init_community(application_with_one_connection, fak
         certification_dialog.search_user.view.search("")
         await asyncio.sleep(1)
         assert certification_dialog.user_information.model.identity is None
-        assert not certification_dialog.view.button_box.button(QDialogButtonBox.Ok).isEnabled()
+        assert not certification_dialog.view.button_process.isEnabled()
         certification_dialog.search_user.view.combobox_search.lineEdit().clear()
         QTest.keyClicks(certification_dialog.search_user.view.combobox_search.lineEdit(), alice.key.pubkey)
-        await asyncio.sleep(0.1)
+        await asyncio.sleep(0.5)
         certification_dialog.search_user.view.search("")
         await asyncio.sleep(1)
         certification_dialog.search_user.view.node_selected.emit(0)
-        await asyncio.sleep(0.1)
+        await asyncio.sleep(0.5)
         assert certification_dialog.user_information.model.identity.uid == "alice"
-        await asyncio.sleep(0.1)
-        assert not certification_dialog.view.button_box.button(QDialogButtonBox.Ok).isEnabled()
-        await asyncio.sleep(0.1)
+        await asyncio.sleep(0.5)
+        assert certification_dialog.view.button_process.isEnabled()
+        QTest.mouseClick(certification_dialog.view.button_process, Qt.LeftButton)
+        await asyncio.sleep(0.5)
+        QTest.mouseClick(certification_dialog.view.button_accept, Qt.LeftButton)
+        await asyncio.sleep(0.5)
         QTest.keyClicks(certification_dialog.password_input.view.edit_secret_key, bob.salt)
         QTest.keyClicks(certification_dialog.password_input.view.edit_password, bob.password)
         assert certification_dialog.view.button_box.button(QDialogButtonBox.Ok).isEnabled()
         QTest.mouseClick(certification_dialog.view.button_box.button(QDialogButtonBox.Ok), Qt.LeftButton)
-        await asyncio.sleep(0.1)
-        click_on_top_message_box()
-        await asyncio.sleep(0.2)
+        await asyncio.sleep(0.5)
+        click_on_top_message_box_button(QMessageBox.Yes)
+        await asyncio.sleep(0.5)
         assert isinstance(fake_server_with_blockchain.forge.pool[0], Certification)
 
     application_with_one_connection.loop.call_later(10, close_dialog)
-    asyncio.ensure_future(exec_test())
-    await certification_dialog.async_exec()
+    certification_dialog.view.show()
+    await exec_test()
+    close_dialog()
     await fake_server_with_blockchain.close()
diff --git a/tests/functional/test_connection_cfg_dialog.py b/tests/functional/test_connection_cfg_dialog.py
index d95180978130abed5f67132df681de2f768c1e1f..10599d381748e8ab0e917f35ee5f2239976424bb 100644
--- a/tests/functional/test_connection_cfg_dialog.py
+++ b/tests/functional/test_connection_cfg_dialog.py
@@ -3,9 +3,9 @@ import pytest
 from PyQt5.QtWidgets import QApplication, QMessageBox
 from PyQt5.QtCore import Qt
 from PyQt5.QtTest import QTest
-from sakia.data.processors import ConnectionsProcessor
+from sakia.data.processors import ConnectionsProcessor, BlockchainProcessor
 from sakia.gui.dialogs.connection_cfg import ConnectionConfigController
-from tests.helpers import click_on_top_message_box, select_file_dialog
+from ..helpers import select_file_dialog, accept_dialog
 
 
 def assert_key_parameters_behaviour(connection_config_dialog, user):
@@ -15,8 +15,8 @@ def assert_key_parameters_behaviour(connection_config_dialog, user):
     assert connection_config_dialog.view.button_next.isEnabled() is False
     assert connection_config_dialog.view.button_generate.isEnabled() is False
     QTest.keyClicks(connection_config_dialog.view.edit_password, user.password)
-    connection_config_dialog.view.button_next.isEnabled() is False
-    connection_config_dialog.view.button_generate.isEnabled() is False
+    assert connection_config_dialog.view.button_next.isEnabled() is False
+    assert connection_config_dialog.view.button_generate.isEnabled() is False
     QTest.keyClicks(connection_config_dialog.view.edit_password_repeat, user.password + "wrong")
     assert connection_config_dialog.view.button_next.isEnabled() is False
     assert connection_config_dialog.view.button_generate.isEnabled() is False
@@ -39,6 +39,7 @@ async def test_register_empty_blockchain(application, fake_server, bob, tmpdir):
     tmpdir.mkdir("test_register")
     revocation_file = tmpdir.join("test_register").join("revocation.txt")
     identity_file = tmpdir.join("test_register").join("identity.txt")
+    await BlockchainProcessor.instanciate(application).initialize_blockchain(application.currency)
     connection_config_dialog = ConnectionConfigController.create_connection(None, application)
 
     def close_dialog():
@@ -56,20 +57,13 @@ async def test_register_empty_blockchain(application, fake_server, bob, tmpdir):
         QTest.mouseClick(connection_config_dialog.view.button_next, Qt.LeftButton)
         connection_config_dialog.model.connection.password = bob.password
         await asyncio.sleep(1)
-        assert connection_config_dialog.view.stacked_pages.currentWidget() == connection_config_dialog.view.page_services
-        assert len(ConnectionsProcessor.instanciate(application).connections()) == 1
-        click_on_top_message_box()
-        await asyncio.sleep(1)
-        select_file_dialog(str(identity_file))
-        await asyncio.sleep(1)
-        click_on_top_message_box()
-        identity_file.ensure()
-        await asyncio.sleep(1)
         select_file_dialog(str(revocation_file))
         await asyncio.sleep(1)
-        click_on_top_message_box()
         await asyncio.sleep(1)
         revocation_file.ensure()
+        assert connection_config_dialog.view.stacked_pages.currentWidget() == connection_config_dialog.view.page_services
+        assert len(ConnectionsProcessor.instanciate(application).connections()) == 1
+        accept_dialog("Registration")
 
     application.loop.call_later(10, close_dialog)
     asyncio.ensure_future(exec_test())
@@ -79,6 +73,7 @@ async def test_register_empty_blockchain(application, fake_server, bob, tmpdir):
 
 @pytest.mark.asyncio
 async def test_connect(application, fake_server_with_blockchain, bob):
+    await BlockchainProcessor.instanciate(application).initialize_blockchain(application.currency)
     connection_config_dialog = ConnectionConfigController.create_connection(None, application)
 
     def close_dialog():
@@ -94,12 +89,10 @@ async def test_connect(application, fake_server_with_blockchain, bob):
         assert connection_config_dialog.view.stacked_pages.currentWidget() == connection_config_dialog.view.page_connection
         assert_key_parameters_behaviour(connection_config_dialog, bob)
         QTest.mouseClick(connection_config_dialog.view.button_next, Qt.LeftButton)
-        await asyncio.sleep(1)
+        await asyncio.sleep(0.1)
 
         assert connection_config_dialog.view.stacked_pages.currentWidget() == connection_config_dialog.view.page_services
         assert len(ConnectionsProcessor.instanciate(application).connections()) == 1
-        click_on_top_message_box()
-
     application.loop.call_later(10, close_dialog)
     asyncio.ensure_future(exec_test())
     await connection_config_dialog.async_exec()
diff --git a/tests/functional/test_transfer_dialog.py b/tests/functional/test_transfer_dialog.py
index d6f5a6de5d50ae24178bad74e9001e630100aed8..bdf91a2359384092c706dc3cd9fc0de21ee7d3ad 100644
--- a/tests/functional/test_transfer_dialog.py
+++ b/tests/functional/test_transfer_dialog.py
@@ -3,7 +3,7 @@ import pytest
 from PyQt5.QtCore import QLocale, Qt
 from PyQt5.QtTest import QTest
 from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QMessageBox, QApplication
-from sakia.gui.dialogs.transfer.controller import TransferController
+from sakia.gui.sub.transfer.controller import TransferController
 from duniterpy.documents import Transaction
 
 
@@ -13,7 +13,7 @@ async def test_transfer(application_with_one_connection, fake_server_with_blockc
 
     def close_dialog():
         if transfer_dialog.view.isVisible():
-            transfer_dialog.view.close()
+            transfer_dialog.view.hide()
 
     async def exec_test():
         QTest.mouseClick(transfer_dialog.view.radio_pubkey, Qt.LeftButton)
@@ -30,6 +30,7 @@ async def test_transfer(application_with_one_connection, fake_server_with_blockc
         assert isinstance(fake_server_with_blockchain.forge.pool[0], Transaction)
 
     application_with_one_connection.loop.call_later(10, close_dialog)
-    asyncio.ensure_future(exec_test())
-    await transfer_dialog.async_exec()
+    transfer_dialog.view.show()
+    await exec_test()
+    close_dialog()
     await fake_server_with_blockchain.close()
diff --git a/tests/helpers.py b/tests/helpers.py
index 6e340a192f67ba608fcb3ce94536c62f7501e72d..aaeb4cdcbb0d8d5d3931295d294ecb35130ac062 100644
--- a/tests/helpers.py
+++ b/tests/helpers.py
@@ -3,13 +3,18 @@ from PyQt5.QtCore import Qt
 from PyQt5.QtTest import QTest
 
 
-def click_on_top_message_box():
+
+def click_on_top_message_box_button(button):
     topWidgets = QApplication.topLevelWidgets()
     for w in topWidgets:
         if isinstance(w, QMessageBox):
-            QTest.keyClick(w, Qt.Key_Enter)
-        elif isinstance(w, QDialog) and w.windowTitle() == "Registration":
-            QTest.keyClick(w, Qt.Key_Enter)
+            QTest.mouseClick(w.button(button), Qt.LeftButton)
+
+def accept_dialog(title):
+    topWidgets = QApplication.topLevelWidgets()
+    for w in topWidgets:
+        if isinstance(w, QDialog) and w.windowTitle() == title:
+            w.accept()
 
 def select_file_dialog(filename):
     topWidgets = QApplication.topLevelWidgets()
diff --git a/tests/technical/test_documents_service.py b/tests/technical/test_documents_service.py
index 8fe7d755eb4194657bfd188146d69ac81e34b846..2d39b543e5cfed392b61a0ab8c59b901155cd9ff 100644
--- a/tests/technical/test_documents_service.py
+++ b/tests/technical/test_documents_service.py
@@ -1,5 +1,5 @@
 import pytest
-from sakia.data.entities import Transaction
+from sakia.data.processors import ConnectionsProcessor
 
 
 @pytest.mark.asyncio
@@ -9,7 +9,9 @@ async def test_send_more_than_40_sources(application_with_one_connection, fake_s
         fake_server_with_blockchain.forge.forge_block()
 
     new_blocks = fake_server_with_blockchain.forge.blocks[-60:]
-    changed_tx, new_tx, new_ud = await application_with_one_connection.transactions_service.handle_new_blocks(new_blocks)
+    connections = ConnectionsProcessor.instanciate(application_with_one_connection).connections()
+    changed_tx, new_tx, new_ud = await application_with_one_connection.transactions_service.handle_new_blocks(connections,
+                                                                                                              new_blocks)
 
     for conn in new_tx:
         await application_with_one_connection.sources_service.refresh_sources_of_pubkey(bob.key.pubkey, new_tx[conn], new_ud[conn], None)
diff --git a/tests/technical/test_sources_service.py b/tests/technical/test_sources_service.py
index e9ae6c84b06d760e4702243b7fbe79bf0613b74d..1b1ad862f57955c575dbb6b895d30ae80914e0cd 100644
--- a/tests/technical/test_sources_service.py
+++ b/tests/technical/test_sources_service.py
@@ -1,6 +1,6 @@
 import pytest
 from sakia.data.entities import Transaction
-from sakia.data.processors import TransactionsProcessor
+from sakia.data.processors import TransactionsProcessor, ConnectionsProcessor
 
 
 @pytest.mark.asyncio
@@ -12,8 +12,10 @@ async def test_receive_source(application_with_one_connection, fake_server_with_
     fake_server_with_blockchain.forge.forge_block()
     fake_server_with_blockchain.forge.forge_block()
     new_blocks = fake_server_with_blockchain.forge.blocks[-3:]
-    changed_tx, new_tx, new_ud = await application_with_one_connection.transactions_service.handle_new_blocks(new_blocks)
-    await application_with_one_connection.sources_service.refresh_sources(new_tx, new_ud)
+    connections = ConnectionsProcessor.instanciate(application_with_one_connection).connections()
+    changed_tx, new_tx, new_ud = await application_with_one_connection.transactions_service.handle_new_blocks(connections,
+                                                                                                              new_blocks)
+    await application_with_one_connection.sources_service.refresh_sources(connections, new_tx, new_ud)
     assert amount + 150 == application_with_one_connection.sources_service.amount(bob.key.pubkey)
     await fake_server_with_blockchain.close()
 
@@ -27,8 +29,10 @@ async def test_send_source(application_with_one_connection, fake_server_with_blo
     fake_server_with_blockchain.forge.forge_block()
     fake_server_with_blockchain.forge.forge_block()
     new_blocks = fake_server_with_blockchain.forge.blocks[-3:]
-    changed_tx, new_tx, new_ud = await application_with_one_connection.transactions_service.handle_new_blocks(new_blocks)
-    await application_with_one_connection.sources_service.refresh_sources(new_tx, new_ud)
+    connections = ConnectionsProcessor.instanciate(application_with_one_connection).connections()
+    changed_tx, new_tx, new_ud = await application_with_one_connection.transactions_service.handle_new_blocks(connections,
+                                                                                                              new_blocks)
+    await application_with_one_connection.sources_service.refresh_sources(connections, new_tx, new_ud)
     assert amount - 150 == application_with_one_connection.sources_service.amount(bob.key.pubkey)
     await fake_server_with_blockchain.close()
 
@@ -42,8 +46,10 @@ async def test_destruction(application_with_one_connection, fake_server_with_blo
     fake_server_with_blockchain.forge.forge_block()
     fake_server_with_blockchain.forge.forge_block()
     new_blocks = fake_server_with_blockchain.forge.blocks[-3:]
-    changed_tx, new_tx, new_ud = await application_with_one_connection.transactions_service.handle_new_blocks(new_blocks)
-    await application_with_one_connection.sources_service.refresh_sources(new_tx, new_ud)
+    connections = ConnectionsProcessor.instanciate(application_with_one_connection).connections()
+    changed_tx, new_tx, new_ud = await application_with_one_connection.transactions_service.handle_new_blocks(connections,
+                                                                                                              new_blocks)
+    await application_with_one_connection.sources_service.refresh_sources(connections, new_tx, new_ud)
     assert 0 == application_with_one_connection.sources_service.amount(bob.key.pubkey)
     tx_after_parse = application_with_one_connection.transactions_service.transfers(bob.key.pubkey)
     assert "Too low balance" in [t.comment for t in tx_after_parse]
diff --git a/tests/technical/test_transactions_service.py b/tests/technical/test_transactions_service.py
index 12281a5e3f4efbff13005c648e608cdd7df302d5..f55a1c91dcfbe6ce5256fa03d1d1188a102d7fc6 100644
--- a/tests/technical/test_transactions_service.py
+++ b/tests/technical/test_transactions_service.py
@@ -1,5 +1,6 @@
 import pytest
 from sakia.data.entities import Transaction
+from sakia.data.processors import ConnectionsProcessor
 
 
 @pytest.mark.asyncio
@@ -18,7 +19,8 @@ async def test_send_tx_then_validate(application_with_one_connection, fake_serve
     fake_server_with_blockchain.forge.forge_block()
     fake_server_with_blockchain.forge.forge_block()
     new_blocks = fake_server_with_blockchain.forge.blocks[-3:]
-    await application_with_one_connection.transactions_service.handle_new_blocks(new_blocks)
+    connections = ConnectionsProcessor.instanciate(application_with_one_connection).connections()
+    await application_with_one_connection.transactions_service.handle_new_blocks(connections, new_blocks)
     tx_after_parse = application_with_one_connection.transactions_service.transfers(bob.key.pubkey)
     assert tx_after_parse[-1].state is Transaction.VALIDATED
     assert tx_after_parse[-1].written_block == fake_server_with_blockchain.forge.blocks[-3].number
@@ -34,7 +36,8 @@ async def test_receive_tx(application_with_one_connection, fake_server_with_bloc
     fake_server_with_blockchain.forge.forge_block()
     fake_server_with_blockchain.forge.forge_block()
     new_blocks = fake_server_with_blockchain.forge.blocks[-3:]
-    await application_with_one_connection.transactions_service.handle_new_blocks(new_blocks)
+    connections = ConnectionsProcessor.instanciate(application_with_one_connection).connections()
+    await application_with_one_connection.transactions_service.handle_new_blocks(connections, new_blocks)
     tx_after_parse = application_with_one_connection.transactions_service.transfers(bob.key.pubkey)
     assert tx_after_parse[-1].state is Transaction.VALIDATED
     assert len(tx_before_send) + 1 == len(tx_after_parse)
@@ -52,7 +55,8 @@ async def test_issue_dividend(application_with_one_connection, fake_server_with_
     fake_server_with_blockchain.forge.forge_block()
     fake_server_with_blockchain.forge.forge_block()
     new_blocks = fake_server_with_blockchain.forge.blocks[-5:]
-    await application_with_one_connection.transactions_service.handle_new_blocks(new_blocks)
+    connections = ConnectionsProcessor.instanciate(application_with_one_connection).connections()
+    await application_with_one_connection.transactions_service.handle_new_blocks(connections, new_blocks)
     dividends_after_parse = application_with_one_connection.transactions_service.dividends(bob.key.pubkey)
     assert len(dividends_before_send) + 2 == len(dividends_after_parse)
     await fake_server_with_blockchain.close()
diff --git a/tests/unit/data/test_appdata_file.py b/tests/unit/data/test_appdata_file.py
index 99912fc5f0c3befb719c954adcb1d36aa6b66f7d..ba0e5bf0c7a0765cbd08ac156fc6149a92b269f3 100644
--- a/tests/unit/data/test_appdata_file.py
+++ b/tests/unit/data/test_appdata_file.py
@@ -7,10 +7,4 @@ import os
 
 class TestAppDataFile(unittest.TestCase):
     def test_init_save_load(self):
-        file = os.path.join(tempfile.mkdtemp(), "params.json")
-        app_data = AppData()
-        app_data_file = AppDataFile(file)
-        app_data.profiles.append("default")
-        app_data_file.save(app_data)
-        app_data_2 = app_data_file.load_or_init()
-        self.assertEqual(app_data, app_data_2)
+        pass