diff --git a/.gitignore b/.gitignore
index 0a45e37a663c0c0a94a4c2c17866bf6689dfec63..31e2395d1a4c711d705552a44d63896f57305e2c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,3 +45,4 @@ res/i18n/qm
 res/i18n/lang-*
 out
 .directory
+temp
diff --git a/.travis.yml b/.travis.yml
index 41666ee505798ef8476a271efb07e9b6570fa759..c2bba1907b5c15bff1096903fbfb90737aa62c44 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -57,6 +57,7 @@ install:
   - pip install base58
   - pip install quamash
   - pip install asyncio
+  - pip install git+https://github.com/Insoleet/pretenders.git@develop
   - python gen_resources.py
   - python gen_translations.py
   - python setup.py build
diff --git a/ci/appveyor/build.cmd b/ci/appveyor/build.cmd
index 91e23da46c5ed6971035621b17bdd0bfc563cafa..79322896d4bb13d3a5c06a136fe680f9edb23fba 100644
--- a/ci/appveyor/build.cmd
+++ b/ci/appveyor/build.cmd
@@ -17,6 +17,7 @@ pip install requests
 pip install base58
 pip install quamash
 pip install asyncio
+pip install git+https://github.com/Insoleet/pretenders.git@develop
 
 python gen_resources.py
 if %errorlevel% neq 0 exit /b 1s
diff --git a/res/icons/AUTHORS b/res/icons/AUTHORS
index 4dc1d78f3193393fcd73bb1eec24f2c481b5d9a0..701840e29eb80d91e0847f992f5c19f87b7ca972 100644
--- a/res/icons/AUTHORS
+++ b/res/icons/AUTHORS
@@ -15,4 +15,12 @@ noun_5197_cc.svg : Created by Bibzee
 noun_38960_cc.svg : Created by Agarunov Oktay-Abraham
 noun_42425_cc.svg : Created by Luis Rodrigues
 noun_62146_cc.svg : Created by Sergey Krivoy
-noun_2149_cc.svg : Created by Anand A Nair
\ No newline at end of file
+noun_2149_cc.svg : Created by Anand A Nair
+noun_152997_cc.svg : Created by Pedro Ivo Hudson
+noun_139613_cc.svg : Created by Aha-Soft
+noun_19900_cc.svg : Created by by Stefan Parnarov
+noun_178785_cc.svg : by Jevgeni Striganov
+noun_41979_cc.svg : by by hunotika
+noun_155533_cc.svg : by anbileru adaleru
+noun_155520_cc.svg : by anbileru adaleru
+noun_155540_cc.svg : by anbileru adaleru
\ No newline at end of file
diff --git a/res/icons/icons.qrc b/res/icons/icons.qrc
index 6bef064abf71418f373ced63370badf17114d71a..8fe92ad92db25a2c85261a719b8b1844ae52af9f 100644
--- a/res/icons/icons.qrc
+++ b/res/icons/icons.qrc
@@ -1,5 +1,13 @@
 <RCC>
   <qresource prefix="icons">
+    <file alias="leave_icon">noun_155520_cc.svg</file>
+    <file alias="new_membership">noun_155540_cc.svg</file>
+    <file alias="payment_icon">noun_178785_cc.svg</file>
+    <file alias="renew_membership">noun_155533_cc.svg</file>
+    <file alias="certification_icon">noun_41979_cc.svg</file>
+    <file alias="logout">noun_19900_cc.svg</file>
+    <file alias="add_community">noun_139613_cc.svg</file>
+    <file alias="connect_icon">noun_152997_cc.svg</file>
     <file alias="home_icon">iconmonstr-home-icon.svg</file>
     <file alias="cutecoin_logo">logo.svg</file>
     <file alias="add_account_icon">noun_7440_cc.svg</file>
diff --git a/res/icons/noun_139613_cc.svg b/res/icons/noun_139613_cc.svg
new file mode 100644
index 0000000000000000000000000000000000000000..18a319b7c607bdfcd7ee5a358eef15e611bc7b34
--- /dev/null
+++ b/res/icons/noun_139613_cc.svg
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   viewBox="0 0 100.00001 125"
+   xml:space="preserve"
+   x="0px"
+   y="0px"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="noun_139613_cc.svg"><metadata
+     id="metadata14"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs12" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="712"
+     id="namedview10"
+     showgrid="false"
+     inkscape:zoom="1.888"
+     inkscape:cx="-42.425844"
+     inkscape:cy="62.5"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" /><path
+     d="m 25.78125,24.656245 c -1.19804,0.03338 -2.390296,0.356511 -3.5,1 -3.551054,2.059166 -4.777916,6.605196 -2.71875,10.15625 2.059166,3.551054 6.605196,4.777916 10.15625,2.71875 0.456937,-0.264966 0.872582,-0.566293 1.25,-0.90625 l 11.90625,8.84375 c -0.102601,-0.265069 -0.210456,-0.53323 -0.28125,-0.8125 -0.377046,-0.995022 -0.216682,-1.991187 0.03125,-2.96875 l -9.9375,-7.34375 c 1.040295,-2.147247 1.036979,-4.749341 -0.25,-6.96875 -1.415677,-2.441349 -4.020561,-3.792192 -6.65625,-3.71875 z m 53.90625,3.09375 c -1.19804,0.03338 -2.421546,0.356511 -3.53125,1 -3.09834,1.796649 -4.395139,5.479306 -3.3125,8.75 l -11.125,6.65625 c -0.01921,1.463022 -0.639159,2.857354 -1.375,4.1875 L 74.25,39.999995 c 2.284876,2.676533 6.222001,3.422095 9.375,1.59375 3.551054,-2.059166 4.746666,-6.605196 2.6875,-10.15625 -1.415677,-2.441349 -3.989311,-3.760942 -6.625,-3.6875 z m -27.625,6.0625 c -6.491611,0 -6.40625,5.65625 -6.40625,5.65625 l -0.0625,3.03125 c -0.530352,-0.0072 -0.65625,0.514594 -0.65625,1.5625 0,1.570663 0.973035,3.213529 1.84375,4.0625 0.295074,1.234764 0.866408,2.327458 1.625,3.15625 -0.02641,0.0162 -0.06722,0.01506 -0.09375,0.03125 -2.587069,1.578079 -5.672508,2.649945 -7.6875,3.71875 -0.555696,0.29448 -1.144777,0.811066 -1.625,1.46875 -0.32697,0.452412 -0.598878,0.935264 -0.84375,1.4375 -0.009,0.01782 -0.0225,0.04466 -0.03125,0.0625 -0.0335,0.0697 -0.06169,0.148406 -0.09375,0.21875 -0.48672,1.041571 -0.840864,2.134504 -1.03125,3.25 -0.004,0.02072 0.0038,0.04182 0,0.0625 -0.0086,0.05238 -0.02313,0.10387 -0.03125,0.15625 -0.03411,0.193194 -0.06636,0.403903 -0.09375,0.59375 -0.02338,0.156384 -0.04306,0.493278 -0.03125,0.65625 -0.0018,0.0099 9e-4,0.02135 0,0.03125 -0.07182,1.018098 1.84375,1.34375 1.84375,1.34375 0.715321,0.211536 2.029012,0.44187 3.625,0.65625 2.847115,0.46989 5.761037,0.630802 8.625,0.71875 0.277992,0.0086 0.572546,-0.0011 0.875,0 l 0.03125,0 c 0.150498,0 0.31314,0.0018 0.46875,0 0.302454,-0.0018 0.59699,0.0086 0.875,0 2.862703,-0.08791 5.779109,-0.249346 8.625,-0.71875 1.598346,-0.21456 2.908924,-0.444498 3.625,-0.65625 0,0 1.915552,-0.325652 1.84375,-1.34375 -0.0018,-0.0099 9e-4,-0.02133 0,-0.03125 0.01188,-0.162972 -0.0079,-0.499866 -0.03125,-0.65625 -0.03917,-0.271261 -0.103166,-0.566172 -0.15625,-0.84375 -0.210852,-1.219968 -0.58763,-2.440343 -1.15625,-3.5625 -0.0063,-0.0126 0.0065,-0.01868 0,-0.03125 -0.23436,-0.469476 -0.505438,-0.918878 -0.8125,-1.34375 -0.480222,-0.657684 -1.069304,-1.17427 -1.625,-1.46875 -2.014992,-1.068805 -5.100449,-2.140671 -7.6875,-3.71875 -0.02651,-0.0162 -0.06734,-0.01497 -0.09375,-0.03125 0.75861,-0.828792 1.329925,-1.921486 1.625,-3.15625 0.870714,-0.848971 1.8125,-2.491837 1.8125,-4.0625 0,-1.047906 -0.12588,-1.569664 -0.65625,-1.5625 l -0.03125,-3.03125 c 0,0 0.08537,-5.65625 -6.40625,-5.65625 z m -13.46875,19.65625 -19.375,4.84375 C 19.115362,58.083617 19.003698,57.846936 18.875,57.624995 16.815834,54.073941 12.269804,52.878329 8.71875,54.937495 5.1676963,56.996661 3.9408337,61.542691 6,65.093745 c 2.059166,3.551054 6.605196,4.746666 10.15625,2.6875 2.450927,-1.42123 3.803575,-4.041145 3.71875,-6.6875 l 15.84375,-3.9375 c 0.07438,-0.159517 0.172762,-0.313302 0.25,-0.46875 0.603648,-1.339254 1.514598,-2.380579 2.625,-3.21875 z m 31.125,7.78125 c 0.20349,1.074546 0.137248,2.244139 -0.3125,3.21875 l 11.3125,7.34375 c -0.855939,2.066285 -0.802327,4.478297 0.40625,6.5625 2.059166,3.551054 6.605196,4.777916 10.15625,2.71875 3.551054,-2.059166 4.777916,-6.605196 2.71875,-10.15625 -2.059166,-3.551054 -6.605196,-4.777916 -10.15625,-2.71875 -0.574435,0.3331 -1.08329,0.738901 -1.53125,1.1875 l -12.59375,-8.15625 z m -25.3125,6.5 -7.96875,20.84375 c -1.689316,-0.317982 -3.52127,-0.05496 -5.125,0.875 -3.551054,2.059166 -4.746666,6.605196 -2.6875,10.15625 2.059166,3.551055 6.605196,4.777915 10.15625,2.718755 3.551054,-2.05917 4.777916,-6.605201 2.71875,-10.156255 -0.607794,-1.048147 -1.45443,-1.883708 -2.40625,-2.5 l 8.3125,-21.65625 c -0.996859,-0.07277 -2.0091,-0.172782 -3,-0.28125 z"
+     style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+     id="path4"
+     inkscape:connector-curvature="0" /></svg>
\ No newline at end of file
diff --git a/res/icons/noun_152997_cc.svg b/res/icons/noun_152997_cc.svg
new file mode 100644
index 0000000000000000000000000000000000000000..3eb27d7384f0cb2f51e42695974d3f31e74e341a
--- /dev/null
+++ b/res/icons/noun_152997_cc.svg
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   x="0px"
+   y="0px"
+   viewBox="-255 347 100 125"
+   enable-background="new -255 347 100 100"
+   xml:space="preserve"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="noun_152997_cc.svg"><metadata
+     id="metadata14"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs12" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="743"
+     inkscape:window-height="480"
+     id="namedview10"
+     showgrid="false"
+     inkscape:zoom="1.888"
+     inkscape:cx="50"
+     inkscape:cy="62.5"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2" /><path
+     d="m -205,364 c -24.9,0 -45,20.1 -45,45 0,24.9 20.1,45 45,45 24.9,0 45,-20.1 45,-45 0,-24.9 -20.1,-45 -45,-45 z m -26,72.4 c 1.8,-0.8 3.6,-1.4 5.5,-1.9 5.2,-1.2 8.3,-2.9 9.3,-5.1 0.8,-1.7 0.3,-4 -1.2,-6.9 -9.6,-17.7 -7.9,-27.7 -4.8,-32.9 3.1,-5.3 9.1,-8.2 16.7,-8.2 7.6,0 13.5,2.9 16.6,8.1 3.1,5.2 4.8,15.2 -4.7,33 -1.6,3 -2,5.3 -1.2,7 1,2.1 4.1,3.8 9.3,5 1.8,0.4 4,1.1 6.3,2.1 -6.7,6.3 -15.8,10.1 -25.7,10.1 -10.2,0.1 -19.3,-3.9 -26.1,-10.3 z"
+     id="path4"
+     inkscape:connector-curvature="0" /></svg>
\ No newline at end of file
diff --git a/res/icons/noun_155520_cc.svg b/res/icons/noun_155520_cc.svg
new file mode 100644
index 0000000000000000000000000000000000000000..1217dfbec87ef8d09662154329e267fb1f6e6512
--- /dev/null
+++ b/res/icons/noun_155520_cc.svg
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   viewBox="0 0 100 125"
+   version="1.1"
+   x="0px"
+   y="0px"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="noun_155520_cc.svg">
+  <metadata
+     id="metadata16">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs14" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="743"
+     inkscape:window-height="480"
+     id="namedview12"
+     showgrid="false"
+     inkscape:zoom="1.888"
+     inkscape:cx="50"
+     inkscape:cy="62.5"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2" />
+  <g
+     transform="matrix(1.3457509,0,0,1.3457509,-17.552378,-1285.5892)"
+     id="g4">
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 15.110586,975.08438 c -0.257006,0 -0.505174,0.0945 -0.703274,0.2579 l -0.01172,0.015 -0.0059,0 C 14.081837,975.61353 14,976.00871 14,976.40929 l 0,34.68311 c 6.2e-5,0.6214 0.503812,1.1252 1.125238,1.1252 l 33.801091,0 c 0.586855,9.7103 8.643142,17.4323 18.49903,17.4323 10.236198,0 18.560564,-8.3214 18.560564,-18.5575 -0.05194,-0.3616 0,-0.6773 0,-1.0052 l 0,-33.68677 c 0.108906,-0.68863 -0.428123,-1.30945 -1.125237,-1.30105 -23.24491,-0.099 -46.520652,0.13953 -69.7501,-0.015 z m 1.139889,2.26514 67.484972,0 0,24.88708 c -3.148794,-5.77627 -9.278805,-9.70217 -16.310089,-9.70217 -9.856474,0 -17.913031,7.72137 -18.49903,17.43237 l -32.675853,0 z m 4.688492,3.56034 c -1.521671,-0.021 -1.521671,2.27207 0,2.25057 l 58.107989,0 c 1.521671,0.021 1.521671,-2.27203 0,-2.25057 z m 0,5.81077 c -1.521685,-0.021 -1.521685,2.272 0,2.2506 l 34.864793,0 c 1.521686,0.021 1.521686,-2.2721 0,-2.2506 z m 0,5.8138 c -1.521685,-0.021 -1.521685,2.272 0,2.2504 l 23.243195,0 c 1.521684,0.021 1.521684,-2.2719 0,-2.2504 z m 46.486391,2.2504 c 9.019957,0 16.310089,7.28737 16.310089,16.30727 0,9.0199 -7.290132,16.3071 -16.310089,16.3071 -8.975386,0 -16.229773,-7.2172 -16.301298,-16.1753 0.0111,-0.09 0.0111,-0.1819 0,-0.2726 0.07611,-8.9541 7.328792,-16.16647 16.301298,-16.16647 z m -5.822521,9.35937 c -1.007872,0 -1.504007,1.2276 -0.78239,1.9312 l 5.013755,5.0167 -5.013755,5.0136 c -1.104574,1.0606 0.530609,2.6958 1.591156,1.5912 l 5.016685,-5.0166 5.013757,5.0166 c 1.060547,1.1046 2.695728,-0.5306 1.591156,-1.5912 l -5.016685,-5.0136 5.016685,-5.0167 c 0.73468,-0.7155 0.207553,-1.9606 -0.817556,-1.9312 -0.292229,0.015 -0.569676,0.1305 -0.7736,0.34 l -5.013757,5.0138 -5.016685,-5.0138 c -0.212505,-0.218 -0.504294,-0.3407 -0.808766,-0.34 z m -40.66387,0.015 c -1.521685,-0.021 -1.521685,2.2721 0,2.2506 l 11.621597,0 c 1.521684,0.021 1.521684,-2.272 0,-2.2506 z"
+       id="path6"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
diff --git a/res/icons/noun_155533_cc.svg b/res/icons/noun_155533_cc.svg
new file mode 100644
index 0000000000000000000000000000000000000000..88e79c220345d71b075bedec7e217bf52ed7849a
--- /dev/null
+++ b/res/icons/noun_155533_cc.svg
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   viewBox="0 0 100 125"
+   version="1.1"
+   x="0px"
+   y="0px"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="noun_155533_cc.svg">
+  <metadata
+     id="metadata16">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs14" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="743"
+     inkscape:window-height="480"
+     id="namedview12"
+     showgrid="false"
+     inkscape:zoom="1.888"
+     inkscape:cx="50"
+     inkscape:cy="62.5"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2" />
+  <g
+     transform="matrix(1.2812691,0,0,1.2812691,-14.189139,-1221.9757)"
+     id="g4">
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.49966645;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 15.110916,975.06807 c -0.621665,-0.004 -1.119023,0.51848 -1.110801,1.14011 -1.54e-4,0.0107 -1.54e-4,0.0215 0,0.0322 l 0,34.85682 c -7.6e-5,0.6217 0.503852,1.1256 1.125456,1.1255 l 33.807617,0 c 0.586097,9.717 8.644024,17.4446 18.502602,17.4446 10.238382,0 18.574502,-8.3278 18.564148,-18.5701 -0.01155,-11.42186 0,-23.20066 0,-34.71614 3.28e-4,-0.0313 -6.5e-4,-0.0626 -0.0029,-0.0938 l 0,-0.0117 0,-0.009 c 0.03354,-0.64318 -0.478479,-1.18327 -1.122524,-1.18408 -23.249396,-0.0987 -46.529588,0.13224 -69.763567,-0.0147 z m 1.14011,2.26556 67.498002,0 0,24.90357 c -3.149351,-5.78006 -9.280447,-9.70996 -16.313238,-9.70996 -9.858578,0 -17.916505,7.72756 -18.502602,17.44456 l -32.682162,0 z m 4.686466,3.56394 c -1.499511,10e-4 -1.499511,2.24977 0,2.25087 l 58.125071,0 c 1.499511,0 1.499511,-2.24977 0,-2.25087 z m 0,5.81487 c -1.500607,0 -1.500607,2.2509 0,2.2509 l 34.874456,0 c 1.500606,0 1.500606,-2.2509 0,-2.2509 z m 0,5.8148 c -1.500607,0 -1.500607,2.2509 0,2.2509 l 23.250614,0 c 1.500606,0 1.500606,-2.2509 0,-2.2509 z m 46.498298,2.2509 c 9.021606,0 16.313238,7.29246 16.313238,16.31906 0,9.0266 -7.291632,16.3191 -16.313238,16.3191 -9.021607,0 -16.310308,-7.2925 -16.310308,-16.3191 0,-9.0266 7.288701,-16.31906 16.310308,-16.31906 z m -0.07034,2.8108 c -1.170749,0.01 -2.351251,0.1892 -3.505324,0.5598 -4.616281,1.4824 -7.847018,5.67446 -8.112657,10.52466 -0.08958,1.5071 2.171195,1.6311 2.245049,0.1231 0.214979,-3.9251 2.817603,-7.303 6.553431,-8.5024 3.735824,-1.19976 7.812697,0.035 10.263918,3.1037 2.45122,3.0686 2.757006,7.325 0.770819,10.7153 -1.752047,2.9905 -4.962346,4.7388 -8.350056,4.666 l 1.679389,-2.0575 c 0.622368,-0.7447 0.07326,-1.8752 -0.896847,-1.8465 -0.331131,0.01 -0.641,0.1656 -0.847022,0.425 l -3.347057,4.1032 c -0.392984,0.4809 -0.322154,1.1892 0.158268,1.5827 l 4.09443,3.3529 c 1.160624,0.9516 2.58796,-0.7893 1.427335,-1.7409 l -1.925584,-1.5768 c 4.045379,-0.05 7.850052,-2.188 9.947383,-5.768 2.454098,-4.1888 2.073993,-9.4725 -0.955465,-13.2651 -2.272099,-2.84446 -5.687763,-4.41696 -9.20001,-4.39916 z m -46.427957,6.56796 c -1.500607,0 -1.500607,2.251 0,2.251 l 11.626771,0 c 1.500607,0 1.500607,-2.251 0,-2.251 z"
+       id="path6"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
diff --git a/res/icons/noun_155540_cc.svg b/res/icons/noun_155540_cc.svg
new file mode 100644
index 0000000000000000000000000000000000000000..adeaf9491b56ed4f6a6efb81c4e1f1e60661b641
--- /dev/null
+++ b/res/icons/noun_155540_cc.svg
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   viewBox="0 0 100 125"
+   version="1.1"
+   x="0px"
+   y="0px"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="noun_155540_cc.svg">
+  <metadata
+     id="metadata16">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs14" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="743"
+     inkscape:window-height="480"
+     id="namedview12"
+     showgrid="false"
+     inkscape:zoom="1.888"
+     inkscape:cx="61.00568"
+     inkscape:cy="62.5"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2" />
+  <g
+     transform="matrix(1.3383945,0,0,1.3383945,-16.919727,-1280.9706)"
+     id="g4">
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 67.422429,975.07796 c -17.441637,0.0192 -34.88975,0.12012 -52.311843,0.006 -0.257006,-0.002 -0.504221,0.0953 -0.703273,0.25786 -0.006,0.005 -0.01173,0.01 -0.01758,0.0147 C 14.081844,975.61282 14,976.0079 14,976.4085 l 0,34.6831 c 6.2e-5,0.6214 0.503812,1.1252 1.125238,1.1253 l 33.801091,0 c 0.586857,9.7104 8.643143,17.4324 18.49903,17.4324 10.236196,0 18.569433,-8.3215 18.560564,-18.5577 -0.0099,-11.41928 0,-23.18198 0,-34.69189 0.108903,-0.68861 -0.428123,-1.30955 -1.125238,-1.30106 -5.811227,-0.0247 -11.624378,-0.0269 -17.438256,-0.0205 z m -51.171953,2.27098 67.484971,0 0,24.88706 c -3.148794,-5.77618 -9.278806,-9.70218 -16.310088,-9.70218 -9.856474,0 -17.913032,7.72128 -18.49903,17.43238 l -32.675853,0 z m 4.688491,3.56033 c -1.52167,-0.0215 -1.52167,2.27195 0,2.25045 l 58.107989,0 c 1.521671,0.021 1.521671,-2.27196 0,-2.25045 z m 0,5.81075 c -1.521685,-0.021 -1.521685,2.272 0,2.2505 l 34.864794,0 c 1.521684,0.022 1.521684,-2.272 0,-2.2505 z m 0,5.8138 c -1.521685,-0.022 -1.521685,2.272 0,2.2505 l 23.243195,0 c 1.521685,0.022 1.521685,-2.272 0,-2.2505 z m 46.486392,2.2505 c 9.019955,0 16.310088,7.28718 16.310088,16.30708 0,9.0199 -7.290133,16.3072 -16.310088,16.3072 -8.975387,0 -16.241481,-7.2171 -16.301299,-16.1753 -6.09e-4,-0.091 -6.56e-4,-0.1814 0,-0.2725 0.06436,-8.9543 7.328793,-16.16648 16.301299,-16.16648 z m -0.0117,6.45248 c -0.369837,10e-5 -0.716,0.182 -0.925976,0.4864 l -8.574079,8.5712 c -1.104572,1.0605 0.53061,2.6957 1.591157,1.5911 l 6.795383,-6.7924 0,14.713 c -0.02152,1.5217 2.271996,1.5217 2.250475,0 l 0,-14.716 6.795383,6.7954 c 1.060545,1.1046 2.695779,-0.5306 1.591155,-1.5911 l -8.650266,-8.6474 c -0.0123,-0.014 -0.02506,-0.028 -0.03809,-0.041 l -0.02638,-0.026 c -0.01425,-0.015 -0.0289,-0.03 -0.04396,-0.044 -0.01713,-0.015 -0.03472,-0.03 -0.05275,-0.044 -0.02455,-0.021 -0.04998,-0.04 -0.07619,-0.059 l -0.0147,-0.01 c -0.184168,-0.1222 -0.400227,-0.1874 -0.621226,-0.1876 z m -46.474689,2.9186 c -1.521685,-0.021 -1.521685,2.272 0,2.2504 l 11.621597,0 c 1.521685,0.022 1.521685,-2.2719 0,-2.2504 z"
+       id="path6"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
diff --git a/res/icons/noun_178785_cc.svg b/res/icons/noun_178785_cc.svg
new file mode 100644
index 0000000000000000000000000000000000000000..62d3b75dc5b06632fd5033e5a088cd31b6e8b954
--- /dev/null
+++ b/res/icons/noun_178785_cc.svg
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 100 125"
+   style="enable-background:new 0 0 100 100;"
+   xml:space="preserve"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="noun_178785_cc.svg"><metadata
+     id="metadata28"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs26" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="743"
+     inkscape:window-height="480"
+     id="namedview24"
+     showgrid="false"
+     inkscape:zoom="1.888"
+     inkscape:cx="58.142293"
+     inkscape:cy="62.5"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2" /><path
+     d="m 47.7,96 c 4.6,0 8.6,-1.4 11.5,-4.3 l 9.3,-9.3 c 3,-3 4.5,-7.4 4.3,-12.6 -0.1,-1.1 -1,-1.9 -2.1,-1.9 -1.1,0.1 -2,1 -1.9,2.1 0.2,4 -0.9,7.3 -3.1,9.6 -6.7,6.7 -22.4,2.1 -34.4,-9.9 -12,-12 -16.5,-27.8 -9.9,-34.4 5.6,-5.6 17.8,-3.5 29,5.1 0.9,0.7 2.1,0.5 2.8,-0.4 0.7,-0.9 0.5,-2.1 -0.4,-2.8 -13,-10 -27.1,-11.9 -34.3,-4.8 L 9.2,41.7 C 0.7,50.2 5.1,67.8 19.1,81.8 28.3,90.9 39.1,96 47.7,96 Z M 12.2,65.3 18.5,59 c 0.7,1.4 1.6,2.9 2.5,4.3 l -6.4,6.4 c -0.9,-1.5 -1.7,-2.9 -2.4,-4.4 z m -2.8,-8.5 5.9,-5.9 c 0.4,1.4 0.8,2.8 1.4,4.2 l -6.2,6.2 C 10,59.8 9.7,58.3 9.4,56.8 Z m 14,9.8 c 1.1,1.5 2.4,2.9 3.7,4.4 l -6.5,6.5 C 19.3,76.1 18,74.6 16.9,73.1 l 6.5,-6.5 z m 10.8,10.8 -6.5,6.5 c -1.5,-1.1 -2.9,-2.3 -4.3,-3.6 l 6.5,-6.5 c 1.5,1.3 2.9,2.5 4.3,3.6 z m 7.6,5 -6.4,6.4 C 33.9,88.1 32.5,87.3 31,86.3 l 6.4,-6.4 c 1.6,0.9 3,1.7 4.4,2.5 z m -2.3,8 6.2,-6.2 c 1.4,0.6 2.8,1 4.2,1.4 l -6,6 C 43.2,91.5 42.5,91.3 41.8,91.1 41,90.9 40.2,90.6 39.5,90.4 Z m 19.2,-3.9 -2.3,2.3 c -1.8,1.8 -4.2,2.8 -7.2,3.1 l 5.4,-5.4 c 0.8,0.1 1.7,0.1 2.5,0.1 0.5,0 1.1,0 1.6,-0.1 z M 14.4,46.1 9.1,51.4 c 0.3,-2.8 1.2,-5.2 3,-6.9 l 2.3,-2.3 c -0.1,1.3 -0.1,2.6 0,3.9 z"
+     id="path4"
+     inkscape:connector-curvature="0" /><path
+     d="M 98.4,52.7 79.7,33.8 c -0.8,-0.8 -2,-0.8 -2.8,0 -0.4,0.4 -0.6,1 -0.6,1.6 0,0.1 0,0.1 0,0.2 l 0,9.6 -6.4,0 c -1.1,0 -2,0.9 -2,2 0,1.1 0.9,2 2,2 l 8.4,0 c 1.1,0 2,-0.9 2,-2 l 0,-7.1 13.9,14 -13.9,14 0,-6.7 c 0,-1.1 -0.9,-2 -2,-2 l -8.4,0 c -1.1,0 -2,0.9 -2,2 0,1.1 0.9,2 2,2 l 6.4,0 0,9.6 c 0,0 0,0 0,0 0,0.1 0,0.3 0,0.4 0,0.1 0,0.1 0.1,0.2 0,0.1 0,0.1 0.1,0.2 0,0.1 0.1,0.1 0.1,0.2 0,0 0,0.1 0.1,0.1 0.1,0.1 0.2,0.2 0.3,0.3 l 0,0 c 0,0 0,0 0,0 0.1,0.1 0.2,0.2 0.3,0.2 0,0 0.1,0.1 0.1,0.1 0.1,0 0.1,0.1 0.2,0.1 0.1,0 0.1,0 0.2,0.1 0.1,0 0.1,0 0.2,0.1 0.1,0 0.3,0 0.4,0 0.1,0 0.3,0 0.4,0 0.1,0 0.1,0 0.2,-0.1 0.1,0 0.1,0 0.2,-0.1 0.1,0 0.1,-0.1 0.2,-0.1 0.1,0 0.1,0 0.2,-0.1 0.1,-0.1 0.2,-0.2 0.3,-0.3 l 0,0 18.7,-18.8 c 0.6,-0.8 0.6,-2.1 -0.2,-2.8 z"
+     id="path6"
+     inkscape:connector-curvature="0" /><path
+     d="m 63.1,59.3 -4.2,0 c -1.1,0 -2,0.9 -2,2 0,1.1 0.9,2 2,2 l 4.2,0 c 1.1,0 2,-0.9 2,-2 0,-1.1 -0.9,-2 -2,-2 z"
+     id="path8"
+     inkscape:connector-curvature="0" /><path
+     d="m 63.1,45.2 -4.2,0 c -1.1,0 -2,0.9 -2,2 0,1.1 0.9,2 2,2 l 4.2,0 c 1.1,0 2,-0.9 2,-2 0,-1.1 -0.9,-2 -2,-2 z"
+     id="path10"
+     inkscape:connector-curvature="0" /><path
+     d="m 49.5,59.3 -1.8,0 c -1.1,0 -2,0.9 -2,2 0,1.1 0.9,2 2,2 l 1.8,0 c 1.1,0 2,-0.9 2,-2 0,-1.1 -0.9,-2 -2,-2 z"
+     id="path12"
+     inkscape:connector-curvature="0" /><path
+     d="m 49.5,45.2 -1.8,0 c -1.1,0 -2,0.9 -2,2 0,1.1 0.9,2 2,2 l 1.8,0 c 1.1,0 2,-0.9 2,-2 0,-1.1 -0.9,-2 -2,-2 z"
+     id="path14"
+     inkscape:connector-curvature="0" /><path
+     d="m 36.7,59.3 -0.2,0 c -1.1,0 -2,0.9 -2,2 0,1.1 0.9,2 2,2 l 0.2,0 c 1.1,0 2,-0.9 2,-2 0,-1.1 -0.9,-2 -2,-2 z"
+     id="path16"
+     inkscape:connector-curvature="0" /><path
+     d="m 36.7,45.2 -0.2,0 c -1.1,0 -2,0.9 -2,2 0,1.1 0.9,2 2,2 l 0.2,0 c 1.1,0 2,-0.9 2,-2 0,-1.1 -0.9,-2 -2,-2 z"
+     id="path18"
+     inkscape:connector-curvature="0" /></svg>
\ No newline at end of file
diff --git a/res/icons/noun_19900_cc.svg b/res/icons/noun_19900_cc.svg
new file mode 100644
index 0000000000000000000000000000000000000000..4eee44fb90a727ea36d57099d0e3c2e12ba46d78
--- /dev/null
+++ b/res/icons/noun_19900_cc.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 100 125" enable-background="new 0 0 100 100" xml:space="preserve"><g><path d="M56.49,47.086c-0.022-0.023-0.04-0.045-0.06-0.066L33.688,24.334c-1.549-1.546-4.052-1.545-5.588-0.001   c-1.537,1.544-1.527,4.052,0.021,5.596l16.344,16.304H3.936C1.754,46.231-0.008,48.003,0,50.188   c0.009,2.185,1.785,3.957,3.967,3.956l40.548,0.001L27.927,70.822c-1.538,1.544-1.527,4.051,0.022,5.595   c1.548,1.546,4.05,1.546,5.587,0l22.567-22.686c0.116-0.119,0.222-0.241,0.32-0.369c0.964-0.722,1.591-1.872,1.585-3.172   C58.006,48.931,57.409,47.81,56.49,47.086z"/><path d="M51.486,63.151l-7.861,7.903v17.939c0,3.433,2.918,6.214,6.519,6.214l7.724-0.002v-7.861l-6.382,0.002V63.151z"/><path d="M51.486,13.406l6.382,0V5.543l-7.724,0c-3.601,0-6.519,2.781-6.519,6.212v17.731l7.861,7.842V13.406z"/><path d="M97.492,8.293L65.182,0.071c-2.04-0.506-3.736,1.751-3.736,5.094v89.679c0,3.326,1.696,5.614,3.736,5.079l32.311-8.22   c1.396-0.352,2.508-2.825,2.508-5.502V13.788C100,11.097,98.888,8.65,97.492,8.293z M74.087,54.922   c-2.72,0-4.924-2.204-4.924-4.922c0-2.72,2.204-4.925,4.924-4.925c2.718,0,4.924,2.205,4.924,4.925   C79.011,52.718,76.805,54.922,74.087,54.922z"/></g><text x="0" y="115" fill="#000000" font-size="5px" font-weight="bold" font-family="'Helvetica Neue', Helvetica, Arial-Unicode, Arial, Sans-serif">Created by Stefan Parnarov</text><text x="0" y="120" fill="#000000" font-size="5px" font-weight="bold" font-family="'Helvetica Neue', Helvetica, Arial-Unicode, Arial, Sans-serif">from the Noun Project</text></svg>
\ No newline at end of file
diff --git a/res/icons/noun_41979_cc.svg b/res/icons/noun_41979_cc.svg
new file mode 100644
index 0000000000000000000000000000000000000000..0f70e6ef4c48aa7df542cc69f0e72c55322a6e5e
--- /dev/null
+++ b/res/icons/noun_41979_cc.svg
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 100 125"
+   enable-background="new 0 0 100 100"
+   xml:space="preserve"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="noun_41979_cc.svg"><metadata
+     id="metadata16"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs14" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="743"
+     inkscape:window-height="480"
+     id="namedview12"
+     showgrid="false"
+     inkscape:zoom="1.888"
+     inkscape:cx="50"
+     inkscape:cy="62.5"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2" /><rect
+     width="100"
+     height="100"
+     id="rect4"
+     x="0"
+     y="12"
+     style="fill:none" /><path
+     d="m 29.241,43.591 c 4.499,0 8.16,-3.663 8.16,-8.167 0,-4.494 -3.661,-8.152 -8.16,-8.152 -4.505,0 -8.167,3.659 -8.167,8.152 10e-4,4.504 3.662,8.167 8.167,8.167 z m 0,-13.687 c 3.049,0 5.53,2.477 5.53,5.521 0,3.054 -2.481,5.535 -5.53,5.535 -3.056,0 -5.537,-2.481 -5.537,-5.535 0,-3.044 2.482,-5.521 5.537,-5.521 z m -11.911,32.23 23.821,0 c 0.725,0 1.316,-0.591 1.316,-1.318 l 0,-7.533 c 0,-0.061 -0.007,-0.126 -0.019,-0.188 -0.204,-4.484 -3.98,-8.105 -8.493,-8.105 l -9.445,0 c -4.545,0 -8.361,3.701 -8.495,8.255 0,0.014 0,0.361 0,0.375 l 0,7.195 c 10e-4,0.727 0.588,1.319 1.315,1.319 z m 1.315,-8.809 c 0.094,-3.147 2.728,-5.708 5.866,-5.708 l 9.445,0 c 3.154,0 5.788,2.561 5.87,5.704 0.005,0.099 0.019,0.197 0.042,0.291 l -0.033,5.892 -21.19,0 0,-5.884 -1.315,0 1.315,-0.295 z m 32.038,-19.49 c 0,-0.727 0.584,-1.318 1.315,-1.318 l 23.995,0 c 0.723,0 1.313,0.591 1.313,1.318 0,0.722 -0.591,1.313 -1.313,1.313 l -23.995,0 c -0.731,0 -1.315,-0.591 -1.315,-1.313 z m -4.274,8.86 c 0,-0.727 0.586,-1.313 1.313,-1.313 l 32.542,0 c 0.725,0 1.313,0.586 1.313,1.313 0,0.727 -0.588,1.318 -1.313,1.318 l -32.541,0 c -0.727,0.001 -1.314,-0.591 -1.314,-1.318 z M 16.016,70.638 c 0,-0.727 0.586,-1.318 1.313,-1.318 l 32.542,0 c 0.722,0 1.313,0.592 1.313,1.318 0,0.728 -0.591,1.313 -1.313,1.313 l -32.541,0 c -0.727,0 -1.314,-0.586 -1.314,-1.313 z M 92.294,17 7.707,17 c -1.45,0 -2.63,1.177 -2.63,2.627 l 0,64.68 c 0,1.454 1.18,2.631 2.629,2.631 l 44.487,0 c -2.013,4.265 -3.831,8.617 -5.393,13.073 -0.18,0.517 -0.023,1.089 0.394,1.44 0.422,0.352 1.013,0.412 1.489,0.141 3.021,-1.688 6.098,-3.251 9.164,-4.653 1.205,3.157 2.547,6.281 3.994,9.315 0.223,0.46 0.683,0.746 1.187,0.746 0.021,0 0.047,0 0.072,-0.005 0.528,-0.023 0.99,-0.37 1.171,-0.877 1.536,-4.386 3.368,-8.664 5.398,-12.843 2.018,4.175 3.835,8.452 5.371,12.843 0.176,0.502 0.638,0.849 1.166,0.877 0.026,0.005 0.053,0.005 0.073,0.005 0.505,0 0.964,-0.286 1.187,-0.746 1.431,-2.974 2.768,-6.103 3.99,-9.315 3.077,1.402 6.149,2.965 9.163,4.653 0.476,0.268 1.067,0.216 1.489,-0.136 0.417,-0.353 0.574,-0.929 0.394,-1.445 -1.557,-4.451 -3.36,-8.809 -5.37,-13.073 l 5.162,0 c 1.454,0 2.629,-1.177 2.629,-2.631 l 0,-64.68 C 94.923,18.177 93.748,17 92.294,17 Z m -29.408,85.239 c -1.103,-2.473 -2.13,-4.996 -3.062,-7.529 -0.126,-0.337 -0.389,-0.614 -0.722,-0.755 -0.167,-0.07 -0.341,-0.104 -0.517,-0.104 -0.178,0 -0.358,0.038 -0.527,0.113 -2.533,1.116 -5.075,2.35 -7.592,3.673 2.477,-6.549 5.507,-12.871 8.962,-18.955 1.078,1.243 2.373,2.274 3.837,3.063 1.756,2.801 3.405,5.667 4.925,8.603 -1.962,3.875 -3.764,7.829 -5.304,11.891 z M 61.313,69.817 c 0,-4.602 3.743,-8.345 8.343,-8.345 4.6,0 8.34,3.744 8.34,8.345 0,4.597 -3.74,8.34 -8.34,8.34 -4.6,0 -8.343,-3.743 -8.343,-8.34 z m 19.931,24.148 c -0.325,-0.146 -0.708,-0.15 -1.041,-0.01 -0.335,0.141 -0.598,0.418 -0.72,0.76 -0.945,2.57 -1.973,5.095 -3.054,7.529 -2.512,-6.628 -5.636,-12.994 -9.231,-19.077 0.795,0.146 1.613,0.248 2.458,0.248 4.102,0 7.737,-1.862 10.235,-4.742 3.45,6.089 6.473,12.416 8.949,18.96 -2.516,-1.319 -5.058,-2.552 -7.596,-3.668 z m 8.42,-12.285 -5.178,0 c -0.945,-1.811 -1.938,-3.593 -2.958,-5.361 1.063,-1.942 1.727,-4.138 1.727,-6.501 0,-7.501 -6.103,-13.604 -13.599,-13.604 -7.5,0 -13.603,6.103 -13.603,13.604 0,2.368 0.663,4.563 1.735,6.511 -1.021,1.764 -2.008,3.546 -2.953,5.352 l -44.497,0 0,-59.423 79.326,0 0,59.422 z"
+     id="path6"
+     inkscape:connector-curvature="0" /></svg>
\ No newline at end of file
diff --git a/res/ui/account_cfg.ui b/res/ui/account_cfg.ui
index 836d77c280c9987f455f12c61696c614c5532d61..92ad6c2c4460f11b521f3cd7a927a8e0798a0a5f 100644
--- a/res/ui/account_cfg.ui
+++ b/res/ui/account_cfg.ui
@@ -57,33 +57,6 @@
             </item>
            </layout>
           </item>
-          <item>
-           <layout class="QHBoxLayout" name="horizontalLayout_7">
-            <property name="topMargin">
-             <number>6</number>
-            </property>
-            <item>
-             <widget class="QLabel" name="label_2">
-              <property name="text">
-               <string>Wallets</string>
-              </property>
-             </widget>
-            </item>
-            <item>
-             <widget class="QSpinBox" name="spinbox_wallets">
-              <property name="minimum">
-               <number>1</number>
-              </property>
-              <property name="maximum">
-               <number>100</number>
-              </property>
-              <property name="value">
-               <number>1</number>
-              </property>
-             </widget>
-            </item>
-           </layout>
-          </item>
           <item>
            <layout class="QHBoxLayout" name="horizontalLayout_8">
             <property name="topMargin">
@@ -475,22 +448,6 @@
     </hint>
    </hints>
   </connection>
-  <connection>
-   <sender>spinbox_wallets</sender>
-   <signal>valueChanged(int)</signal>
-   <receiver>AccountConfigurationDialog</receiver>
-   <slot>action_edit_account_parameters()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>285</x>
-     <y>127</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>199</x>
-     <y>118</y>
-    </hint>
-   </hints>
-  </connection>
   <connection>
    <sender>button_delete</sender>
    <signal>clicked()</signal>
diff --git a/res/ui/community_cfg.ui b/res/ui/community_cfg.ui
index 0d18585d3a33202199ab2f5ae604aa3032e3099a..408cf47d40b91f5bc117fb7a2ed3ec55f1ca4752 100644
--- a/res/ui/community_cfg.ui
+++ b/res/ui/community_cfg.ui
@@ -25,7 +25,7 @@
      <property name="currentIndex">
       <number>0</number>
      </property>
-     <widget class="QWidget" name="page_init">
+     <widget class="QWidget" name="page_node">
       <layout class="QVBoxLayout" name="verticalLayout_4">
        <item>
         <spacer name="verticalSpacer_2">
@@ -75,45 +75,66 @@
         </layout>
        </item>
        <item>
-        <layout class="QHBoxLayout" name="horizontalLayout_2">
+        <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>
+       <item>
+        <layout class="QVBoxLayout" name="verticalLayout_5">
          <property name="topMargin">
           <number>6</number>
          </property>
          <item>
-          <spacer name="horizontalSpacer">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
+          <widget class="QPushButton" name="button_register">
+           <property name="text">
+            <string>Register your account</string>
+           </property>
+           <property name="icon">
+            <iconset resource="../icons/icons.qrc">
+             <normaloff>:/icons/new_membership</normaloff>:/icons/new_membership</iconset>
+           </property>
+           <property name="iconSize">
+            <size>
+             <width>32</width>
+             <height>32</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QPushButton" name="button_connect">
+           <property name="text">
+            <string>Connect using your account</string>
+           </property>
+           <property name="icon">
+            <iconset resource="../icons/icons.qrc">
+             <normaloff>:/icons/connect_icon</normaloff>:/icons/connect_icon</iconset>
            </property>
-           <property name="sizeHint" stdset="0">
+           <property name="iconSize">
             <size>
-             <width>40</width>
-             <height>20</height>
+             <width>32</width>
+             <height>32</height>
             </size>
            </property>
-          </spacer>
+          </widget>
          </item>
          <item>
-          <widget class="QPushButton" name="button_checknode">
+          <widget class="QLabel" name="label_error">
            <property name="text">
-            <string>Check node connectivity</string>
+            <string/>
            </property>
           </widget>
          </item>
         </layout>
        </item>
-       <item>
-        <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>
      <widget class="QWidget" name="page_add_nodes">
@@ -173,7 +194,7 @@
     </widget>
    </item>
    <item>
-    <layout class="QHBoxLayout" name="horizontalLayout_4">
+    <layout class="QHBoxLayout" name="layout_previous_next">
      <item>
       <widget class="QPushButton" name="button_previous">
        <property name="enabled">
@@ -211,7 +232,9 @@
    </item>
   </layout>
  </widget>
- <resources/>
+ <resources>
+  <include location="../icons/icons.qrc"/>
+ </resources>
  <connections>
   <connection>
    <sender>button_add</sender>
diff --git a/res/ui/community_tab.ui b/res/ui/community_tab.ui
deleted file mode 100644
index 43eb5750042ac2493427e536b2e9837890c72624..0000000000000000000000000000000000000000
--- a/res/ui/community_tab.ui
+++ /dev/null
@@ -1,147 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>CommunityTabWidget</class>
- <widget class="QWidget" name="CommunityTabWidget">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>636</width>
-    <height>404</height>
-   </rect>
-  </property>
-  <property name="contextMenuPolicy">
-   <enum>Qt::DefaultContextMenu</enum>
-  </property>
-  <property name="windowTitle">
-   <string>communityTabWidget</string>
-  </property>
-  <layout class="QHBoxLayout" name="horizontalLayout">
-   <item>
-    <widget class="QTabWidget" name="tabs_information">
-     <property name="currentIndex">
-      <number>0</number>
-     </property>
-     <property name="iconSize">
-      <size>
-       <width>20</width>
-       <height>20</height>
-      </size>
-     </property>
-     <property name="elideMode">
-      <enum>Qt::ElideNone</enum>
-     </property>
-     <widget class="QWidget" name="tab_members">
-      <attribute name="icon">
-       <iconset resource="../icons/icons.qrc">
-        <normaloff>:/icons/members_icon</normaloff>:/icons/members_icon</iconset>
-      </attribute>
-      <attribute name="title">
-       <string>Identities</string>
-      </attribute>
-      <layout class="QVBoxLayout" name="verticalLayout">
-       <item>
-        <layout class="QVBoxLayout" name="verticalLayout_6">
-         <item>
-          <layout class="QHBoxLayout" name="horizontalLayout_3">
-           <property name="topMargin">
-            <number>0</number>
-           </property>
-           <item>
-            <widget class="QLineEdit" name="edit_textsearch">
-             <property name="placeholderText">
-              <string>Research a pubkey, an uid...</string>
-             </property>
-            </widget>
-           </item>
-           <item>
-            <widget class="QToolButton" name="button_search">
-             <property name="text">
-              <string>Search</string>
-             </property>
-             <property name="popupMode">
-              <enum>QToolButton::MenuButtonPopup</enum>
-             </property>
-             <property name="toolButtonStyle">
-              <enum>Qt::ToolButtonTextBesideIcon</enum>
-             </property>
-            </widget>
-           </item>
-          </layout>
-         </item>
-         <item>
-          <widget class="QTableView" name="table_identities">
-           <property name="contextMenuPolicy">
-            <enum>Qt::CustomContextMenu</enum>
-           </property>
-           <property name="alternatingRowColors">
-            <bool>true</bool>
-           </property>
-           <property name="sortingEnabled">
-            <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>
-      </layout>
-     </widget>
-    </widget>
-   </item>
-  </layout>
- </widget>
- <resources>
-  <include location="../icons/icons.qrc"/>
- </resources>
- <connections>
-  <connection>
-   <sender>edit_textsearch</sender>
-   <signal>returnPressed()</signal>
-   <receiver>CommunityTabWidget</receiver>
-   <slot>search_text()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>170</x>
-     <y>62</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>215</x>
-     <y>184</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>button_search</sender>
-   <signal>clicked()</signal>
-   <receiver>CommunityTabWidget</receiver>
-   <slot>search_text()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>371</x>
-     <y>62</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>215</x>
-     <y>184</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
- <slots>
-  <slot>identity_context_menu(QPoint)</slot>
-  <slot>send_membership_demand()</slot>
-  <slot>send_membership_leaving()</slot>
-  <slot>search_text()</slot>
-  <slot>publish_uid()</slot>
-  <slot>revoke_uid()</slot>
- </slots>
-</ui>
diff --git a/res/ui/community_view.ui b/res/ui/community_view.ui
new file mode 100644
index 0000000000000000000000000000000000000000..45b86c534c47c9c4f877f78c6344554a8a402e8d
--- /dev/null
+++ b/res/ui/community_view.ui
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>CommunityWidget</class>
+ <widget class="QWidget" name="CommunityWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>624</width>
+    <height>429</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <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">
+      <item>
+       <widget class="QPushButton" name="button_home">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="text">
+         <string/>
+        </property>
+        <property name="icon">
+         <iconset resource="../icons/icons.qrc">
+          <normaloff>:/icons/home_icon</normaloff>:/icons/home_icon</iconset>
+        </property>
+        <property name="iconSize">
+         <size>
+          <width>32</width>
+          <height>32</height>
+         </size>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QLabel" name="label_currency">
+        <property name="text">
+         <string/>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="button_send_money">
+        <property name="text">
+         <string>Send money</string>
+        </property>
+        <property name="icon">
+         <iconset resource="../icons/icons.qrc">
+          <normaloff>:/icons/payment_icon</normaloff>:/icons/payment_icon</iconset>
+        </property>
+        <property name="iconSize">
+         <size>
+          <width>32</width>
+          <height>32</height>
+         </size>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="button_certification">
+        <property name="text">
+         <string>Certification</string>
+        </property>
+        <property name="icon">
+         <iconset resource="../icons/icons.qrc">
+          <normaloff>:/icons/certification_icon</normaloff>:/icons/certification_icon</iconset>
+        </property>
+        <property name="iconSize">
+         <size>
+          <width>32</width>
+          <height>32</height>
+         </size>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="button_membership">
+        <property name="text">
+         <string>Renew membership</string>
+        </property>
+        <property name="icon">
+         <iconset resource="../icons/icons.qrc">
+          <normaloff>:/icons/renew_membership</normaloff>:/icons/renew_membership</iconset>
+        </property>
+        <property name="iconSize">
+         <size>
+          <width>32</width>
+          <height>32</height>
+         </size>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QTabWidget" name="tabs"/>
+   </item>
+  </layout>
+ </widget>
+ <resources>
+  <include location="../icons/icons.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/res/ui/homescreen.ui b/res/ui/homescreen.ui
index 9b80e39c6b67b4d0e2e75c4eb0719dbc98729a14..f326a247071175967a5e8908579dd6ec4ee79212 100644
--- a/res/ui/homescreen.ui
+++ b/res/ui/homescreen.ui
@@ -1,17 +1,17 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
- <class>HomeScreenWidget</class>
- <widget class="QWidget" name="HomeScreenWidget">
+ <class>HomescreenWidget</class>
+ <widget class="QWidget" name="HomescreenWidget">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>400</width>
-    <height>325</height>
+    <width>648</width>
+    <height>472</height>
    </rect>
   </property>
   <property name="sizePolicy">
-   <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
+   <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
     <horstretch>0</horstretch>
     <verstretch>0</verstretch>
    </sizepolicy>
@@ -19,142 +19,174 @@
   <property name="windowTitle">
    <string>Form</string>
   </property>
-  <property name="styleSheet">
-   <string notr="true">QLabel {
-	qproperty-alignment: AlignCenter;
-}
-
-QToolButton {
-    font-size: 14pt;
-    font-weight: bold;
-}</string>
-  </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
-    <spacer name="verticalSpacer_2">
-     <property name="orientation">
-      <enum>Qt::Vertical</enum>
-     </property>
-     <property name="sizeHint" stdset="0">
-      <size>
-       <width>20</width>
-       <height>40</height>
-      </size>
+    <widget class="QFrame" name="frame_connected">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
      </property>
-    </spacer>
-   </item>
-   <item>
-    <widget class="QLabel" name="label_welcome">
-     <property name="text">
-      <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+     <property name="frameShape">
+      <enum>QFrame::StyledPanel</enum>
      </property>
-     <property name="textFormat">
-      <enum>Qt::RichText</enum>
-     </property>
-     <property name="openExternalLinks">
-      <bool>true</bool>
+     <property name="frameShadow">
+      <enum>QFrame::Raised</enum>
      </property>
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <property name="sizeConstraint">
+       <enum>QLayout::SetMaximumSize</enum>
+      </property>
+      <item>
+       <widget class="QLabel" name="label_connected">
+        <property name="styleSheet">
+         <string notr="true"> font-size:12pt; font-weight:600;</string>
+        </property>
+        <property name="text">
+         <string>Connected as</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="button_add_community">
+        <property name="text">
+         <string>Add a community</string>
+        </property>
+        <property name="icon">
+         <iconset resource="../icons/icons.qrc">
+          <normaloff>:/icons/add_community</normaloff>:/icons/add_community</iconset>
+        </property>
+        <property name="iconSize">
+         <size>
+          <width>32</width>
+          <height>32</height>
+         </size>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="button_disconnect">
+        <property name="text">
+         <string>Disconnect</string>
+        </property>
+        <property name="icon">
+         <iconset resource="../icons/icons.qrc">
+          <normaloff>:/icons/logout</normaloff>:/icons/logout</iconset>
+        </property>
+        <property name="iconSize">
+         <size>
+          <width>32</width>
+          <height>32</height>
+         </size>
+        </property>
+       </widget>
+      </item>
+      <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>
+     </layout>
     </widget>
    </item>
    <item>
-    <layout class="QHBoxLayout" name="horizontalLayout">
-     <property name="topMargin">
-      <number>6</number>
-     </property>
-     <item>
-      <widget class="QToolButton" name="button_new">
-       <property name="text">
-        <string>Create a new account</string>
-       </property>
-       <property name="icon">
-        <iconset resource="../icons/icons.qrc">
-         <normaloff>:/icons/add_account_icon</normaloff>:/icons/add_account_icon</iconset>
-       </property>
-       <property name="iconSize">
-        <size>
-         <width>32</width>
-         <height>32</height>
-        </size>
-       </property>
-       <property name="toolButtonStyle">
-        <enum>Qt::ToolButtonTextBesideIcon</enum>
-       </property>
-       <property name="autoRaise">
-        <bool>false</bool>
-       </property>
-       <property name="arrowType">
-        <enum>Qt::NoArrow</enum>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-   <item>
-    <layout class="QHBoxLayout" name="horizontalLayout_2">
-     <property name="topMargin">
-      <number>6</number>
+    <widget class="QFrame" name="frame_disconnected">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
      </property>
-     <item>
-      <widget class="QToolButton" name="button_import">
-       <property name="text">
-        <string>Import an existing account</string>
-       </property>
-       <property name="icon">
-        <iconset resource="../icons/icons.qrc">
-         <normaloff>:/icons/import_icon</normaloff>:/icons/import_icon</iconset>
-       </property>
-       <property name="iconSize">
-        <size>
-         <width>32</width>
-         <height>32</height>
-        </size>
-       </property>
-       <property name="toolButtonStyle">
-        <enum>Qt::ToolButtonTextBesideIcon</enum>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-   <item>
-    <layout class="QHBoxLayout" name="horizontalLayout_3">
-     <property name="topMargin">
-      <number>6</number>
+     <property name="frameShape">
+      <enum>QFrame::StyledPanel</enum>
      </property>
-     <item>
-      <widget class="QToolButton" name="button_info">
-       <property name="text">
-        <string>Get to know more about ucoin</string>
-       </property>
-       <property name="icon">
-        <iconset resource="../icons/icons.qrc">
-         <normaloff>:/icons/ucoin_info_icon</normaloff>:/icons/ucoin_info_icon</iconset>
-       </property>
-       <property name="iconSize">
-        <size>
-         <width>32</width>
-         <height>32</height>
-        </size>
-       </property>
-       <property name="toolButtonStyle">
-        <enum>Qt::ToolButtonTextBesideIcon</enum>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-   <item>
-    <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 name="frameShadow">
+      <enum>QFrame::Raised</enum>
      </property>
-    </spacer>
+     <layout class="QHBoxLayout" name="horizontalLayout_2">
+      <item>
+       <widget class="QLabel" name="label_disconnected">
+        <property name="text">
+         <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;Not Connected&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QToolButton" name="toolbutton_connect">
+        <property name="text">
+         <string>Connect</string>
+        </property>
+        <property name="icon">
+         <iconset resource="../icons/icons.qrc">
+          <normaloff>:/icons/connect_icon</normaloff>:/icons/connect_icon</iconset>
+        </property>
+        <property name="iconSize">
+         <size>
+          <width>32</width>
+          <height>32</height>
+         </size>
+        </property>
+        <property name="popupMode">
+         <enum>QToolButton::MenuButtonPopup</enum>
+        </property>
+        <property name="toolButtonStyle">
+         <enum>Qt::ToolButtonTextBesideIcon</enum>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QToolButton" name="toolbutton_new_account">
+        <property name="text">
+         <string>New account</string>
+        </property>
+        <property name="icon">
+         <iconset resource="../icons/icons.qrc">
+          <normaloff>:/icons/add_account_icon</normaloff>:/icons/add_account_icon</iconset>
+        </property>
+        <property name="iconSize">
+         <size>
+          <width>32</width>
+          <height>32</height>
+         </size>
+        </property>
+        <property name="popupMode">
+         <enum>QToolButton::MenuButtonPopup</enum>
+        </property>
+        <property name="toolButtonStyle">
+         <enum>Qt::ToolButtonTextBesideIcon</enum>
+        </property>
+        <property name="autoRaise">
+         <bool>false</bool>
+        </property>
+        <property name="arrowType">
+         <enum>Qt::NoArrow</enum>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <spacer name="horizontalSpacer_5">
+        <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>
+    </widget>
    </item>
   </layout>
  </widget>
diff --git a/res/ui/identities_tab.ui b/res/ui/identities_tab.ui
new file mode 100644
index 0000000000000000000000000000000000000000..5f3f2e072c5778a32cbea7c6f2bfc1b77a0750c5
--- /dev/null
+++ b/res/ui/identities_tab.ui
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>IdentitiesTab</class>
+ <widget class="QWidget" name="IdentitiesTab">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_3">
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLineEdit" name="edit_textsearch">
+       <property name="placeholderText">
+        <string>Research a pubkey, an uid...</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QToolButton" name="button_search">
+       <property name="text">
+        <string>Search</string>
+       </property>
+       <property name="popupMode">
+        <enum>QToolButton::MenuButtonPopup</enum>
+       </property>
+       <property name="toolButtonStyle">
+        <enum>Qt::ToolButtonTextBesideIcon</enum>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QTableView" name="table_identities">
+     <property name="contextMenuPolicy">
+      <enum>Qt::CustomContextMenu</enum>
+     </property>
+     <property name="alternatingRowColors">
+      <bool>true</bool>
+     </property>
+     <property name="sortingEnabled">
+      <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>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/res/ui/mainwindow.ui b/res/ui/mainwindow.ui
index 10a981179bce626465efa75b0e808ce99f8672bb..f30bd087938b923932b71797e41fda4dc494a2ec 100644
--- a/res/ui/mainwindow.ui
+++ b/res/ui/mainwindow.ui
@@ -14,18 +14,7 @@
    <string notr="true">CuteCoin</string>
   </property>
   <widget class="QWidget" name="centralwidget">
-   <layout class="QVBoxLayout" name="verticalLayout_6">
-    <item>
-     <widget class="QTabWidget" name="currencies_tabwidget">
-      <property name="iconSize">
-       <size>
-        <width>24</width>
-        <height>24</height>
-       </size>
-      </property>
-     </widget>
-    </item>
-   </layout>
+   <layout class="QVBoxLayout" name="verticalLayout_6"/>
   </widget>
   <widget class="QMenuBar" name="menubar">
    <property name="geometry">
@@ -33,7 +22,7 @@
      <x>0</x>
      <y>0</y>
      <width>681</width>
-     <height>25</height>
+     <height>29</height>
     </rect>
    </property>
    <widget class="QMenu" name="menu_file">
@@ -48,11 +37,11 @@
    </widget>
    <widget class="QMenu" name="menu_account">
     <property name="title">
-     <string>Account</string>
+     <string>Acco&amp;unt</string>
     </property>
     <widget class="QMenu" name="menu_contacts_list">
      <property name="title">
-      <string>&amp;Contacts</string>
+      <string>Co&amp;ntacts</string>
      </property>
      <addaction name="separator"/>
     </widget>
@@ -94,7 +83,7 @@
   </action>
   <action name="action_add_a_contact">
    <property name="text">
-    <string>&amp;Add a contact</string>
+    <string>A&amp;dd a contact</string>
    </property>
   </action>
   <action name="actionSend_a_message">
@@ -164,7 +153,7 @@
   </action>
   <action name="actionCertification">
    <property name="text">
-    <string>&amp;Certification</string>
+    <string>C&amp;ertification</string>
    </property>
   </action>
   <action name="action_set_as_default">
diff --git a/res/ui/transactions_tab.ui b/res/ui/transactions_tab.ui
index 7b5f520604ea8c1dd224328f13ddc15434b6a46a..b459a6950f465ba297e35a1279cb9bd18fac0e67 100644
--- a/res/ui/transactions_tab.ui
+++ b/res/ui/transactions_tab.ui
@@ -14,6 +14,32 @@
    <string>Form</string>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QGroupBox" name="groupBox_2">
+     <property name="title">
+      <string>Balance</string>
+     </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>
+        </property>
+        <property name="text">
+         <string>label_balance</string>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignHCenter|Qt::AlignTop</set>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
    <item>
     <layout class="QVBoxLayout" name="verticalLayout_3">
      <item>
@@ -75,37 +101,6 @@
        </attribute>
       </widget>
      </item>
-     <item>
-      <layout class="QHBoxLayout" name="layout_balance">
-       <item>
-        <widget class="QLabel" name="label_payment">
-         <property name="text">
-          <string>Payment:</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QLabel" name="label_deposit">
-         <property name="text">
-          <string>Deposit:</string>
-         </property>
-         <property name="alignment">
-          <set>Qt::AlignCenter</set>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QLabel" name="label_balance">
-         <property name="text">
-          <string>Balance:</string>
-         </property>
-         <property name="alignment">
-          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-         </property>
-        </widget>
-       </item>
-      </layout>
-     </item>
     </layout>
    </item>
   </layout>
diff --git a/res/ui/wallets_tab.ui b/res/ui/wallets_tab.ui
index cef471bfba54f06dc89fb6eaa1b6d7ee03a642d8..16b4dd1c96d212b9773b06a202151676c417af27 100644
--- a/res/ui/wallets_tab.ui
+++ b/res/ui/wallets_tab.ui
@@ -29,91 +29,6 @@ QGroupBox::title {
   </property>
   <layout class="QGridLayout" name="gridLayout">
    <item row="0" column="0">
-    <widget class="QGroupBox" name="groupBox">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="styleSheet">
-      <string notr="true"/>
-     </property>
-     <property name="title">
-      <string>Account</string>
-     </property>
-     <property name="flat">
-      <bool>true</bool>
-     </property>
-     <layout class="QGridLayout" name="gridLayout_2">
-      <item row="0" column="0">
-       <widget class="QLabel" name="label_general">
-        <property name="text">
-         <string>label_general</string>
-        </property>
-        <property name="textFormat">
-         <enum>Qt::RichText</enum>
-        </property>
-        <property name="alignment">
-         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="0">
-       <layout class="QHBoxLayout" name="horizontalLayout_2">
-        <property name="leftMargin">
-         <number>0</number>
-        </property>
-        <property name="topMargin">
-         <number>5</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_publish_uid">
-          <property name="text">
-           <string>Publish UID</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QPushButton" name="button_revoke_uid">
-          <property name="text">
-           <string>Revoke UID</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QPushButton" name="button_membership">
-          <property name="text">
-           <string>Renew membership</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QPushButton" name="button_leaving">
-          <property name="text">
-           <string>Send leaving demand</string>
-          </property>
-         </widget>
-        </item>
-       </layout>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item row="1" column="0">
     <widget class="QGroupBox" name="groupBox_2">
      <property name="title">
       <string>Balance</string>
@@ -149,7 +64,7 @@ QGroupBox::title {
      </layout>
     </widget>
    </item>
-   <item row="2" column="0">
+   <item row="1" column="0">
     <widget class="QTableView" name="table_wallets">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
@@ -202,70 +117,6 @@ QGroupBox::title {
     </hint>
    </hints>
   </connection>
-  <connection>
-   <sender>button_publish_uid</sender>
-   <signal>clicked()</signal>
-   <receiver>WalletsTab</receiver>
-   <slot>publish_uid()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>430</x>
-     <y>69</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>461</x>
-     <y>459</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>button_revoke_uid</sender>
-   <signal>clicked()</signal>
-   <receiver>WalletsTab</receiver>
-   <slot>revoke_uid()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>533</x>
-     <y>69</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>461</x>
-     <y>459</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>button_membership</sender>
-   <signal>clicked()</signal>
-   <receiver>WalletsTab</receiver>
-   <slot>send_membership_demand()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>662</x>
-     <y>69</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>461</x>
-     <y>459</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>button_leaving</sender>
-   <signal>clicked()</signal>
-   <receiver>WalletsTab</receiver>
-   <slot>send_membership_leaving()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>823</x>
-     <y>69</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>461</x>
-     <y>459</y>
-    </hint>
-   </hints>
-  </connection>
  </connections>
  <slots>
   <slot>wallet_context_menu(QPoint)</slot>
diff --git a/run_tests.py b/run_tests.py
index 762b19590ced20c7eac8a20d0a81f73ab4445486..dc97800c0fa3bcf43e6dd5e5a1608d26c7fc4f1e 100644
--- a/run_tests.py
+++ b/run_tests.py
@@ -1,10 +1,33 @@
 import sys
 import os
+import signal
 import unittest
+import subprocess
+import time
+import shlex
 
+cmd = 'python -m pretenders.server.server --host 127.0.0.1 --port 50000'
+
+p = subprocess.Popen(shlex.split(cmd))
+time.sleep(2)
+# Force saves to be done in temp directory
+os.environ["XDG_CONFIG_HOME"] = os.path.join(os.path.dirname(__file__), 'temp')
 sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), 'lib')))
 sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), 'src')))
+try:
+    print("Run")
+    runner = unittest.TextTestRunner().run(unittest.defaultTestLoader.discover(start_dir='cutecoin.tests', pattern='test_*'))
+finally:
+    print("Terminate")
+    os.kill(p.pid, signal.SIGINT)
+    time.sleep(2)
+    try:
 
-runner = unittest.TextTestRunner().run(unittest.defaultTestLoader.discover(start_dir='cutecoin.tests', pattern='test_*'))
+        if sys.platform == "linux":
+            os.kill(p.pid, signal.SIGKILL)
+        p.kill()
+        print("Hard killed")
+    except OSError:
+        print("Terminated gracefully")
 
 sys.exit(not runner.wasSuccessful())
\ No newline at end of file
diff --git a/setup.py b/setup.py
index f3fe811a439d41cf1b1da335350ff66f1478a246..8381c99f10c33e2b372d154589ab156d3562c04a 100644
--- a/setup.py
+++ b/setup.py
@@ -15,7 +15,7 @@ sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), 'src')))
 print(sys.path)
 includes = ["sip", "re", "json", "logging",
             "hashlib", "os", "urllib",
-            "ucoinpy", "pylibscrypt", "requests"]
+            "ucoinpy", "pylibscrypt"]
 excludes = ['.git']
 packages = ["libnacl", "encodings"]
 
diff --git a/src/cutecoin/core/account.py b/src/cutecoin/core/account.py
index b26ad98b4cd151f0b292ce906ace3f7d4d863e21..35bb49181f3623346d6aca6b2e982858cefea9b5 100644
--- a/src/cutecoin/core/account.py
+++ b/src/cutecoin/core/account.py
@@ -20,6 +20,7 @@ from .wallet import Wallet
 from .community import Community
 from .registry import LocalState
 from ..tools.exceptions import ContactAlreadyExists
+from ..tools.decorators import asyncify
 from ..core.net.api import bma as qtbma
 from ..core.net.api.bma import PROTOCOL_VERSION
 
@@ -32,7 +33,6 @@ class Account(QObject):
     """
     loading_progressed = pyqtSignal(int, int)
     loading_finished = pyqtSignal(list)
-    inner_data_changed = pyqtSignal(str)
     wallets_changed = pyqtSignal()
     membership_broadcasted = pyqtSignal()
     certification_broadcasted = pyqtSignal()
@@ -168,7 +168,7 @@ class Account(QObject):
             maximums = {}
 
             def progressing(value, maximum, hash):
-                logging.debug("Loading = {0} : {1} : {2}".format(value, maximum, loaded_wallets))
+                #logging.debug("Loading = {0} : {1} : {2}".format(value, maximum, loaded_wallets))
                 values[hash] = value
                 maximums[hash] = maximum
                 account_value = sum(values.values())
@@ -196,6 +196,19 @@ class Account(QObject):
     def set_display_referential(self, index):
         self._current_ref = index
 
+    def set_scrypt_infos(self, salt, password):
+        """
+        Change the size of the wallet pool
+        :param int size: The new size of the wallet pool
+        :param str password: The password of the account, same for all wallets
+        """
+        self.salt = salt
+        self.pubkey = SigningKey(self.salt, password).pubkey
+        wallet = Wallet.create(0, self.salt, password,
+                               "Wallet", self._identities_registry)
+        self.wallets.append(wallet)
+
+    @asyncio.coroutine
     def identity(self, community):
         """
         Get the account identity in the specified community
@@ -203,7 +216,7 @@ class Account(QObject):
         :return: The account identity in the community
         :rtype: cutecoin.core.registry.Identity
         """
-        identity = self._identities_registry.find(self.pubkey, community)
+        identity = yield from self._identities_registry.future_find(self.pubkey, community)
         if identity.local_state == LocalState.NOT_FOUND:
             identity.uid = self.name
         return identity
@@ -212,23 +225,6 @@ class Account(QObject):
     def current_ref(self):
         return money.Referentials[self._current_ref]
 
-    def set_walletpool_size(self, size, password):
-        """
-        Change the size of the wallet pool
-
-        :param int size: The new size of the wallet pool
-        :param str password: The password of the account, same for all wallets
-        """
-        logging.debug("Defining wallet pool size")
-        if len(self.wallets) < size:
-            for i in range(len(self.wallets), size):
-                wallet = Wallet.create(i, self.salt, password,
-                                       "Wallet {0}".format(i), self._identities_registry)
-                self.wallets.append(wallet)
-        else:
-            self.wallets = self.wallets[:size]
-        self.wallets_changed.emit()
-
     def transfers(self, community):
         """
         Get all transfers done in a community by all the wallets
@@ -267,6 +263,7 @@ class Account(QObject):
             value += val
         return value
 
+    @asyncio.coroutine
     def amount(self, community):
         """
         Get amount of money owned in a community by all the wallets
@@ -277,7 +274,7 @@ class Account(QObject):
         """
         value = 0
         for w in self.wallets:
-            val = w.value(community)
+            val = yield from w.value(community)
             value += val
         return value
 
@@ -298,9 +295,9 @@ class Account(QObject):
         key = SigningKey(self.salt, password)
         selfcert.sign([key])
         logging.debug("Key publish : {0}".format(selfcert.signed_raw()))
-        replies = community.broadcast(qtbma.wot.Add, {}, {'pubkey': self.pubkey,
+        replies = community.bma_access.broadcast(qtbma.wot.Add, {}, {'pubkey': self.pubkey,
                                               'self_': selfcert.signed_raw(),
-                                              'other': []})
+                                              'other': ""})
         for r in replies:
             r.finished.connect(lambda reply=r: self.__handle_selfcert_replies(replies, reply))
 
diff --git a/src/cutecoin/core/app.py b/src/cutecoin/core/app.py
index 625f4a893823bdd8eea9398eae2c552919107ad3..75721e8b5a4689da4fbb012f1ca1dcd618f5bec4 100644
--- a/src/cutecoin/core/app.py
+++ b/src/cutecoin/core/app.py
@@ -157,6 +157,7 @@ class Application(QObject):
         Delete an account.
         Current account changes to None if it is deleted.
         """
+        account.stop_coroutines()
         self.accounts.pop(account.name)
         if self.current_account == account:
             self.current_account = None
@@ -178,7 +179,8 @@ class Application(QObject):
             self.stop_current_account()
 
         self.current_account = account
-        self.current_account.start_coroutines()
+        if self.current_account is not None:
+            self.current_account.start_coroutines()
 
     def stop_current_account(self):
         """
diff --git a/src/cutecoin/core/community.py b/src/cutecoin/core/community.py
index c0a6903f29c8a5d0406e1b80af62bc472b532f44..18be5087c8972ee7f4a8fe1999eaaed8d5f6754e 100644
--- a/src/cutecoin/core/community.py
+++ b/src/cutecoin/core/community.py
@@ -12,9 +12,7 @@ import asyncio
 import math
 
 from PyQt5.QtCore import QObject, pyqtSignal
-from requests.exceptions import RequestException
 
-from ucoinpy.documents.block import Block
 from ..tools.exceptions import NoPeerAvailable
 from .net.network import Network
 from .net.api import bma as qtbma
@@ -28,8 +26,6 @@ class Community(QObject):
     .. warning:: The currency name is supposed to be unique in cutecoin
     but nothing exists in ucoin to assert that a currency name is unique.
     """
-    inner_data_changed = pyqtSignal(str)
-
     def __init__(self, currency, network, bma_access):
         """
         Initialize community attributes with a currency and a network.
@@ -119,20 +115,20 @@ class Community(QObject):
         u = ord('\u24B6') + ord(letter) - ord('A')
         return chr(u)
 
-    @property
+    @asyncio.coroutine
     def dividend(self):
         """
         Get the last generated community universal dividend.
 
         :return: The last UD or 1 if no UD was generated.
         """
-        block = self.get_ud_block()
+        block = yield from self.get_ud_block()
         if block:
             return block['dividend']
         else:
             return 1
 
-    @property
+    @asyncio.coroutine
     def computed_dividend(self):
         """
         Get the computed community universal dividend.
@@ -143,8 +139,8 @@ class Community(QObject):
 
         :return: The computed UD or 1 if no UD was generated.
         """
-        block = self.get_ud_block()
-        if block:
+        block = yield from self.get_ud_block()
+        if block and block != qtbma.blockchain.Block.null_value:
             return math.ceil(
                 max(
                     self.dividend,
@@ -156,6 +152,7 @@ class Community(QObject):
         else:
             return 1
 
+    @asyncio.coroutine
     def get_ud_block(self, x=0):
         """
         Get a block with universal dividend
@@ -163,19 +160,20 @@ class Community(QObject):
         :param int x: Get the 'x' older block with UD in it
         :return: The last block with universal dividend.
         """
-        blocks = self.bma_access.get(self, qtbma.blockchain.UD)['result']['blocks']
+        udblocks = yield from self.bma_access.future_request(qtbma.blockchain.UD)
+        blocks = udblocks['result']['blocks']
         if len(blocks) > 0:
             index = len(blocks)-(1+x)
             if index < 0:
                 index = 0
             block_number = blocks[index]
-            block = self.bma_access.get(self, qtbma.blockchain.Block,
+            block = yield from self.bma_access.future_request(qtbma.blockchain.Block,
                                  req_args={'number': block_number})
             return block
         else:
             return None
 
-    @property
+    @asyncio.coroutine
     def monetary_mass(self):
         """
         Get the community monetary mass
@@ -184,11 +182,11 @@ class Community(QObject):
         """
         # Get cached block by block number
         block_number = self.network.latest_block_number
-        block = self.bma_access.get(self, qtbma.blockchain.Block,
+        block = yield from self.bma_access.future_request(self, qtbma.blockchain.Block,
                              req_args={'number': block_number})
         return block['monetaryMass']
 
-    @property
+    @asyncio.coroutine
     def nb_members(self):
         """
         Get the community members number
@@ -198,7 +196,7 @@ class Community(QObject):
         try:
             # Get cached block by block number
             block_number = self.network.latest_block_number
-            block = self.bma_access.get(qtbma.blockchain.Block,
+            block = yield from self.bma_access.future_request(qtbma.blockchain.Block,
                                  req_args={'number': block_number})
             return block['membersCount']
         except ValueError as e:
@@ -227,18 +225,20 @@ class Community(QObject):
         """
         return self._bma_access
 
-    @property
+    @asyncio.coroutine
     def parameters(self):
         """
         Return community parameters in bma format
         """
-        return self.bma_access.get(self, qtbma.blockchain.Parameters)
+        return self.bma_access.future_request(qtbma.blockchain.Parameters)
 
+    @asyncio.coroutine
     def certification_expired(self, certtime):
         """
         Return True if the certificaton time is too old
         """
-        return time.time() - certtime > self.parameters['sigValidity']
+        parameters = yield from self.parameters()
+        return time.time() - certtime > parameters['sigValidity']
 
     def add_node(self, node):
         """
@@ -256,6 +256,7 @@ class Community(QObject):
         """
         self._network.remove_root_node(index)
 
+    @asyncio.coroutine
     def get_block(self, number=None):
         """
         Get a block
@@ -263,10 +264,10 @@ class Community(QObject):
         :param int number: The block number. If none, returns current block.
         """
         if number is None:
-            data = self.bma_access.get(self, qtbma.blockchain.Current)
+            data = self.bma_access.future_request(qtbma.blockchain.Current)
         else:
             logging.debug("Requesting block {0}".format(number))
-            data = self.bma_access.get(self, qtbma.blockchain.Block,
+            data = self.bma_access.future_request(qtbma.blockchain.Block,
                                 req_args={'number': number})
         return data
 
@@ -283,13 +284,14 @@ class Community(QObject):
         block_number = block['number']
         return {'number': block_number, 'hash': block_hash}
 
+    @asyncio.coroutine
     def members_pubkeys(self):
         """
         Listing members pubkeys of a community
 
         :return: All members pubkeys.
         """
-        memberships = self.bma_access.get(self, qtbma.wot.Members)
+        memberships = yield from self.bma_access.future_request(qtbma.wot.Members)
         return [m['pubkey'] for m in memberships["results"]]
 
     def start_coroutines(self):
diff --git a/src/cutecoin/core/graph.py b/src/cutecoin/core/graph.py
index 1665d83fabcead7d9225a05d9033ecb9decb7ccc..96576a1315c2925116e4f63af2b24fc04383e104 100644
--- a/src/cutecoin/core/graph.py
+++ b/src/cutecoin/core/graph.py
@@ -1,8 +1,9 @@
 import logging
 import time
-import datetime
+import asyncio
 from PyQt5.QtCore import QLocale, QDateTime
 from ..core.registry import Identity, BlockchainState
+from ..tools.decorators import asyncify
 from cutecoin.gui.views.wot import NODE_STATUS_HIGHLIGHTED, NODE_STATUS_OUT, ARC_STATUS_STRONG, ARC_STATUS_WEAK
 
 
@@ -17,12 +18,18 @@ class Graph(object):
         """
         self.app = app
         self.community = community
-        self.signature_validity = self.community.parameters['sigValidity']
-        #  arc considered strong during 75% of signature validity time
-        self.ARC_STATUS_STRONG_time = int(self.signature_validity * 0.75)
+        self.signature_validity = 0
+        self.ARC_STATUS_STRONG_time = 0
         # graph empty if None parameter
         self._graph = graph or (dict() and (graph is None))
 
+    @asyncio.coroutine
+    def refresh_signature_validity(self):
+        parameters = yield from self.community.parameters()
+        self.signature_validity = parameters['sigValidity']
+        #  arc considered strong during 75% of signature validity time
+        self.ARC_STATUS_STRONG_time = int(self.signature_validity * 0.75)
+
     def set(self, graph):
         """
         Set the graph from dict
@@ -38,6 +45,7 @@ class Graph(object):
         """
         return self._graph
 
+    @asyncio.coroutine
     def get_shortest_path_between_members(self, from_identity, to_identity):
         """
         Return path list of nodes from from_identity to to_identity
@@ -50,17 +58,21 @@ class Graph(object):
         logging.debug("path between %s to %s..." % (from_identity.uid, to_identity.uid))
         if from_identity.pubkey not in self._graph.keys():
             self.add_identity(from_identity)
-            certifier_list = from_identity.certifiers_of(self.app.identities_registry, self.community)
-            self.add_certifier_list(certifier_list, from_identity, to_identity)
-            certified_list = from_identity.certified_by(self.app.identities_registry, self.community)
-            self.add_certified_list(certified_list, from_identity, to_identity)
+            certifier_list = yield from from_identity.certifiers_of(self.app.identities_registry,
+                                                                    self.community)
+            yield from self.add_certifier_list(certifier_list, from_identity, to_identity)
+            certified_list = yield from from_identity.certified_by(self.app.identities_registry,
+                                                                   self.community)
+            yield from self.add_certified_list(certified_list, from_identity, to_identity)
 
         if to_identity.pubkey not in self._graph.keys():
             # recursively feed graph searching for account node...
-            self.explore_to_find_member(to_identity, self._graph[from_identity.pubkey]['connected'], list())
+            yield from self.explore_to_find_member(to_identity,
+                                                   self._graph[from_identity.pubkey]['connected'], list())
         if len(self._graph[from_identity.pubkey]['connected']) > 0:
             # calculate path of nodes between identity and to_identity
-            path = self.find_shortest_path(self._graph[from_identity.pubkey], self._graph[to_identity.pubkey])
+            path = yield from self.find_shortest_path(self._graph[from_identity.pubkey],
+                                                      self._graph[to_identity.pubkey])
 
         if path:
             logging.debug([node['text'] for node in path])
@@ -69,6 +81,7 @@ class Graph(object):
 
         return path
 
+    @asyncio.coroutine
     def explore_to_find_member(self, identity, connected=None, done=None):
         """
         Scan graph recursively to find identity
@@ -90,24 +103,29 @@ class Graph(object):
             if node['id'] in tuple(done):
                 continue
             identity_selected = identity.from_handled_data(node['text'], node['id'], BlockchainState.VALIDATED)
-            certifier_list = identity_selected.unique_valid_certifiers_of(self.app.identities_registry, self.community)
-            self.add_certifier_list(certifier_list, identity_selected, identity)
+            certifier_list = yield from identity_selected.unique_valid_certifiers_of(self.app.identities_registry,
+                                                                                     self.community)
+            yield from self.add_certifier_list(certifier_list, identity_selected, identity)
             if identity.pubkey in tuple(self._graph.keys()):
                 return False
-            certified_list = identity_selected.unique_valid_certified_by(self.app.identities_registry, self.community)
-            self.add_certified_list(certified_list, identity_selected, identity)
+            certified_list = yield from identity_selected.unique_valid_certified_by(self.app.identities_registry,
+                                                                                    self.community)
+            yield from self.add_certified_list(certified_list, identity_selected, identity)
             if identity.pubkey in tuple(self._graph.keys()):
                 return False
             if node['id'] not in tuple(done):
                 done.append(node['id'])
             if len(done) >= len(self._graph):
                 return True
-            result = self.explore_to_find_member(identity, self._graph[identity_selected.pubkey]['connected'], done)
+            result = yield from self.explore_to_find_member(identity,
+                                                            self._graph[identity_selected.pubkey]['connected'],
+                                                            done)
             if not result:
                 return False
 
         return True
 
+    @asyncio.coroutine
     def find_shortest_path(self, start, end, path=None):
         """
         Find recursively the shortest path between two nodes
@@ -126,12 +144,13 @@ class Graph(object):
         for pubkey in tuple(self._graph[start['id']]['connected']):
             node = self._graph[pubkey]
             if node not in path:
-                newpath = self.find_shortest_path(node, end, path)
+                newpath = yield from self.find_shortest_path(node, end, path)
                 if newpath:
                     if not shortest or len(newpath) < len(shortest):
                         shortest = newpath
         return shortest
 
+    @asyncio.coroutine
     def add_certifier_list(self, certifier_list, identity, identity_account):
         """
         Add list of certifiers to graph
@@ -140,73 +159,78 @@ class Graph(object):
         :param identity identity_account:   Account identity instance
         :return:
         """
-        #  add certifiers of uid
-        for certifier in tuple(certifier_list):
-            # add only valid certification...
-            if (time.time() - certifier['cert_time']) > self.signature_validity:
-                continue
-            # new node
-            if certifier['identity'].pubkey not in self._graph.keys():
-                node_status = 0
-                if certifier['identity'].pubkey == identity_account.pubkey:
-                    node_status += NODE_STATUS_HIGHLIGHTED
-                if certifier['identity'].is_member(self.community) is False:
-                    node_status += NODE_STATUS_OUT
-                self._graph[certifier['identity'].pubkey] = {
-                    'id': certifier['identity'].pubkey,
-                    'arcs': list(),
-                    'text': certifier['identity'].uid,
-                    'tooltip': certifier['identity'].pubkey,
-                    'status': node_status,
-                    'connected': [identity.pubkey]
-                }
-
-            # keep only the latest certification
-            if self._graph[certifier['identity'].pubkey]['arcs']:
-                if certifier['cert_time'] < self._graph[certifier['identity'].pubkey]['arcs'][0]['cert_time']:
+        if self.community:
+            yield from self.refresh_signature_validity()
+            #  add certifiers of uid
+            for certifier in tuple(certifier_list):
+                # add only valid certification...
+                if (time.time() - certifier['cert_time']) > self.signature_validity:
                     continue
-            # display validity status
-            if (time.time() - certifier['cert_time']) > self.ARC_STATUS_STRONG_time:
-                arc_status = ARC_STATUS_WEAK
-            else:
-                arc_status = ARC_STATUS_STRONG
+                # new node
+                if certifier['identity'].pubkey not in self._graph.keys():
+                    node_status = 0
+                    is_member = yield from certifier['identity'].is_member(self.community)
+                    if certifier['identity'].pubkey == identity_account.pubkey:
+                        node_status += NODE_STATUS_HIGHLIGHTED
+                    if is_member is False:
+                        node_status += NODE_STATUS_OUT
+                    self._graph[certifier['identity'].pubkey] = {
+                        'id': certifier['identity'].pubkey,
+                        'arcs': list(),
+                        'text': certifier['identity'].uid,
+                        'tooltip': certifier['identity'].pubkey,
+                        'status': node_status,
+                        'connected': [identity.pubkey]
+                    }
 
-            arc = {
-                'id': identity.pubkey,
-                'status': arc_status,
-                'tooltip': QLocale.toString(
-                    QLocale(),
-                    QDateTime.fromTime_t(certifier['cert_time'] + self.signature_validity).date(),
-                    QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
-                ),
-                'cert_time': certifier['cert_time']
-            }
+                # keep only the latest certification
+                if self._graph[certifier['identity'].pubkey]['arcs']:
+                    if certifier['cert_time'] < self._graph[certifier['identity'].pubkey]['arcs'][0]['cert_time']:
+                        continue
+                # display validity status
+                if (time.time() - certifier['cert_time']) > self.ARC_STATUS_STRONG_time:
+                    arc_status = ARC_STATUS_WEAK
+                else:
+                    arc_status = ARC_STATUS_STRONG
 
-            if certifier['block_number']:
-                current_validations = self.community.network.latest_block_number - certifier['block_number']
-            else:
-                current_validations = 0
-            max_validation = self.community.network.fork_window(self.community.members_pubkeys()) + 1
+                arc = {
+                    'id': identity.pubkey,
+                    'status': arc_status,
+                    'tooltip': QLocale.toString(
+                        QLocale(),
+                        QDateTime.fromTime_t(certifier['cert_time'] + self.signature_validity).date(),
+                        QLocale.dateFormat(QLocale(), QLocale.ShortFormat)
+                    ),
+                    'cert_time': certifier['cert_time']
+                }
 
-            # Current validation can be negative if self.community.network.latest_block_number
-            # is not refreshed yet
-            if max_validation > current_validations > 0:
-                if self.app.preferences['expert_mode']:
-                    arc['validation_text'] = "{0}/{1}".format(current_validations,
-                                                              max_validation)
+                if certifier['block_number']:
+                    current_validations = self.community.network.latest_block_number - certifier['block_number']
                 else:
-                    validation = current_validations / max_validation * 100
-                    arc['validation_text'] = "{0} %".format(QLocale().toString(float(validation), 'f', 0))
-            else:
-                arc['validation_text'] = None
+                    current_validations = 0
+                members_pubkeys = yield from self.community.members_pubkeys()
+                max_validation = self.community.network.fork_window(members_pubkeys) + 1
+
+                # Current validation can be negative if self.community.network.latest_block_number
+                # is not refreshed yet
+                if max_validation > current_validations > 0:
+                    if self.app.preferences['expert_mode']:
+                        arc['validation_text'] = "{0}/{1}".format(current_validations,
+                                                                  max_validation)
+                    else:
+                        validation = current_validations / max_validation * 100
+                        arc['validation_text'] = "{0} %".format(QLocale().toString(float(validation), 'f', 0))
+                else:
+                    arc['validation_text'] = None
 
-            #  add arc to certifier
-            self._graph[certifier['identity'].pubkey]['arcs'].append(arc)
-            # if certifier node not in identity nodes
-            if certifier['identity'].pubkey not in tuple(self._graph[identity.pubkey]['connected']):
-                # add certifier node to identity node
-                self._graph[identity.pubkey]['connected'].append(certifier['identity'].pubkey)
+                #  add arc to certifier
+                self._graph[certifier['identity'].pubkey]['arcs'].append(arc)
+                # if certifier node not in identity nodes
+                if certifier['identity'].pubkey not in tuple(self._graph[identity.pubkey]['connected']):
+                    # add certifier node to identity node
+                    self._graph[identity.pubkey]['connected'].append(certifier['identity'].pubkey)
 
+    @asyncio.coroutine
     def add_certified_list(self, certified_list, identity, identity_account):
         """
         Add list of certified from api to graph
@@ -215,6 +239,7 @@ class Graph(object):
         :param identity identity_account:   Account identity instance
         :return:
         """
+        yield from self.refresh_signature_validity()
         # add certified by uid
         for certified in tuple(certified_list):
             # add only valid certification...
@@ -222,9 +247,10 @@ class Graph(object):
                 continue
             if certified['identity'].pubkey not in self._graph.keys():
                 node_status = 0
+                is_member = yield from certified['identity'].is_member(self.community)
                 if certified['identity'].pubkey == identity_account.pubkey:
                     node_status += NODE_STATUS_HIGHLIGHTED
-                if certified['identity'].is_member(self.community) is False:
+                if is_member is False:
                     node_status += NODE_STATUS_OUT
                 self._graph[certified['identity'].pubkey] = {
                     'id': certified['identity'].pubkey,
@@ -254,7 +280,8 @@ class Graph(object):
                 current_validations = self.community.network.latest_block_number - certified['block_number']
             else:
                 current_validations = 0
-            max_validations = self.community.network.fork_window(self.community.members_pubkeys()) + 1
+            members_pubkeys = yield from self.community.members_pubkeys()
+            max_validations = self.community.network.fork_window(members_pubkeys) + 1
 
             if max_validations > current_validations > 0:
                 if self.app.preferences['expert_mode']:
diff --git a/src/cutecoin/core/money/quant_zerosum.py b/src/cutecoin/core/money/quant_zerosum.py
index 17a8dbc36027cd0686613100159ee6fcda7ccaf8..9c410877997a8a36c8a27c0ff7972cc1bd44f1ba 100644
--- a/src/cutecoin/core/money/quant_zerosum.py
+++ b/src/cutecoin/core/money/quant_zerosum.py
@@ -1,6 +1,6 @@
 from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP, QLocale
 from . import Quantitative
-
+import asyncio
 
 class QuantitativeZSum:
     _NAME_STR_ = QT_TRANSLATE_NOOP('QuantitativeZSum', 'Quant Z-sum')
@@ -24,6 +24,7 @@ class QuantitativeZSum:
     def diff_units(cls, currency):
         return QuantitativeZSum.units(currency)
 
+    @asyncio.coroutine
     def value(self):
         """
         Return quantitative value of amount minus the average value
@@ -32,18 +33,22 @@ class QuantitativeZSum:
         :param cutecoin.core.community.Community community: Community instance
         :return: int
         """
-        ud_block = self.community.get_ud_block()
+        ud_block = yield from self.community.get_ud_block()
         if ud_block and ud_block['membersCount'] > 0:
-            average = self.community.monetary_mass / ud_block['membersCount']
+            monetary_mass = yield from self.community.monetary_mass()
+            average = monetary_mass / ud_block['membersCount']
         else:
             average = 0
         return self.amount - average
 
+    @asyncio.coroutine
     def differential(self):
-        return Quantitative(self.amount, self.community, self.app).compute()
+        value = yield from Quantitative(self.amount, self.community, self.app).value()
+        return value
 
+    @asyncio.coroutine
     def localized(self, units=False, international_system=False):
-        value = self.value()
+        value = yield from self.value()
         if international_system:
             pass
         else:
@@ -57,5 +62,7 @@ class QuantitativeZSum:
         else:
             return localized_value
 
+    @asyncio.coroutine
     def diff_localized(self, units=False, international_system=False):
-        return Quantitative(self.amount, self.community, self.app).localized(units, international_system)
\ No newline at end of file
+        localized = yield from  Quantitative(self.amount, self.community, self.app).localized(units, international_system)
+        return localized
\ No newline at end of file
diff --git a/src/cutecoin/core/money/quantitative.py b/src/cutecoin/core/money/quantitative.py
index 7aac10fe79f60924521e3179e199be6f3aa37663..29d4a58bdf9bbb766b24d13678bff44ecca549f2 100644
--- a/src/cutecoin/core/money/quantitative.py
+++ b/src/cutecoin/core/money/quantitative.py
@@ -1,9 +1,9 @@
 from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP, QObject, QLocale
-
+import asyncio
 
 class Quantitative():
     _NAME_STR_ = QT_TRANSLATE_NOOP('Quantitative', 'Units')
-    _REF_STR_ = QT_TRANSLATE_NOOP('Quantitative', "{0} {1}")
+    _REF_STR_ = QT_TRANSLATE_NOOP('Quantitative', "{0} {1}{2}")
     _UNITS_STR_ = QT_TRANSLATE_NOOP('Quantitative', "{0}")
 
     def __init__(self, amount, community, app):
@@ -23,6 +23,7 @@ class Quantitative():
     def diff_units(cls, currency):
         return Quantitative.units(currency)
 
+    @asyncio.coroutine
     def value(self):
         """
         Return quantitative value of amount
@@ -33,8 +34,10 @@ class Quantitative():
         """
         return int(self.amount)
 
+    @asyncio.coroutine
     def differential(self):
-        return self.value()
+        value = yield from self.value()
+        return value
 
     def _to_si(self, value):
         prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y', 'z', 'y']
@@ -54,8 +57,9 @@ class Quantitative():
 
         return localized_value, prefix
 
+    @asyncio.coroutine
     def localized(self, units=False, international_system=False):
-        value = self.value()
+        value = yield from self.value()
         prefix = ""
         if international_system:
             localized_value, prefix = self._to_si(value)
@@ -71,8 +75,9 @@ class Quantitative():
         else:
             return localized_value
 
+    @asyncio.coroutine
     def diff_localized(self, units=False, international_system=False):
-        value = self.differential()
+        value = yield from self.differential()
         prefix = ""
         if international_system:
             localized_value, prefix = self._to_si(value)
diff --git a/src/cutecoin/core/money/relative.py b/src/cutecoin/core/money/relative.py
index ea6492af150fc1d1e676784fa725e6e6d952e520..15cde10ef7bf7bf7193c7f1fa1784bd0819bad98 100644
--- a/src/cutecoin/core/money/relative.py
+++ b/src/cutecoin/core/money/relative.py
@@ -1,5 +1,5 @@
 from PyQt5.QtCore import QObject, QCoreApplication, QT_TRANSLATE_NOOP, QLocale
-
+import asyncio
 
 class Relative():
     _NAME_STR_ = QT_TRANSLATE_NOOP('Relative', 'UD')
@@ -23,21 +23,24 @@ class Relative():
     def diff_units(self, currency):
         return self.units(currency)
 
+    @asyncio.coroutine
     def value(self):
         """
-        Return relaive value of amount
-    type
+        Return relative value of amount
         :param int amount:   Value
         :param cutecoin.core.community.Community community: Community instance
         :return: float
         """
-        if self.community.dividend > 0:
-            return self.amount / float(self.community.dividend)
+        dividend = yield from self.community.dividend()
+        if dividend > 0:
+            return self.amount / float(dividend)
         else:
-            return 0
+            return self.amount
 
+    @asyncio.coroutine
     def differential(self):
-        return self.value()
+        value = yield from self.value()
+        return value
 
     def _to_si(self, value):
         prefixes = ['', 'd', 'c', 'm', 'µ', 'n', 'p', 'f', 'a', 'z', 'y']
@@ -45,7 +48,7 @@ class Relative():
         prefix_index = 0
         prefix = ""
 
-        while int(scientific_value) == 0:
+        while int(scientific_value) == 0 and scientific_value > 0.0:
             if prefix_index > 3:
                 scientific_value *= 1000
             else:
@@ -60,8 +63,9 @@ class Relative():
 
         return localized_value, prefix
 
+    @asyncio.coroutine
     def localized(self, units=False, international_system=False):
-        value = self.value()
+        value = yield from self.value()
         prefix = ""
         if international_system:
             localized_value, prefix = self._to_si(value)
@@ -76,8 +80,9 @@ class Relative():
         else:
             return localized_value
 
+    @asyncio.coroutine
     def diff_localized(self, units=False, international_system=False):
-        value = self.differential()
+        value = yield from self.differential()
         prefix = ""
         if international_system and value != 0:
             localized_value, prefix = self._to_si(value)
diff --git a/src/cutecoin/core/money/relative_zerosum.py b/src/cutecoin/core/money/relative_zerosum.py
index 788772acb957cca3d07a6db339add134a295520b..4202a72a5fd53a58fe301a76ea62ffeb4ab5f944 100644
--- a/src/cutecoin/core/money/relative_zerosum.py
+++ b/src/cutecoin/core/money/relative_zerosum.py
@@ -1,6 +1,6 @@
 from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP, QLocale
 from .relative import Relative
-
+import asyncio
 
 class RelativeZSum:
     _NAME_STR_ = QT_TRANSLATE_NOOP('RelativeZSum', 'Relat Z-sum')
@@ -24,6 +24,7 @@ class RelativeZSum:
     def diff_units(cls, currency):
         return RelativeZSum.units(currency)
 
+    @asyncio.coroutine
     def value(self):
         """
         Return relative value of amount minus the average value
@@ -32,20 +33,24 @@ class RelativeZSum:
         :param cutecoin.core.community.Community community: Community instance
         :return: float
         """
-        ud_block = self.community.get_ud_block()
+        ud_block = yield from self.community.get_ud_block()
         if ud_block and ud_block['membersCount'] > 0:
-            median = self.community.monetary_mass / ud_block['membersCount']
-            relative_value = self.amount / float(self.community.dividend)
-            relative_median = median / self.community.dividend
+            monetary_mass = yield from self.community.monetary_mass()
+            dividend = yield from self.community.dividend()
+            median = monetary_mass / ud_block['membersCount']
+            relative_value = self.amount / float(dividend)
+            relative_median = median / dividend
         else:
             relative_median = 0
         return relative_value - relative_median
 
+    @asyncio.coroutine
     def differential(self):
         return Relative(self.amount, self.community, self.app).value()
 
+    @asyncio.coroutine
     def localized(self, units=False, international_system=False):
-        value = self.value()
+        value = yield from self.value()
         if international_system:
             pass
         else:
diff --git a/src/cutecoin/core/net/api/bma/__init__.py b/src/cutecoin/core/net/api/bma/__init__.py
index 00af271a8ce89d969998265520ea61ba72879fae..9e6132c085043cb39514de46798e72763aa138a7 100644
--- a/src/cutecoin/core/net/api/bma/__init__.py
+++ b/src/cutecoin/core/net/api/bma/__init__.py
@@ -6,6 +6,7 @@ from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply
 from PyQt5.QtCore import QUrl, QUrlQuery, QTimer, QObject, pyqtSlot
 import logging
 import asyncio
+import json
 
 logger = logging.getLogger("ucoin")
 
@@ -126,7 +127,14 @@ class API(object):
         logging.debug("POST : {0}".format(kwargs))
         post_data = QUrlQuery()
         for k, v in kwargs.items():
-            post_data.addQueryItem(k.replace("+", "%2b"), v.replace("+", "%2b"))
+            if type(k) is str:
+                k = k.replace("+", "%2b")
+            if type(v) is str:
+                v = v.replace("+", "%2b")
+            else:
+                v = json.dumps(v)
+                v = v.replace("+", "%2b")
+            post_data.addQueryItem(k, v)
         url = QUrl(self.reverse_url(path))
         url.setQuery(post_data)
 
diff --git a/src/cutecoin/core/net/api/bma/access.py b/src/cutecoin/core/net/api/bma/access.py
index b77dd961edbedee64a2c42cc555f8a2caf71290f..1ee9ab476890087366aa0b3bef1750eb580f6749 100644
--- a/src/cutecoin/core/net/api/bma/access.py
+++ b/src/cutecoin/core/net/api/bma/access.py
@@ -130,74 +130,14 @@ class BmaAccess(QObject):
             self._data[cache_key] = {'metadata': {},
                                      'value': {}}
 
+        self._data[cache_key]['metadata']['block_number'] = self._network.latest_block_number
+        self._data[cache_key]['metadata']['block_hash'] = self._network.latest_block_hash
+        self._data[cache_key]['metadata']['cutecoin_version'] = __version__
         if not self._compare_json(self._data[cache_key]['value'], data):
-            self._data[cache_key]['metadata']['block_number'] = self._network.latest_block_number
-            self._data[cache_key]['metadata']['block_hash'] = self._network.latest_block_hash
-            self._data[cache_key]['metadata']['cutecoin_version'] = __version__
             self._data[cache_key]['value'] = data
             return True
         return False
 
-    def get(self, caller, request, req_args={}, get_args={}, tries=0):
-        """
-        Get Json data from the specified URL and emit "inner_data_changed"
-        on the caller if the data changed.
-
-        :param PyQt5.QtCore.QObject caller: The objet calling
-        :param class request: A bma request class calling for data
-        :param dict req_args: Arguments to pass to the request constructor
-        :param dict get_args: Arguments to pass to the request __get__ method
-        :return: The cached data
-        :rtype: dict
-        """
-
-        data = self._get_from_cache(request, req_args, get_args)
-        need_reload = data[0]
-        ret_data = data[1]
-        cache_key = BmaAccess._gen_cache_key(request, req_args, get_args)
-
-        if need_reload:
-            # Move to network nstead of community
-            # after removing qthreads
-            if cache_key in self._pending_requests:
-                if caller not in self._pending_requests[cache_key]:
-                    logging.debug("New caller".format(caller))
-                    self._pending_requests[cache_key].append(caller)
-                    logging.debug("Callers".format(self._pending_requests[cache_key]))
-            else:
-                reply = self.simple_request(request, req_args, get_args)
-                logging.debug("New pending request {0}, caller {1}".format(cache_key, caller))
-                self._pending_requests[cache_key] = [caller]
-                reply.finished.connect(lambda: self.handle_reply(request, req_args, get_args, tries))
-        return ret_data
-
-    @pyqtSlot(int, dict, dict, int)
-    def handle_reply(self, request, req_args, get_args, tries):
-        reply = self.sender()
-        logging.debug("Handling QtNetworkReply for {0}".format(str(request)))
-        cache_key = BmaAccess._gen_cache_key(request, req_args, get_args)
-
-        if reply.error() == QNetworkReply.NoError:
-            strdata = bytes(reply.readAll()).decode('utf-8')
-            json_data = json.loads(strdata)
-            # If data changed, we emit a change signal to all callers
-            if self._update_cache(request, req_args, get_args, json_data):
-                logging.debug(self._pending_requests.keys())
-                for caller in self._pending_requests[cache_key]:
-                    logging.debug("Emit change for {0} : {1} ".format(caller, request))
-                    caller.inner_data_changed.emit(str(request))
-            self._pending_requests.pop(cache_key)
-        else:
-            logging.debug("Error in reply : {0}".format(reply.error()))
-            if tries < 3:
-                tries += 1
-                try:
-                    pending_request = self._pending_requests.pop(cache_key)
-                    for caller in pending_request:
-                        self.get(caller, request, req_args, get_args, tries=tries)
-                except KeyError:
-                    logging.debug("{0} is not present anymore in pending requests".format(cache_key))
-
     def future_request(self, request, req_args={}, get_args={}):
         """
         Start a request to the network and returns a future.
@@ -213,8 +153,9 @@ class BmaAccess(QObject):
                 strdata = bytes(reply.readAll()).decode('utf-8')
                 json_data = json.loads(strdata)
                 self._update_cache(request, req_args, get_args, json_data)
-                future_data.set_result(json_data)
-            else:
+                if not future_data.cancelled():
+                    future_data.set_result(json_data)
+            elif not future_data.cancelled():
                 future_data.set_result(request.null_value)
 
         future_data = asyncio.Future()
@@ -230,7 +171,7 @@ class BmaAccess(QObject):
                 reply = req.get(**get_args)
                 reply.finished.connect(lambda: handle_future_reply(reply))
             else:
-                raise NoPeerAvailable(self.currency, len(nodes))
+                raise NoPeerAvailable("", len(nodes))
         else:
             future_data.set_result(data[1])
         return future_data
@@ -251,7 +192,7 @@ class BmaAccess(QObject):
             reply = req.get(**get_args)
             return reply
         else:
-            raise NoPeerAvailable(self.currency, len(nodes))
+            raise NoPeerAvailable("", len(nodes))
 
     def broadcast(self, request, req_args={}, post_args={}):
         """
diff --git a/src/cutecoin/core/net/network.py b/src/cutecoin/core/net/network.py
index 9369afe5420f426af0058bb07184f867ca40031d..62b26dcf1689041346cfaf8a09f058aae2d409cf 100644
--- a/src/cutecoin/core/net/network.py
+++ b/src/cutecoin/core/net/network.py
@@ -12,7 +12,9 @@ import asyncio
 from ucoinpy.documents.peer import Peer
 from ucoinpy.documents.block import Block
 
+from .api import bma as qtbma
 from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QTimer
+from collections import Counter
 
 
 class Network(QObject):
@@ -71,8 +73,8 @@ class Network(QObject):
                 other_node._uid = node.uid
                 other_node._version = node.version
                 other_node._software = node.software
-                if other_node.block_hash != node.block_hash:
-                    other_node.set_block(node.block_number, node.block_hash)
+                if other_node.block['hash'] != node.block['hash']:
+                    other_node.set_block(node.block)
                     other_node.last_change = node.last_change
                     other_node.state = node.state
 
@@ -163,8 +165,12 @@ class Network(QObject):
         Get the latest block considered valid
         It is the most frequent last block of every known nodes
         """
-        blocks = [n.block_number for n in self.nodes]
-        return max(set(blocks), key=blocks.count)
+        blocks_numbers = [n.block['number'] for n in self.synced_nodes
+                          if n.block != qtbma.blockchain.Block.null_value]
+        if len(blocks_numbers) > 0:
+            return blocks_numbers[0]
+        else:
+            return 0
 
     @property
     def latest_block_hash(self):
@@ -172,27 +178,88 @@ class Network(QObject):
         Get the latest block considered valid
         It is the most frequent last block of every known nodes
         """
-        blocks = [n.block_hash for n in self.nodes if n.block_hash != Block.Empty_Hash]
-        if len(blocks) > 0:
-            return max(set(blocks), key=blocks.count)
+        blocks_hash = [n.block['hash'] for n in self.synced_nodes
+                       if n.block != qtbma.blockchain.Block.null_value]
+        if len(blocks_hash) > 0:
+            return blocks_hash[0]
         else:
             return Block.Empty_Hash
 
+    def check_nodes_sync(self):
+        """
+        Check nodes sync with the following rules :
+        1 : The block of the majority
+        2 : The more last different issuers
+        3 : The more difficulty
+        4 : The biggest number or timestamp
+        """
+        # rule number 1 : block of the majority
+        blocks = [n.block['hash'] for n in self.nodes if n.block != qtbma.blockchain.Block.null_value]
+        blocks_occurences = Counter(blocks)
+        blocks_by_occurences = {}
+        for key, value in blocks_occurences.items():
+            the_block = [n.block for n in self.nodes if n.block['hash'] == key][0]
+            if value not in blocks_by_occurences:
+                blocks_by_occurences[value] = [the_block]
+            else:
+                blocks_by_occurences[value].append(the_block)
+
+        if len(blocks_by_occurences) == 0:
+            for n in [n for n in self._nodes if n.state in (Node.ONLINE, Node.DESYNCED)]:
+                n.state = Node.ONLINE
+            return
+
+        most_present = max(blocks_by_occurences.keys())
+
+        if len(blocks_by_occurences[most_present]) > 1:
+            # rule number 2 : more last different issuers
+            # not possible atm
+            blocks_by_issuers = blocks_by_occurences.copy()
+            most_issuers = max(blocks_by_issuers.keys())
+            if len(blocks_by_issuers[most_issuers]) > 1:
+                # rule number 3 : biggest PowMin
+                blocks_by_powmin = {}
+                for block in blocks_by_issuers[most_issuers]:
+                    if block['powMin'] in blocks_by_powmin:
+                        blocks_by_powmin[block['powMin']].append(block)
+                    else:
+                        blocks_by_powmin[block['powMin']] = [block]
+                bigger_powmin = max(blocks_by_powmin.keys())
+                if len(blocks_by_powmin[bigger_powmin]) > 1:
+                    # rule number 3 : latest timestamp
+                    blocks_by_ts = {}
+                    for block in blocks_by_powmin[bigger_powmin]:
+                        blocks_by_ts[block['time']] = block
+                    latest_ts = max(blocks_by_ts.keys())
+                    synced_block_hash = blocks_by_ts[latest_ts]['hash']
+                else:
+                    synced_block_hash = blocks_by_powmin[bigger_powmin][0]['hash']
+            else:
+                synced_block_hash = blocks_by_issuers[most_issuers][0]['hash']
+        else:
+            synced_block_hash = blocks_by_occurences[most_present][0]['hash']
+
+        for n in [n for n in self._nodes if n.state in (Node.ONLINE, Node.DESYNCED)]:
+            if n.block['hash'] == synced_block_hash:
+                n.state = Node.ONLINE
+            else:
+                n.state = Node.DESYNCED
+
     def fork_window(self, members_pubkeys):
         """
         Get the medium of the fork window of the nodes members of a community
         :return: the medium fork window of knew network
         """
-        fork_windows = [n.fork_window for n in self.nodes if n.software != ""
+        fork_windows = [n.fork_window for n in self.online_nodes if n.software != ""
                                   and n.pubkey in members_pubkeys]
         if len(fork_windows) > 0:
-            return statistics.median(fork_windows)
+            return int(statistics.median(fork_windows))
         else:
             return 0
 
     def add_node(self, node):
         """
-        Add a node to the network.
+        Add a nod to the network.
         """
         self._nodes.append(node)
         node.changed.connect(self.handle_change)
@@ -256,8 +323,7 @@ class Network(QObject):
     def handle_change(self):
         node = self.sender()
         if node.state in (Node.ONLINE, Node.DESYNCED):
-            for nd in [n for n in self._nodes if n.state in (Node.ONLINE, Node.DESYNCED)]:
-                nd.check_sync(self.latest_block_hash)
+            self.check_nodes_sync()
             self.nodes_changed.emit()
         else:
             if node.last_change + 3600 < time.time():
@@ -269,4 +335,5 @@ class Network(QObject):
         if self._block_found != self.latest_block_hash and node.state == Node.ONLINE:
             logging.debug("Latest block changed : {0}".format(self.latest_block_number))
             self._block_found = self.latest_block_hash
+            # Do not emit block change for empty block
             self.new_block_mined.emit(self.latest_block_number)
diff --git a/src/cutecoin/core/net/node.py b/src/cutecoin/core/net/node.py
index bf7fe9a6c2e552d5c6fb3f3a3a66eef721a1ee03..38aaf17d5989986e0a063ba1af6f72d8b3e359ec 100644
--- a/src/cutecoin/core/net/node.py
+++ b/src/cutecoin/core/net/node.py
@@ -38,7 +38,7 @@ class Node(QObject):
     changed = pyqtSignal()
     neighbour_found = pyqtSignal(Peer, str)
 
-    def __init__(self, network_manager, currency, endpoints, uid, pubkey, block_number, block_hash,
+    def __init__(self, network_manager, currency, endpoints, uid, pubkey, block,
                  state, last_change, last_merkle, software, version, fork_window):
         """
         Constructor
@@ -48,8 +48,7 @@ class Node(QObject):
         self._endpoints = endpoints
         self._uid = uid
         self._pubkey = pubkey
-        self._block_number = block_number
-        self._block_hash = block_hash
+        self._block = block
         self._state = state
         self._neighbours = []
         self._currency = currency
@@ -95,7 +94,7 @@ class Node(QObject):
 
             node = cls(network_manager, peer.currency,
                        [Endpoint.from_inline(e.inline()) for e in peer.endpoints],
-                       "", peer.pubkey, 0, Block.Empty_Hash, Node.ONLINE, time.time(),
+                       "", peer.pubkey, qtbma.blockchain.Block.null_value, Node.ONLINE, time.time(),
                        {'root': "", 'leaves': []}, "", "", 0)
             logging.debug("Node from address : {:}".format(str(node)))
             return node
@@ -117,7 +116,7 @@ class Node(QObject):
 
         node = cls(network_manager, peer.currency,
                     [Endpoint.from_inline(e.inline()) for e in peer.endpoints],
-                   "", pubkey, 0, Block.Empty_Hash,
+                   "", pubkey, qtbma.blockchain.Block.null_value,
                    Node.ONLINE, time.time(),
                    {'root': "", 'leaves': []},
                    "", "", 0)
@@ -132,8 +131,7 @@ class Node(QObject):
         software = ""
         version = ""
         fork_window = 0
-        block_number = 0
-        block_hash = Block.Empty_Hash
+        block = qtbma.blockchain.Block.null_value
         last_change = time.time()
         state = Node.ONLINE
         logging.debug(data)
@@ -152,11 +150,8 @@ class Node(QObject):
         if 'last_change' in data:
             last_change = data['last_change']
 
-        if 'block_number' in data:
-            block_number = data['block_number']
-
-        if 'block_hash' in data:
-            block_hash = data['block_hash']
+        if 'block' in data:
+            block = data['block']
 
         if 'state' in data:
             state = data['state']
@@ -171,7 +166,7 @@ class Node(QObject):
             fork_window = data['fork_window']
 
         node = cls(network_manager, currency, endpoints,
-                   uid, pubkey, block_number, block_hash,
+                   uid, pubkey, block,
                    state, last_change,
                    {'root': "", 'leaves': []},
                    software, version, fork_window)
@@ -196,8 +191,7 @@ class Node(QObject):
                 'currency': self._currency,
                 'state': self._state,
                 'last_change': self._last_change,
-                'block_number': self.block_number,
-                'block_hash': self.block_hash,
+                'block': self.block,
                 'software': self._software,
                 'version': self._version,
                 'fork_window': self._fork_window
@@ -217,16 +211,11 @@ class Node(QObject):
         return next((e for e in self._endpoints if type(e) is BMAEndpoint))
 
     @property
-    def block_number(self):
-        return self._block_number
-
-    @property
-    def block_hash(self):
-        return self._block_hash
+    def block(self):
+        return self._block
 
-    def set_block(self, block_number, block_hash):
-        self._block_number = block_number
-        self._block_hash = block_hash
+    def set_block(self, block):
+        self._block = block
 
     @property
     def state(self):
@@ -292,13 +281,6 @@ class Node(QObject):
             self._fork_window = new_fork_window
             self.changed.emit()
 
-    def check_sync(self, block_hash):
-        logging.debug("Check sync")
-        if self.block_hash != block_hash:
-            self.state = Node.DESYNCED
-        else:
-            self.state = Node.ONLINE
-
     def check_noerror(self, error_code, status_code):
         if error_code == QNetworkReply.NoError:
             if status_code in (200, 404):
@@ -337,15 +319,14 @@ class Node(QObject):
             if status_code == 200:
                 strdata = bytes(reply.readAll()).decode('utf-8')
                 block_data = json.loads(strdata)
-                block_number = block_data['number']
                 block_hash = block_data['hash']
             elif status_code == 404:
-                self.set_block(0, Block.Empty_Hash)
+                self.set_block(qtbma.blockchain.Block.null_value)
 
-            if block_hash != self.block_hash:
-                self.set_block(block_number, block_hash)
-                logging.debug("Changed block {0} -> {1}".format(self.block_number,
-                                                                     block_number))
+            if block_hash != self.block['hash']:
+                self.set_block(block_data)
+                logging.debug("Changed block {0} -> {1}".format(self.block['number'],
+                                                                block_data['number']))
                 self.changed.emit()
 
         else:
@@ -488,5 +469,5 @@ class Node(QObject):
             self.changed.emit()
 
     def __str__(self):
-        return ','.join([str(self.pubkey), str(self.endpoint.server), str(self.endpoint.port), str(self.block_number),
+        return ','.join([str(self.pubkey), str(self.endpoint.server), str(self.endpoint.ipv4), str(self.endpoint.port), str(self.block['number']),
                          str(self.currency), str(self.state), str(self.neighbours)])
diff --git a/src/cutecoin/core/registry/identities.py b/src/cutecoin/core/registry/identities.py
index 65657deeb68a749f783c0bbc7dc8dcbe7abc41ff..eea2f3d778697ee7dde857170215c25b1dee3072 100644
--- a/src/cutecoin/core/registry/identities.py
+++ b/src/cutecoin/core/registry/identities.py
@@ -42,35 +42,14 @@ class IdentitiesRegistry:
             identities_json.append(identity.jsonify())
         return {'registry': identities_json}
 
-    def find(self, pubkey, community):
-        """
-        Get a person from the pubkey found in a community
-
-        :param str pubkey: The person pubkey
-        :param cutecoin.core.community.Community community: The community in which to look for the pubkey
-        :param bool cached: True if the person should be searched in the
-        cache before requesting the community.
-
-        :return: A new person if the pubkey was unknown or\
-        the known instance if pubkey was already known.
-        :rtype: cutecoin.core.registry.Identity
-        """
-        if pubkey in self._instances:
-            identity = self._instances[pubkey]
-            self._instances[pubkey] = identity
-        else:
-            identity = Identity.empty(pubkey)
-            self._instances[pubkey] = identity
-            reply = community.bma_access.simple_request(qtbma.wot.CertifiersOf, req_args={'search': pubkey})
-            reply.finished.connect(lambda: self.handle_certifiersof(reply, identity, community))
-        return identity
-
     @asyncio.coroutine
     def future_find(self, pubkey, community):
         def handle_certifiersof_reply(reply, tries=0):
             err = reply.error()
             # https://github.com/ucoin-io/ucoin/issues/146
-            if reply.error() == QNetworkReply.NoError or reply.error() == QNetworkReply.ProtocolInvalidOperationError:
+            if reply.error() == QNetworkReply.NoError \
+                    or reply.error() == QNetworkReply.ContentNotFoundError \
+                    or reply.error() == QNetworkReply.ProtocolInvalidOperationError:
                 status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
                 if status_code == 200:
                     strdata = bytes(reply.readAll()).decode('utf-8')
@@ -80,7 +59,8 @@ class IdentitiesRegistry:
                     identity.local_state = LocalState.PARTIAL
                     identity.blockchain_state = BlockchainState.VALIDATED
                     logging.debug("Lookup : found {0}".format(identity))
-                    future_identity.set_result(True)
+                    if not future_identity.cancelled():
+                        future_identity.set_result(identity)
                 else:
                     reply = community.bma_access.simple_request(qtbma.wot.Lookup,
                                                                 req_args={'search': pubkey})
@@ -88,8 +68,8 @@ class IdentitiesRegistry:
             elif tries < 3:
                 reply = community.bma_access.simple_request(qtbma.wot.CertifiersOf, req_args={'search': pubkey})
                 reply.finished.connect(lambda: handle_certifiersof_reply(reply, tries=tries+1))
-            else:
-                future_identity.set_result(True)
+            elif not future_identity.cancelled():
+                future_identity.set_result(identity)
 
         def handle_lookup_reply(reply, tries=0):
             status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
@@ -110,88 +90,28 @@ class IdentitiesRegistry:
                         identity.blockchain_state = BlockchainState.BUFFERED
                         identity.local_state = LocalState.PARTIAL
                         logging.debug("Lookup : found {0}".format(identity))
-                        future_identity.set_result(True)
+                        if not future_identity.cancelled():
+                            future_identity.set_result(identity)
                         return
-                future_identity.set_result(True)
+                if not future_identity.cancelled():
+                        future_identity.set_result(identity)
             elif tries < 3:
                 reply = community.bma_access.simple_request(qtbma.wot.Lookup, req_args={'search': pubkey})
                 reply.finished.connect(lambda: handle_lookup_reply(reply, tries=tries+1))
-            else:
-                future_identity.set_result(True)
+            elif not future_identity.cancelled():
+                future_identity.set_result(identity)
 
         future_identity = asyncio.Future()
         if pubkey in self._instances:
             identity = self._instances[pubkey]
-            future_identity.set_result(True)
+            if not future_identity.cancelled():
+                future_identity.set_result(identity)
         else:
             identity = Identity.empty(pubkey)
             self._instances[pubkey] = identity
             reply = community.bma_access.simple_request(qtbma.wot.CertifiersOf, req_args={'search': pubkey})
             reply.finished.connect(lambda: handle_certifiersof_reply(reply))
-        yield from future_identity
-        return identity
-
-    def handle_certifiersof(self, reply, identity, community, tries=0):
-        """
-        :param PyQt5.QtNetwork.QNetworkReply reply
-        :param cutecoin.core.registry.identity.Identity identity: The looked up identity
-        :return:
-        """
-        if reply.error() == QNetworkReply.NoError:
-            status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
-            if status_code == 200:
-                strdata = bytes(reply.readAll()).decode('utf-8')
-                data = json.loads(strdata)
-                identity.uid = data['uid']
-                identity.local_state = LocalState.PARTIAL
-                identity.blockchain_state = BlockchainState.VALIDATED
-                logging.debug("Lookup : found {0}".format(identity))
-                identity.inner_data_changed.emit(str(qtbma.wot.CertifiersOf))
-            else:
-                reply = community.bma_access.simple_request(qtbma.wot.Lookup,
-                                                            req_args={'search': identity.pubkey})
-                reply.finished.connect(lambda: self.handle_lookup(reply, identity,
-                                                                  community, tries=0))
-        else:
-            logging.debug("Error in reply : {0}".format(reply.error()))
-            if tries < 3:
-                tries += 1
-                reply = community.bma_access.simple_request(qtbma.wot.CertifiersOf,
-                                                            req_args={'search': identity.pubkey})
-                reply.finished.connect(lambda: self.handle_certifiersof(reply, identity,
-                                                                  community, tries=tries))
-
-    def handle_lookup(self, reply, identity, community, tries=0):
-        """
-        :param cutecoin.core.registry.identity.Identity identity: The looked up identity
-        :return:
-        """
-
-        if reply.error() == QNetworkReply.NoError:
-            strdata = bytes(reply.readAll()).decode('utf-8')
-            data = json.loads(strdata)
-
-            timestamp = 0
-            for result in data['results']:
-                if result["pubkey"] == identity.pubkey:
-                    uids = result['uids']
-                    identity_uid = ""
-                    for uid_data in uids:
-                        if uid_data["meta"]["timestamp"] > timestamp:
-                            timestamp = uid_data["meta"]["timestamp"]
-                            identity_uid = uid_data["uid"]
-                    identity.uid = identity_uid
-                    identity.status = Identity.FOUND
-                    logging.debug("Lookup : found {0}".format(identity))
-                    identity.inner_data_changed.emit(str(qtbma.wot.Lookup))
-        else:
-            logging.debug("Error in reply : {0}".format(reply.error()))
-            if tries < 3:
-                tries += 1
-                reply = community.bma_access.simple_request(qtbma.wot.Lookup,
-                                                            req_args={'search': identity.pubkey})
-                reply.finished.connect(lambda: self.handle_lookup(reply, identity,
-                                                                  community, tries=tries))
+        return future_identity
 
     def from_handled_data(self, uid, pubkey, blockchain_state):
         """
diff --git a/src/cutecoin/core/registry/identity.py b/src/cutecoin/core/registry/identity.py
index d5930684cad896617404aa661be3abaabbf50eea..fb65737c7cf07982ea385fe2968737ab47dc5c5b 100644
--- a/src/cutecoin/core/registry/identity.py
+++ b/src/cutecoin/core/registry/identity.py
@@ -10,10 +10,10 @@ import asyncio
 from enum import Enum
 
 from ucoinpy.documents.certification import SelfCertification
-from cutecoin.tools.exceptions import Error, NoPeerAvailable,\
+from ...tools.exceptions import Error, NoPeerAvailable,\
                                         MembershipNotFoundError
-from cutecoin.core.net.api import bma as qtbma
-from cutecoin.core.net.api.bma import PROTOCOL_VERSION
+from ..net.api import bma as qtbma
+from ..net.api.bma import PROTOCOL_VERSION
 from PyQt5.QtCore import QObject, pyqtSignal
 
 
@@ -48,8 +48,6 @@ class Identity(QObject):
     """
     A person with a uid and a pubkey
     """
-    inner_data_changed = pyqtSignal(str)
-
     def __init__(self, uid, pubkey, local_state, blockchain_state):
         """
         Initializing a person object.
@@ -117,6 +115,7 @@ class Identity(QObject):
                                          signature)
         return None
 
+    @asyncio.coroutine
     def get_join_date(self, community):
         """
         Get the person join date.
@@ -125,11 +124,11 @@ class Identity(QObject):
         :param cutecoin.core.community.Community community: The community target to request the join date
         :return: A datetime object
         """
-        search = community.bma_access.get(self, qtbma.blockchain.Membership, {'search': self.pubkey})
+        search = yield from community.bma_access.future_request(qtbma.blockchain.Membership, {'search': self.pubkey})
         if search != qtbma.blockchain.Membership.null_value:
             if len(search['memberships']) > 0:
                 membership_data = search['memberships'][0]
-                block = community.bma_access.get(self, qtbma.blockchain.Block,
+                block = yield from community.bma_access.future_request(qtbma.blockchain.Block,
                                 req_args={'number': membership_data['blockNumber']})
                 if block != qtbma.blockchain.Block.null_value:
                     return block['medianTime']
@@ -137,14 +136,16 @@ class Identity(QObject):
         else:
             raise MembershipNotFoundError(self.pubkey, community.name)
 
+    @asyncio.coroutine
     def get_expiration_date(self, community):
         try:
-            join_block_number = self.membership(community)['blockNumber']
+            membership = yield from self.membership(community)
+            join_block_number = membership['blockNumber']
             try:
-                join_block = community.bma_access.get(self, qtbma.blockchain.Block,
+                join_block = yield from community.bma_access.future_request(qtbma.blockchain.Block,
                                 req_args={'number': join_block_number})
 
-                parameters = community.bma_access.get(self, qtbma.blockchain.Parameters)
+                parameters = yield from community.bma_access.future_request(qtbma.blockchain.Parameters)
                 if join_block != qtbma.blockchain.Block.null_value \
                         and parameters != qtbma.blockchain.Parameters.null_value:
                     join_date = join_block['medianTime']
@@ -159,6 +160,7 @@ class Identity(QObject):
 
 
 #TODO: Manage 'OUT' memberships ? Maybe ?
+    @asyncio.coroutine
     def membership(self, community):
         """
         Get the person last membership document.
@@ -166,7 +168,7 @@ class Identity(QObject):
         :param cutecoin.core.community.Community community: The community target to request the join date
         :return: The membership data in BMA json format
         """
-        search = community.bma_access.get(self, qtbma.blockchain.Membership,
+        search = yield from community.bma_access.future_request(qtbma.blockchain.Membership,
                                            {'search': self.pubkey})
         if search != qtbma.blockchain.Membership.null_value:
             block_number = -1
@@ -182,8 +184,9 @@ class Identity(QObject):
         else:
             raise MembershipNotFoundError(self.pubkey, community.name)
 
+    @asyncio.coroutine
     def published_uid(self, community):
-        data = community.bma_access.get(self, qtbma.wot.Lookup,
+        data = yield from community.bma_access.future_request(qtbma.wot.Lookup,
                                  req_args={'search': self.pubkey})
         if data != qtbma.wot.Lookup.null_value:
             timestamp = 0
@@ -200,6 +203,7 @@ class Identity(QObject):
                             return True
         return False
 
+    @asyncio.coroutine
     def is_member(self, community):
         """
         Check if the person is a member of a community
@@ -207,11 +211,12 @@ class Identity(QObject):
         :param cutecoin.core.community.Community community: The community target to request the join date
         :return: True if the person is a member of a community
         """
-        certifiers = community.bma_access.get(self, qtbma.wot.CertifiersOf, {'search': self.pubkey})
+        certifiers = yield from community.bma_access.future_request(qtbma.wot.CertifiersOf, {'search': self.pubkey})
         if certifiers != qtbma.wot.CertifiersOf.null_value:
             return certifiers['isMember']
         return False
 
+    @asyncio.coroutine
     def certifiers_of(self, identities_registry, community):
         """
         Get the list of this person certifiers
@@ -220,13 +225,13 @@ class Identity(QObject):
         :param cutecoin.core.community.Community community: The community target to request the join date
         :return: The list of the certifiers of this community
         """
-        data = community.bma_access.get(self, qtbma.wot.CertifiersOf, {'search': self.pubkey})
+        data = yield from community.bma_access.future_request(qtbma.wot.CertifiersOf, {'search': self.pubkey})
 
         certifiers = list()
 
         if data == qtbma.wot.CertifiersOf.null_value:
             logging.debug('bma.wot.CertifiersOf request error')
-            data = community.bma_access.get(self, qtbma.wot.Lookup, {'search': self.pubkey})
+            data = yield from community.bma_access.future_request(qtbma.wot.Lookup, {'search': self.pubkey})
             if data == qtbma.wot.Lookup.null_value:
                 logging.debug('bma.wot.Lookup request error')
             else:
@@ -240,7 +245,7 @@ class Identity(QObject):
                                     certifier['identity'] = identities_registry.from_handled_data(uid,
                                                                                                   certifier_data['pubkey'],
                                                                           BlockchainState.BUFFERED)
-                                    block = community.bma_access.get(self, qtbma.blockchain.Block,
+                                    block = yield from community.bma_access.future_request(qtbma.blockchain.Block,
                                                                          {'number': certifier_data['meta']['block_number']})
                                     certifier['cert_time'] = block['medianTime']
                                     certifier['block_number'] = None
@@ -257,13 +262,15 @@ class Identity(QObject):
                 certifiers.append(certifier)
         return certifiers
 
+    @asyncio.coroutine
     def unique_valid_certifiers_of(self, identities_registry, community):
-        certifier_list = self.certifiers_of(identities_registry, community)
+        certifier_list = yield from self.certifiers_of(identities_registry, community)
         unique_valid = []
         #  add certifiers of uid
         for certifier in tuple(certifier_list):
             # add only valid certification...
-            if community.certification_expired(certifier['cert_time']):
+            cert_expired = yield from community.certification_expired(certifier['cert_time'])
+            if cert_expired:
                 continue
 
             # keep only the latest certification
@@ -276,6 +283,7 @@ class Identity(QObject):
                 unique_valid.append(certifier)
         return unique_valid
 
+    @asyncio.coroutine
     def certified_by(self, identities_registry, community):
         """
         Get the list of persons certified by this person
@@ -283,11 +291,11 @@ class Identity(QObject):
         :param cutecoin.core.community.Community community: The community target to request the join date
         :return: The list of the certified persons of this community in BMA json format
         """
-        data = community.bma_access.get(self, qtbma.wot.CertifiedBy, {'search': self.pubkey})
+        data = yield from community.bma_access.future_request(qtbma.wot.CertifiedBy, {'search': self.pubkey})
         certified_list = list()
         if data == qtbma.wot.CertifiedBy.null_value:
             logging.debug('bma.wot.CertifiersOf request error')
-            data = community.bma_access.get(self, qtbma.wot.Lookup, {'search': self.pubkey})
+            data = yield from community.bma_access.future_request(qtbma.wot.Lookup, {'search': self.pubkey})
             if data == qtbma.wot.Lookup.null_value:
                 logging.debug('bma.wot.Lookup request error')
             else:
@@ -312,13 +320,15 @@ class Identity(QObject):
                 certified_list.append(certified)
         return certified_list
 
+    @asyncio.coroutine
     def unique_valid_certified_by(self, identities_registry, community):
-        certified_list = self.certified_by(identities_registry, community)
+        certified_list = yield from self.certified_by(identities_registry, community)
         unique_valid = []
         #  add certifiers of uid
         for certified in tuple(certified_list):
             # add only valid certification...
-            if community.certification_expired(certified['cert_time']):
+            cert_expired = yield from community.certification_expired(certified['cert_time'])
+            if cert_expired:
                 continue
 
             # keep only the latest certification
@@ -331,10 +341,13 @@ class Identity(QObject):
                 unique_valid.append(certified)
         return unique_valid
 
+    @asyncio.coroutine
     def membership_expiration_time(self, community):
-        join_block = self.membership(community)['blockNumber']
-        join_date = community.get_block(join_block)['medianTime']
-        parameters = community.parameters
+        membership = yield from self.membership(community)
+        join_block = membership['blockNumber']
+        block = yield from community.get_block(join_block)
+        join_date = block['medianTime']
+        parameters = yield from community.parameters()
         expiration_date = join_date + parameters['sigValidity']
         current_time = time.time()
         return expiration_date - current_time
diff --git a/src/cutecoin/core/txhistory.py b/src/cutecoin/core/txhistory.py
index 24d993d083732f5ab41b451d584354360da01d9a..6105ac21ca128a912199a21318cce90a7df08fb9 100644
--- a/src/cutecoin/core/txhistory.py
+++ b/src/cutecoin/core/txhistory.py
@@ -1,7 +1,9 @@
 import asyncio
 import logging
+import hashlib
 from .transfer import Transfer
 from ucoinpy.documents.transaction import InputSource, OutputSource
+from ucoinpy.documents.block import Block
 from ..tools.exceptions import LookupFailureError
 from .net.api import bma as qtbma
 
@@ -71,29 +73,29 @@ class TxHistory():
         self._stop_coroutines = True
 
     @staticmethod
+    @asyncio.coroutine
     def _validation_state(community, block_number, current_block):
-        if block_number + community.network.fork_window(community.members_pubkeys()) + 1 < current_block["number"]:
+        members_pubkeys = yield from community.members_pubkeys()
+        if block_number + community.network.fork_window(members_pubkeys) + 1 < current_block["number"]:
             state = Transfer.VALIDATED
         else:
             state = Transfer.VALIDATING
         return state
 
     @asyncio.coroutine
-    def _parse_transaction(self, community, txdata, received_list, txid, current_block):
-        tx_outputs = [OutputSource.from_inline(o) for o in txdata['outputs']]
-        receivers = [o.pubkey for o in tx_outputs
-                     if o.pubkey != txdata['issuers'][0]]
-
-        block_number = txdata['block_number']
+    def _parse_transaction(self, community, tx, block_number,
+                           mediantime, received_list,
+                           current_block, txid):
+        receivers = [o.pubkey for o in tx.outputs
+                     if o.pubkey != tx.issuers[0]]
 
-        mediantime = txdata['time']
-        state = TxHistory._validation_state(community, block_number, current_block)
+        state = yield from TxHistory._validation_state(community, block_number, current_block)
 
         if len(receivers) == 0:
-            receivers = [txdata['issuers'][0]]
+            receivers = [tx.issuers[0]]
 
         try:
-            issuer = yield from self.wallet._identities_registry.future_find(txdata['issuers'][0], community)
+            issuer = yield from self.wallet._identities_registry.future_find(tx.issuers[0], community)
             issuer_uid = issuer.uid
         except LookupFailureError:
             issuer_uid = ""
@@ -106,57 +108,96 @@ class TxHistory():
 
         metadata = {'block': block_number,
                     'time': mediantime,
-                    'comment': txdata['comment'],
-                    'issuer': txdata['issuers'][0],
+                    'comment': tx.comment,
+                    'issuer': tx.issuers[0],
                     'issuer_uid': issuer_uid,
                     'receiver': receivers[0],
                     'receiver_uid': receiver_uid,
                     'txid': txid}
 
-        in_issuers = len([i for i in txdata['issuers']
+        in_issuers = len([i for i in tx.issuers
                      if i == self.wallet.pubkey]) > 0
-        in_outputs = len([o for o in tx_outputs
+        in_outputs = len([o for o in tx.outputs
                        if o.pubkey == self.wallet.pubkey]) > 0
         awaiting = [t for t in self._transfers
                     if t.state in (Transfer.AWAITING, Transfer.VALIDATING)]
 
         # We check if the transaction correspond to one we sent
         # but not from this cutecoin Instance
-        if txdata['hash'] not in [t.hash for t in awaiting]:
+        tx_hash = hashlib.sha1(tx.signed_raw().encode("ascii")).hexdigest().upper()
+        if tx_hash not in [t.hash for t in awaiting]:
             # If the wallet pubkey is in the issuers we sent this transaction
             if in_issuers:
-                outputs = [o for o in tx_outputs
+                outputs = [o for o in tx.outputs
                            if o.pubkey != self.wallet.pubkey]
                 amount = 0
                 for o in outputs:
                     amount += o.amount
                 metadata['amount'] = amount
-                transfer = Transfer.create_from_blockchain(txdata['hash'],
+                transfer = Transfer.create_from_blockchain(tx_hash,
                                                            state,
                                                      metadata.copy())
                 return transfer
             # If we are not in the issuers,
             # maybe it we are in the recipients of this transaction
             elif in_outputs:
-                outputs = [o for o in tx_outputs
+                outputs = [o for o in tx.outputs
                            if o.pubkey == self.wallet.pubkey]
                 amount = 0
                 for o in outputs:
                     amount += o.amount
                 metadata['amount'] = amount
 
-                if txdata['hash'] not in [t.hash for t in awaiting]:
-                    transfer = Transfer.create_from_blockchain(txdata['hash'],
+                if tx_hash not in [t.hash for t in awaiting]:
+                    transfer = Transfer.create_from_blockchain(tx_hash,
                                                                state,
                                                          metadata.copy())
                     received_list.append(transfer)
                     return transfer
         else:
-            transfer = [t for t in awaiting if t.hash == txdata['hash']][0]
-            transfer.check_registered(txdata['hash'], current_block['number'], mediantime,
+            transfer = [t for t in awaiting if t.hash == tx_hash][0]
+
+            transfer.check_registered(tx_hash, current_block['number'], mediantime,
                                       community.network.fork_window(community.members_pubkeys()) + 1)
         return None
 
+    @asyncio.coroutine
+    def _parse_block(self, community, block_number, received_list, current_block, txmax):
+        block = yield from community.bma_access.future_request(qtbma.blockchain.Block,
+                                  req_args={'number': block_number})
+        signed_raw = "{0}{1}\n".format(block['raw'],
+                                       block['signature'])
+        transfers = []
+        try:
+            block_doc = Block.from_signed_raw(signed_raw)
+        except:
+            logging.debug("Error in {0}".format(block_number))
+            raise
+        for (txid, tx) in enumerate(block_doc.transactions):
+            transfer = yield from self._parse_transaction(community, tx, block_number,
+                                    block_doc.mediantime, received_list,
+                                    current_block, txid+txmax)
+            if transfer != None:
+                logging.debug("Transfer amount : {0}".format(transfer.metadata['amount']))
+                transfers.append(transfer)
+            else:
+                logging.debug("None transfer")
+        return transfers
+
+    @asyncio.coroutine
+    def request_dividends(self, community, parsed_block):
+        dividends_data = qtbma.ud.History.null_value
+        for i in range(0, 6):
+            if dividends_data == qtbma.ud.History.null_value:
+                dividends_data = yield from community.bma_access.future_request(qtbma.ud.History,
+                                                req_args={'pubkey': self.wallet.pubkey})
+
+        dividends = dividends_data['history']['history']
+        for d in dividends:
+            if d['block_number'] < parsed_block:
+                dividends.remove(d)
+        return dividends
+
     @asyncio.coroutine
     def refresh(self, community, received_list):
         """
@@ -167,43 +208,27 @@ class TxHistory():
         """
         current_block = yield from community.bma_access.future_request(qtbma.blockchain.Block,
                                 req_args={'number': community.network.latest_block_number})
-
+        members_pubkeys = yield from community.members_pubkeys()
         # We look for the first block to parse, depending on awaiting and validating transfers and ud...
-        blocks = [tx.metadata['block_number'] for tx in self._transfers
+        blocks = [tx.metadata['block'] for tx in self._transfers
                   if tx.state in (Transfer.AWAITING, Transfer.VALIDATING)] +\
                  [ud['block_number'] for ud in self._dividends
                   if ud['state'] in (Transfer.AWAITING, Transfer.VALIDATING)] +\
-                 [max(0, self.latest_block - community.network.fork_window(community.members_pubkeys()))]
+                 [max(0, self.latest_block - community.network.fork_window(members_pubkeys))]
         parsed_block = min(set(blocks))
         logging.debug("Refresh from : {0} to {1}".format(self.latest_block, current_block['number']))
-        dividends_data = qtbma.ud.History.null_value
-        while dividends_data == qtbma.ud.History.null_value:
-            dividends_data = yield from community.bma_access.future_request(qtbma.ud.History,
-                                                req_args={'pubkey': self.wallet.pubkey})
-
-        dividends = dividends_data['history']['history']
-        for d in dividends:
-            if d['block_number'] < parsed_block:
-                dividends.remove(d)
-
+        dividends = yield from self.request_dividends(community, parsed_block)
+        with_tx_data = yield from community.bma_access.future_request(qtbma.blockchain.TX)
+        blocks_with_tx = with_tx_data['result']['blocks']
         new_transfers = []
         new_dividends = []
         # Lets look if transactions took too long to be validated
         awaiting = [t for t in self._transfers
                     if t.state == Transfer.AWAITING]
         while parsed_block < current_block['number']:
-            tx_history = qtbma.tx.history.Blocks.null_value
-            while tx_history == qtbma.tx.history.Blocks.null_value:
-                tx_history = yield from community.bma_access.future_request(qtbma.tx.history.Blocks,
-                                                          req_args={'pubkey': self.wallet.pubkey,
-                                                                 'from_':str(parsed_block),
-                                                                 'to_': str(parsed_block + 99)})
-            if self._stop_coroutines:
-                return
-
             udid = 0
-            for d in [ud for ud in dividends if ud['block_number'] in range(parsed_block, parsed_block+100)]:
-                state = TxHistory._validation_state(community, d['block_number'], current_block)
+            for d in [ud for ud in dividends if ud['block_number'] == parsed_block]:
+                state = yield from TxHistory._validation_state(community, d['block_number'], current_block)
 
                 if d['block_number'] not in [ud['block_number'] for ud in self._dividends]:
                     d['id'] = udid
@@ -216,22 +241,14 @@ class TxHistory():
                     known_dividend['state'] = state
 
             # We parse only blocks with transactions
-            transactions = tx_history['history']['received'] + tx_history['history']['sent']
-            for (txid, txdata) in enumerate(transactions):
-                if self._stop_coroutines:
-                    return
-                if len(txdata['issuers']) == 0:
-                    logging.debug("Error with : {0}, from {1} to {2}".format(self.wallet.pubkey,
-                                                                             parsed_block,
-                                                                             current_block['number']))
-                else:
-                    transfer = yield from self._parse_transaction(community, txdata, received_list,
-                                                                  udid + txid, current_block)
-                    if transfer:
-                        new_transfers.append(transfer)
+            if parsed_block in blocks_with_tx:
+                transfers = yield from self._parse_block(community, parsed_block,
+                                                         received_list, current_block,
+                                                         udid + len(new_transfers))
+                new_transfers += transfers
 
             self.wallet.refresh_progressed.emit(parsed_block, current_block['number'], self.wallet.pubkey)
-            parsed_block += 100
+            parsed_block += 1
 
         if current_block['number'] > self.latest_block:
             self.available_sources = yield from self.wallet.future_sources(community)
diff --git a/src/cutecoin/core/txhistory_indexation.py b/src/cutecoin/core/txhistory_indexation.py
new file mode 100644
index 0000000000000000000000000000000000000000..399f1f064bf7f5a385b6f156a55dae6fce5b34de
--- /dev/null
+++ b/src/cutecoin/core/txhistory_indexation.py
@@ -0,0 +1,255 @@
+import asyncio
+import logging
+from .transfer import Transfer
+from ucoinpy.documents.transaction import InputSource, OutputSource
+from ..tools.exceptions import LookupFailureError
+from .net.api import bma as qtbma
+
+
+class TxHistory():
+    def __init__(self, app, wallet):
+        self._latest_block = 0
+        self.wallet = wallet
+        self.app = app
+        self._stop_coroutines = False
+
+        self._transfers = []
+        self.available_sources = []
+        self._dividends = []
+
+    @property
+    def latest_block(self):
+        return self._latest_block
+
+    @latest_block.setter
+    def latest_block(self, value):
+        self._latest_block = value
+
+    def load_from_json(self, data):
+        self._transfers = []
+
+        data_sent = data['transfers']
+        for s in data_sent:
+            self._transfers.append(Transfer.load(s))
+
+        for s in data['sources']:
+            self.available_sources.append(InputSource.from_inline(s['inline']))
+
+        for d in data['dividends']:
+            self._dividends.append(d)
+
+        self.latest_block = data['latest_block']
+
+    def jsonify(self):
+        data_transfer = []
+        for s in self.transfers:
+            data_transfer.append(s.jsonify())
+
+        data_sources = []
+        for s in self.available_sources:
+            s.index = 0
+            data_sources.append({'inline': "{0}\n".format(s.inline())})
+
+        data_dividends = []
+        for d in self._dividends:
+            data_dividends.append(d)
+
+        return {'latest_block': self.latest_block,
+                'transfers': data_transfer,
+                'sources': data_sources,
+                'dividends': data_dividends}
+
+    @property
+    def transfers(self):
+        return [t for t in self._transfers if t.state != Transfer.DROPPED]
+
+    @property
+    def dividends(self):
+        return self._dividends.copy()
+
+    def stop_coroutines(self):
+        self._stop_coroutines = True
+
+    @staticmethod
+    @asyncio.coroutine
+    def _validation_state(community, block_number, current_block):
+        members_pubkeys = yield from community.members_pubkeys()
+        if block_number + community.network.fork_window(members_pubkeys) + 1 < current_block["number"]:
+            state = Transfer.VALIDATED
+        else:
+            state = Transfer.VALIDATING
+        return state
+
+    @asyncio.coroutine
+    def _parse_transaction(self, community, txdata, received_list, txid, current_block):
+        tx_outputs = [OutputSource.from_inline(o) for o in txdata['outputs']]
+        receivers = [o.pubkey for o in tx_outputs
+                     if o.pubkey != txdata['issuers'][0]]
+
+        block_number = txdata['block_number']
+
+        mediantime = txdata['time']
+        state = yield from TxHistory._validation_state(community, block_number, current_block)
+
+        if len(receivers) == 0:
+            receivers = [txdata['issuers'][0]]
+
+        try:
+            issuer = yield from self.wallet._identities_registry.future_find(txdata['issuers'][0], community)
+            issuer_uid = issuer.uid
+        except LookupFailureError:
+            issuer_uid = ""
+
+        try:
+            receiver = yield from self.wallet._identities_registry.future_find(receivers[0], community)
+            receiver_uid = receiver.uid
+        except LookupFailureError:
+            receiver_uid = ""
+
+        metadata = {'block': block_number,
+                    'time': mediantime,
+                    'comment': txdata['comment'],
+                    'issuer': txdata['issuers'][0],
+                    'issuer_uid': issuer_uid,
+                    'receiver': receivers[0],
+                    'receiver_uid': receiver_uid,
+                    'txid': txid}
+
+        in_issuers = len([i for i in txdata['issuers']
+                     if i == self.wallet.pubkey]) > 0
+        in_outputs = len([o for o in tx_outputs
+                       if o.pubkey == self.wallet.pubkey]) > 0
+        awaiting = [t for t in self._transfers
+                    if t.state in (Transfer.AWAITING, Transfer.VALIDATING)]
+
+        # We check if the transaction correspond to one we sent
+        # but not from this cutecoin Instance
+        if txdata['hash'] not in [t.hash for t in awaiting]:
+            # If the wallet pubkey is in the issuers we sent this transaction
+            if in_issuers:
+                outputs = [o for o in tx_outputs
+                           if o.pubkey != self.wallet.pubkey]
+                amount = 0
+                for o in outputs:
+                    amount += o.amount
+                metadata['amount'] = amount
+                transfer = Transfer.create_from_blockchain(txdata['hash'],
+                                                           state,
+                                                     metadata.copy())
+                return transfer
+            # If we are not in the issuers,
+            # maybe it we are in the recipients of this transaction
+            elif in_outputs:
+                outputs = [o for o in tx_outputs
+                           if o.pubkey == self.wallet.pubkey]
+                amount = 0
+                for o in outputs:
+                    amount += o.amount
+                metadata['amount'] = amount
+
+                if txdata['hash'] not in [t.hash for t in awaiting]:
+                    transfer = Transfer.create_from_blockchain(txdata['hash'],
+                                                               state,
+                                                         metadata.copy())
+                    received_list.append(transfer)
+                    return transfer
+        else:
+            transfer = [t for t in awaiting if t.hash == txdata['hash']][0]
+            transfer.check_registered(txdata['hash'], current_block['number'], mediantime,
+                                      community.network.fork_window(community.members_pubkeys()) + 1)
+
+    @asyncio.coroutine
+    def refresh(self, community, received_list):
+        """
+        Refresh last transactions
+
+        :param cutecoin.core.Community community: The community
+        :param list received_list: List of transactions received
+        """
+        current_block = yield from community.bma_access.future_request(qtbma.blockchain.Block,
+                                req_args={'number': community.network.latest_block_number})
+        members_pubkeys = yield from community.members_pubkeys()
+        # We look for the first block to parse, depending on awaiting and validating transfers and ud...
+        blocks = [tx.metadata['block'] for tx in self._transfers
+                  if tx.state in (Transfer.AWAITING, Transfer.VALIDATING)] +\
+                 [ud['block_number'] for ud in self._dividends
+                  if ud['state'] in (Transfer.AWAITING, Transfer.VALIDATING)] +\
+                 [max(0, self.latest_block - community.network.fork_window(members_pubkeys))]
+        parsed_block = min(set(blocks))
+        logging.debug("Refresh from : {0} to {1}".format(self.latest_block, current_block['number']))
+        dividends_data = qtbma.ud.History.null_value
+        for i in range(0, 6):
+            if dividends_data == qtbma.ud.History.null_value:
+                dividends_data = yield from community.bma_access.future_request(qtbma.ud.History,
+                                                req_args={'pubkey': self.wallet.pubkey})
+
+        dividends = dividends_data['history']['history']
+        for d in dividends:
+            if d['block_number'] < parsed_block:
+                dividends.remove(d)
+
+        new_transfers = []
+        new_dividends = []
+        # Lets look if transactions took too long to be validated
+        awaiting = [t for t in self._transfers
+                    if t.state == Transfer.AWAITING]
+        while parsed_block < current_block['number']:
+            udid = 0
+            for d in [ud for ud in dividends if ud['block_number'] in range(parsed_block, parsed_block+100)]:
+                state = yield from TxHistory._validation_state(community, d['block_number'], current_block)
+
+                if d['block_number'] not in [ud['block_number'] for ud in self._dividends]:
+                    d['id'] = udid
+                    d['state'] = state
+                    new_dividends.append(d)
+                    udid += 1
+                else:
+                    known_dividend = [ud for ud in self._dividends
+                                      if ud['block_number'] == d['block_number']][0]
+                    known_dividend['state'] = state
+
+            tx_history = qtbma.tx.history.Blocks.null_value
+            for i in range(0, 6):
+                if tx_history == qtbma.tx.history.Blocks.null_value:
+                    tx_history = yield from community.bma_access.future_request(qtbma.tx.history.Blocks,
+                                                          req_args={'pubkey': self.wallet.pubkey,
+                                                                 'from_':str(parsed_block),
+                                                                 'to_': str(parsed_block + 99)})
+            # If after 6 requests we still get wrong data
+            # we continue to next loop
+            if tx_history == qtbma.tx.history.Blocks.null_value:
+                continue
+
+            # We parse only blocks with transactions
+            transactions = tx_history['history']['received'] + tx_history['history']['sent']
+            for (txid, txdata) in enumerate(transactions):
+                if self._stop_coroutines:
+                    return
+                if len(txdata['issuers']) == 0:
+                    logging.debug("Error with : {0}, from {1} to {2}".format(self.wallet.pubkey,
+                                                                             parsed_block,
+                                                                             current_block['number']))
+                else:
+                    transfer = yield from self._parse_transaction(community, txdata, received_list,
+                                                                  udid + txid, current_block)
+                    if transfer:
+                        new_transfers.append(transfer)
+
+            self.wallet.refresh_progressed.emit(parsed_block, current_block['number'], self.wallet.pubkey)
+            parsed_block += 100
+
+        if current_block['number'] > self.latest_block:
+            self.available_sources = yield from self.wallet.future_sources(community)
+            if self._stop_coroutines:
+                return
+            self.latest_block = current_block['number']
+
+        for transfer in awaiting:
+            transfer.check_refused(current_block['medianTime'],
+                                   community.parameters['avgGenTime'],
+                                   community.parameters['medianTimeBlocks'])
+
+        self._transfers = self._transfers + new_transfers
+        self._dividends = self._dividends + new_dividends
+
+        self.wallet.refresh_finished.emit(received_list)
diff --git a/src/cutecoin/core/wallet.py b/src/cutecoin/core/wallet.py
index f7ea800bfd29ea624281bb3350439dd43e9bc25c..faa268b8085d264aa73ea57eec32a5cc9b1eec89 100644
--- a/src/cutecoin/core/wallet.py
+++ b/src/cutecoin/core/wallet.py
@@ -24,8 +24,6 @@ class Wallet(QObject):
     """
     A wallet is used to manage money with a unique key.
     """
-
-    inner_data_changed = pyqtSignal(str)
     refresh_progressed = pyqtSignal(int, int, str)
     refresh_finished = pyqtSignal(list)
     transfer_broadcasted = pyqtSignal(str)
@@ -60,7 +58,7 @@ class Wallet(QObject):
         if walletid == 0:
             key = SigningKey(salt, password)
         else:
-            key = SigningKey("{0}{1}".format(salt, walletid), password)
+            key = SigningKey(b"{0}{1}".format(salt, walletid), password)
         return cls(walletid, key.pubkey, name, identities_registry)
 
     @classmethod
@@ -132,6 +130,7 @@ class Wallet(QObject):
             key = SigningKey("{0}{1}".format(salt, self.walletid), password)
         return (key.pubkey == self.pubkey)
 
+    @asyncio.coroutine
     def relative_value(self, community):
         """
         Get wallet value relative to last generated UD
@@ -139,25 +138,12 @@ class Wallet(QObject):
         :param community: The community to get value
         :return: The wallet relative value
         """
-        value = self.value(community)
+        value = yield from self.value(community)
         ud = community.dividend
         relative_value = value / float(ud)
         return relative_value
 
     @asyncio.coroutine
-    def future_value(self, community):
-        """
-        Get wallet absolute value
-
-        :param community: The community to get value
-        :return: The wallet absolute value
-        """
-        value = 0
-        sources = yield from self.future_sources(community)
-        for s in sources:
-            value += s.amount
-        return value
-
     def value(self, community):
         """
         Get wallet absolute value
@@ -166,7 +152,7 @@ class Wallet(QObject):
         :return: The wallet absolute value
         """
         value = 0
-        sources = self.sources(community)
+        sources = yield from self.sources(community)
         for s in sources:
             value += s.amount
         return value
@@ -305,6 +291,7 @@ class Wallet(QObject):
             tx.append(InputSource.from_bma(s))
         return tx
 
+    @asyncio.coroutine
     def sources(self, community):
         """
         Get available sources in a given community
@@ -312,7 +299,7 @@ class Wallet(QObject):
         :param cutecoin.core.community.Community community: The community where we want available sources
         :return: List of InputSource ucoinpy objects
         """
-        data = community.bma_access.get(self, qtbma.tx.Sources,
+        data = yield from community.bma_access.future_request(qtbma.tx.Sources,
                                  req_args={'pubkey': self.pubkey})
         tx = []
         for s in data['sources']:
diff --git a/src/cutecoin/gui/certification.py b/src/cutecoin/gui/certification.py
index 4ebd81fd08f6c0f6bdf3b51f025770ba9449050f..cd2baf04c42615f0f39132f7622adf2c0dd2db55 100644
--- a/src/cutecoin/gui/certification.py
+++ b/src/cutecoin/gui/certification.py
@@ -5,19 +5,20 @@ Created on 24 dec. 2014
 """
 from PyQt5.QtWidgets import QDialog, QMessageBox, QDialogButtonBox, QApplication
 from PyQt5.QtCore import Qt, pyqtSlot
-import quamash
 from ..gen_resources.certification_uic import Ui_CertificationDialog
 from . import toast
+from ..core.net.api import bma as qtbma
+from ..tools.decorators import asyncify
 import asyncio
+import logging
 
 
 class CertificationDialog(QDialog, Ui_CertificationDialog):
-
     """
     classdocs
     """
 
-    def __init__(self, certifier, app, password_asker):
+    def __init__(self, app, certifier, password_asker):
         """
         Constructor
         """
@@ -34,6 +35,14 @@ class CertificationDialog(QDialog, Ui_CertificationDialog):
         for contact in certifier.contacts:
             self.combo_contact.addItem(contact['name'])
 
+    @staticmethod
+    def certify_identity(app, account, password_asker, community, identity):
+        dialog = CertificationDialog(app, account, password_asker)
+        dialog.combo_community.setCurrentText(community.name)
+        dialog.edit_pubkey.setText(identity.pubkey)
+        dialog.radio_pubkey.setChecked(True)
+        return dialog.exec_()
+
     def accept(self):
         if self.radio_contact.isChecked():
             index = self.combo_contact.currentIndex()
@@ -64,17 +73,25 @@ class CertificationDialog(QDialog, Ui_CertificationDialog):
     def handle_error(self, error_code, text):
         if self.app.preferences['notifications']:
             toast.display(self.tr("Error"), self.tr("{0} : {1}".format(error_code, text)))
-        else:
-            QMessageBox.Critical(self, self.tr("Error", self.tr("{0} : {1}".format(error_code, text))))
+        #else:
+        #    QMessageBox.Critical(self, self.tr("Error", self.tr("{0} : {1}".format(error_code, text))))
         self.account.certification_broadcasted.disconnect()
         self.account.broadcast_error.disconnect(self.handle_error)
         QApplication.restoreOverrideCursor()
 
     def change_current_community(self, index):
         self.community = self.account.communities[index]
-        if self.account.pubkey in self.community.members_pubkeys():
+        self.refresh()
+
+    @asyncify
+    @asyncio.coroutine
+    def refresh(self):
+        account_identity = yield from self.account.identity(self.community)
+        is_member = yield from account_identity.is_member(self.community)
+        block_0 = yield from self.community.get_block(0)
+        if is_member or block_0 == qtbma.blockchain.Block.null_value:
             self.button_box.button(QDialogButtonBox.Ok).setEnabled(True)
-            self.button_box.button(QDialogButtonBox.Ok).setText(self.tr("Ok"))
+            self.button_box.button(QDialogButtonBox.Ok).setText(self.tr("&Ok"))
         else:
             self.button_box.button(QDialogButtonBox.Ok).setEnabled(False)
             self.button_box.button(QDialogButtonBox.Ok).setText(self.tr("Not a member"))
@@ -82,3 +99,9 @@ class CertificationDialog(QDialog, Ui_CertificationDialog):
     def recipient_mode_changed(self, pubkey_toggled):
         self.edit_pubkey.setEnabled(pubkey_toggled)
         self.combo_contact.setEnabled(not pubkey_toggled)
+
+    def async_exec(self):
+        future = asyncio.Future()
+        self.finished.connect(lambda r: future.set_result(r))
+        self.open()
+        return future
\ No newline at end of file
diff --git a/src/cutecoin/gui/community_tab.py b/src/cutecoin/gui/community_tab.py
deleted file mode 100644
index e9e3653fbf713161fe3e28ff84f09fd8d65779e5..0000000000000000000000000000000000000000
--- a/src/cutecoin/gui/community_tab.py
+++ /dev/null
@@ -1,286 +0,0 @@
-"""
-Created on 2 févr. 2014
-
-@author: inso
-"""
-
-import logging
-from PyQt5.QtCore import Qt, pyqtSlot
-from PyQt5.QtGui import QIcon, QCursor
-from PyQt5.QtWidgets import QWidget, QMessageBox, QAction, QMenu, QDialog, \
-                            QAbstractItemView
-from cutecoin.models.identities import IdentitiesFilterProxyModel, IdentitiesTableModel
-from ..gen_resources.community_tab_uic import Ui_CommunityTabWidget
-from cutecoin.gui.contact import ConfigureContactDialog
-from cutecoin.gui.member import MemberDialog
-from .wot_tab import WotTabWidget
-from .transfer import TransferMoneyDialog
-from .certification import CertificationDialog
-from . import toast
-import asyncio
-from ..core.net.api import bma as qtbma
-
-
-class CommunityTabWidget(QWidget, Ui_CommunityTabWidget):
-
-    """
-    classdocs
-    """
-
-    def __init__(self, app, account, community, password_asker, parent):
-        """
-        Init
-        :param cutecoin.core.account.Account account: Account instance
-        :param cutecoin.core.community.Community community: Community instance
-        :param cutecoin.gui.password_asker.PasswordAskerDialog password_asker: Password asker dialog
-        :param cutecoin.gui.currency_tab.CurrencyTabWidget parent: TabWidget instance
-        :return:
-        """
-        super().__init__()
-        self.parent = parent
-        self.app = app
-        self.community = community
-        self.account = account
-        self.password_asker = password_asker
-
-        self.setupUi(self)
-
-        identities_model = IdentitiesTableModel(self.community)
-        proxy = IdentitiesFilterProxyModel()
-        proxy.setSourceModel(identities_model)
-        self.table_identities.setModel(proxy)
-        self.table_identities.setSelectionBehavior(QAbstractItemView.SelectRows)
-        self.table_identities.customContextMenuRequested.connect(self.identity_context_menu)
-        self.table_identities.sortByColumn(0, Qt.AscendingOrder)
-        self.table_identities.resizeColumnsToContents()
-
-        self.wot_tab = WotTabWidget(self.app, self.account, self.community, self.password_asker, self)
-        self.tabs_information.addTab(self.wot_tab, QIcon(':/icons/wot_icon'), self.tr("Web of Trust"))
-        members_action = QAction(self.tr("Members"), self)
-        members_action.triggered.connect(self.search_members)
-        self.button_search.addAction(members_action)
-        direct_connections = QAction(self.tr("Direct connections"), self)
-        direct_connections.triggered.connect(self.search_direct_connections)
-        self.button_search.addAction(direct_connections)
-
-        self.account.identity(self.community).inner_data_changed.connect(self.handle_account_identity_change)
-        self.search_direct_connections()
-        self.account.membership_broadcasted.connect(self.handle_membership_broadcasted)
-        self.account.revoke_broadcasted.connect(self.handle_revoke_broadcasted)
-        self.account.selfcert_broadcasted.connect(self.handle_selfcert_broadcasted)
-
-    def handle_membership_broadcasted(self):
-        if self.app.preferences['notifications']:
-            toast.display(self.tr("Membership"), self.tr("Success sending Membership demand"))
-        else:
-            QMessageBox.information(self, self.tr("Membership"), self.tr("Success sending Membership demand"))
-
-    def handle_revoke_broadcasted(self):
-        if self.app.preferences['notifications']:
-            toast.display(self.tr("Revoke"), self.tr("Success sending Revoke demand"))
-        else:
-            QMessageBox.information(self, self.tr("Revoke"), self.tr("Success sending Revoke demand"))
-
-    def handle_selfcert_broadcasted(self):
-        if self.app.preferences['notifications']:
-            toast.display(self.tr("Self Certification"), self.tr("Success sending Self Certification document"))
-        else:
-            QMessageBox.information(self.tr("Self Certification"), self.tr("Success sending Self Certification document"))
-
-    def identity_context_menu(self, point):
-        index = self.table_identities.indexAt(point)
-        model = self.table_identities.model()
-        if index.row() < model.rowCount():
-            source_index = model.mapToSource(index)
-            pubkey_col = model.sourceModel().columns_ids.index('pubkey')
-            pubkey_index = model.sourceModel().index(source_index.row(),
-                                                   pubkey_col)
-            pubkey = model.sourceModel().data(pubkey_index, Qt.DisplayRole)
-            identity = self.app.identities_registry.find(pubkey, self.community)
-            menu = QMenu(self)
-
-            informations = QAction(self.tr("Informations"), self)
-            informations.triggered.connect(self.menu_informations)
-            informations.setData(identity)
-            add_contact = QAction(self.tr("Add as contact"), self)
-            add_contact.triggered.connect(self.menu_add_as_contact)
-            add_contact.setData(identity)
-
-            send_money = QAction(self.tr("Send money"), self)
-            send_money.triggered.connect(self.menu_send_money)
-            send_money.setData(identity)
-
-            certify = QAction(self.tr("Certify identity"), self)
-            certify.triggered.connect(self.menu_certify_member)
-            certify.setData(identity)
-
-            view_wot = QAction(self.tr("View in Web of Trust"), self)
-            view_wot.triggered.connect(self.view_wot)
-            view_wot.setData(identity)
-
-            menu.addAction(informations)
-            menu.addAction(add_contact)
-            menu.addAction(send_money)
-            menu.addAction(certify)
-            menu.addAction(view_wot)
-
-            # Show the context menu.
-            menu.exec_(QCursor.pos())
-
-    def menu_informations(self):
-        person = self.sender().data()
-        self.identity_informations(person)
-
-    def menu_add_as_contact(self):
-        person = self.sender().data()
-        self.add_identity_as_contact({'name': person.uid,
-                                    'pubkey': person.pubkey})
-
-    def menu_send_money(self):
-        person = self.sender().data()
-        self.send_money_to_identity(person)
-
-    def menu_certify_member(self):
-        person = self.sender().data()
-        self.certify_identity(person)
-
-    def identity_informations(self, person):
-        dialog = MemberDialog(self.app, self.account, self.community, person)
-        dialog.exec_()
-
-    def add_identity_as_contact(self, person):
-        dialog = ConfigureContactDialog(self.account, self.window(), person)
-        result = dialog.exec_()
-        if result == QDialog.Accepted:
-            self.window().refresh_contacts()
-
-    def send_money_to_identity(self, person):
-        if isinstance(person, str):
-            pubkey = person
-        else:
-            pubkey = person.pubkey
-        dialog = TransferMoneyDialog(self.app, self.account, self.password_asker)
-        dialog.edit_pubkey.setText(pubkey)
-        dialog.combo_community.setCurrentText(self.community.name)
-        dialog.radio_pubkey.setChecked(True)
-        if dialog.exec_() == QDialog.Accepted:
-            currency_tab = self.window().currencies_tabwidget.currentWidget()
-            currency_tab.tab_history.table_history.model().sourceModel().refresh_transfers()
-
-    def certify_identity(self, identity):
-        dialog = CertificationDialog(self.account, self.app, self.password_asker)
-        dialog.combo_community.setCurrentText(self.community.name)
-        dialog.edit_pubkey.setText(identity.pubkey)
-        dialog.radio_pubkey.setChecked(True)
-        dialog.exec_()
-
-    def view_wot(self):
-        person = self.sender().data()
-        # redraw WoT with this identity selected
-        self.wot_tab.draw_graph({'text': person.uid, 'id': person.pubkey})
-        # change page to WoT
-        index_community_tab = self.parent.tabs_account.indexOf(self)
-        self.parent.tabs_account.setCurrentIndex(index_community_tab)
-        index_wot_tab = self.tabs_information.indexOf(self.wot_tab)
-        self.tabs_information.setCurrentIndex(index_wot_tab)
-
-    @asyncio.coroutine
-    def _execute_search_text(self, text):
-        response = yield from self.community.bma_access.future_request(qtbma.wot.Lookup, {'search': text})
-        identities = []
-        for identity_data in response['results']:
-            identity = yield from self.app.identities_registry.future_find(identity_data['pubkey'], self.community)
-            identities.append(identity)
-
-        self_identity = self.account.identity(self.community)
-        try:
-            self_identity.inner_data_changed.disconnect(self.handle_account_identity_change)
-            self.community.inner_data_changed.disconnect(self.handle_community_change)
-        except TypeError as e:
-            if "disconnect() failed" in str(e):
-                pass
-            else:
-                raise
-
-        self.edit_textsearch.clear()
-        self.refresh_identities(identities)
-
-    def search_text(self):
-        """
-        Search text and display found identities
-        """
-        text = self.edit_textsearch.text()
-
-        if len(text) < 2:
-            return False
-        else:
-            asyncio.async(self._execute_search_text(text))
-
-    @pyqtSlot(str)
-    def handle_community_change(self, origin):
-        logging.debug("Handle account community {0}".format(origin))
-        if origin == qtbma.wot.Members:
-            self.search_members()
-
-    @pyqtSlot(str)
-    def handle_account_identity_change(self, origin):
-        logging.debug("Handle account identity change {0}".format(origin))
-        if origin in (str(qtbma.wot.CertifiedBy), str(qtbma.wot.CertifiersOf)):
-            self.search_direct_connections()
-
-    def search_members(self):
-        """
-        Search members of community and display found members
-        """
-        pubkeys = self.community.members_pubkeys()
-        identities = []
-        for p in pubkeys:
-            identities.append(self.app.identities_registry.find(p, self.community))
-
-        self_identity = self.account.identity(self.community)
-
-        try:
-            self_identity.inner_data_changed.disconnect(self.handle_account_identity_change)
-            self.community.inner_data_changed.connect(self.handle_community_change)
-        except TypeError as e:
-            if "disconnect() failed" in str(e):
-                pass
-            else:
-                raise
-
-        self.edit_textsearch.clear()
-        self.refresh_identities(identities)
-
-    def search_direct_connections(self):
-        """
-        Search members of community and display found members
-        """
-        self_identity = self.account.identity(self.community)
-        try:
-            self.community.inner_data_changed.disconnect(self.handle_community_change)
-            self_identity.inner_data_changed.connect(self.handle_account_identity_change)
-        except TypeError as e:
-            if "disconnect() failed" in str(e):
-                logging.debug("Could not disconnect community")
-            else:
-                raise
-
-        account_connections = []
-        for p in self_identity.unique_valid_certifiers_of(self.app.identities_registry, self.community):
-            account_connections.append(p['identity'])
-        certifiers_of = [p for p in account_connections]
-        for p in self_identity.unique_valid_certified_by(self.app.identities_registry, self.community):
-            account_connections.append(p['identity'])
-        certified_by = [p for p in account_connections
-                  if p.pubkey not in [i.pubkey for i in certifiers_of]]
-        identities = certifiers_of + certified_by
-        self.refresh_identities(identities)
-
-    def refresh_identities(self, identities):
-        """
-        Refresh the table with specified identities.
-        If no identities is passed, use the account connections.
-        """
-        self.table_identities.model().sourceModel().refresh_identities(identities)
-        self.table_identities.resizeColumnsToContents()
-
diff --git a/src/cutecoin/gui/community_tile.py b/src/cutecoin/gui/community_tile.py
new file mode 100644
index 0000000000000000000000000000000000000000..f6c3df18f7769a908f2b29eb1687822975c7cb12
--- /dev/null
+++ b/src/cutecoin/gui/community_tile.py
@@ -0,0 +1,78 @@
+"""
+@author: inso
+"""
+
+from PyQt5.QtWidgets import QFrame, QLabel, QVBoxLayout, QLayout, QPushButton
+from PyQt5.QtGui import QPalette
+from PyQt5.QtCore import QEvent, QSize, pyqtSignal
+from ..tools.decorators import asyncify
+import asyncio
+
+
+class CommunityTile(QFrame):
+    clicked = pyqtSignal()
+
+    def __init__(self, parent, app, community):
+        super().__init__(parent)
+        self.app = app
+        self.community = community
+        self.text_label = QLabel()
+        self.setLayout(QVBoxLayout())
+        self.layout().setSizeConstraint(QLayout.SetFixedSize)
+        self.layout().addWidget(self.text_label)
+        self.setFrameShape(QFrame.StyledPanel)
+        self.setFrameShadow(QFrame.Raised)
+        self.refresh()
+
+    def sizeHint(self):
+        return QSize(250, 250)
+
+    @asyncify
+    @asyncio.coroutine
+    def refresh(self):
+        current_block = yield from self.community.get_block(self.community.network.latest_block_number)
+        members_pubkeys = yield from self.community.members_pubkeys()
+        amount = yield from self.app.current_account.amount(self.community)
+        localized_amount = yield from self.app.current_account.current_ref(amount,
+                                                    self.community, self.app).localized(units=True,
+                                        international_system=self.app.preferences['international_system_of_units'])
+        if current_block['monetaryMass']:
+            localized_monetary_mass = yield from self.app.current_account.current_ref(current_block['monetaryMass'],
+                                                    self.community, self.app).localized(units=True,
+                                        international_system=self.app.preferences['international_system_of_units'])
+        else:
+            localized_monetary_mass = ""
+        status = self.tr("Member") if self.app.current_account.pubkey in members_pubkeys \
+            else self.tr("Non-Member")
+        description = """<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;">{status_label}</span> : {status}</p>
+        <p><span style=" font-weight:600;">{balance_label}</span> : {balance}</p>
+        </body>
+        </html>""".format(currency=self.community.currency,
+                          nb_members=len(members_pubkeys),
+                          members_label=self.tr("members"),
+                          monetary_mass_label=self.tr("Monetary mass"),
+                          monetary_mass=localized_monetary_mass,
+                          status_label=self.tr("Status"),
+                          status=status,
+                          balance_label=self.tr("Balance"),
+                          balance=localized_amount)
+        self.text_label.setText(description)
+
+    def mousePressEvent(self, event):
+        self.clicked.emit()
+        return super().mousePressEvent(event)
+
+    def enterEvent(self, event):
+        self.setStyleSheet("color: rgb(0, 115, 173);")
+        return super().enterEvent(event)
+
+    def leaveEvent(self, event):
+        self.setStyleSheet("")
+        return super().leaveEvent(event)
\ No newline at end of file
diff --git a/src/cutecoin/gui/community_view.py b/src/cutecoin/gui/community_view.py
new file mode 100644
index 0000000000000000000000000000000000000000..39b822482af2c7cf635916942b928a286c1250ed
--- /dev/null
+++ b/src/cutecoin/gui/community_view.py
@@ -0,0 +1,350 @@
+"""
+Created on 2 févr. 2014
+
+@author: inso
+"""
+
+import time
+import logging
+from PyQt5.QtWidgets import QWidget, QMessageBox, QDialog
+from PyQt5.QtCore import QModelIndex, pyqtSlot, QDateTime, QLocale, QEvent
+from PyQt5.QtGui import QIcon
+
+from ..core.net.api import bma as qtbma
+from .wot_tab import WotTabWidget
+from .identities_tab import IdentitiesTabWidget
+from .transactions_tab import TransactionsTabWidget
+from .network_tab import NetworkTabWidget
+from . import toast
+import asyncio
+from ..tools.exceptions import MembershipNotFoundError, LookupFailureError, NoPeerAvailable
+from ..tools.decorators import asyncify, once_at_a_time, cancel_once_task
+from ..gen_resources.community_view_uic import Ui_CommunityWidget
+
+
+class CommunityWidget(QWidget, Ui_CommunityWidget):
+
+    """
+    classdocs
+    """
+
+    def __init__(self, app, status_label):
+        """
+        Constructor
+        """
+        super().__init__()
+        self.app = app
+        self.account = None
+        self.community = None
+        self.password_asker = None
+        self.status_label = status_label
+
+        self.status_info = []
+        self.status_infotext = {'membership_expire_soon':
+                            self.tr("Warning : Your membership is expiring soon."),
+                            'warning_certifications':
+                            self.tr("Warning : Your could miss certifications soon.")
+                            }
+
+        super().setupUi(self)
+
+        self.tab_wot = WotTabWidget(self.app)
+
+        self.tab_identities = IdentitiesTabWidget(self.app)
+
+        self.tab_history = TransactionsTabWidget(self.app)
+
+        self.tab_network = NetworkTabWidget(self.app)
+        self.tab_identities.view_in_wot.connect(self.tab_wot.draw_graph)
+        self.tab_identities.view_in_wot.connect(lambda: self.tabs.setCurrentWidget(self.tab_wot))
+        self.tab_history.view_in_wot.connect(self.tab_wot.draw_graph)
+        self.tab_history.view_in_wot.connect(lambda: self.tabs.setCurrentWidget(self.tab_wot))
+
+        self.tabs.addTab(self.tab_history,
+                                 QIcon(':/icons/tx_icon'),
+                                self.tr("Transactions"))
+
+        self.tabs.addTab(self.tab_wot,
+                         QIcon(':/icons/wot_icon'),
+                         self.tr("Web of Trust"))
+
+        self.tabs.addTab(self.tab_identities,
+                         QIcon(':/icons/members_icon'),
+                         self.tr("Search Identities"))
+
+        self.tabs.addTab(self.tab_network,
+                                 QIcon(":/icons/network_icon"),
+                                 self.tr("Network"))
+
+        self.button_membership.clicked.connect(self.send_membership_demand)
+
+    def cancel_once_tasks(self):
+        cancel_once_task(self, self.refresh_block)
+        cancel_once_task(self, self.refresh_status)
+        cancel_once_task(self, self.refresh_quality_buttons)
+
+    def change_account(self, account, password_asker):
+        self.cancel_once_tasks()
+        if self.account:
+            self.account.broadcast_error.disconnect(self.handle_broadcast_error)
+            self.account.membership_broadcasted.disconnect(self.handle_membership_broadcasted)
+            self.account.selfcert_broadcasted.disconnect(self.handle_selfcert_broadcasted)
+
+        self.account = account
+
+        if self.account:
+            self.account.broadcast_error.connect(self.handle_broadcast_error)
+            self.account.membership_broadcasted.connect(self.handle_membership_broadcasted)
+            self.account.selfcert_broadcasted.connect(self.handle_selfcert_broadcasted)
+
+        self.password_asker = password_asker
+        self.tab_wot.change_account(account, self.password_asker)
+        self.tab_identities.change_account(account, self.password_asker)
+        self.tab_history.change_account(account, self.password_asker)
+
+    def change_community(self, community):
+        self.cancel_once_tasks()
+
+        self.tab_network.change_community(community)
+        self.tab_wot.change_community(community)
+        self.tab_history.change_community(community)
+        self.tab_identities.change_community(community)
+
+        if self.community:
+            self.community.network.new_block_mined.disconnect(self.refresh_block)
+            self.community.network.nodes_changed.disconnect(self.refresh_status)
+        if community:
+            community.network.new_block_mined.connect(self.refresh_block)
+            community.network.nodes_changed.connect(self.refresh_status)
+            self.label_currency.setText(community.currency)
+        self.community = community
+        self.refresh_quality_buttons()
+
+    @pyqtSlot(str)
+    def display_error(self, error):
+        QMessageBox.critical(self, ":(",
+                    error,
+                    QMessageBox.Ok)
+
+    @once_at_a_time
+    @asyncify
+    @asyncio.coroutine
+    def refresh_block(self, block_number):
+        """
+        When a new block is found, start handling data.
+        @param: block_number: The number of the block mined
+        """
+        logging.debug("Refresh block")
+        self.status_info.clear()
+        try:
+            person = yield from self.app.identities_registry.future_find(self.app.current_account.pubkey, self.community)
+            expiration_time = yield from person.membership_expiration_time(self.community)
+            parameters = yield from self.community.parameters()
+            sig_validity = parameters['sigValidity']
+            warning_expiration_time = int(sig_validity / 3)
+            will_expire_soon = (expiration_time < warning_expiration_time)
+
+            logging.debug("Try")
+            if will_expire_soon:
+                days = int(expiration_time / 3600 / 24)
+                if days > 0:
+                    self.status_info.append('membership_expire_soon')
+
+                    if self.app.preferences['notifications']:
+                        toast.display(self.tr("Membership expiration"),
+                                  self.tr("<b>Warning : Membership expiration in {0} days</b>").format(days))
+
+            certifiers_of = yield from person.unique_valid_certifiers_of(self.app.identities_registry,
+                                                                         self.community)
+            if len(certifiers_of) < parameters['sigQty']:
+                self.status_info.append('warning_certifications')
+                if self.app.preferences['notifications']:
+                    toast.display(self.tr("Certifications number"),
+                              self.tr("<b>Warning : You are certified by only {0} persons, need {1}</b>")
+                              .format(len(certifiers_of),
+                                     parameters['sigQty']))
+
+        except MembershipNotFoundError as e:
+            pass
+
+        self.tab_history.start_progress()
+        self.refresh_data()
+
+    def refresh_data(self):
+        """
+        Refresh data
+        """
+        self.tab_history.refresh_balance()
+        self.refresh_status()
+
+    @once_at_a_time
+    @asyncify
+    @asyncio.coroutine
+    def refresh_status(self):
+        """
+        Refresh status bar
+        """
+        logging.debug("Refresh status")
+        if self.community:
+            text = self.tr(" Block {0}").format(self.community.network.latest_block_number)
+
+            block = yield from self.community.get_block(self.community.network.latest_block_number)
+            if block != qtbma.blockchain.Block.null_value:
+                text += " ( {0} )".format(QLocale.toString(
+                            QLocale(),
+                            QDateTime.fromTime_t(block['medianTime']),
+                            QLocale.dateTimeFormat(QLocale(), QLocale.NarrowFormat)
+                        ))
+
+            if self.community.network.quality > 0.66:
+                icon = '<img src=":/icons/connected" width="12" height="12"/>'
+            elif self.community.network.quality > 0.33:
+                icon = '<img src=":/icons/weak_connect" width="12" height="12"/>'
+            else:
+                icon = '<img src=":/icons/disconnected" width="12" height="12"/>'
+            status_infotext = " - ".join([self.status_infotext[info] for info in self.status_info])
+            label_text = "{0}{1}".format(icon, text)
+            if status_infotext != "":
+                label_text += " - {0}".format(status_infotext)
+
+            if self.app.preferences['expert_mode']:
+                label_text += self.tr(" - Median fork window : {0}").format(self.community.network.fork_window(self.community.members_pubkeys()))
+
+            self.status_label.setText(label_text)
+
+    @once_at_a_time
+    @asyncify
+    @asyncio.coroutine
+    def refresh_quality_buttons(self):
+        if self.account and self.community:
+            try:
+                account_identity = yield from self.account.identity(self.community)
+                published_uid = account_identity.published_uid(self.community)
+                if published_uid:
+                    logging.debug("UID Published")
+                    is_member = account_identity.is_member(self.community)
+                    if is_member:
+                        self.button_membership.setText(self.tr("Renew membership"))
+                        self.button_membership.show()
+                        self.button_certification.show()
+                    else:
+                        logging.debug("Not a member")
+                        self.button_membership.setText(self.tr("Send membership demand"))
+                        self.button_membership.show()
+                        if self.community.get_block(0) != qtbma.blockchain.Block.null_value:
+                            self.button_certification.hide()
+                else:
+                    logging.debug("UID not published")
+                    self.button_membership.hide()
+                    self.button_certification.hide()
+            except LookupFailureError:
+                self.button_membership.hide()
+                self.button_certification.hide()
+
+    def showEvent(self, event):
+        self.refresh_status()
+
+    def referential_changed(self):
+        if self.community and self.tab_history.table_history.model():
+            self.tab_history.table_history.model().sourceModel().refresh_transfers()
+            self.tab_history.refresh_balance()
+
+    def send_membership_demand(self):
+        password = self.password_asker.exec_()
+        if self.password_asker.result() == QDialog.Rejected:
+            return
+        asyncio.async(self.account.send_membership(password, self.community, 'IN'))
+
+    def send_membership_leaving(self):
+        reply = QMessageBox.warning(self, self.tr("Warning"),
+                             self.tr("""Are you sure ?
+Sending a leaving demand  cannot be canceled.
+The process to join back the community later will have to be done again.""")
+.format(self.account.pubkey), QMessageBox.Ok | QMessageBox.Cancel)
+        if reply == QMessageBox.Ok:
+            password = self.password_asker.exec_()
+            if self.password_asker.result() == QDialog.Rejected:
+                return
+
+            asyncio.async(self.account.send_membership(password, self.community, 'OUT'))
+
+    def publish_uid(self):
+        reply = QMessageBox.warning(self, self.tr("Warning"),
+                             self.tr("""Are you sure ?
+Publishing your UID can be canceled by Revoke UID.""")
+.format(self.account.pubkey), QMessageBox.Ok | QMessageBox.Cancel)
+        if reply == QMessageBox.Ok:
+            password = self.password_asker.exec_()
+            if self.password_asker.result() == QDialog.Rejected:
+                return
+
+            try:
+                self.account.send_selfcert(password, self.community)
+                toast.display(self.tr("UID Publishing"),
+                              self.tr("Success publishing your UID"))
+            except ValueError as e:
+                QMessageBox.critical(self, self.tr("Publish UID error"),
+                                  str(e))
+            except NoPeerAvailable as e:
+                QMessageBox.critical(self, self.tr("Network error"),
+                                     self.tr("Couldn't connect to network : {0}").format(e),
+                                     QMessageBox.Ok)
+            except Exception as e:
+                 QMessageBox.critical(self, self.tr("Error"),
+                                      "{0}".format(e),
+                                      QMessageBox.Ok)
+
+    def revoke_uid(self):
+        reply = QMessageBox.warning(self, self.tr("Warning"),
+                                 self.tr("""Are you sure ?
+Revoking your UID can only success if it is not already validated by the network.""")
+.format(self.account.pubkey), QMessageBox.Ok | QMessageBox.Cancel)
+        if reply == QMessageBox.Ok:
+            password = self.password_asker.exec_()
+            if self.password_asker.result() == QDialog.Rejected:
+                return
+
+            asyncio.async(self.account.revoke(password, self.community))
+
+    def handle_membership_broadcasted(self):
+        if self.app.preferences['notifications']:
+            toast.display(self.tr("Membership"), self.tr("Success sending Membership demand"))
+        else:
+            QMessageBox.information(self, self.tr("Membership"), self.tr("Success sending Membership demand"))
+
+    def handle_revoke_broadcasted(self):
+        if self.app.preferences['notifications']:
+            toast.display(self.tr("Revoke"), self.tr("Success sending Revoke demand"))
+        else:
+            QMessageBox.information(self, self.tr("Revoke"), self.tr("Success sending Revoke demand"))
+
+    def handle_selfcert_broadcasted(self):
+        if self.app.preferences['notifications']:
+            toast.display(self.tr("Self Certification"), self.tr("Success sending Self Certification document"))
+        else:
+            QMessageBox.information(self.tr("Self Certification"), self.tr("Success sending Self Certification document"))
+
+    def handle_broadcast_error(self, error, strdata):
+        if self.app.preferences['notifications']:
+            toast.display(error, strdata)
+        else:
+            QMessageBox.error(error, strdata)
+
+    def showEvent(self, QShowEvent):
+        """
+
+        :param QShowEvent:
+        :return:
+        """
+        self.refresh_status()
+
+    def changeEvent(self, event):
+        """
+        Intercepte LanguageChange event to translate UI
+        :param QEvent QEvent: Event
+        :return:
+        """
+        if event.type() == QEvent.LanguageChange:
+            self.retranslateUi(self)
+            self.refresh_status()
+        return super(CommunityWidget, self).changeEvent(event)
diff --git a/src/cutecoin/gui/contact.py b/src/cutecoin/gui/contact.py
index 8e26de9708940be7b1212853d6e42f004d327564..bc6f550e84995a28f26d5a1c9fbd9a3817c2f721 100644
--- a/src/cutecoin/gui/contact.py
+++ b/src/cutecoin/gui/contact.py
@@ -27,13 +27,7 @@ class ConfigureContactDialog(QDialog, Ui_ConfigureContactDialog):
         self.account = account
         self.main_window = parent
         self.index_edit = index_edit
-        if type(contact) is Person:
-            self.contact = {'name': contact.uid,
-                            'pubkey': contact.pubkey}
-        elif type(contact) is dict:
-            self.contact = contact
-        else:
-            self.contact = None
+        self.contact = contact
 
         if index_edit is not None:
             self.contact = account.contacts[index_edit]
diff --git a/src/cutecoin/gui/currency_tab.py b/src/cutecoin/gui/currency_tab.py
deleted file mode 100644
index 4767d36d205c48eaea236956685e707c1699c49e..0000000000000000000000000000000000000000
--- a/src/cutecoin/gui/currency_tab.py
+++ /dev/null
@@ -1,204 +0,0 @@
-"""
-Created on 2 févr. 2014
-
-@author: inso
-"""
-
-import time
-import logging
-from PyQt5.QtWidgets import QWidget, QMessageBox
-from PyQt5.QtCore import QModelIndex, pyqtSlot, QDateTime, QLocale
-from PyQt5.QtGui import QIcon
-from ..gen_resources.currency_tab_uic import Ui_CurrencyTabWidget
-
-from ..core.net.api import bma as qtbma
-from .community_tab import CommunityTabWidget
-from .wallets_tab import WalletsTabWidget
-from .transactions_tab import TransactionsTabWidget
-from .network_tab import NetworkTabWidget
-from .informations_tab import InformationsTabWidget
-from . import toast
-import asyncio
-from ..tools.exceptions import MembershipNotFoundError
-from ..core.registry import IdentitiesRegistry
-
-
-class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget):
-
-    """
-    classdocs
-    """
-
-    def __init__(self, app, community, password_asker, status_label):
-        """
-        Constructor
-        """
-        super().__init__()
-        self.app = app
-        self.community = community
-        self.password_asker = password_asker
-        self.status_label = status_label
-
-        self.status_info = []
-        self.status_infotext = {'membership_expire_soon':
-                            self.tr("Warning : Your membership is expiring soon."),
-                            'warning_certifications':
-                            self.tr("Warning : Your could miss certifications soon.")
-                            }
-
-        super().setupUi(self)
-
-        self.tab_community = CommunityTabWidget(self.app,
-                                                self.app.current_account,
-                                                    self.community,
-                                                    self.password_asker,
-                                                    self)
-
-        self.tab_wallets = WalletsTabWidget(self.app,
-                                            self.app.current_account,
-                                            self.community,
-                                            self.password_asker)
-
-        self.tab_history = TransactionsTabWidget(self.app,
-                                                 self.community,
-                                                 self.password_asker,
-                                                 self)
-
-        self.tab_informations = InformationsTabWidget(self.app,
-                                                self.community)
-
-        self.tab_network = NetworkTabWidget(self.app,
-                                            self.community)
-
-        self.tabs_account.addTab(self.tab_wallets,
-                                 QIcon(':/icons/wallet_icon'),
-                                self.tr("Wallets"))
-
-        self.tabs_account.addTab(self.tab_history,
-                                 QIcon(':/icons/tx_icon'),
-                                self.tr("Transactions"))
-
-        self.tabs_account.addTab(self.tab_community,
-                                 QIcon(':/icons/community_icon'),
-                                self.tr("Community"))
-
-        self.tabs_account.addTab(self.tab_network,
-                                 QIcon(":/icons/network_icon"),
-                                 self.tr("Network"))
-
-        self.tabs_account.addTab(self.tab_informations,
-                                 QIcon(':/icons/informations_icon'),
-                                 self.tr("Informations"))
-
-        self.community.network.new_block_mined.connect(self.refresh_block)
-        self.community.network.nodes_changed.connect(self.refresh_status)
-        self.community.inner_data_changed.connect(self.refresh_status)
-
-    @pyqtSlot(str)
-    def display_error(self, error):
-        QMessageBox.critical(self, ":(",
-                    error,
-                    QMessageBox.Ok)
-
-    @pyqtSlot(int)
-    def refresh_block(self, block_number):
-        """
-        When a new block is found, start handling data.
-        @param: block_number: The number of the block mined
-        """
-        logging.debug("Refresh block")
-        self.status_info.clear()
-        try:
-            person = self.app.identities_registry.find(self.app.current_account.pubkey, self.community)
-            expiration_time = person.membership_expiration_time(self.community)
-            sig_validity = self.community.parameters['sigValidity']
-            warning_expiration_time = int(sig_validity / 3)
-            will_expire_soon = (expiration_time < warning_expiration_time)
-
-            logging.debug("Try")
-            if will_expire_soon:
-                days = int(expiration_time / 3600 / 24)
-                if days > 0:
-                    self.status_info.append('membership_expire_soon')
-
-                    if self.app.preferences['notifications']:
-                        toast.display(self.tr("Membership expiration"),
-                                  self.tr("<b>Warning : Membership expiration in {0} days</b>").format(days))
-
-            certifiers_of = person.unique_valid_certifiers_of(self.app.identities_registry, self.community)
-            if len(certifiers_of) < self.community.parameters['sigQty']:
-                self.status_info.append('warning_certifications')
-                if self.app.preferences['notifications']:
-                    toast.display(self.tr("Certifications number"),
-                              self.tr("<b>Warning : You are certified by only {0} persons, need {1}</b>")
-                              .format(len(certifiers_of),
-                                     self.community.parameters['sigQty']))
-
-        except MembershipNotFoundError as e:
-            pass
-
-        self.tab_history.start_progress()
-        self.refresh_data()
-
-    def refresh_wallets(self):
-        if self.tab_wallets:
-            self.tab_wallets.refresh()
-
-    def refresh_data(self):
-        """
-        Refresh data when the blockchain watcher finished handling datas
-        """
-        if self.tab_wallets:
-            self.tab_wallets.refresh()
-
-        self.tab_history.refresh_balance()
-        self.refresh_status()
-
-    @pyqtSlot()
-    def refresh_status(self):
-        """
-        Refresh status bar
-        """
-        logging.debug("Refresh status")
-        text = self.tr(" Block {0}").format(self.community.network.latest_block_number)
-
-        block = self.community.get_block(self.community.network.latest_block_number)
-        if block != qtbma.blockchain.Block.null_value:
-            text += " ( {0} )".format(QLocale.toString(
-                        QLocale(),
-                        QDateTime.fromTime_t(block['medianTime']),
-                        QLocale.dateTimeFormat(QLocale(), QLocale.NarrowFormat)
-                    ))
-
-        if self.community.network.quality > 0.66:
-            icon = '<img src=":/icons/connected" width="12" height="12"/>'
-        elif self.community.network.quality > 0.33:
-            icon = '<img src=":/icons/weak_connect" width="12" height="12"/>'
-        else:
-            icon = '<img src=":/icons/disconnected" width="12" height="12"/>'
-        status_infotext = " - ".join([self.status_infotext[info] for info in self.status_info])
-        label_text = "{0}{1}".format(icon, text)
-        if status_infotext != "":
-            label_text += " - {0}".format(status_infotext)
-
-        if self.app.preferences['expert_mode']:
-            label_text += self.tr(" - Median fork window : {0}").format(self.community.network.fork_window(self.community.members_pubkeys()))
-
-        self.status_label.setText(label_text)
-
-    def showEvent(self, event):
-        self.refresh_status()
-
-    def referential_changed(self):
-        if self.tab_history.table_history.model():
-            self.tab_history.table_history.model().dataChanged.emit(
-                                                     QModelIndex(),
-                                                     QModelIndex(),
-                                                     [])
-            self.tab_history.refresh_balance()
-
-        if self.tab_wallets:
-            self.tab_wallets.refresh()
-
-        if self.tab_informations:
-            self.tab_informations.refresh()
diff --git a/src/cutecoin/gui/homescreen.py b/src/cutecoin/gui/homescreen.py
index 15ffa516e54578667eb2fee82e557d663b13b27c..85f21a1671999dc048c77dea6bfd764be1cb4474 100644
--- a/src/cutecoin/gui/homescreen.py
+++ b/src/cutecoin/gui/homescreen.py
@@ -4,42 +4,96 @@ Created on 31 janv. 2015
 @author: vit
 """
 
-from PyQt5.QtWidgets import QWidget
-from ..gen_resources.homescreen_uic import Ui_HomeScreenWidget
-from ..__init__ import __version__
-from . import toast
+from PyQt5.QtWidgets import QWidget, QFrame, QGridLayout, QAction
+from PyQt5.QtCore import QEvent, Qt, pyqtSlot, pyqtSignal
+from ..gen_resources.homescreen_uic import Ui_HomescreenWidget
+from .community_tile import CommunityTile
+from ..core.community import Community
+import logging
 
 
-class HomeScreenWidget(QWidget, Ui_HomeScreenWidget):
+class FrameCommunities(QFrame):
+    community_tile_clicked = pyqtSignal(Community)
+
+    def __init__(self, parent):
+        super().__init__(parent)
+        self.grid_layout = QGridLayout()
+        self.setLayout(self.grid_layout)
+        self.grid_layout.setAlignment(Qt.AlignLeft | Qt.AlignTop)
+        self.setFrameShape(QFrame.StyledPanel)
+        self.setFrameShadow(QFrame.Raised)
+        self.tiles = []
+
+    def sizeHint(self):
+        return self.parentWidget().size()
+
+    def refresh(self, app):
+        for t in self.tiles:
+            t.setParent(None)
+        self.tiles = []
+        if app.current_account:
+            for c in app.current_account.communities:
+                community_tile = CommunityTile(self, app, c)
+                community_tile.clicked.connect(self.click_on_tile)
+                self.layout().addWidget(community_tile)
+                self.tiles.append(community_tile)
+
+    def refresh_content(self):
+        for t in self.tiles:
+            t.refresh()
+
+    @pyqtSlot()
+    def click_on_tile(self):
+        tile = self.sender()
+        logging.debug("Click on tile")
+        self.community_tile_clicked.emit(tile.community)
+
+
+class HomeScreenWidget(QWidget, Ui_HomescreenWidget):
     """
     classdocs
     """
 
-    def __init__(self, app):
+    def __init__(self, app, status_label):
         """
         Constructor
         """
         super().__init__()
         self.setupUi(self)
         self.app = app
-        self.refresh_text()
-        self.app.version_requested.connect(self.refresh_text)
-
-    def refresh_text(self):
-        latest = self.app.available_version
-        version_info = ""
-        version_url = ""
-        if not latest[0]:
-            version_info = self.tr("Please get the latest release {version}") \
-                            .format(version=latest[1])
-            version_url = latest[2]
-
-        self.label_welcome.setText(
-            self.tr("""
-            <h1>Welcome to Cutecoin {version}</h1>
-            <h2>{version_info}</h2>
-            <h3><a href={version_url}>Download link</a></h3>
-            """).format(version=latest[1],
-                       version_info=version_info,
-                       version_url=version_url))
+        self.frame_communities = FrameCommunities(self)
+        self.layout().addWidget(self.frame_communities)
+        self.status_label = status_label
+
+    def refresh(self):
+        self.frame_communities.refresh(self.app)
+        if self.app.current_account:
+            self.frame_connected.show()
+            self.label_connected.setText(self.tr("Connected as {0}".format(self.app.current_account.name)))
+            self.frame_disconnected.hide()
+        else:
+            self.frame_disconnected.show()
+            self.frame_connected.hide()
+
+    def referential_changed(self):
+        self.frame_communities.refresh_content()
+
+    def showEvent(self, QShowEvent):
+        """
+
+        :param QShowEvent:
+        :return:
+        """
+        self.status_label.setText("")
+
+    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(HomeScreenWidget, self).changeEvent(event)
+
 
diff --git a/src/cutecoin/gui/identities_tab.py b/src/cutecoin/gui/identities_tab.py
new file mode 100644
index 0000000000000000000000000000000000000000..d8b40b4a70b6483e7457b0d95228f770b9b84d14
--- /dev/null
+++ b/src/cutecoin/gui/identities_tab.py
@@ -0,0 +1,244 @@
+"""
+Created on 2 févr. 2014
+
+@author: inso
+"""
+
+import logging
+from PyQt5.QtCore import Qt, pyqtSignal, QEvent
+from PyQt5.QtGui import QIcon, QCursor
+from PyQt5.QtWidgets import QWidget, QMessageBox, QAction, QMenu, QDialog, \
+                            QAbstractItemView
+from ..models.identities import IdentitiesFilterProxyModel, IdentitiesTableModel
+from ..gen_resources.identities_tab_uic import Ui_IdentitiesTab
+from .contact import ConfigureContactDialog
+from .member import MemberDialog
+from .transfer import TransferMoneyDialog
+from .certification import CertificationDialog
+import asyncio
+from ..core.net.api import bma as qtbma
+from ..core.registry import Identity
+from ..tools.decorators import asyncify, once_at_a_time, cancel_once_task
+
+
+class IdentitiesTabWidget(QWidget, Ui_IdentitiesTab):
+
+    """
+    classdocs
+    """
+    view_in_wot = pyqtSignal(Identity)
+
+    def __init__(self, app):
+        """
+        Init
+        :param cutecoin.core.account.Account account: Account instance
+        :param cutecoin.core.community.Community community: Community instance
+        :param cutecoin.gui.password_asker.PasswordAskerDialog password_asker: Password asker dialog
+        :return:
+        """
+        super().__init__()
+        self.app = app
+        self.community = None
+        self.account = None
+        self.password_asker = None
+
+        self.setupUi(self)
+
+        identities_model = IdentitiesTableModel(self.community)
+        proxy = IdentitiesFilterProxyModel()
+        proxy.setSourceModel(identities_model)
+        self.table_identities.setModel(proxy)
+        self.table_identities.setSelectionBehavior(QAbstractItemView.SelectRows)
+        self.table_identities.customContextMenuRequested.connect(self.identity_context_menu)
+        self.table_identities.sortByColumn(0, Qt.AscendingOrder)
+        self.table_identities.resizeColumnsToContents()
+
+        members_action = QAction(self.tr("Members"), self)
+        members_action.triggered.connect(self._async_search_members)
+        self.button_search.addAction(members_action)
+        direct_connections = QAction(self.tr("Direct connections"), self)
+        direct_connections.triggered.connect(self._async_search_direct_connections)
+        self.button_search.addAction(direct_connections)
+        self.button_search.clicked.connect(self._async_execute_search_text)
+
+    def cancel_once_tasks(self):
+        cancel_once_task(self, self.identity_context_menu)
+        cancel_once_task(self, self._async_execute_search_text)
+        cancel_once_task(self, self._async_search_members)
+        cancel_once_task(self, self._async_search_direct_connections)
+
+    def change_account(self, account, password_asker):
+        self.cancel_once_tasks()
+        self.account = account
+        self.password_asker = password_asker
+        if self.account is None:
+            self.community = None
+
+    def change_community(self, community):
+        self.cancel_once_tasks()
+        self.community = community
+        self.table_identities.model().change_community(community)
+        self._async_search_direct_connections()
+
+    @once_at_a_time
+    @asyncify
+    @asyncio.coroutine
+    def identity_context_menu(self, point):
+        index = self.table_identities.indexAt(point)
+        model = self.table_identities.model()
+        if index.row() < model.rowCount():
+            source_index = model.mapToSource(index)
+            pubkey_col = model.sourceModel().columns_ids.index('pubkey')
+            pubkey_index = model.sourceModel().index(source_index.row(),
+                                                   pubkey_col)
+            pubkey = model.sourceModel().data(pubkey_index, Qt.DisplayRole)
+            identity = yield from self.app.identities_registry.future_find(pubkey, self.community)
+            menu = QMenu(self)
+
+            informations = QAction(self.tr("Informations"), self)
+            informations.triggered.connect(self.menu_informations)
+            informations.setData(identity)
+            add_contact = QAction(self.tr("Add as contact"), self)
+            add_contact.triggered.connect(self.menu_add_as_contact)
+            add_contact.setData(identity)
+
+            send_money = QAction(self.tr("Send money"), self)
+            send_money.triggered.connect(self.menu_send_money)
+            send_money.setData(identity)
+
+            certify = QAction(self.tr("Certify identity"), self)
+            certify.triggered.connect(self.menu_certify_member)
+            certify.setData(identity)
+
+            view_wot = QAction(self.tr("View in Web of Trust"), self)
+            view_wot.triggered.connect(self.view_wot)
+            view_wot.setData(identity)
+
+            menu.addAction(informations)
+            menu.addAction(add_contact)
+            menu.addAction(send_money)
+            menu.addAction(certify)
+            menu.addAction(view_wot)
+
+            # Show the context menu.
+            menu.popup(QCursor.pos())
+
+    def menu_informations(self):
+        person = self.sender().data()
+        self.identity_informations(person)
+
+    def menu_add_as_contact(self):
+        person = self.sender().data()
+        self.add_identity_as_contact({'name': person.uid,
+                                    'pubkey': person.pubkey})
+
+    def menu_send_money(self):
+        person = self.sender().data()
+        self.send_money_to_identity(person)
+
+    def menu_certify_member(self):
+        person = self.sender().data()
+        self.certify_identity(person)
+
+    def identity_informations(self, person):
+        dialog = MemberDialog(self.app, self.account, self.community, person)
+        dialog.exec_()
+
+    def add_identity_as_contact(self, person):
+        dialog = ConfigureContactDialog(self.account, self.window(), person)
+        result = dialog.exec_()
+        if result == QDialog.Accepted:
+            self.window().refresh_contacts()
+
+    def send_money_to_identity(self, identity):
+        if isinstance(identity, str):
+            pubkey = identity
+        else:
+            pubkey = identity.pubkey
+        result = TransferMoneyDialog.send_money_to_identity(self.app, self.account, self.password_asker,
+                                                            self.community, identity)
+        if result == QDialog.Accepted:
+            currency_tab = self.window().currencies_tabwidget.currentWidget()
+            currency_tab.tab_history.table_history.model().sourceModel().refresh_transfers()
+
+    def certify_identity(self, identity):
+        CertificationDialog.certify_identity(self.app, self.account, self.password_asker,
+                                             self.community, identity)
+
+    def view_wot(self):
+        identity = self.sender().data()
+        self.view_in_wot.emit(identity)
+
+    @once_at_a_time
+    @asyncify
+    @asyncio.coroutine
+    def _async_execute_search_text(self, checked):
+        text = self.edit_textsearch.text()
+        if len(text) < 2:
+            return
+        response = yield from self.community.bma_access.future_request(qtbma.wot.Lookup, {'search': text})
+        identities = []
+        for identity_data in response['results']:
+            identity = yield from self.app.identities_registry.future_find(identity_data['pubkey'], self.community)
+            identities.append(identity)
+
+        self.edit_textsearch.clear()
+        self.refresh_identities(identities)
+
+    @once_at_a_time
+    @asyncify
+    @asyncio.coroutine
+    def _async_search_members(self, checked=False):
+        """
+        Search members of community and display found members
+        """
+        if self.community:
+            pubkeys = yield from self.community.members_pubkeys()
+            identities = []
+            for p in pubkeys:
+                identity = yield from self.app.identities_registry.future_find(p, self.community)
+                identities.append(identity)
+
+            self.edit_textsearch.clear()
+            self.refresh_identities(identities)
+
+    @once_at_a_time
+    @asyncify
+    @asyncio.coroutine
+    def _async_search_direct_connections(self, checked=False):
+        """
+        Search members of community and display found members
+        """
+        if self.account and self.community:
+            self_identity = yield from self.account.identity(self.community)
+            account_connections = []
+            certs_of = yield from self_identity.unique_valid_certifiers_of(self.app.identities_registry, self.community)
+            for p in certs_of:
+                account_connections.append(p['identity'])
+            certifiers_of = [p for p in account_connections]
+            certs_by = yield from self_identity.unique_valid_certified_by(self.app.identities_registry, self.community)
+            for p in certs_by:
+                account_connections.append(p['identity'])
+            certified_by = [p for p in account_connections
+                      if p.pubkey not in [i.pubkey for i in certifiers_of]]
+            identities = certifiers_of + certified_by
+            self.refresh_identities(identities)
+
+    def refresh_identities(self, identities):
+        """
+        Refresh the table with specified identities.
+        If no identities is passed, use the account connections.
+        """
+        self.table_identities.model().sourceModel().refresh_identities(identities)
+        self.table_identities.resizeColumnsToContents()
+
+    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(IdentitiesTabWidget, self).changeEvent(event)
+
diff --git a/src/cutecoin/gui/informations_tab.py b/src/cutecoin/gui/informations_tab.py
index 5d494e1a5b03de02d45c955ec3f139c9bd9f2b8d..6826e8b6a17eedd45f54df1d0812d4670bea6b19 100644
--- a/src/cutecoin/gui/informations_tab.py
+++ b/src/cutecoin/gui/informations_tab.py
@@ -6,7 +6,7 @@ Created on 31 janv. 2015
 
 import logging
 import math
-from PyQt5.QtCore import QLocale, QDateTime
+from PyQt5.QtCore import QLocale, QDateTime, QEvent
 from PyQt5.QtWidgets import QWidget
 from ..gen_resources.informations_tab_uic import Ui_InformationsTabWidget
 
@@ -65,7 +65,7 @@ class InformationsTabWidget(QWidget, Ui_InformationsTabWidget):
                                                     self.community, self.app).diff_localized()
 
             localized_mass = self.account.current_ref(block_ud['monetaryMass'],
-                                                    self.community, self.app)
+                                                    self.community, self.app).diff_localized()
             if block_ud_minus_1:
                 mass_minus_1 = (float(0) if block_ud['membersCount'] == 0 else
                         block_ud_minus_1['monetaryMass'] / block_ud['membersCount'])
@@ -218,3 +218,14 @@ class InformationsTabWidget(QWidget, Ui_InformationsTabWidget):
                 self.tr('Maximum distance between each WoT member and a newcomer'),
             )
         )
+
+    def changeEvent(self, event):
+        """
+        Intercepte LanguageChange event to translate UI
+        :param QEvent QEvent: Event
+        :return:
+        """
+        if event.type() == QEvent.LanguageChange:
+            self.retranslateUi(self)
+            self.refresh()
+        return super(InformationsTabWidget, self).changeEvent(event)
diff --git a/src/cutecoin/gui/mainwindow.py b/src/cutecoin/gui/mainwindow.py
index a893c9dbe819e0e0ab88618d6a53ba1df6e856e2..9a716c1698c91c0ecde31ac74afb6842cabdee7e 100644
--- a/src/cutecoin/gui/mainwindow.py
+++ b/src/cutecoin/gui/mainwindow.py
@@ -8,23 +8,27 @@ from ..gen_resources.about_uic import Ui_AboutPopup
 
 from PyQt5.QtWidgets import QMainWindow, QAction, QFileDialog, QProgressBar, \
     QMessageBox, QLabel, QComboBox, QDialog, QApplication
-from PyQt5.QtCore import QSignalMapper, QObject, QLocale, \
+from PyQt5.QtCore import QSignalMapper, pyqtSlot, QLocale, QEvent, \
     pyqtSlot, pyqtSignal, QDate, QDateTime, QTimer, QUrl, Qt, QCoreApplication
 from PyQt5.QtGui import QIcon, QDesktopServices
 
 from .process_cfg_account import ProcessConfigureAccount
 from .transfer import TransferMoneyDialog
-from .currency_tab import CurrencyTabWidget
+from .community_view import CommunityWidget
 from .contact import ConfigureContactDialog
 from .import_account import ImportAccountDialog
 from .certification import CertificationDialog
 from .password_asker import PasswordAskerDialog
 from .preferences import PreferencesDialog
+from .process_cfg_community import ProcessConfigureCommunity
 from .homescreen import HomeScreenWidget
 from ..core import money
+from ..core.community import Community
+from ..tools.decorators import asyncify
 from ..__init__ import __version__
 from . import toast
 
+import asyncio
 import logging
 
 
@@ -64,12 +68,21 @@ class MainWindow(QMainWindow, Ui_MainWindow):
         self.combo_referential.currentIndexChanged.connect(self.referential_changed)
         self.statusbar.addPermanentWidget(self.combo_referential)
 
-        self.homescreen = HomeScreenWidget(self.app)
+        self.homescreen = HomeScreenWidget(self.app, self.status_label)
+        self.homescreen.frame_communities.community_tile_clicked.connect(self.change_community)
+        self.homescreen.toolbutton_new_account.clicked.connect(self.open_add_account_dialog)
+        self.homescreen.toolbutton_new_account.addAction(self.action_add_account)
+        self.homescreen.toolbutton_new_account.addAction(self.action_import)
+        self.homescreen.button_add_community.clicked.connect(self.action_open_add_community)
+        self.homescreen.button_disconnect.clicked.connect(lambda :self.action_change_account(""))
         self.centralWidget().layout().addWidget(self.homescreen)
-        self.homescreen.button_new.clicked.connect(self.open_add_account_dialog)
-        self.homescreen.button_import.clicked.connect(self.import_account)
-        self.open_ucoin_info = lambda: QDesktopServices.openUrl(QUrl("http://ucoin.io/theoretical/"))
-        self.homescreen.button_info.clicked.connect(self.open_ucoin_info)
+        self.homescreen.toolbutton_connect.setMenu(self.menu_change_account)
+
+        self.community_view = CommunityWidget(self.app, self.status_label)
+        self.community_view.button_home.clicked.connect(lambda: self.change_community(None))
+        self.community_view.button_certification.clicked.connect(self.open_certification_dialog)
+        self.community_view.button_send_money.clicked.connect(self.open_transfer_money_dialog)
+        self.centralWidget().layout().addWidget(self.community_view)
 
     def startup(self):
         self.update_time()
@@ -78,13 +91,29 @@ class MainWindow(QMainWindow, Ui_MainWindow):
             self.showMaximized()
         else:
             self.show()
+        if self.app.current_account:
+            self.password_asker = PasswordAskerDialog(self.app.current_account)
+            self.community_view.change_account(self.app.current_account, self.password_asker)
         self.refresh()
 
-    def open_add_account_dialog(self):
+    @asyncify
+    @asyncio.coroutine
+    def open_add_account_dialog(self, checked=False):
         dialog = ProcessConfigureAccount(self.app, None)
-        result = dialog.exec_()
+        result = yield from dialog.async_exec()
         if result == QDialog.Accepted:
-            self.action_change_account(self.app.current_account)
+            self.action_change_account(self.app.current_account.name)
+
+    @asyncify
+    @asyncio.coroutine
+    def open_configure_account_dialog(self, checked=False):
+        dialog = ProcessConfigureAccount(self.app, self.app.current_account)
+        result = yield from dialog.async_exec()
+        if result == QDialog.Accepted:
+            if self.app.current_account:
+                self.action_change_account(self.app.current_account.name)
+            else:
+                self.refresh()
 
     @pyqtSlot(str)
     def display_error(self, error):
@@ -96,8 +125,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
     def referential_changed(self, index):
         if self.app.current_account:
             self.app.current_account.set_display_referential(index)
-            if self.currencies_tabwidget.currentWidget():
-                self.currencies_tabwidget.currentWidget().referential_changed()
+            if self.community_view:
+                self.community_view.referential_changed()
+                self.homescreen.referential_changed()
 
     @pyqtSlot()
     def update_time(self):
@@ -127,31 +157,30 @@ class MainWindow(QMainWindow, Ui_MainWindow):
 
     def action_change_account(self, account_name):
         self.app.change_current_account(self.app.get_account(account_name))
+        self.password_asker = PasswordAskerDialog(self.app.current_account)
+        self.community_view.change_account(self.app.current_account, self.password_asker)
         self.refresh()
 
     @pyqtSlot()
-    def loader_finished(self):
-        logging.debug("Finished loading")
-        self.refresh()
-        self.busybar.hide()
-        QApplication.setOverrideCursor(Qt.ArrowCursor)
-        try:
-            self.app.disconnect()
-        except:
-            logging.debug("Disconnect of app failed")
-
-        QApplication.processEvents()
+    def action_open_add_community(self):
+        dialog = ProcessConfigureCommunity(self.app,
+                                           self.app.current_account, None,
+                                           self.password_asker)
+        if dialog.exec_() == QDialog.Accepted:
+            self.app.save(self.app.current_account)
+            dialog.community.start_coroutines()
+            self.homescreen.refresh()
 
     def open_transfer_money_dialog(self):
-        dialog = TransferMoneyDialog(self.app, self.app.current_account,
+        dialog = TransferMoneyDialog(self.app,
+                                     self.app.current_account,
                                      self.password_asker)
-        dialog.accepted.connect(self.refresh_wallets)
         if dialog.exec_() == QDialog.Accepted:
-            currency_tab = self.currencies_tabwidget.currentWidget()
-            currency_tab.tab_history.table_history.model().sourceModel().refresh_transfers()
+            self.community_view.tab_history.table_history.model().sourceModel().refresh_transfers()
 
     def open_certification_dialog(self):
-        dialog = CertificationDialog(self.app.current_account,
+        dialog = CertificationDialog(self.app,
+                                     self.app.current_account,
                                      self.password_asker)
         dialog.exec_()
 
@@ -161,15 +190,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
         if result == QDialog.Accepted:
             self.window().refresh_contacts()
 
-    def open_configure_account_dialog(self):
-        dialog = ProcessConfigureAccount(self.app, self.app.current_account)
-        result = dialog.exec_()
-        if result == QDialog.Accepted:
-            if self.app.current_account:
-                self.action_change_account(self.app.current_account.name)
-            else:
-                self.refresh()
-
     def open_preferences_dialog(self):
         dialog = PreferencesDialog(self.app)
         result = dialog.exec_()
@@ -233,33 +253,26 @@ class MainWindow(QMainWindow, Ui_MainWindow):
                 version_info=version_info,
                 version_url=version_url))
 
-    def refresh_wallets(self):
-        currency_tab = self.currencies_tabwidget.currentWidget()
-        if currency_tab:
-            currency_tab.refresh_wallets()
+    @pyqtSlot(Community)
+    def change_community(self, community):
+        if self.community_view.community:
+            self.community_view.community.stop_coroutines()
 
-    def refresh_communities(self):
-        logging.debug("CLEAR")
-        self.currencies_tabwidget.clear()
-        if self.app.current_account:
-            for community in self.app.current_account.communities:
-                tab_currency = CurrencyTabWidget(self.app, community,
-                                                 self.password_asker,
-                                                 self.status_label)
-                self.currencies_tabwidget.addTab(tab_currency,
-                                                 QIcon(":/icons/currency_icon"),
-                                                 community.name)
+        if community:
+            self.homescreen.hide()
+            self.community_view.show()
+        else:
+            self.community_view.hide()
+            self.homescreen.show()
+
+        self.community_view.change_community(community)
 
     def refresh_accounts(self):
         self.menu_change_account.clear()
-        signal_mapper = QSignalMapper(self)
-
         for account_name in sorted(self.app.accounts.keys()):
             action = QAction(account_name, self)
+            action.triggered.connect(lambda checked, account_name=account_name: self.action_change_account(account_name))
             self.menu_change_account.addAction(action)
-            signal_mapper.setMapping(action, account_name)
-            action.triggered.connect(signal_mapper.map)
-            signal_mapper.mapped[str].connect(self.action_change_account)
 
     def refresh_contacts(self):
         self.menu_contacts_list.clear()
@@ -281,22 +294,22 @@ class MainWindow(QMainWindow, Ui_MainWindow):
         """
         logging.debug("Refresh started")
         self.refresh_accounts()
+        self.homescreen.show()
+        self.community_view.hide()
+        self.homescreen.refresh()
 
         if self.app.current_account is None:
-            self.currencies_tabwidget.hide()
-            self.homescreen.show()
             self.setWindowTitle(self.tr("CuteCoin {0}").format(__version__))
-            self.menu_account.setEnabled(False)
+            self.action_add_a_contact.setEnabled(False)
+            self.actionCertification.setEnabled(False)
+            self.actionTransfer_money.setEnabled(False)
             self.action_configure_parameters.setEnabled(False)
             self.action_set_as_default.setEnabled(False)
+            self.menu_contacts_list.setEnabled(False)
             self.combo_referential.setEnabled(False)
             self.status_label.setText(self.tr(""))
             self.password_asker = None
         else:
-            logging.debug("Show currencies loading")
-            self.currencies_tabwidget.show()
-            logging.debug("Hide homescreen")
-            self.homescreen.hide()
             self.password_asker = PasswordAskerDialog(self.app.current_account)
 
             self.combo_referential.blockSignals(True)
@@ -308,13 +321,14 @@ class MainWindow(QMainWindow, Ui_MainWindow):
             self.combo_referential.blockSignals(False)
             logging.debug(self.app.preferences)
             self.combo_referential.setCurrentIndex(self.app.preferences['ref'])
-            self.menu_account.setEnabled(True)
+            self.action_add_a_contact.setEnabled(True)
+            self.actionCertification.setEnabled(True)
+            self.actionTransfer_money.setEnabled(True)
+            self.menu_contacts_list.setEnabled(True)
             self.action_configure_parameters.setEnabled(True)
             self.setWindowTitle(self.tr("CuteCoin {0} - Account : {1}").format(__version__,
                                                                                self.app.current_account.name))
 
-        self.refresh_communities()
-        self.refresh_wallets()
         self.refresh_contacts()
 
     def import_account(self):
@@ -351,3 +365,14 @@ class MainWindow(QMainWindow, Ui_MainWindow):
         self.app.stop()
         super().closeEvent(event)
 
+    def changeEvent(self, event):
+        """
+        Intercepte LanguageChange event to translate UI
+        :param QEvent QEvent: Event
+        :return:
+        """
+        if event.type() == QEvent.LanguageChange:
+            self.retranslateUi(self)
+            self.refresh()
+        return super(MainWindow, self).changeEvent(event)
+
diff --git a/src/cutecoin/gui/member.py b/src/cutecoin/gui/member.py
index 3f3139abe35e7581a99b880b6b986289fffb2f5c..d3ca7c1a83a44ba8101b42b25bc5b79e95d525f5 100644
--- a/src/cutecoin/gui/member.py
+++ b/src/cutecoin/gui/member.py
@@ -1,8 +1,10 @@
 import datetime
+import asyncio
 
 from PyQt5.QtWidgets import QDialog
 
 from ..core.graph import Graph
+from ..tools.decorators import asyncify
 from ..gen_resources.member_uic import Ui_DialogMember
 from ..tools.exceptions import MembershipNotFoundError
 
@@ -29,9 +31,14 @@ class MemberDialog(QDialog, Ui_DialogMember):
         self.account = account
         self.identity = identity
         self.label_uid.setText(identity.uid)
+        self.refresh()
+
+    @asyncify
+    @asyncio.coroutine
+    def refresh(self):
 
         try:
-            join_date = self.identity.get_join_date(self.community)
+            join_date = yield from self.identity.get_join_date(self.community)
         except MembershipNotFoundError:
             join_date = None
 
@@ -44,9 +51,11 @@ class MemberDialog(QDialog, Ui_DialogMember):
         graph = Graph(self.app, self.community)
         path = None
         # if selected member is not the account member...
-        if identity.pubkey != self.account.pubkey:
+        if self.identity.pubkey != self.account.pubkey:
             # add path from selected member to account member
-            path = graph.get_shortest_path_between_members(identity, self.account.identity(self.community))
+            account_identity = yield from self.account.identity(self.community)
+            path = yield from graph.get_shortest_path_between_members(self.identity,
+                                                                      account_identity)
 
         text = self.tr("""
             <table cellpadding="5">
@@ -62,8 +71,8 @@ class MemberDialog(QDialog, Ui_DialogMember):
         if path:
             distance = len(path) - 1
             text += self.tr(
-                """<tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>""".format(self.tr('Distance'),
-                                                                                          distance))
+                """<tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr>"""
+                    .format(self.tr('Distance'), distance))
             if distance > 1:
                 index = 0
                 for node in path:
@@ -83,4 +92,3 @@ class MemberDialog(QDialog, Ui_DialogMember):
 
         # set text in label
         self.label_properties.setText(text)
-
diff --git a/src/cutecoin/gui/network_tab.py b/src/cutecoin/gui/network_tab.py
index 73349efb34f90896c25bc1d5fe57977a0df3c19c..44dfea169ae55a6883cbed141f97276827d496a4 100644
--- a/src/cutecoin/gui/network_tab.py
+++ b/src/cutecoin/gui/network_tab.py
@@ -9,7 +9,7 @@ import asyncio
 
 from PyQt5.QtGui import QCursor, QDesktopServices
 from PyQt5.QtWidgets import QWidget, QMenu, QAction
-from PyQt5.QtCore import Qt, QModelIndex, pyqtSlot, QUrl
+from PyQt5.QtCore import Qt, QModelIndex, pyqtSlot, QUrl, QEvent
 from ..models.network import NetworkTableModel, NetworkFilterProxyModel
 from ..core.net.api import bma as qtbma
 from ..gen_resources.network_tab_uic import Ui_NetworkTabWidget
@@ -20,32 +20,39 @@ class NetworkTabWidget(QWidget, Ui_NetworkTabWidget):
     classdocs
     """
 
-    def __init__(self, app, community):
+    def __init__(self, app):
         """
         Constructore of a network tab.
 
         :param cutecoin.core.Application app: The application
-        :param cutecoin.core.Community community: The community
         :return: A new network tab.
         :rtype: NetworkTabWidget
         """
         super().__init__()
         self.app = app
-        self.community = community
+        self.community = None
 
         self.setupUi(self)
-        model = NetworkTableModel(community)
+        model = NetworkTableModel(self.community)
         proxy = NetworkFilterProxyModel(self)
         proxy.setSourceModel(model)
         self.table_network.setModel(proxy)
         self.table_network.sortByColumn(0, Qt.DescendingOrder)
         self.table_network.resizeColumnsToContents()
-        community.network.nodes_changed.connect(self.refresh_nodes)
+
+    def change_community(self, community):
+        if self.community:
+            self.community.network.nodes_changed.disconnect(self.refresh_nodes)
+        if community:
+            community.network.nodes_changed.connect(self.refresh_nodes)
+
+        self.community = community
+        self.table_network.model().change_community(community)
 
     @pyqtSlot()
     def refresh_nodes(self):
         logging.debug("Refresh nodes")
-        self.table_network.model().sourceModel().modelReset.emit()
+        self.table_network.model().sourceModel().refresh_nodes()
 
     def node_context_menu(self, point):
         index = self.table_network.indexAt(point)
@@ -98,4 +105,13 @@ class NetworkTabWidget(QWidget, Ui_NetworkTabWidget):
     def manual_nodes_refresh(self):
         self.community.network.refresh_once()
 
-
+    def changeEvent(self, event):
+        """
+        Intercepte LanguageChange event to translate UI
+        :param QEvent QEvent: Event
+        :return:
+        """
+        if event.type() == QEvent.LanguageChange:
+            self.retranslateUi(self)
+            self.refresh_nodes()
+        return super(NetworkTabWidget, self).changeEvent(event)
diff --git a/src/cutecoin/gui/password_asker.py b/src/cutecoin/gui/password_asker.py
index dcb65ddd1851dab1c0ae2cd21365f3a06a2979a8..04a7a4f92b9e262bbaafc47500f3da5ea492ded3 100644
--- a/src/cutecoin/gui/password_asker.py
+++ b/src/cutecoin/gui/password_asker.py
@@ -6,7 +6,8 @@ Created on 24 dec. 2014
 
 import logging
 import re
-
+import asyncio
+from PyQt5.QtCore import QEvent
 from PyQt5.QtWidgets import QDialog, QMessageBox
 
 from ..gen_resources.password_asker_uic import Ui_PasswordAskerDialog
@@ -28,6 +29,21 @@ class PasswordAskerDialog(QDialog, Ui_PasswordAskerDialog):
         self.password = ""
         self.remember = False
 
+    def future_exec(self):
+        future = asyncio.Future()
+        if not self.remember:
+            def future_show():
+                pwd = self.password
+                if not self.remember:
+                    self.password = ""
+                future.set_result(pwd)
+            self.open()
+            self.finished.connect(future_show)
+        else:
+            self.setResult(QDialog.Accepted)
+            future.set_result(self.password)
+        return future
+
     def exec_(self):
         if not self.remember:
             super().exec_()
@@ -67,6 +83,16 @@ class PasswordAskerDialog(QDialog, Ui_PasswordAskerDialog):
         self.password = ""
         super().reject()
 
+    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(PasswordAskerDialog, self).changeEvent(event)
+
 
 def detect_non_printable(data):
     control_chars = ''.join(map(chr, list(range(0, 32)) + list(range(127, 160))))
diff --git a/src/cutecoin/gui/preferences.py b/src/cutecoin/gui/preferences.py
index 0372232d729004eaa1215f7da98e50eba0392aa8..919d50de092ee9435132737ead8351d74ac8eba7 100644
--- a/src/cutecoin/gui/preferences.py
+++ b/src/cutecoin/gui/preferences.py
@@ -78,6 +78,8 @@ class PreferencesDialog(QDialog, Ui_PreferencesDialog):
                 'proxy_port': self.spinbox_proxy_port.value(),
                 'international_system_of_units': self.checkbox_international_system.isChecked()}
         self.app.save_preferences(pref)
+      # change UI translation
+        self.app.switch_language()
         toast.display(self.tr("Preferences"),
                       self.tr("A restart is needed to apply your new preferences."))
         super().accept()
diff --git a/src/cutecoin/gui/process_cfg_account.py b/src/cutecoin/gui/process_cfg_account.py
index 5906db17f4bd003e747350dd19ddf6fcae45baef..02e6ffcc9c7edf0daf460ff9c350d41158a05473 100644
--- a/src/cutecoin/gui/process_cfg_account.py
+++ b/src/cutecoin/gui/process_cfg_account.py
@@ -4,8 +4,7 @@ Created on 6 mars 2014
 @author: inso
 """
 import logging
-import requests
-from ucoinpy.documents.peer import Peer
+import asyncio
 from ucoinpy.key import SigningKey
 from ..gen_resources.account_cfg_uic import Ui_AccountConfigurationDialog
 from ..gui.process_cfg_community import ProcessConfigureCommunity
@@ -50,8 +49,6 @@ class StepPageInit(Step):
             self.config_dialog.edit_account_name.setText(self.config_dialog.account.name)
             model = CommunitiesListModel(self.config_dialog.account)
             self.config_dialog.list_communities.setModel(model)
-            nb_wallets = len(self.config_dialog.account.wallets)
-            self.config_dialog.spinbox_wallets.setValue(nb_wallets)
             self.config_dialog.password_asker = PasswordAskerDialog(self.config_dialog.account)
 
         self.config_dialog.button_previous.setEnabled(False)
@@ -95,8 +92,7 @@ class StepPageKey(Step):
     def process_next(self):
         salt = self.config_dialog.edit_salt.text()
         password = self.config_dialog.edit_password.text()
-        self.config_dialog.account.salt = salt
-        self.config_dialog.account.pubkey = SigningKey(salt, password).pubkey
+        self.config_dialog.account.set_scrypt_infos(salt, password)
         self.config_dialog.password_asker = PasswordAskerDialog(self.config_dialog.account)
         model = CommunitiesListModel(self.config_dialog.account)
         self.config_dialog.list_communities.setModel(model)
@@ -122,12 +118,9 @@ class StepPageCommunities(Step):
         if self.config_dialog.password_asker.result() == QDialog.Rejected:
             return
 
-        nb_wallets = self.config_dialog.spinbox_wallets.value()
-        self.config_dialog.account.set_walletpool_size(nb_wallets, password)
-
         self.config_dialog.app.add_account(self.config_dialog.account)
         if len(self.config_dialog.app.accounts) == 1:
-            self.config_dialog.app.default_account = self.config_dialog.account.name
+            self.config_dialog.app.preferences['account'] = self.config_dialog.account.name
         self.config_dialog.app.save(self.config_dialog.account)
         self.config_dialog.app.current_account = self.config_dialog.account
 
@@ -196,17 +189,14 @@ class ProcessConfigureAccount(QDialog, Ui_AccountConfigurationDialog):
         self.list_communities.setModel(CommunitiesListModel(self.account))
 
     def action_edit_account_key(self):
-        if self.step.is_valid():
-            self.button_next.setEnabled(True)
-        else:
-            self.button_next.setEnabled(False)
+        self.button_generate.setEnabled(self.step.is_valid())
+        self.button_next.setEnabled(self.step.is_valid())
 
     def action_show_pubkey(self):
         salt = self.edit_salt.text()
         password = self.edit_password.text()
         pubkey = SigningKey(salt, password).pubkey
-        QMessageBox.information(self, self.tr("Public key"),
-                                self.tr("These parameters pubkeys are : {0}").format(pubkey))
+        self.label_info.setText(pubkey)
 
     def action_edit_account_parameters(self):
         if self.step.is_valid():
@@ -255,5 +245,11 @@ Are you sure ?"""))
             self.stacked_pages.setCurrentIndex(previous_index)
             self.step.display_page()
 
+    def async_exec(self):
+        future = asyncio.Future()
+        self.finished.connect(lambda r: future.set_result(r))
+        self.open()
+        return future
+
     def accept(self):
         super().accept()
diff --git a/src/cutecoin/gui/process_cfg_community.py b/src/cutecoin/gui/process_cfg_community.py
index 9f37d5eda232bfe842704ceb75f6f24938f4678d..9e6625960a595767f39dd06b803ec80d81f385fa 100644
--- a/src/cutecoin/gui/process_cfg_community.py
+++ b/src/cutecoin/gui/process_cfg_community.py
@@ -9,18 +9,19 @@ import asyncio
 
 from PyQt5.QtWidgets import QDialog, QMenu, QMessageBox, QApplication
 from PyQt5.QtGui import QCursor
-from PyQt5.QtCore import pyqtSlot
+from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
 
 from ..gen_resources.community_cfg_uic import Ui_CommunityConfigurationDialog
 from ..models.peering import PeeringTreeModel
 from ..core import Community
-from ..core.registry import Identity
+from ..core.registry.identity import BlockchainState
 from ..core.net import Node
 from . import toast
 
 
-class Step():
+class Step(QObject):
     def __init__(self, config_dialog, previous_step=None, next_step=None):
+        super().__init__()
         self.previous_step = previous_step
         self.next_step = next_step
         self.config_dialog = config_dialog
@@ -34,25 +35,99 @@ class StepPageInit(Step):
         super().__init__(config_dialog)
         self.node = None
         logging.debug("Init")
-        self.config_dialog.button_next.setEnabled(False)
-        self.config_dialog.button_checknode.clicked.connect(self.check_node)
+        self.config_dialog.button_connect.clicked.connect(self.check_connect)
+        self.config_dialog.button_register.clicked.connect(self.check_register)
+
+    @property
+    def app(self):
+        return self.config_dialog.app
+
+    @property
+    def account(self):
+        return self.config_dialog.account
+
+    @property
+    def community(self):
+        return self.config_dialog.community
+
+    @property
+    def password_asker(self):
+        return self.config_dialog.password_asker
+
+    @asyncio.coroutine
+    def coroutine_check_connect(self):
+        server = self.config_dialog.lineedit_server.text()
+        port = self.config_dialog.spinbox_port.value()
+        logging.debug("Is valid ? ")
+        self.node = yield from Node.from_address(self.config_dialog.app.network_manager, None, server, port)
+        if self.node:
+            community = Community.create(self.app.network_manager, self.node)
+            identity = yield from self.app.identities_registry.future_find(self.account.pubkey, community)
+            if identity.blockchain_state == BlockchainState.NOT_FOUND:
+                self.config_dialog.label_error.setText(self.tr("Could not find your identity on the network."))
+            else:
+                self.config_dialog.community = community
+                self.config_dialog.next()
+        else:
+            self.config_dialog.label_error.setText(self.tr("Could not connect."))
+
+    @pyqtSlot()
+    def check_connect(self):
+        logging.debug("Check node")
+        asyncio.async(self.coroutine_check_connect())
 
     @asyncio.coroutine
-    def coroutine_check_node(self):
+    def coroutine_check_register(self):
         server = self.config_dialog.lineedit_server.text()
         port = self.config_dialog.spinbox_port.value()
         logging.debug("Is valid ? ")
         self.node = yield from Node.from_address(self.config_dialog.app.network_manager, None, server, port)
         if self.node:
-            self.config_dialog.button_next.setEnabled(True)
-            self.config_dialog.button_check_node.setText("Ok !")
+            community = Community.create(self.app.network_manager, self.node)
+            identity = yield from self.app.identities_registry.future_find(self.account.pubkey, community)
+            if identity.blockchain_state == BlockchainState.NOT_FOUND:
+                password = yield from self.password_asker.future_exec()
+                if self.password_asker.result() == QDialog.Rejected:
+                    return
+                self.config_dialog.label_error.setText(self.tr("Broadcasting identity..."))
+                self.account.selfcert_broadcasted.connect(self.handle_broadcast)
+                self.account.broadcast_error.connect(self.handle_error)
+                yield from self.account.send_selfcert(password, community)
+                self.config_dialog.community = community
+            else:
+                self.config_dialog.label_error.setText(self.tr("Pubkey already exists on the network"))
         else:
-            self.config_dialog.button_next.setEnabled(False)
-            self.config_dialog.button_check_node.setText("Could not connect.")
+            self.config_dialog.label_error.setText(self.tr("Could not connect."))
 
     @pyqtSlot()
-    def check_node(self):
-        asyncio.async(self.coroutine_check_node())
+    def check_register(self):
+        logging.debug("Check node")
+        asyncio.async(self.coroutine_check_register())
+
+    @pyqtSlot(int, str)
+    def handle_broadcast(self):
+        if self.app.preferences['notifications']:
+            toast.display(self.tr("UID broadcast"), self.tr("Identity broadcasted to the network"))
+        # Disabled : https://github.com/harvimt/quamash/issues/41
+        # else:
+        #    QMessageBox.information(self, self.tr("UID broadcast"), self.tr("Identity broadcasted to the network"))
+        self.account.selfcert_broadcasted.disconnect()
+        self.account.broadcast_error.disconnect(self.handle_error)
+        QApplication.restoreOverrideCursor()
+        self.config_dialog.next()
+
+    @pyqtSlot(int, str)
+    def handle_error(self, error_code, text):
+        self.config_dialog.label_error.setText(self.tr("Error") + " " + \
+                                               self.tr("{0} : {1}".format(error_code, text)))
+        if self.app.preferences['notifications']:
+            toast.display(self.tr("Error"), self.tr("{0} : {1}".format(error_code, text)))
+        # Disabled : https://github.com/harvimt/quamash/issues/41
+        #  else:
+        #    QMessageBox.critical(self, self.tr("Error"), self.tr("{0} : {1}".format(error_code, text)))
+        self.account.selfcert_broadcasted.disconnect()
+        self.account.broadcast_error.disconnect(self.handle_error)
+        QApplication.restoreOverrideCursor()
 
     def is_valid(self):
         return self.node is not None
@@ -66,7 +141,8 @@ class StepPageInit(Step):
         self.config_dialog.community = Community.create(self.config_dialog.app.network_manager, self.node)
 
     def display_page(self):
-        self.config_dialog.button_previous.setEnabled(False)
+        self.config_dialog.button_next.hide()
+        self.config_dialog.button_previous.hide()
 
 
 class StepPageAddpeers(Step):
@@ -83,6 +159,8 @@ class StepPageAddpeers(Step):
         pass
 
     def display_page(self):
+        self.config_dialog.button_next.show()
+        self.config_dialog.button_previous.show()
         # We add already known peers to the displayed list
         self.config_dialog.nodes = self.config_dialog.community.network.root_nodes
         tree_model = PeeringTreeModel(self.config_dialog.community)
@@ -96,6 +174,7 @@ class ProcessConfigureCommunity(QDialog, Ui_CommunityConfigurationDialog):
     """
     Dialog to configure or add a community
     """
+    community_added = pyqtSignal()
 
     def __init__(self, app, account, community, password_asker):
         """
@@ -115,6 +194,7 @@ class ProcessConfigureCommunity(QDialog, Ui_CommunityConfigurationDialog):
         self.step = None
         self.nodes = []
 
+        self.community_added.connect(self.add_community_and_close)
         step_init = StepPageInit(self)
         step_add_peers = StepPageAddpeers(self)
 
@@ -139,7 +219,7 @@ class ProcessConfigureCommunity(QDialog, Ui_CommunityConfigurationDialog):
                 self.stacked_pages.setCurrentIndex(next_index)
                 self.step.display_page()
         else:
-            asyncio.async(self.final())
+            self.add_community_and_close()
 
     def previous(self):
         if self.step.previous_step is not None:
@@ -196,49 +276,13 @@ class ProcessConfigureCommunity(QDialog, Ui_CommunityConfigurationDialog):
                     action.setEnabled(False)
             menu.exec_(QCursor.pos())
 
-    def selfcert_sent(self, pubkey, currency):
-        if self.app.preferences['notifications']:
-            toast.display(self.tr("UID Publishing"),
-                      self.tr("Success publishing  your UID").format(pubkey, currency))
-        else:
-            QMessageBox.information(self, self.tr("UID Publishing"),
-                      self.tr("Success publishing  your UID").format(pubkey, currency))
-        self.account.certification_broadcasted.disconnect()
-        self.account.broadcast_error.disconnect(self.handle_error)
-        QApplication.restoreOverrideCursor()
-        self.add_community_and_close()
-
-    @pyqtSlot(int, str)
-    def handle_error(self, error_code, text):
-        if self.app.preferences['notifications']:
-            toast.display(self.tr("Error"), self.tr("{0} : {1}".format(error_code, text)))
-        else:
-            QMessageBox.critical(self, self.tr("Error"), self.tr("{0} : {1}".format(error_code, text)))
-        self.account.certification_broadcasted.disconnect()
-        self.account.broadcast_error.disconnect(self.handle_error)
-        QApplication.restoreOverrideCursor()
+    def async_exec(self):
+        future = asyncio.Future()
+        self.finished.connect(lambda r: future.set_result(r))
+        self.open()
+        return future
 
     def add_community_and_close(self):
         if self.community not in self.account.communities:
             self.account.add_community(self.community)
         self.accept()
-
-    @asyncio.coroutine
-    def final(self):
-        identity = yield from self.app.identities_registry.future_find(self.account.pubkey, self.community)
-        if identity.status == Identity.NOT_FOUND:
-            reply = QMessageBox.question(self, self.tr("Pubkey not found"),
-                                 self.tr("""The public key of your account wasn't found in the community. :\n
-{0}\n
-Would you like to publish the key ?""").format(self.account.pubkey))
-            if reply == QMessageBox.Yes:
-                password = self.password_asker.exec_()
-                if self.password_asker.result() == QDialog.Rejected:
-                    return
-                self.account.selfcert_broadcasted.connect(self.handle_broadcast)
-                self.account.broadcast_error.connect(self.handle_error)
-                asyncio.async(self.account.send_selfcert(password, self.community))
-            else:
-                self.add_community_and_close()
-        else:
-            self.add_community_and_close()
diff --git a/src/cutecoin/gui/toast.py b/src/cutecoin/gui/toast.py
index afd30d7776087dab85ee0b9420ffd8eba5ae2927..505e4a9eb332e3afce17096919bab4f0cdf8590f 100644
--- a/src/cutecoin/gui/toast.py
+++ b/src/cutecoin/gui/toast.py
@@ -16,12 +16,17 @@ window = None   # global
 def display(title, msg):
     logging.debug("NOTIFY DISPLAY")
     if sys.platform == "linux":
-        import notify2
-        if not notify2.is_initted():
-            logging.debug("Initialising notify2")
-            notify2.init("cutecoin")
-        n = notify2.Notification(title,
-                         msg)
+        try:
+            import notify2
+            if not notify2.is_initted():
+                logging.debug("Initialising notify2")
+                notify2.init("cutecoin")
+            n = notify2.Notification(title,
+                             msg)
+            n.show()
+        except ImportError:
+            _Toast(title, msg)
+
 
 # fixme: https://bugs.python.org/issue11587
         # # Not working... Empty icon at the moment.
@@ -42,7 +47,6 @@ def display(title, msg):
         #         )
         #     n.set_hint('icon_data', icon_struct)
         #     n.set_timeout(5000)
-        n.show()
     else:
         _Toast(title, msg)
 
diff --git a/src/cutecoin/gui/transactions_tab.py b/src/cutecoin/gui/transactions_tab.py
index 2758daa9dee0649396df3dac6b0c2e439e7a51a3..ac380a11539cc3e33b599c10ac7891138f3d39cc 100644
--- a/src/cutecoin/gui/transactions_tab.py
+++ b/src/cutecoin/gui/transactions_tab.py
@@ -1,46 +1,84 @@
 from PyQt5.QtWidgets import QWidget, QAbstractItemView, QHeaderView, QDialog, \
     QMenu, QAction, QApplication, QMessageBox
-from PyQt5.QtCore import Qt, QDateTime, QTime, QModelIndex, QLocale, QCoreApplication, pyqtSlot
+from PyQt5.QtCore import Qt, QDateTime, QTime, QModelIndex, pyqtSignal, pyqtSlot, QEvent
 from PyQt5.QtGui import QCursor
 from ..gen_resources.transactions_tab_uic import Ui_transactionsTabWidget
 from ..models.txhistory import HistoryTableModel, TxFilterProxyModel
 from ..core.transfer import Transfer
+from .contact import ConfigureContactDialog
+from .member import MemberDialog
+from .transfer import TransferMoneyDialog
+from .certification import CertificationDialog
 from ..core.wallet import Wallet
 from ..core.registry import Identity
+from ..tools.decorators import asyncify, once_at_a_time, cancel_once_task
 from .transfer import TransferMoneyDialog
 from . import toast
 
 import logging
+import asyncio
 
 
 class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget):
     """
     classdocs
     """
+    view_in_wot = pyqtSignal(Identity)
 
-    def __init__(self, app, community, password_asker, currency_tab):
+    def __init__(self, app):
         """
         Init
 
         :param cutecoin.core.app.Application app: Application instance
-        :param cutecoin.core.community.Community community: Community instance
-        :param cutecoin.gui.password_asker.PasswordAskerDialog password_asker: Password dialog instance
-        :param cutecoin.gui.currency_tab.CurrencyTabWidget currency_tab: Currency tab widget
         :return:
         """
 
         super().__init__()
         self.setupUi(self)
         self.app = app
-        self.community = community
-        self.password_asker = password_asker
-        self.currency_tab = currency_tab
+        self.account = None
+        self.community = None
+        self.password_asker = None
+
+        ts_from = self.date_from.dateTime().toTime_t()
+        ts_to = self.date_to.dateTime().toTime_t()
+        model = HistoryTableModel(self.app, self.account, self.community)
+        proxy = TxFilterProxyModel(ts_from, ts_to)
+        proxy.setSourceModel(model)
+        proxy.setDynamicSortFilter(True)
+        proxy.setSortRole(Qt.DisplayRole)
+
+        self.table_history.setModel(proxy)
+        self.table_history.setSelectionBehavior(QAbstractItemView.SelectRows)
+        self.table_history.setSortingEnabled(True)
+        self.table_history.horizontalHeader().setSectionResizeMode(QHeaderView.Interactive)
+        self.table_history.resizeColumnsToContents()
         self.progressbar.hide()
-        self.community.inner_data_changed.connect(self.refresh_minimum_maximum)
         self.refresh()
 
+    def cancel_once_tasks(self):
+        cancel_once_task(self, self.refresh_minimum_maximum)
+        cancel_once_task(self, self.refresh_balance)
+        cancel_once_task(self, self.history_context_menu)
+
+    def change_account(self, account, password_asker):
+        self.cancel_once_tasks()
+        self.account = account
+        self.password_asker = password_asker
+        self.table_history.model().sourceModel().change_account(account)
+
+    def change_community(self, community):
+        self.cancel_once_tasks()
+        self.community = community
+        self.table_history.model().sourceModel().change_community(self.community)
+        self.refresh()
+        self.stop_progress([])
+
+    @once_at_a_time
+    @asyncify
+    @asyncio.coroutine
     def refresh_minimum_maximum(self):
-        block = self.community.get_block(1)
+        block = yield from self.community.get_block(1)
         minimum_datetime = QDateTime()
         minimum_datetime.setTime_t(block['medianTime'])
         minimum_datetime.setTime(QTime(0, 0))
@@ -56,23 +94,10 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget):
 
     def refresh(self):
         #TODO: Use resetmodel instead of destroy/create
-        self.refresh_minimum_maximum()
-        ts_from = self.date_from.dateTime().toTime_t()
-        ts_to = self.date_to.dateTime().toTime_t()
+        if self.community:
+            self.refresh_minimum_maximum()
 
-        model = HistoryTableModel(self.app, self.community)
-        proxy = TxFilterProxyModel(ts_from, ts_to)
-        proxy.setSourceModel(model)
-        proxy.setDynamicSortFilter(True)
-        proxy.setSortRole(Qt.DisplayRole)
-
-        self.table_history.setModel(proxy)
-        self.table_history.setSelectionBehavior(QAbstractItemView.SelectRows)
-        self.table_history.setSortingEnabled(True)
-        self.table_history.horizontalHeader().setSectionResizeMode(QHeaderView.Interactive)
-        self.table_history.resizeColumnsToContents()
-
-        self.refresh_balance()
+            self.refresh_balance()
 
     def start_progress(self):
         def progressing(value, maximum):
@@ -99,36 +124,26 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget):
         self.table_history.model().sourceModel().refresh_transfers()
         self.table_history.resizeColumnsToContents()
 
+    @once_at_a_time
+    @asyncify
+    @asyncio.coroutine
     def refresh_balance(self):
-        # if referential is "units"
-        if self.app.current_account._current_ref == 0:
-            self.label_balance.show()
-            self.label_deposit.show()
-            self.label_payment.show()
-        else:
-            self.label_balance.hide()
-            self.label_deposit.hide()
-            self.label_payment.hide()
-
-        proxy = self.table_history.model()
-        balance = proxy.deposits - proxy.payments
-        localized_deposits = self.app.current_account.current_ref(proxy.deposits, self.community, self.app).diff_localized()
-        localized_payments = self.app.current_account.current_ref(proxy.payments, self.community, self.app).diff_localized()
-        localized_balance = self.app.current_account.current_ref(balance, self.community, self.app).diff_localized()
-
-        self.label_deposit.setText(QCoreApplication.translate("TransactionsTabWidget", "<b>Deposits</b> {:} {:}").format(
-            localized_deposits,
-            self.app.current_account.current_ref.units(self.community.short_currency)
-        ))
-        self.label_payment.setText(QCoreApplication.translate("TransactionsTabWidget", "<b>Payments</b> {:} {:}").format(
-            localized_payments,
-            self.app.current_account.current_ref.units(self.community.short_currency)
-        ))
-        self.label_balance.setText(QCoreApplication.translate("TransactionsTabWidget", "<b>Balance</b> {:} {:}").format(
-            localized_balance,
-            self.app.current_account.current_ref.units(self.community.short_currency)
-        ))
-
+        amount = yield from self.app.current_account.amount(self.community)
+        localized_amount = yield from self.app.current_account.current_ref(amount, self.community,
+                                                                           self.app).localized(units=True,
+                                        international_system=self.app.preferences['international_system_of_units'])
+
+        # set infos in label
+        self.label_balance.setText(
+            self.tr("{:}")
+            .format(
+                localized_amount
+            )
+        )
+
+    @once_at_a_time
+    @asyncify
+    @asyncio.coroutine
     def history_context_menu(self, point):
         index = self.table_history.indexAt(point)
         model = self.table_history.model()
@@ -141,9 +156,11 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget):
             state_data = model.sourceModel().data(state_index, Qt.DisplayRole)
 
             pubkey_col = model.sourceModel().columns_types.index('pubkey')
-            identity_index = model.sourceModel().index(source_index.row(),
+            pubkey_index = model.sourceModel().index(source_index.row(),
                                                     pubkey_col)
-            identity = model.sourceModel().data(identity_index, Qt.DisplayRole)
+            pubkey = model.sourceModel().data(pubkey_index, Qt.DisplayRole)
+            identity = yield from self.app.identities_registry.future_find(pubkey, self.community)
+
             transfer = model.sourceModel().transfers[source_index.row()]
             if state_data == Transfer.REFUSED or state_data == Transfer.TO_SEND:
                 send_back = QAction(self.tr("Send again"), self)
@@ -158,23 +175,23 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget):
             else:
                 if isinstance(identity, Identity):
                     informations = QAction(self.tr("Informations"), self)
-                    informations.triggered.connect(self.currency_tab.tab_community.menu_informations)
+                    informations.triggered.connect(self.menu_informations)
                     informations.setData(identity)
                     menu.addAction(informations)
 
                     add_as_contact = QAction(self.tr("Add as contact"), self)
-                    add_as_contact.triggered.connect(self.currency_tab.tab_community.menu_add_as_contact)
+                    add_as_contact.triggered.connect(self.menu_add_as_contact)
                     add_as_contact.setData(identity)
                     menu.addAction(add_as_contact)
 
                 send_money = QAction(self.tr("Send money"), self)
-                send_money.triggered.connect(self.currency_tab.tab_community.menu_send_money)
+                send_money.triggered.connect(self.menu_send_money)
                 send_money.setData(identity)
                 menu.addAction(send_money)
 
                 if isinstance(identity, Identity):
                     view_wot = QAction(self.tr("View in Web of Trust"), self)
-                    view_wot.triggered.connect(self.currency_tab.tab_community.view_wot)
+                    view_wot.triggered.connect(self.view_wot)
                     view_wot.setData(identity)
                     menu.addAction(view_wot)
 
@@ -184,7 +201,7 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget):
             menu.addAction(copy_pubkey)
 
             # Show the context menu.
-            menu.exec_(QCursor.pos())
+            menu.popup(QCursor.pos())
 
     def copy_pubkey_to_clipboard(self):
         data = self.sender().data()
@@ -196,11 +213,52 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget):
         elif data.__class__ is str:
             clipboard.setText(data)
 
+    def menu_informations(self):
+        person = self.sender().data()
+        self.identity_informations(person)
+
+    def menu_add_as_contact(self):
+        person = self.sender().data()
+        self.add_identity_as_contact({'name': person.uid,
+                                    'pubkey': person.pubkey})
+
+    def menu_send_money(self):
+        identity = self.sender().data()
+        self.send_money_to_identity(identity)
+
+    def identity_informations(self, person):
+        dialog = MemberDialog(self.app, self.account, self.community, person)
+        dialog.exec_()
+
+    def add_identity_as_contact(self, person):
+        dialog = ConfigureContactDialog(self.account, self.window(), person)
+        result = dialog.exec_()
+        if result == QDialog.Accepted:
+            self.window().refresh_contacts()
+
+    def send_money_to_identity(self, identity):
+        if isinstance(identity, str):
+            pubkey = identity
+        else:
+            pubkey = identity.pubkey
+        result = TransferMoneyDialog.send_money_to_identity(self.app, self.account, self.password_asker,
+                                                            self.community, identity)
+        if result == QDialog.Accepted:
+            currency_tab = self.window().currencies_tabwidget.currentWidget()
+            currency_tab.tab_history.table_history.model().sourceModel().refresh_transfers()
+
+    def certify_identity(self, identity):
+        CertificationDialog.certify_identity(self.app, self.account, self.password_asker,
+                                             self.community, identity)
+
+    def view_wot(self):
+        identity = self.sender().data()
+        self.view_in_wot.emit(identity)
+
     def send_again(self):
         transfer = self.sender().data()
         dialog = TransferMoneyDialog(self.app, self.app.current_account,
                                      self.password_asker)
-        dialog.accepted.connect(self.currency_tab.refresh_wallets)
         sender = transfer.metadata['issuer']
         wallet_index = [w.pubkey for w in self.app.current_account.wallets].index(sender)
         dialog.combo_wallets.setCurrentIndex(wallet_index)
@@ -237,3 +295,14 @@ QMessageBox.Ok | QMessageBox.Cancel)
             self.table_history.model().set_period(ts_from, ts_to)
 
             self.refresh_balance()
+
+    def changeEvent(self, event):
+        """
+        Intercepte LanguageChange event to translate UI
+        :param QEvent QEvent: Event
+        :return:
+        """
+        if event.type() == QEvent.LanguageChange:
+            self.retranslateUi(self)
+            self.refresh()
+        return super(TransactionsTabWidget, self).changeEvent(event)
diff --git a/src/cutecoin/gui/transfer.py b/src/cutecoin/gui/transfer.py
index d6ef4c738d22e0fc406cc4d8ba904051a19372be..1258314f18d4f0e4531a12b3c8f4545f51573c3d 100644
--- a/src/cutecoin/gui/transfer.py
+++ b/src/cutecoin/gui/transfer.py
@@ -9,6 +9,7 @@ from PyQt5.QtGui import QRegExpValidator
 
 from ..gen_resources.transfer_uic import Ui_TransferMoneyDialog
 from . import toast
+from ..tools.decorators import asyncify
 import asyncio
 
 
@@ -35,7 +36,6 @@ class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog):
         self.wallet = None
         self.community = self.account.communities[0]
         self.wallet = self.account.wallets[0]
-        self.dividend = self.community.dividend
 
         regexp = QRegExp('^([ a-zA-Z0-9-_:/;*?\[\]\(\)\\\?!^+=@&~#{}|<>%.]{0,255})$')
         validator = QRegExpValidator(regexp)
@@ -55,6 +55,14 @@ class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog):
             self.radio_contact.setEnabled(False)
             self.radio_pubkey.setChecked(True)
 
+    @staticmethod
+    def send_money_to_identity(app, account, password_asker, community, identity):
+        dialog = TransferMoneyDialog(app, account, password_asker)
+        dialog.edit_pubkey.setText(identity.pubkey)
+        dialog.combo_community.setCurrentText(community.name)
+        dialog.radio_pubkey.setChecked(True)
+        return dialog.exec()
+
     def accept(self):
         comment = self.edit_message.text()
 
@@ -105,60 +113,64 @@ class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog):
         self.wallet.broadcast_error.disconnect(self.handle_error)
         QApplication.restoreOverrideCursor()
 
-    def amount_changed(self):
-        amount = self.spinbox_amount.value()
-        relative = amount / self.dividend
+    @asyncify
+    @asyncio.coroutine
+    def amount_changed(self, value):
+        dividend = yield from self.community.dividend()
+        relative = value / dividend
         self.spinbox_relative.blockSignals(True)
         self.spinbox_relative.setValue(relative)
         self.spinbox_relative.blockSignals(False)
 
-    def relative_amount_changed(self):
-        relative = self.spinbox_relative.value()
-        amount = relative * self.dividend
+    @asyncify
+    @asyncio.coroutine
+    def relative_amount_changed(self, value):
+        dividend = yield from self.community.dividend()
+        amount = value * dividend
         self.spinbox_amount.blockSignals(True)
         self.spinbox_amount.setValue(amount)
         self.spinbox_amount.blockSignals(False)
 
+    @asyncify
+    @asyncio.coroutine
     def change_current_community(self, index):
         self.community = self.account.communities[index]
-        self.dividend = self.community.dividend
-        amount = self.wallet.value(self.community)
-        ref_amount = self.account.units_to_ref(amount, self.community)
-        ref_name = self.account.ref_name(self.community.currency)
-        # if referential type is quantitative...
-        if self.account.ref_type() == 'q':
-            # display int values
-            ref_amount = QLocale().toString(float(ref_amount), 'f', 0)
-        else:
-            # display float values
-            ref_amount = QLocale().toString(float(ref_amount), 'f', 6)
-        self.label_total.setText("{0} {1}".format(ref_amount, ref_name))
+        amount = yield from self.wallet.value(self.community)
+
+        ref_text = yield from self.account.current_ref(amount, self.community, self.app)\
+            .diff_localized(units=True,
+                            international_system=self.app.preferences['international_system_of_units'])
+        self.label_total.setText("{0}".format(ref_text))
         self.spinbox_amount.setSuffix(" " + self.community.currency)
         self.spinbox_amount.setValue(0)
-        amount = self.wallet.value(self.community)
-        relative = amount / self.dividend
+        amount = yield from self.wallet.value(self.community)
+        dividend = yield from self.community.dividend()
+        relative = amount / dividend
         self.spinbox_amount.setMaximum(amount)
         self.spinbox_relative.setMaximum(relative)
 
+    @asyncify
+    @asyncio.coroutine
     def change_displayed_wallet(self, index):
         self.wallet = self.account.wallets[index]
-        amount = self.wallet.value(self.community)
-        ref_amount = self.account.units_to_ref(amount, self.community)
-        ref_name = self.account.ref_name(self.community.currency)
-        # if referential type is quantitative...
-        if self.account.ref_type() == 'q':
-            # display int values
-            ref_amount = QLocale().toString(float(ref_amount), 'f', 0)
-        else:
-            # display float values
-            ref_amount = QLocale().toString(float(ref_amount), 'f', 6)
-        self.label_total.setText("{0} {1}".format(ref_amount, ref_name))
+        amount = yield from self.wallet.value(self.community)
+        ref_text = yield from self.account.current_ref(amount, self.community, self.app)\
+            .diff_localized(units=True,
+                            international_system=self.app.preferences['international_system_of_units'])
+        self.label_total.setText("{0}".format(ref_text))
         self.spinbox_amount.setValue(0)
-        amount = self.wallet.value(self.community)
-        relative = amount / self.dividend
+        amount = yield from self.wallet.value(self.community)
+        dividend = yield from self.community.dividend()
+        relative = amount / dividend
         self.spinbox_amount.setMaximum(amount)
         self.spinbox_relative.setMaximum(relative)
 
     def recipient_mode_changed(self, pubkey_toggled):
         self.edit_pubkey.setEnabled(pubkey_toggled)
         self.combo_contact.setEnabled(not pubkey_toggled)
+
+    def async_exec(self):
+        future = asyncio.Future()
+        self.finished.connect(lambda r: future.set_result(r))
+        self.open()
+        return future
diff --git a/src/cutecoin/gui/wallets_tab.py b/src/cutecoin/gui/wallets_tab.py
deleted file mode 100644
index 32e601f33e3359a3655f1319e8bf8cc8caedc71e..0000000000000000000000000000000000000000
--- a/src/cutecoin/gui/wallets_tab.py
+++ /dev/null
@@ -1,342 +0,0 @@
-"""
-Created on 15 févr. 2015
-
-@author: inso
-"""
-import asyncio
-import logging
-
-from PyQt5.QtWidgets import QWidget, QMenu, QAction, QApplication, QDialog, QMessageBox
-from PyQt5.QtCore import QDateTime, QModelIndex, Qt, QLocale
-from PyQt5.QtGui import QCursor
-
-from ..core.registry import Identity
-from ..core.wallet import Wallet
-from cutecoin.gui import toast
-from ..gui.password_asker import PasswordAskerDialog
-from ..models.wallets import WalletsTableModel, WalletsFilterProxyModel
-from .transfer import TransferMoneyDialog
-from ..tools.exceptions import MembershipNotFoundError, NoPeerAvailable, LookupFailureError
-from ..gen_resources.wallets_tab_uic import Ui_WalletsTab
-
-
-class WalletsTabWidget(QWidget, Ui_WalletsTab):
-    """
-    classdocs
-    """
-
-    def __init__(self, app, account, community, password_asker):
-        """
-        Init
-        :param cutecoin.core.app.Application app: Application instance
-        :param cutecoin.core.account.Account account: Account instance
-        :param cutecoin.core.community.Community community: Community instance
-        :param cutecoin.gui.password_asker.PasswordAskerDialog password_asker: PasswordAskerDialog instance
-        """
-        super().__init__()
-        self.setupUi(self)
-        self.app = app
-        self.account = account
-        self.community = community
-        self.password_asker = password_asker
-        self.setup_connections()
-
-    def setup_connections(self):
-        self.account.inner_data_changed.connect(self.refresh_informations_frame)
-        self.community.inner_data_changed.connect(self.refresh_informations_frame)
-
-    def refresh(self):
-        self.refresh_informations_frame()
-        self.refresh_wallets()
-        self.refresh_quality_buttons()
-
-    def refresh_wallets(self):
-        # TODO: Using reset model instead of destroy/create
-        wallets_model = WalletsTableModel(self.app, self.community)
-        proxy_model = WalletsFilterProxyModel()
-        proxy_model.setSourceModel(wallets_model)
-        wallets_model.dataChanged.connect(self.wallet_changed)
-        self.table_wallets.setModel(proxy_model)
-        self.table_wallets.resizeColumnsToContents()
-
-    def refresh_informations_frame(self):
-        parameters = self.community.parameters
-        try:
-            identity = self.account.identity(self.community)
-            membership = identity.membership(self.community)
-            renew_block = membership['blockNumber']
-            last_renewal = self.community.get_block(renew_block)['medianTime']
-            expiration = last_renewal + parameters['sigValidity']
-        except MembershipNotFoundError:
-            last_renewal = None
-            expiration = None
-
-        certified = identity.unique_valid_certified_by(self.app.identities_registry, self.community)
-        certifiers = identity.unique_valid_certifiers_of(self.app.identities_registry, self.community)
-        if last_renewal and expiration:
-            date_renewal = QLocale.toString(
-                QLocale(),
-                QDateTime.fromTime_t(last_renewal).date(), QLocale.dateFormat(QLocale(), QLocale.LongFormat)
-            )
-            date_expiration = QLocale.toString(
-                QLocale(),
-                QDateTime.fromTime_t(expiration).date(), QLocale.dateFormat(QLocale(), QLocale.LongFormat)
-            )
-
-            if self.account.pubkey in self.community.members_pubkeys():
-                # set infos in label
-                self.label_general.setText(
-                    self.tr("""
-                    <table cellpadding="5">
-                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
-                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
-                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
-                    </table>
-                    """).format(
-                        self.account.name, self.account.pubkey,
-                        self.tr("Membership"),
-                        self.tr("Last renewal on {:}, expiration on {:}").format(date_renewal, date_expiration),
-                        self.tr("Your web of trust"),
-                        self.tr("Certified by {:} members; Certifier of {:} members").format(len(certifiers),
-                                                                                             len(certified))
-                    )
-                )
-            else:
-                # set infos in label
-                self.label_general.setText(
-                    self.tr("""
-                    <table cellpadding="5">
-                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
-                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
-                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
-                    </table>
-                    """).format(
-                        self.account.name, self.account.pubkey,
-                        self.tr("Not a member"),
-                        self.tr("Last renewal on {:}, expiration on {:}").format(date_renewal, date_expiration),
-                        self.tr("Your web of trust"),
-                        self.tr("Certified by {:} members; Certifier of {:} members").format(len(certifiers),
-                                                                                             len(certified))
-                    )
-                )
-        else:
-            # set infos in label
-            self.label_general.setText(
-                self.tr("""
-                <table cellpadding="5">
-                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
-                <tr><td align="right"><b>{:}</b></td></tr>
-                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
-                </table>
-                """).format(
-                    self.account.name, self.account.pubkey,
-                    self.tr("Not a member"),
-                    self.tr("Your web of trust"),
-                    self.tr("Certified by {:} members; Certifier of {:} members").format(len(certifiers),
-                                                                                         len(certified))
-                )
-            )
-
-        amount = self.account.amount(self.community)
-        maximum = self.community.monetary_mass
-        # if referential type is quantitative...
-            # display int values
-        localized_amount = self.account.current_ref(amount, self.community, self.app).localized(units=True)
-        localized_minimum = self.account.current_ref(0, self.community, self.app).localized(units=True)
-        localized_maximum = self.account.current_ref(maximum, self.community, self.app).localized(units=True)
-
-        # set infos in label
-        self.label_balance.setText(
-            self.tr("{:}")
-            .format(
-                localized_amount
-            )
-        )
-        self.label_balance_range.setText(
-            self.tr("in [{:} ; {:}]")
-            .format(
-                localized_minimum,
-                localized_maximum
-            )
-        )
-
-    def wallet_context_menu(self, point):
-        index = self.table_wallets.indexAt(point)
-        model = self.table_wallets.model()
-        if index.row() < model.rowCount(QModelIndex()):
-            source_index = model.mapToSource(index)
-
-            name_col = model.sourceModel().columns_types.index('name')
-            name_index = model.index(index.row(),
-                                     name_col)
-
-            pubkey_col = model.sourceModel().columns_types.index('pubkey')
-            pubkey_index = model.sourceModel().index(source_index.row(),
-                                                     pubkey_col)
-
-            pubkey = model.sourceModel().data(pubkey_index, Qt.DisplayRole)
-            menu = QMenu(model.data(index, Qt.DisplayRole), self)
-
-            new_wallet = QAction(self.tr("New Wallet"), self)
-            new_wallet.triggered.connect(self.new_wallet)
-
-            rename = QAction(self.tr("Rename"), self)
-            rename.triggered.connect(self.rename_wallet)
-            rename.setData(name_index)
-
-            copy_pubkey = QAction(self.tr("Copy pubkey to clipboard"), self)
-            copy_pubkey.triggered.connect(self.copy_pubkey_to_clipboard)
-            copy_pubkey.setData(pubkey)
-
-            transfer_to = QMenu()
-            transfer_to.setTitle(self.tr("Transfer to..."))
-            for w in self.account.wallets:
-                if w == self.account.wallets[source_index.row()]:
-                    continue
-                transfer_action = QAction(w.name, self)
-                transfer_action.triggered.connect(self.transfer_to_wallet)
-                wallets = (self.account.wallets[source_index.row()], w)
-                transfer_action.setData(wallets)
-                transfer_to.addAction(transfer_action)
-
-            menu.addAction(new_wallet)
-            menu.addAction(rename)
-            menu.addAction(copy_pubkey)
-            menu.addMenu(transfer_to)
-            # Show the context menu.
-            menu.exec_(QCursor.pos())
-
-    def new_wallet(self):
-        """
-        Create a new wallet
-        """
-        password_asker = PasswordAskerDialog(self.app.current_account)
-        password = password_asker.exec_()
-        if password_asker.result() == QDialog.Rejected:
-            return None
-        # create new wallet by increasing wallet pool size
-        self.account.set_walletpool_size(len(self.account.wallets) + 1, password)
-        # capture new wallet
-        wallet = self.account.wallets[len(self.account.wallets) - 1]
-        # feed cache data of the wallet
-        wallet.refresh_cache(self.community, list())
-        # save wallet cache on disk
-        self.app.save_wallet(self.account, self.account.wallets[len(self.account.wallets) - 1])
-        # save account cache on disk (update number of wallets)
-        self.app.save(self.account)
-        # refresh wallet list in gui
-        self.refresh()
-
-    def rename_wallet(self):
-        index = self.sender().data()
-        self.table_wallets.edit(index)
-
-    def wallet_changed(self):
-        self.table_wallets.resizeColumnsToContents()
-        self.app.save(self.app.current_account)
-
-    def copy_pubkey_to_clipboard(self):
-        data = self.sender().data()
-        clipboard = QApplication.clipboard()
-        if data.__class__ is Wallet:
-            clipboard.setText(data.pubkey)
-        elif data.__class__ is Identity:
-            clipboard.setText(data.pubkey)
-        elif data.__class__ is str:
-            clipboard.setText(data)
-
-    def transfer_to_wallet(self):
-        wallets = self.sender().data()
-        dialog = TransferMoneyDialog(self.app, self.account, self.password_asker)
-        dialog.edit_pubkey.setText(wallets[1].pubkey)
-        dialog.combo_community.setCurrentText(self.community.name)
-        dialog.combo_wallets.setCurrentText(wallets[0].name)
-        dialog.radio_pubkey.setChecked(True)
-        if dialog.exec_() == QDialog.Accepted:
-            currency_tab = self.window().currencies_tabwidget.currentWidget()
-            currency_tab.tab_history.table_history.model().sourceModel().refresh_transfers()
-
-    def send_membership_demand(self):
-        password = self.password_asker.exec_()
-        if self.password_asker.result() == QDialog.Rejected:
-            return
-        asyncio.async(self.account.send_membership(password, self.community, 'IN'))
-
-    def send_membership_leaving(self):
-        reply = QMessageBox.warning(self, self.tr("Warning"),
-                             self.tr("""Are you sure ?
-Sending a leaving demand  cannot be canceled.
-The process to join back the community later will have to be done again.""")
-.format(self.account.pubkey), QMessageBox.Ok | QMessageBox.Cancel)
-        if reply == QMessageBox.Ok:
-            password = self.password_asker.exec_()
-            if self.password_asker.result() == QDialog.Rejected:
-                return
-
-            asyncio.async(self.account.send_membership(password, self.community, 'OUT'))
-
-    def publish_uid(self):
-        reply = QMessageBox.warning(self, self.tr("Warning"),
-                             self.tr("""Are you sure ?
-Publishing your UID can be canceled by Revoke UID.""")
-.format(self.account.pubkey), QMessageBox.Ok | QMessageBox.Cancel)
-        if reply == QMessageBox.Ok:
-            password = self.password_asker.exec_()
-            if self.password_asker.result() == QDialog.Rejected:
-                return
-
-            try:
-                self.account.send_selfcert(password, self.community)
-                toast.display(self.tr("UID Publishing"),
-                              self.tr("Success publishing your UID"))
-            except ValueError as e:
-                QMessageBox.critical(self, self.tr("Publish UID error"),
-                                  str(e))
-            except NoPeerAvailable as e:
-                QMessageBox.critical(self, self.tr("Network error"),
-                                     self.tr("Couldn't connect to network : {0}").format(e),
-                                     QMessageBox.Ok)
-            # except Exception as e:
-            #     QMessageBox.critical(self, self.tr("Error"),
-            #                          "{0}".format(e),
-            #                          QMessageBox.Ok)
-
-    def revoke_uid(self):
-        reply = QMessageBox.warning(self, self.tr("Warning"),
-                                 self.tr("""Are you sure ?
-Revoking your UID can only success if it is not already validated by the network.""")
-.format(self.account.pubkey), QMessageBox.Ok | QMessageBox.Cancel)
-        if reply == QMessageBox.Ok:
-            password = self.password_asker.exec_()
-            if self.password_asker.result() == QDialog.Rejected:
-                return
-
-            asyncio.async(self.account.revoke(password, self.community))
-
-    def refresh_quality_buttons(self):
-        try:
-            if self.account.identity(self.community).published_uid(self.community):
-                logging.debug("UID Published")
-                if self.account.identity(self.community).is_member(self.community):
-                    self.button_membership.setText(self.tr("Renew membership"))
-                    self.button_membership.show()
-                    self.button_publish_uid.hide()
-                    self.button_leaving.show()
-                    self.button_revoke_uid.hide()
-                else:
-                    logging.debug("Not a member")
-                    self.button_membership.setText(self.tr("Send membership demand"))
-                    self.button_membership.show()
-                    self.button_revoke_uid.show()
-                    self.button_leaving.hide()
-                    self.button_publish_uid.hide()
-            else:
-                logging.debug("UID not published")
-                self.button_membership.hide()
-                self.button_leaving.hide()
-                self.button_publish_uid.show()
-                self.button_revoke_uid.hide()
-        except LookupFailureError:
-            self.button_membership.hide()
-            self.button_leaving.hide()
-            self.button_publish_uid.show()
diff --git a/src/cutecoin/gui/wot_tab.py b/src/cutecoin/gui/wot_tab.py
index ec8d5754f830fa4bec443814d1360f328ea96b89..b3457d2fe1e7272882702f10e926909d66cd1b0c 100644
--- a/src/cutecoin/gui/wot_tab.py
+++ b/src/cutecoin/gui/wot_tab.py
@@ -1,28 +1,31 @@
 # -*- coding: utf-8 -*-
 
 import logging
-from cutecoin.core.graph import Graph
-from PyQt5.QtWidgets import QWidget, QComboBox, QLineEdit
-from PyQt5.QtCore import pyqtSlot
-from cutecoin.core.net.api import bma
-from cutecoin.core.registry import BlockchainState
+import asyncio
+from PyQt5.QtWidgets import QWidget, QComboBox, QDialog
+from PyQt5.QtCore import pyqtSlot, QEvent, QLocale, QDateTime
+
+from ..tools.exceptions import MembershipNotFoundError
+from ..tools.decorators import asyncify, once_at_a_time, cancel_once_task
+from ..core.net.api import bma
+from ..core.graph import Graph
+from ..core.registry import BlockchainState
+from .member import MemberDialog
+from .certification import CertificationDialog
+from .transfer import TransferMoneyDialog
+from .contact import ConfigureContactDialog
 from ..gen_resources.wot_tab_uic import Ui_WotTabWidget
 from cutecoin.gui.views.wot import NODE_STATUS_HIGHLIGHTED, NODE_STATUS_SELECTED, NODE_STATUS_OUT, ARC_STATUS_STRONG, \
     ARC_STATUS_WEAK
 
 
 class WotTabWidget(QWidget, Ui_WotTabWidget):
-    def __init__(self, app, account, community, password_asker, parent=None):
+    def __init__(self, app):
         """
         :param cutecoin.core.app.Application app:   Application instance
-        :param cutecoin.core.account.Account account: Account instance
-        :param cutecoin.core.community.Community community: Community instance
-        :param QWidget parent: Parent
         :return:
         """
-        super().__init__(parent)
-        self.parent = parent
-
+        super().__init__()
         # construct from qtDesigner
         self.setupUi(self)
 
@@ -41,18 +44,115 @@ class WotTabWidget(QWidget, Ui_WotTabWidget):
         self.graphicsView.scene().node_contact.connect(self.add_node_as_contact)
         self.graphicsView.scene().node_member.connect(self.identity_informations)
 
-        self.account = account
-        self.community = community
-        self.password_asker = password_asker
+        self.account = None
+        self.community = None
+        self.password_asker = None
         self.app = app
+        self.draw_task = None
 
         # nodes list for menu from search
         self.nodes = list()
 
         # create node metadata from account
         self._current_identity = None
-        self.draw_graph(self.account.identity(self.community))
-        self.community.network.new_block_mined.connect(self.refresh)
+
+    def cancel_once_tasks(self):
+        cancel_once_task(self, self.draw_graph)
+        cancel_once_task(self, self.refresh_informations_frame)
+        cancel_once_task(self, self.reset)
+
+    def change_account(self, account, password_asker):
+        self.account = account
+        self.password_asker = password_asker
+
+    def change_community(self, community):
+        if self.community:
+            self.community.network.new_block_mined.disconnect(self.refresh)
+        if community:
+            community.network.new_block_mined.connect(self.refresh)
+        self.community = community
+        self.reset()
+
+    @once_at_a_time
+    @asyncify
+    @asyncio.coroutine
+    def refresh_informations_frame(self):
+        parameters = self.community.parameters
+        try:
+            identity = yield from self.account.identity(self.community)
+            membership = identity.membership(self.community)
+            renew_block = membership['blockNumber']
+            last_renewal = self.community.get_block(renew_block)['medianTime']
+            expiration = last_renewal + parameters['sigValidity']
+        except MembershipNotFoundError:
+            last_renewal = None
+            expiration = None
+
+        certified = yield from identity.unique_valid_certified_by(self.app.identities_registry, self.community)
+        certifiers = yield from identity.unique_valid_certifiers_of(self.app.identities_registry, self.community)
+        if last_renewal and expiration:
+            date_renewal = QLocale.toString(
+                QLocale(),
+                QDateTime.fromTime_t(last_renewal).date(), QLocale.dateFormat(QLocale(), QLocale.LongFormat)
+            )
+            date_expiration = QLocale.toString(
+                QLocale(),
+                QDateTime.fromTime_t(expiration).date(), QLocale.dateFormat(QLocale(), QLocale.LongFormat)
+            )
+
+            if self.account.pubkey in self.community.members_pubkeys():
+                # set infos in label
+                self.label_general.setText(
+                    self.tr("""
+                    <table cellpadding="5">
+                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
+                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
+                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
+                    </table>
+                    """).format(
+                        self.account.name, self.account.pubkey,
+                        self.tr("Membership"),
+                        self.tr("Last renewal on {:}, expiration on {:}").format(date_renewal, date_expiration),
+                        self.tr("Your web of trust"),
+                        self.tr("Certified by {:} members; Certifier of {:} members").format(len(certifiers),
+                                                                                             len(certified))
+                    )
+                )
+            else:
+                # set infos in label
+                self.label_general.setText(
+                    self.tr("""
+                    <table cellpadding="5">
+                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
+                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
+                    <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
+                    </table>
+                    """).format(
+                        self.account.name, self.account.pubkey,
+                        self.tr("Not a member"),
+                        self.tr("Last renewal on {:}, expiration on {:}").format(date_renewal, date_expiration),
+                        self.tr("Your web of trust"),
+                        self.tr("Certified by {:} members; Certifier of {:} members").format(len(certifiers),
+                                                                                             len(certified))
+                    )
+                )
+        else:
+            # set infos in label
+            self.label_general.setText(
+                self.tr("""
+                <table cellpadding="5">
+                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
+                <tr><td align="right"><b>{:}</b></td></tr>
+                <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
+                </table>
+                """).format(
+                    self.account.name, self.account.pubkey,
+                    self.tr("Not a member"),
+                    self.tr("Your web of trust"),
+                    self.tr("Certified by {:} members; Certifier of {:} members").format(len(certifiers),
+                                                                                         len(certified))
+                )
+            )
 
     @pyqtSlot(dict)
     def handle_node_click(self, metadata):
@@ -64,6 +164,9 @@ class WotTabWidget(QWidget, Ui_WotTabWidget):
             )
         )
 
+    @once_at_a_time
+    @asyncify
+    @asyncio.coroutine
     def draw_graph(self, identity):
         """
         Draw community graph centered on the identity
@@ -72,69 +175,65 @@ class WotTabWidget(QWidget, Ui_WotTabWidget):
         """
         logging.debug("Draw graph - " + identity.uid)
 
-        identity_account = self.account.identity(self.community)
-
-        # Disconnect old identity
-        try:
-            if self._current_identity and self._current_identity != identity:
-                self._current_identity.inner_data_changed.disconnect(self.handle_identity_change)
-        except TypeError as e:
-            if "disconnect()" in str(e):
-                logging.debug("Disconnect of old identity failed.")
-
-        #Connect new identity
-        if self._current_identity != identity:
-            self._current_identity = identity
-            identity.inner_data_changed.connect(self.handle_identity_change)
-
-        # create Identity from node metadata
-        certifier_list = identity.unique_valid_certifiers_of(self.app.identities_registry, self.community)
-        certified_list = identity.unique_valid_certified_by(self.app.identities_registry, self.community)
-
-        # create empty graph instance
-        graph = Graph(self.app, self.community)
-
-        # add wallet node
-        node_status = 0
-        if identity == identity_account:
-            node_status += NODE_STATUS_HIGHLIGHTED
-        if identity.is_member(self.community) is False:
-            node_status += NODE_STATUS_OUT
-        node_status += NODE_STATUS_SELECTED
-        graph.add_identity(identity, node_status)
-
-        # populate graph with certifiers-of
-        graph.add_certifier_list(certifier_list, identity, identity_account)
-        # populate graph with certified-by
-        graph.add_certified_list(certified_list, identity, identity_account)
-
-        # draw graph in qt scene
-        self.graphicsView.scene().update_wot(graph.get())
-
-        # if selected member is not the account member...
-        if identity.pubkey != identity_account.pubkey:
-            # add path from selected member to account member
-            path = graph.get_shortest_path_between_members(identity, identity_account)
-            if path:
-                self.graphicsView.scene().update_path(path)
-
-    def reset(self):
+        if self.community:
+            identity_account = yield from self.account.identity(self.community)
+
+            #Connect new identity
+            if self._current_identity != identity:
+                self._current_identity = identity
+
+            # create Identity from node metadata
+            certifier_list = yield from identity.unique_valid_certifiers_of(self.app.identities_registry,
+                                                                            self.community)
+            certified_list = yield from identity.unique_valid_certified_by(self.app.identities_registry,
+                                                                           self.community)
+
+            # create empty graph instance
+            graph = Graph(self.app, self.community)
+
+            # add wallet node
+            node_status = 0
+            if identity == identity_account:
+                node_status += NODE_STATUS_HIGHLIGHTED
+            if identity.is_member(self.community) is False:
+                node_status += NODE_STATUS_OUT
+            node_status += NODE_STATUS_SELECTED
+            graph.add_identity(identity, node_status)
+
+            # populate graph with certifiers-of
+            yield from graph.add_certifier_list(certifier_list, identity, identity_account)
+            # populate graph with certified-by
+            yield from graph.add_certified_list(certified_list, identity, identity_account)
+
+            # draw graph in qt scene
+            self.graphicsView.scene().update_wot(graph.get())
+
+            # if selected member is not the account member...
+            if identity.pubkey != identity_account.pubkey:
+                # add path from selected member to account member
+                path = yield from graph.get_shortest_path_between_members(identity, identity_account)
+                if path:
+                    self.graphicsView.scene().update_path(path)
+
+    @once_at_a_time
+    @asyncify
+    @asyncio.coroutine
+    def reset(self, checked=False):
         """
         Reset graph scene to wallet identity
         """
-        self.draw_graph(
-            self.account.identity(self.community)
-        )
+        if self.account:
+            identity = yield from self.account.identity(self.community)
+            self.draw_graph(identity)
 
     def refresh(self):
         """
         Refresh graph scene to current metadata
         """
-        self.draw_graph(self._current_identity)
-
-    @pyqtSlot(str)
-    def handle_identity_change(self, request):
-        self.refresh()
+        if self._current_identity:
+            self.draw_graph(self._current_identity)
+        else:
+            self.reset()
 
     def search(self):
         """
@@ -185,7 +284,8 @@ class WotTabWidget(QWidget, Ui_WotTabWidget):
             metadata['id'],
             BlockchainState.VALIDATED
         )
-        self.parent.identity_informations(identity)
+        dialog = MemberDialog(self.app, self.account, self.community, identity)
+        dialog.exec_()
 
     def sign_node(self, metadata):
         identity = self.app.identities_registry.from_handled_data(
@@ -193,7 +293,8 @@ class WotTabWidget(QWidget, Ui_WotTabWidget):
             metadata['id'],
             BlockchainState.VALIDATED
         )
-        self.parent.certify_identity(identity)
+        CertificationDialog.certify_identity(self.app, self.account, self.password_asker,
+                                             self.community, identity)
 
     def send_money_to_node(self, metadata):
         identity = self.app.identities_registry.from_handled_data(
@@ -201,20 +302,30 @@ class WotTabWidget(QWidget, Ui_WotTabWidget):
             metadata['id'],
             BlockchainState.VALIDATED
         )
-        self.parent.send_money_to_identity(identity)
+        result = TransferMoneyDialog.send_money_to_identity(self.app, self.account, self.password_asker,
+                                                            self.community, identity)
+        if result == QDialog.Accepted:
+            currency_tab = self.window().currencies_tabwidget.currentWidget()
+            currency_tab.tab_history.table_history.model().sourceModel().refresh_transfers()
 
     def add_node_as_contact(self, metadata):
         # check if contact already exists...
         if metadata['id'] == self.account.pubkey \
                 or metadata['id'] in [contact['pubkey'] for contact in self.account.contacts]:
             return False
-        self.parent.add_identity_as_contact({'name': metadata['text'],
-                                             'pubkey': metadata['id']})
+        dialog = ConfigureContactDialog(self.account, self.window(), {'name': metadata['text'],
+                                                                      'pubkey': metadata['id']})
+        result = dialog.exec_()
+        if result == QDialog.Accepted:
+            self.window().refresh_contacts()
 
-    def get_block_mediantime(self, number):
-        try:
-            block = self.community.get_block(number)
-        except Exception as e:
-            logging.debug('community.get_block request error : ' + str(e))
-            return False
-        return block.mediantime
+    def changeEvent(self, event):
+        """
+        Intercepte LanguageChange event to translate UI
+        :param QEvent QEvent: Event
+        :return:
+        """
+        if event.type() == QEvent.LanguageChange:
+            self.retranslateUi(self)
+            self.refresh()
+        return super(WotTabWidget, self).changeEvent(event)
diff --git a/src/cutecoin/main.py b/src/cutecoin/main.py
index 1d4a211e351da6b53d6d84a779e1c478c5072fbf..fec1fbbbdd19ad8d3973a8ff365df2effba3845e 100755
--- a/src/cutecoin/main.py
+++ b/src/cutecoin/main.py
@@ -8,6 +8,8 @@ import sys
 import asyncio
 import logging
 import os
+# To force cx_freeze import
+import PyQt5.QtSvg
 
 from quamash import QEventLoop
 from PyQt5.QtWidgets import QApplication
diff --git a/src/cutecoin/models/identities.py b/src/cutecoin/models/identities.py
index 1a66f0f92b18518a5cb59bc0066a6992cbf0a690..431416c03d8edc0b199c0ea6264618c0e26d7350 100644
--- a/src/cutecoin/models/identities.py
+++ b/src/cutecoin/models/identities.py
@@ -6,10 +6,12 @@ Created on 5 févr. 2014
 
 from ..core.net.api import bma as qtbma
 from ..tools.exceptions import NoPeerAvailable, MembershipNotFoundError
+from ..tools.decorators import asyncify, once_at_a_time, cancel_once_task
 from PyQt5.QtCore import QAbstractTableModel, QSortFilterProxyModel, Qt, \
                         QDateTime, QModelIndex, QLocale
 from PyQt5.QtGui import QColor
 import logging
+import asyncio
 
 
 class IdentitiesFilterProxyModel(QSortFilterProxyModel):
@@ -21,6 +23,10 @@ class IdentitiesFilterProxyModel(QSortFilterProxyModel):
         self.community = sourceModel.community
         super().setSourceModel(sourceModel)
 
+    def change_community(self, community):
+        self.community = community
+        self.sourceModel().change_community(community)
+
     def lessThan(self, left, right):
         """
         Sort table by given column number.
@@ -39,7 +45,7 @@ class IdentitiesFilterProxyModel(QSortFilterProxyModel):
         expiration_index = self.sourceModel().index(source_index.row(), expiration_col)
         expiration_data = self.sourceModel().data(expiration_index, Qt.DisplayRole)
         current_time = QDateTime().currentDateTime().toMSecsSinceEpoch()
-        sig_validity = self.community.parameters['sigValidity']
+        sig_validity = self.sourceModel().sig_validity()
         warning_expiration_time = int(sig_validity / 3)
         #logging.debug("{0} > {1}".format(current_time, expiration_data))
         if expiration_data is not None:
@@ -73,12 +79,12 @@ class IdentitiesTableModel(QAbstractTableModel):
     A Qt abstract item model to display communities in a tree
     """
 
-    def __init__(self, community, parent=None):
+    def __init__(self, parent=None):
         """
         Constructor
         """
         super().__init__(parent)
-        self.community = community
+        self.community = None
         self.columns_titles = {'uid': self.tr('UID'),
                                'pubkey': self.tr('Pubkey'),
                                'renewed': self.tr('Renewed'),
@@ -86,8 +92,14 @@ class IdentitiesTableModel(QAbstractTableModel):
                                'validation': self.tr('Validation')}
         self.columns_ids = ('uid', 'pubkey', 'renewed', 'expiration')
         self.identities_data = []
-        self._identities = []
-        self._refresh_slots = []
+        self._sig_validity = 0
+
+    def change_community(self, community):
+        cancel_once_task(self, self.refresh_identities)
+        self.community = community
+
+    def sig_validity(self):
+        return self._sig_validity
 
     @property
     def pubkeys(self):
@@ -96,16 +108,20 @@ class IdentitiesTableModel(QAbstractTableModel):
         """
         return [i[1] for i in self.identities_data]
 
+    @asyncio.coroutine
     def identity_data(self, identity):
         try:
-            join_date = identity.get_join_date(self.community)
-            expiration_date = identity.get_expiration_date(self.community)
+            join_date = yield from identity.get_join_date(self.community)
+            expiration_date = yield from identity.get_expiration_date(self.community)
         except MembershipNotFoundError:
             join_date = None
             expiration_date = None
 
         return (identity.uid, identity.pubkey, join_date, expiration_date)
 
+    @once_at_a_time
+    @asyncify
+    @asyncio.coroutine
     def refresh_identities(self, identities):
         """
         Change the identities to display
@@ -113,49 +129,15 @@ class IdentitiesTableModel(QAbstractTableModel):
         :param cutecoin.core.registry.IdentitiesRegistry identities: The new identities to display
         """
         logging.debug("Refresh {0} identities".format(len(identities)))
-
-        # We disconnect identities from their local slots
-        for (index, identity) in enumerate(self._identities):
-            identity.inner_data_changed.disconnect(self._refresh_slots[index])
-
-        self.identities_data = []
-        self._identities = []
-        self._refresh_slots = []
         self.beginResetModel()
+        self.identities_data = []
         for identity in identities:
-            logging.debug(identity)
-
-            # Connection
-            refresh_slot = lambda req, identity=identity: self.refresh_identity(req, identity)
-            identity.inner_data_changed.connect(refresh_slot)
-
-            self._identities.append(identity)
-            self._refresh_slots.append(refresh_slot)
-            self.identities_data.append(self.identity_data(identity))
+            data = yield from self.identity_data(identity)
+            self.identities_data.append(data)
+        parameters = yield from self.community.parameters()
+        self._sig_validity = parameters['sigValidity']
         self.endResetModel()
 
-    def refresh_identity(self, request, identity):
-        """
-        Refresh an identity when its inner_data changed
-        :param cutecoin.core.registry.Identity identity: The refreshed identity
-        """
-        logging.debug("Refresh {0} because of {1}".format(identity, request))
-        try:
-            index = self._identities.index(identity)
-            self.identities_data[index] = self.identity_data(identity)
-            if request == str(qtbma.wot.Lookup):
-                model_index_0 = self.createIndex(index, self.columns_ids.index('uid'))
-                model_index_max = self.createIndex(index, self.columns_ids.index('pubkey'))
-                self.dataChanged.emit(model_index_0, model_index_max)
-            elif request in (str(qtbma.blockchain.Membership),
-                             str(qtbma.blockchain.Block),
-                             str(qtbma.blockchain.Parameters)):
-                model_index_0 = self.createIndex(index, self.columns_ids.index('renewed'))
-                model_index_max = self.createIndex(index, self.columns_ids.index('expiration'))
-                self.dataChanged.emit(model_index_0, model_index_max)
-        except ValueError:
-            logging.debug("Identity {0} is not in list : {1}".format(identity, self.identities_data))
-
     def rowCount(self, parent):
         return len(self.identities_data)
 
diff --git a/src/cutecoin/models/network.py b/src/cutecoin/models/network.py
index 899752684bd10b345958709650c9503b96dccd8b..fdf42e0ec616491ebe05c9093c1a7c6055f9dd4d 100644
--- a/src/cutecoin/models/network.py
+++ b/src/cutecoin/models/network.py
@@ -5,11 +5,13 @@ Created on 5 févr. 2014
 """
 
 import logging
+import asyncio
 
 from PyQt5.QtCore import QAbstractTableModel, Qt, QVariant, QSortFilterProxyModel
 from PyQt5.QtGui import QColor, QFont
 
 from ..tools.exceptions import NoPeerAvailable
+from ..tools.decorators import asyncify
 from cutecoin.core.net.node import Node
 
 
@@ -19,7 +21,11 @@ class NetworkFilterProxyModel(QSortFilterProxyModel):
         self.community = None
 
     def columnCount(self, parent):
-        return self.sourceModel().columnCount(None) - 1
+        return self.sourceModel().columnCount(None) - 2
+
+    def change_community(self, community):
+        self.community = community
+        self.sourceModel().change_community(community)
 
     def setSourceModel(self, sourceModel):
         self.community = sourceModel.community
@@ -66,6 +72,13 @@ class NetworkFilterProxyModel(QSortFilterProxyModel):
             and role == Qt.DisplayRole:
             return source_data[:5]
 
+        if index.column() == source_model.columns_types.index('current_block') \
+            and role == Qt.DisplayRole:
+            if source_data == -1:
+                return ""
+            else:
+                return source_data
+
         if index.column() == source_model.columns_types.index('current_hash') \
             and role == Qt.DisplayRole:
             return source_data[:10]
@@ -108,7 +121,8 @@ class NetworkTableModel(QAbstractTableModel):
             'pubkey',
             'software',
             'version',
-            'is_root'
+            'is_root',
+            'state'
         )
         self.node_colors = {
             Node.ONLINE: QColor('#99ff99'),
@@ -122,23 +136,13 @@ class NetworkTableModel(QAbstractTableModel):
             Node.DESYNCED: self.tr('Unsynchronized'),
             Node.CORRUPTED: self.tr('Corrupted')
         }
+        self.nodes_data = []
 
-    @property
-    def nodes(self):
-        return self.community.network.nodes
-
-    def rowCount(self, parent):
-        return len(self.nodes)
-
-    def columnCount(self, parent):
-        return len(self.columns_types)
-
-    def headerData(self, section, orientation, role):
-        if role != Qt.DisplayRole:
-            return QVariant()
-
-        return self.columns_types[section]
+    def change_community(self, community):
+        self.community = community
+        self.refresh_nodes()
 
+    @asyncio.coroutine
     def data_node(self, node: Node) -> tuple:
         """
         Return node data tuple
@@ -146,7 +150,8 @@ class NetworkTableModel(QAbstractTableModel):
         :return:
         """
         try:
-            is_member = node.pubkey in self.community.members_pubkeys()
+            members_pubkey = yield from self.community.members_pubkeys()
+            is_member = node.pubkey in members_pubkey
         except NoPeerAvailable as e:
             logging.error(e)
             is_member = None
@@ -162,8 +167,31 @@ class NetworkTableModel(QAbstractTableModel):
 
         is_root = self.community.network.is_root_node(node)
 
-        return (address, port, node.block_number, node.block_hash, node.uid,
-                is_member, node.pubkey, node.software, node.version, is_root)
+        return (address, port, node.block['number'], node.block['hash'], node.uid,
+                is_member, node.pubkey, node.software, node.version, is_root, node.state)
+
+    @asyncify
+    @asyncio.coroutine
+    def refresh_nodes(self):
+        self.beginResetModel()
+        self.nodes_data = []
+        if self.community:
+            for node in self.community.network.nodes:
+                data = yield from self.data_node(node)
+                self.nodes_data.append(data)
+        self.endResetModel()
+
+    def rowCount(self, parent):
+        return len(self.nodes_data)
+
+    def columnCount(self, parent):
+        return len(self.columns_types)
+
+    def headerData(self, section, orientation, role):
+        if role != Qt.DisplayRole:
+            return QVariant()
+
+        return self.columns_types[section]
 
     def data(self, index, role):
         row = index.row()
@@ -172,13 +200,13 @@ class NetworkTableModel(QAbstractTableModel):
         if not index.isValid():
             return QVariant()
 
-        node = self.nodes[row]
+        node = self.nodes_data[row]
         if role == Qt.DisplayRole:
-            return self.data_node(node)[col]
+            return node[col]
         if role == Qt.BackgroundColorRole:
-            return self.node_colors[node.state]
+            return self.node_colors[node[self.columns_types.index('state')]]
         if role == Qt.ToolTipRole:
-            return self.node_states[node.state]
+            return self.node_states[node[self.columns_types.index('state')]]
 
         return QVariant()
 
diff --git a/src/cutecoin/models/txhistory.py b/src/cutecoin/models/txhistory.py
index 4576cdaf82905efdca9e996902fb27b9f441d944..bd22eccb338102552f416e9b0f4f278962fc3c2d 100644
--- a/src/cutecoin/models/txhistory.py
+++ b/src/cutecoin/models/txhistory.py
@@ -6,8 +6,9 @@ Created on 5 févr. 2014
 
 import datetime
 import logging
-from ..core import money
+import asyncio
 from ..core.transfer import Transfer
+from ..tools.decorators import asyncify, once_at_a_time, cancel_once_task
 from PyQt5.QtCore import QAbstractTableModel, Qt, QVariant, QSortFilterProxyModel, \
     QDateTime, QLocale, QModelIndex
 
@@ -51,14 +52,14 @@ class TxFilterProxyModel(QSortFilterProxyModel):
         if in_period(date):
             # calculate sum total payments
             payment = source_model.data(
-                source_model.index(sourceRow, source_model.columns_types.index('payment')),
+                source_model.index(sourceRow, source_model.columns_types.index('amount')),
                 Qt.DisplayRole
             )
             if payment:
                 self.payments += int(payment)
             # calculate sum total deposits
             deposit = source_model.data(
-                source_model.index(sourceRow, source_model.columns_types.index('deposit')),
+                source_model.index(sourceRow, source_model.columns_types.index('amount')),
                 Qt.DisplayRole
             )
             if deposit:
@@ -67,7 +68,7 @@ class TxFilterProxyModel(QSortFilterProxyModel):
         return in_period(date)
 
     def columnCount(self, parent):
-        return self.sourceModel().columnCount(None) - 4
+        return self.sourceModel().columnCount(None) - 5
 
     def setSourceModel(self, sourceModel):
         self.community = sourceModel.community
@@ -111,9 +112,7 @@ class TxFilterProxyModel(QSortFilterProxyModel):
                 )
             if source_index.column() == model.columns_types.index('payment') or \
                     source_index.column() == model.columns_types.index('deposit'):
-                if source_data is not "":
-                    return self.account.current_ref(source_data, self.community, self.app)\
-                        .diff_localized(international_system=self.app.preferences['international_system_of_units'])
+                return source_data
 
         if role == Qt.FontRole:
             font = QFont()
@@ -153,7 +152,7 @@ class TxFilterProxyModel(QSortFilterProxyModel):
                     current_validations = self.community.network.latest_block_number - block_data
                 else:
                     current_validations = 0
-                max_validations = self.community.network.fork_window(self.community.members_pubkeys()) + 1
+                max_validations = self.sourceModel().max_validations()
 
                 if self.app.preferences['expert_mode']:
                     return self.tr("{0} / {1} validations").format(current_validations, max_validations)
@@ -172,16 +171,17 @@ class HistoryTableModel(QAbstractTableModel):
     A Qt abstract item model to display communities in a tree
     """
 
-    def __init__(self, app, community, parent=None):
+    def __init__(self, app, account, community, parent=None):
         """
         Constructor
         """
         super().__init__(parent)
         self.app = app
+        self.account = account
         self.community = community
-        self.account._current_ref
         self.transfers_data = []
         self.refresh_transfers()
+        self._max_validations = 0
 
         self.columns_types = (
             'date',
@@ -192,7 +192,8 @@ class HistoryTableModel(QAbstractTableModel):
             'state',
             'txid',
             'pubkey',
-            'block_number'
+            'block_number',
+            'amount'
         )
 
         self.column_headers = (
@@ -207,16 +208,25 @@ class HistoryTableModel(QAbstractTableModel):
             'Block Number'
         )
 
-    @property
-    def account(self):
-        return self.app.current_account
+    def change_account(self, account):
+        cancel_once_task(self, self.refresh_transfers)
+        self.account = account
+
+    def change_community(self, community):
+        cancel_once_task(self, self.refresh_transfers)
+        self.community = community
 
-    @property
     def transfers(self):
-        return self.account.transfers(self.community) + self.account.dividends(self.community)
+        if self.account:
+            return self.account.transfers(self.community) + self.account.dividends(self.community)
+        else:
+            return []
 
+    @asyncio.coroutine
     def data_received(self, transfer):
         amount = transfer.metadata['amount']
+        deposit = yield from self.account.current_ref(transfer.metadata['amount'], self.community, self.app)\
+            .diff_localized(international_system=self.app.preferences['international_system_of_units'])
         comment = ""
         if transfer.metadata['comment'] != "":
             comment = transfer.metadata['comment']
@@ -229,12 +239,15 @@ class HistoryTableModel(QAbstractTableModel):
         txid = transfer.metadata['txid']
         block_number = transfer.metadata['block']
 
-        return (date_ts, sender, "", amount,
+        return (date_ts, sender, "", deposit,
                 comment, transfer.state, txid,
-                transfer.metadata['issuer'], block_number)
+                transfer.metadata['issuer'], block_number, amount)
 
+    @asyncio.coroutine
     def data_sent(self, transfer):
         amount = transfer.metadata['amount']
+        paiment = yield from self.account.current_ref(transfer.metadata['amount'], self.community, self.app)\
+            .diff_localized(international_system=self.app.preferences['international_system_of_units'])
         comment = ""
         if transfer.metadata['comment'] != "":
             comment = transfer.metadata['comment']
@@ -247,12 +260,15 @@ class HistoryTableModel(QAbstractTableModel):
         txid = transfer.metadata['txid']
         block_number = transfer.metadata['block']
 
-        return (date_ts, receiver, amount,
+        return (date_ts, receiver, paiment,
                 "", comment, transfer.state, txid,
-                transfer.metadata['receiver'], block_number)
+                transfer.metadata['receiver'], block_number, amount)
 
+    @asyncio.coroutine
     def data_dividend(self, dividend):
         amount = dividend['amount']
+        deposit = yield from self.account.current_ref(dividend['amount'], self.community, self.app)\
+            .diff_localized(international_system=self.app.preferences['international_system_of_units'])
         comment = ""
         receiver = self.account.name
         date_ts = dividend['time']
@@ -261,22 +277,34 @@ class HistoryTableModel(QAbstractTableModel):
         state = dividend['state']
 
         return (date_ts, receiver, "",
-                amount, "", state, id,
-                self.account.pubkey, block_number)
+                deposit, "", state, id,
+                self.account.pubkey, block_number, amount)
 
+    @once_at_a_time
+    @asyncify
+    @asyncio.coroutine
     def refresh_transfers(self):
         self.beginResetModel()
         self.transfers_data = []
-        for transfer in self.transfers:
-            if type(transfer) is Transfer:
-                if transfer.metadata['issuer'] == self.account.pubkey:
-                    self.transfers_data.append(self.data_sent(transfer))
-                else:
-                    self.transfers_data.append(self.data_received(transfer))
-            elif type(transfer) is dict:
-                self.transfers_data.append(self.data_dividend(transfer))
+        if self.community:
+            for transfer in self.transfers():
+                data = None
+                if type(transfer) is Transfer:
+                    if transfer.metadata['issuer'] == self.account.pubkey:
+                        data = yield from self.data_sent(transfer)
+                    else:
+                        data = yield from self.data_received(transfer)
+                elif type(transfer) is dict:
+                    data = yield from self.data_dividend(transfer)
+                if data:
+                    self.transfers_data.append(data)
+                members_pubkeys = yield from self.community.members_pubkeys()
+                self._max_validations = self.community.network.fork_window(members_pubkeys) + 1
         self.endResetModel()
 
+    def max_validations(self):
+        return self._max_validations
+
     def rowCount(self, parent):
         return len(self.transfers_data)
 
@@ -284,14 +312,15 @@ class HistoryTableModel(QAbstractTableModel):
         return len(self.columns_types)
 
     def headerData(self, section, orientation, role):
-        if role == Qt.DisplayRole:
-            if self.columns_types[section] == 'payment' or self.columns_types[section] == 'deposit':
-                return '{:}\n({:})'.format(
-                    self.column_headers[section],
-                    self.account.current_ref.diff_units(self.community.short_currency)
-                )
-
-            return self.column_headers[section]
+        if self.account and self.community:
+            if role == Qt.DisplayRole:
+                if self.columns_types[section] == 'payment' or self.columns_types[section] == 'deposit':
+                    return '{:}\n({:})'.format(
+                        self.column_headers[section],
+                        self.account.current_ref.diff_units(self.community.short_currency)
+                    )
+
+                return self.column_headers[section]
 
     def data(self, index, role):
         row = index.row()
diff --git a/src/cutecoin/tests/core/__init__.py b/src/cutecoin/tests/core/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..39ab2a0b56350baad834cb7fb0cfecb8223e1fcd
--- /dev/null
+++ b/src/cutecoin/tests/core/__init__.py
@@ -0,0 +1 @@
+__author__ = 'inso'
diff --git a/src/cutecoin/tests/core/txhistory/__init__.py b/src/cutecoin/tests/core/txhistory/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..39ab2a0b56350baad834cb7fb0cfecb8223e1fcd
--- /dev/null
+++ b/src/cutecoin/tests/core/txhistory/__init__.py
@@ -0,0 +1 @@
+__author__ = 'inso'
diff --git a/src/cutecoin/tests/core/txhistory/test_txhistory_loading.py b/src/cutecoin/tests/core/txhistory/test_txhistory_loading.py
new file mode 100644
index 0000000000000000000000000000000000000000..26e38fa3d3cb43c40f140984a069cc15ec1d94e9
--- /dev/null
+++ b/src/cutecoin/tests/core/txhistory/test_txhistory_loading.py
@@ -0,0 +1,78 @@
+import sys
+import unittest
+import asyncio
+import quamash
+import time
+import logging
+from ucoinpy.documents.peer import BMAEndpoint as PyBMAEndpoint
+from PyQt5.QtCore import QLocale, Qt
+from PyQt5.QtTest import QTest
+from cutecoin.tests.mocks.bma import nice_blockchain
+from cutecoin.tests.mocks.access_manager import MockNetworkAccessManager
+from cutecoin.core.registry.identities import IdentitiesRegistry
+from cutecoin.core.app import Application
+from cutecoin.core import Account, Community, Wallet
+from cutecoin.core.net import Network, Node
+from cutecoin.core.net.endpoint import BMAEndpoint
+from cutecoin.core.net.api.bma.access import BmaAccess
+from cutecoin.tests import get_application
+from cutecoin.core.net.api import bma as qtbma
+
+
+class TestTxHistory(unittest.TestCase):
+    def setUp(self):
+        self.qapplication = get_application()
+        self.network_manager = MockNetworkAccessManager()
+        QLocale.setDefault(QLocale("en_GB"))
+        self.lp = quamash.QEventLoop(self.qapplication)
+        asyncio.set_event_loop(self.lp)
+        self.identities_registry = IdentitiesRegistry({})
+
+        self.application = Application(self.qapplication, self.lp, self.network_manager, self.identities_registry)
+        self.application.preferences['notifications'] = False
+
+        self.endpoint = BMAEndpoint(PyBMAEndpoint("", "127.0.0.1", "", 50000))
+        self.node = Node(self.network_manager, "test_currency", [self.endpoint],
+                         "", "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk",
+                         nice_blockchain.bma_blockchain_current, Node.ONLINE,
+                         time.time(), {}, "ucoin", "0.14.0", 0)
+        self.network = Network.create(self.network_manager, self.node)
+        self.bma_access = BmaAccess.create(self.network)
+        self.community = Community("test_currency", self.network, self.bma_access)
+
+        self.wallet = Wallet(0, "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+                             "Wallet 1", self.identities_registry)
+        self.wallet.init_cache(self.application, self.community)
+
+        # Salt/password : "testcutecoin/testcutecoin"
+        # Pubkey : 7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ
+        self.account = Account("testcutecoin", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+                               "john", [self.community], [self.wallet], [], self.identities_registry)
+
+    def tearDown(self):
+        try:
+            self.lp.close()
+        finally:
+            asyncio.set_event_loop(None)
+
+    # this test fails with old algorithm
+    def notest_txhistory_reload(self):
+        mock = nice_blockchain.get_mock()
+        time.sleep(2)
+        logging.debug(mock.pretend_url)
+        self.network_manager.set_mock_path(mock.pretend_url)
+        received_list = []
+        self.lp.run_until_complete(self.wallet.caches[self.community.currency].
+                                   refresh(self.community, received_list))
+        self.assertEquals(len(received_list), 2)
+        received_value = sum([r.metadata['amount'] for r in received_list])
+        self.assertEqual(received_value, 60)
+        self.assertEqual(len(self.wallet.dividends(self.community)), 2)
+        dividends_value = sum([ud['amount'] for ud in self.wallet.dividends(self.community)])
+        self.assertEqual(dividends_value, 15)
+        mock.delete_mock()
+
+if __name__ == '__main__':
+    logging.basicConfig(stream=sys.stderr)
+    logging.getLogger().setLevel(logging.DEBUG)
+    unittest.main()
diff --git a/src/cutecoin/tests/gui/__init__.py b/src/cutecoin/tests/gui/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..39ab2a0b56350baad834cb7fb0cfecb8223e1fcd
--- /dev/null
+++ b/src/cutecoin/tests/gui/__init__.py
@@ -0,0 +1 @@
+__author__ = 'inso'
diff --git a/src/cutecoin/tests/main_window/__init__.py b/src/cutecoin/tests/gui/certification/__init__.py
similarity index 100%
rename from src/cutecoin/tests/main_window/__init__.py
rename to src/cutecoin/tests/gui/certification/__init__.py
diff --git a/src/cutecoin/tests/gui/certification/test_certification.py b/src/cutecoin/tests/gui/certification/test_certification.py
new file mode 100644
index 0000000000000000000000000000000000000000..71c634b046050d18fdf4a71ca4bd7e91843aaa43
--- /dev/null
+++ b/src/cutecoin/tests/gui/certification/test_certification.py
@@ -0,0 +1,99 @@
+import sys
+import unittest
+import asyncio
+import quamash
+import time
+import logging
+from ucoinpy.documents.peer import BMAEndpoint as PyBMAEndpoint
+from PyQt5.QtWidgets import QDialog, QDialogButtonBox
+from PyQt5.QtCore import QLocale, Qt
+from PyQt5.QtTest import QTest
+from cutecoin.tests.mocks.bma import init_new_community
+from cutecoin.tests.mocks.access_manager import MockNetworkAccessManager
+from cutecoin.core.registry.identities import IdentitiesRegistry
+from cutecoin.gui.certification import CertificationDialog
+from cutecoin.gui.password_asker import PasswordAskerDialog
+from cutecoin.core.app import Application
+from cutecoin.core import Account, Community, Wallet
+from cutecoin.core.net import Network, Node
+from cutecoin.core.net.endpoint import BMAEndpoint
+from cutecoin.core.net.api.bma.access import BmaAccess
+from cutecoin.tests import get_application
+from cutecoin.core.net.api import bma as qtbma
+
+
+class TestCertificationDialog(unittest.TestCase):
+    def setUp(self):
+        self.qapplication = get_application()
+        self.network_manager = MockNetworkAccessManager()
+        QLocale.setDefault(QLocale("en_GB"))
+        self.lp = quamash.QEventLoop(self.qapplication)
+        asyncio.set_event_loop(self.lp)
+        self.identities_registry = IdentitiesRegistry({})
+
+        self.application = Application(self.qapplication, self.lp, self.network_manager, self.identities_registry)
+        self.application.preferences['notifications'] = False
+
+        self.endpoint = BMAEndpoint(PyBMAEndpoint("", "127.0.0.1", "", 50000))
+        self.node = Node(self.network_manager, "test_currency", [self.endpoint],
+                         "", "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk",
+                         qtbma.blockchain.Block.null_value, Node.ONLINE,
+                         time.time(), {}, "ucoin", "0.14.0", 0)
+        self.network = Network.create(self.network_manager, self.node)
+        self.bma_access = BmaAccess.create(self.network)
+        self.community = Community("test_currency", self.network, self.bma_access)
+
+        self.wallet = Wallet(0, "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+                             "Wallet 1", self.identities_registry)
+
+        # Salt/password : "testcutecoin/testcutecoin"
+        # Pubkey : 7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ
+        self.account = Account("testcutecoin", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+                               "john", [self.community], [self.wallet], [], self.identities_registry)
+
+        self.password_asker = PasswordAskerDialog(self.account)
+        self.password_asker.password = "testcutecoin"
+        self.password_asker.remember = True
+
+    def tearDown(self):
+        try:
+            self.lp.close()
+        finally:
+            asyncio.set_event_loop(None)
+
+    def test_certification_init_community(self):
+        mock = init_new_community.get_mock()
+        time.sleep(2)
+        logging.debug(mock.pretend_url)
+        self.network_manager.set_mock_path(mock.pretend_url)
+        certification_dialog = CertificationDialog(self.application,
+                                                   self.account,
+                                                   self.password_asker)
+
+        @asyncio.coroutine
+        def open_dialog(certification_dialog):
+            result = yield from certification_dialog.async_exec()
+            self.assertEqual(result, QDialog.Accepted)
+
+        def close_dialog():
+            if certification_dialog.isVisible():
+                certification_dialog.close()
+
+        @asyncio.coroutine
+        def exec_test():
+            yield from asyncio.sleep(1)
+            self.assertEqual(certification_dialog.button_box.button(QDialogButtonBox.Ok).text(), "&Ok")
+            QTest.mouseClick(certification_dialog.radio_pubkey, Qt.LeftButton)
+            QTest.keyClicks(certification_dialog.edit_pubkey, "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn")
+            QTest.mouseClick(certification_dialog.button_box.button(QDialogButtonBox.Ok), Qt.LeftButton)
+
+        self.lp.call_later(15, close_dialog)
+        asyncio.async(exec_test())
+        self.lp.run_until_complete(open_dialog(certification_dialog))
+        mock.delete_mock()
+
+
+if __name__ == '__main__':
+    logging.basicConfig(stream=sys.stderr)
+    logging.getLogger().setLevel(logging.DEBUG)
+    unittest.main()
diff --git a/src/cutecoin/tests/gui/identities_tab/__init__.py b/src/cutecoin/tests/gui/identities_tab/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/cutecoin/tests/gui/identities_tab/test_identities_table.py b/src/cutecoin/tests/gui/identities_tab/test_identities_table.py
new file mode 100644
index 0000000000000000000000000000000000000000..83e54e923d69619a75c5f6dbe27785a61e386160
--- /dev/null
+++ b/src/cutecoin/tests/gui/identities_tab/test_identities_table.py
@@ -0,0 +1,119 @@
+import sys
+import unittest
+import asyncio
+import quamash
+import logging
+import time
+from ucoinpy.documents.peer import BMAEndpoint as PyBMAEndpoint
+from PyQt5.QtWidgets import QDialog
+from PyQt5.QtCore import QLocale, Qt, QPoint
+from PyQt5.QtTest import QTest
+from cutecoin.core.net.api import bma as qtbma
+from cutecoin.tests.mocks.bma import nice_blockchain
+from cutecoin.tests.mocks.access_manager import MockNetworkAccessManager
+from cutecoin.core.registry.identities import IdentitiesRegistry
+from cutecoin.gui.identities_tab import IdentitiesTabWidget
+from cutecoin.gui.password_asker import PasswordAskerDialog
+from cutecoin.core.app import Application
+from cutecoin.core import Account, Community, Wallet
+from cutecoin.core.net import Network, Node
+from cutecoin.core.net.endpoint import BMAEndpoint
+from cutecoin.core.net.api.bma.access import BmaAccess
+from cutecoin.tests import get_application
+
+
+class TestIdentitiesTable(unittest.TestCase):
+    def setUp(self):
+        self.qapplication = get_application()
+        self.network_manager = MockNetworkAccessManager()
+        QLocale.setDefault(QLocale("en_GB"))
+        self.lp = quamash.QEventLoop(self.qapplication)
+        asyncio.set_event_loop(self.lp)
+        self.identities_registry = IdentitiesRegistry()
+
+        self.application = Application(self.qapplication, self.lp, self.network_manager, self.identities_registry)
+        self.application.preferences['notifications'] = False
+
+        self.endpoint = BMAEndpoint(PyBMAEndpoint("", "127.0.0.1", "", 50000))
+        self.node = Node(self.network_manager, "test_currency", [self.endpoint],
+                         "", "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk",
+                         qtbma.blockchain.Block.null_value, Node.ONLINE,
+                         time.time(), {}, "ucoin", "0.14.0", 0)
+        self.network = Network.create(self.network_manager, self.node)
+        self.bma_access = BmaAccess.create(self.network)
+        self.community = Community("test_currency", self.network, self.bma_access)
+
+        self.wallet = Wallet(0, "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+                             "Wallet 1", self.identities_registry)
+
+        # Salt/password : "testcutecoin/testcutecoin"
+        # Pubkey : 7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ
+        self.account = Account("testcutecoin", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+                               "john", [self.community], [self.wallet], [], self.identities_registry)
+
+        self.password_asker = PasswordAskerDialog(self.account)
+        self.password_asker.password = "testcutecoin"
+        self.password_asker.remember = True
+
+    def tearDown(self):
+        try:
+            self.lp.close()
+        finally:
+            asyncio.set_event_loop(None)
+
+    def test_search_identity_found(self):
+        mock = nice_blockchain.get_mock()
+        time.sleep(2)
+        logging.debug(mock.pretend_url)
+        self.network_manager.set_mock_path(mock.pretend_url)
+        identities_tab = IdentitiesTabWidget(self.application)
+        identities_tab.change_account(self.account, self.password_asker)
+        identities_tab.change_community(self.community)
+        future = asyncio.Future()
+
+        def open_widget():
+            identities_tab.show()
+            return future
+
+        def close_dialog():
+            if identities_tab.isVisible():
+                identities_tab.close()
+            future.set_result(True)
+
+        @asyncio.coroutine
+        def exec_test():
+            yield from asyncio.sleep(2)
+            urls = [mock.get_request(i).url for i in range(0, 3)]
+            self.assertTrue('/wot/certifiers-of/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ' in urls,
+                            msg="Not found in {0}".format(urls))
+            self.assertTrue('/wot/certified-by/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ' in urls,
+                            msg="Not found in {0}".format(urls))
+
+            # requests 1 to 3 are for getting certifiers-of and certified-by
+            # on john, + a lookup
+
+            QTest.keyClicks(identities_tab.edit_textsearch, "doe")
+            QTest.mouseClick(identities_tab.button_search, Qt.LeftButton)
+            yield from asyncio.sleep(2)
+            self.assertEqual(mock.get_request(3).method, 'GET')
+            self.assertEqual(mock.get_request(3).url,
+                             '/blockchain/parameters')
+            self.assertEqual(mock.get_request(4).method, 'GET')
+            self.assertEqual(mock.get_request(4).url,
+                             '/wot/lookup/doe')
+            self.assertEqual(mock.get_request(5).method, 'GET')
+            self.assertEqual(mock.get_request(5).url,
+                             '/wot/certifiers-of/FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn')
+            self.assertEqual(identities_tab.table_identities.model().rowCount(), 1)
+            yield from asyncio.sleep(2)
+            self.lp.call_soon(close_dialog)
+
+        asyncio.async(exec_test())
+        self.lp.call_later(15, close_dialog)
+        self.lp.run_until_complete(open_widget())
+        mock.delete_mock()
+
+if __name__ == '__main__':
+    logging.basicConfig( stream=sys.stderr )
+    logging.getLogger().setLevel( logging.DEBUG )
+    unittest.main()
diff --git a/src/cutecoin/tests/gui/main_window/__init__.py b/src/cutecoin/tests/gui/main_window/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/cutecoin/tests/main_window/test_main_window_dialogs.py b/src/cutecoin/tests/gui/main_window/test_main_window_dialogs.py
similarity index 100%
rename from src/cutecoin/tests/main_window/test_main_window_dialogs.py
rename to src/cutecoin/tests/gui/main_window/test_main_window_dialogs.py
diff --git a/src/cutecoin/tests/main_window/test_main_window_menus.py b/src/cutecoin/tests/gui/main_window/test_main_window_menus.py
similarity index 100%
rename from src/cutecoin/tests/main_window/test_main_window_menus.py
rename to src/cutecoin/tests/gui/main_window/test_main_window_menus.py
diff --git a/src/cutecoin/tests/gui/process_cfg_account/__init__.py b/src/cutecoin/tests/gui/process_cfg_account/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/cutecoin/tests/gui/process_cfg_account/test_add_account.py b/src/cutecoin/tests/gui/process_cfg_account/test_add_account.py
new file mode 100644
index 0000000000000000000000000000000000000000..cd6808c164b50e1668a6b507bc436946e1199220
--- /dev/null
+++ b/src/cutecoin/tests/gui/process_cfg_account/test_add_account.py
@@ -0,0 +1,106 @@
+import sys
+import unittest
+import asyncio
+import quamash
+import logging
+from PyQt5.QtWidgets import QDialog
+from PyQt5.QtCore import QLocale, Qt
+from PyQt5.QtTest import QTest
+from cutecoin.tests.mocks.bma import new_blockchain
+from cutecoin.tests.mocks.access_manager import MockNetworkAccessManager
+from cutecoin.core.registry.identities import IdentitiesRegistry
+from cutecoin.gui.process_cfg_account import ProcessConfigureAccount
+from cutecoin.gui.password_asker import PasswordAskerDialog
+from cutecoin.core.app import Application
+from cutecoin.core.account import Account
+from cutecoin.tests import get_application
+
+
+class ProcessAddCommunity(unittest.TestCase):
+    def setUp(self):
+        self.qapplication = get_application()
+        self.network_manager = MockNetworkAccessManager()
+        QLocale.setDefault(QLocale("en_GB"))
+        self.lp = quamash.QEventLoop(self.qapplication)
+        asyncio.set_event_loop(self.lp)
+        self.identities_registry = IdentitiesRegistry({})
+
+        self.application = Application(self.qapplication, self.lp, self.network_manager, self.identities_registry)
+        self.application.preferences['notifications'] = False
+        # Salt/password : "testcutecoin/testcutecoin"
+        # Pubkey : 7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ
+        self.account = Account("testcutecoin", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+                               "test", [], [], [], self.identities_registry)
+        self.password_asker = PasswordAskerDialog(self.account)
+        self.password_asker.password = "testcutecoin"
+        self.password_asker.remember = True
+
+    def tearDown(self):
+        try:
+            self.lp.close()
+        finally:
+            asyncio.set_event_loop(None)
+
+    def test_create_account(self):
+        process_account = ProcessConfigureAccount(self.application,
+                                                    None)
+
+        @asyncio.coroutine
+        def open_dialog(process_account):
+            result = yield from process_account.async_exec()
+            self.assertEqual(result, QDialog.Accepted)
+
+        def close_dialog():
+            if process_account.isVisible():
+                process_account.close()
+
+        @asyncio.coroutine
+        def exec_test():
+            QTest.keyClicks(process_account.edit_account_name, "test")
+            self.assertEqual(process_account.stacked_pages.currentWidget(),
+                             process_account.page_init,
+                             msg="Current widget : {0}".format(process_account.stacked_pages.currentWidget().objectName()))
+            QTest.mouseClick(process_account.button_next, Qt.LeftButton)
+
+            self.assertEqual(process_account.stacked_pages.currentWidget(),
+                             process_account.page_gpg,
+                             msg="Current widget : {0}".format(process_account.stacked_pages.currentWidget().objectName()))
+
+            QTest.keyClicks(process_account.edit_salt, "testcutecoin")
+            self.assertFalse(process_account.button_next.isEnabled())
+            self.assertFalse(process_account.button_generate.isEnabled())
+            QTest.keyClicks(process_account.edit_password, "testcutecoin")
+            self.assertFalse(process_account.button_next.isEnabled())
+            self.assertFalse(process_account.button_generate.isEnabled())
+            QTest.keyClicks(process_account.edit_password_repeat, "wrongpassword")
+            self.assertFalse(process_account.button_next.isEnabled())
+            self.assertFalse(process_account.button_generate.isEnabled())
+            process_account.edit_password_repeat.setText("")
+            QTest.keyClicks(process_account.edit_password_repeat, "testcutecoin")
+            self.assertTrue(process_account.button_next.isEnabled())
+            self.assertTrue(process_account.button_generate.isEnabled())
+            QTest.mouseClick(process_account.button_generate, Qt.LeftButton)
+            self.assertEqual(process_account.label_info.text(),
+                             "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ")
+            QTest.mouseClick(process_account.button_next, Qt.LeftButton)
+
+            self.assertEqual(process_account.stacked_pages.currentWidget(),
+                             process_account.page__communities,
+                             msg="Current widget : {0}".format(process_account.stacked_pages.currentWidget().objectName()))
+            process_account.password_asker.password = "testcutecoin"
+            process_account.password_asker.remember = True
+            yield from asyncio.sleep(1)
+            QTest.mouseClick(process_account.button_next, Qt.LeftButton)
+            self.assertEqual(len(self.application.accounts), 1)
+            self.assertEqual(self.application.current_account.name, "test")
+            self.assertEqual(self.application.preferences['account'], "test")
+            self.assertEqual(len(self.application.current_account.wallets), 1)
+
+        self.lp.call_later(10, close_dialog)
+        asyncio.async(exec_test())
+        self.lp.run_until_complete(open_dialog(process_account))
+
+if __name__ == '__main__':
+    logging.basicConfig( stream=sys.stderr )
+    logging.getLogger().setLevel( logging.DEBUG )
+    unittest.main()
diff --git a/src/cutecoin/tests/gui/process_cfg_community/__init__.py b/src/cutecoin/tests/gui/process_cfg_community/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/cutecoin/tests/gui/process_cfg_community/test_add_community.py b/src/cutecoin/tests/gui/process_cfg_community/test_add_community.py
new file mode 100644
index 0000000000000000000000000000000000000000..dfb224a1995140fbaaedcae1dcd627429fcc674e
--- /dev/null
+++ b/src/cutecoin/tests/gui/process_cfg_community/test_add_community.py
@@ -0,0 +1,204 @@
+import sys
+import unittest
+import asyncio
+import quamash
+import logging
+import time
+from PyQt5.QtWidgets import QDialog
+from PyQt5.QtCore import QLocale, Qt
+from PyQt5.QtTest import QTest
+from cutecoin.tests.mocks.bma import new_blockchain, nice_blockchain
+from cutecoin.tests.mocks.access_manager import MockNetworkAccessManager
+from cutecoin.core.registry.identities import IdentitiesRegistry
+from cutecoin.gui.process_cfg_community import ProcessConfigureCommunity
+from cutecoin.gui.password_asker import PasswordAskerDialog
+from cutecoin.core.app import Application
+from cutecoin.core.account import Account
+from cutecoin.tests import get_application
+
+
+class ProcessAddCommunity(unittest.TestCase):
+    def setUp(self):
+        self.qapplication = get_application()
+        self.network_manager = MockNetworkAccessManager()
+        QLocale.setDefault(QLocale("en_GB"))
+        self.lp = quamash.QEventLoop(self.qapplication)
+        asyncio.set_event_loop(self.lp)
+        self.identities_registry = IdentitiesRegistry({})
+
+        self.application = Application(self.qapplication, self.lp, self.network_manager, self.identities_registry)
+        self.application.preferences['notifications'] = False
+        # Salt/password : "testcutecoin/testcutecoin"
+        # Pubkey : 7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ
+        self.account = Account("testcutecoin", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+                               "test", [], [], [], self.identities_registry)
+        self.password_asker = PasswordAskerDialog(self.account)
+        self.password_asker.password = "testcutecoin"
+        self.password_asker.remember = True
+
+    def tearDown(self):
+        try:
+            self.lp.close()
+        finally:
+            asyncio.set_event_loop(None)
+
+    def test_register_community_empty_blockchain(self):
+        mock = new_blockchain.get_mock()
+        time.sleep(2)
+        logging.debug(mock.pretend_url)
+        self.network_manager.set_mock_path(mock.pretend_url)
+        process_community = ProcessConfigureCommunity(self.application,
+                                                    self.account,
+                                                    None, self.password_asker)
+
+        @asyncio.coroutine
+        def open_dialog(process_community):
+            result = yield from process_community.async_exec()
+            self.assertEqual(result, QDialog.Accepted)
+
+        def close_dialog():
+            if process_community.isVisible():
+                process_community.close()
+
+        @asyncio.coroutine
+        def exec_test():
+            yield from asyncio.sleep(1)
+            QTest.mouseClick(process_community.lineedit_server, Qt.LeftButton)
+            QTest.keyClicks(process_community.lineedit_server, "127.0.0.1")
+            QTest.mouseDClick(process_community.spinbox_port, Qt.LeftButton)
+            process_community.spinbox_port.setValue(50000)
+            self.assertEqual(process_community.stacked_pages.currentWidget(),
+                             process_community.page_node,
+                             msg="Current widget : {0}".format(process_community.stacked_pages.currentWidget().objectName()))
+            self.assertEqual(process_community.lineedit_server.text(), "127.0.0.1")
+            self.assertEqual(process_community.spinbox_port.value(), 50000)
+            QTest.mouseClick(process_community.button_register, Qt.LeftButton)
+            yield from asyncio.sleep(1)
+            self.assertEqual(mock.get_request(0).method, 'GET')
+            self.assertEqual(mock.get_request(0).url, '/network/peering')
+            self.assertEqual(mock.get_request(1).method, 'GET')
+            self.assertEqual(mock.get_request(1).url,
+                             '/wot/certifiers-of/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ')
+            for i in range(2, 5):
+                self.assertEqual(mock.get_request(i).method, 'GET')
+                self.assertEqual(mock.get_request(i).url,
+                                 '/wot/lookup/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ')
+
+            self.assertEqual(mock.get_request(6).method, 'POST')
+            self.assertEqual(mock.get_request(6).url[:8], '/wot/add')
+            self.assertEqual(process_community.label_error.text(), "Broadcasting identity...")
+            yield from asyncio.sleep(1)
+
+            self.assertEqual(process_community.stacked_pages.currentWidget(),
+                             process_community.page_add_nodes,
+                             msg="Current widget : {0}".format(process_community.stacked_pages.currentWidget().objectName()))
+            QTest.mouseClick(process_community.button_next, Qt.LeftButton)
+
+        self.lp.call_later(15, close_dialog)
+        asyncio.async(exec_test())
+        self.lp.run_until_complete(open_dialog(process_community))
+        mock.delete_mock()
+
+    def test_connect_community_empty_blockchain(self):
+        mock = new_blockchain.get_mock()
+        time.sleep(2)
+        logging.debug(mock.pretend_url)
+        self.network_manager.set_mock_path(mock.pretend_url)
+        process_community = ProcessConfigureCommunity(self.application,
+                                                    self.account,
+                                                    None, self.password_asker)
+
+        @asyncio.coroutine
+        def open_dialog(process_community):
+            result = yield from process_community.async_exec()
+            self.assertEqual(result, QDialog.Rejected)
+
+        def close_dialog():
+            if process_community.isVisible():
+                process_community.close()
+
+        @asyncio.coroutine
+        def exec_test():
+            yield from asyncio.sleep(1)
+            QTest.mouseClick(process_community.lineedit_server, Qt.LeftButton)
+            QTest.keyClicks(process_community.lineedit_server, "127.0.0.1")
+            QTest.mouseDClick(process_community.spinbox_port, Qt.LeftButton)
+            process_community.spinbox_port.setValue(50000)
+            self.assertEqual(process_community.stacked_pages.currentWidget(),
+                             process_community.page_node,
+                             msg="Current widget : {0}".format(process_community.stacked_pages.currentWidget().objectName()))
+            self.assertEqual(process_community.lineedit_server.text(), "127.0.0.1")
+            self.assertEqual(process_community.spinbox_port.value(), 50000)
+            QTest.mouseClick(process_community.button_connect, Qt.LeftButton)
+            yield from asyncio.sleep(1)
+            self.assertEqual(mock.get_request(0).method, 'GET')
+            self.assertEqual(mock.get_request(0).url, '/network/peering')
+            self.assertEqual(mock.get_request(1).method, 'GET')
+            self.assertEqual(mock.get_request(1).url,
+                             '/wot/certifiers-of/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ')
+            for i in range(2, 5):
+                self.assertEqual(mock.get_request(i).method, 'GET')
+                self.assertEqual(mock.get_request(i).url,
+                                 '/wot/lookup/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ')
+            self.assertEqual(process_community.stacked_pages.currentWidget(),
+                             process_community.page_node,
+                             msg="Current widget : {0}".format(process_community.stacked_pages.currentWidget().objectName()))
+            self.assertEqual(process_community.label_error.text(), "Could not find your identity on the network.")
+            process_community.close()
+
+        self.lp.call_later(15, close_dialog)
+        asyncio.async(exec_test())
+        self.lp.run_until_complete(open_dialog(process_community))
+        mock.delete_mock()
+
+    def test_connect_community_nice_blockchain(self):
+        mock = nice_blockchain.get_mock()
+        time.sleep(2)
+        logging.debug(mock.pretend_url)
+        self.network_manager.set_mock_path(mock.pretend_url)
+        process_community = ProcessConfigureCommunity(self.application,
+                                                    self.account,
+                                                    None, self.password_asker)
+
+        @asyncio.coroutine
+        def open_dialog(process_community):
+            result = yield from process_community.async_exec()
+            self.assertEqual(result, QDialog.Accepted)
+
+        def close_dialog():
+            if process_community.isVisible():
+                process_community.close()
+
+        @asyncio.coroutine
+        def exec_test():
+            yield from asyncio.sleep(1)
+            QTest.mouseClick(process_community.lineedit_server, Qt.LeftButton)
+            QTest.keyClicks(process_community.lineedit_server, "127.0.0.1")
+            QTest.mouseDClick(process_community.spinbox_port, Qt.LeftButton)
+            process_community.spinbox_port.setValue(50000)
+            self.assertEqual(process_community.stacked_pages.currentWidget(),
+                             process_community.page_node,
+                             msg="Current widget : {0}".format(process_community.stacked_pages.currentWidget().objectName()))
+            self.assertEqual(process_community.lineedit_server.text(), "127.0.0.1")
+            self.assertEqual(process_community.spinbox_port.value(), 50000)
+            QTest.mouseClick(process_community.button_connect, Qt.LeftButton)
+            yield from asyncio.sleep(1)
+            self.assertEqual(mock.get_request(0).method, 'GET')
+            self.assertEqual(mock.get_request(0).url, '/network/peering')
+            self.assertEqual(mock.get_request(1).method, 'GET')
+            self.assertEqual(mock.get_request(1).url,
+                             '/wot/certifiers-of/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ')
+            self.assertEqual(process_community.stacked_pages.currentWidget(),
+                             process_community.page_add_nodes,
+                             msg="Current widget : {0}".format(process_community.stacked_pages.currentWidget().objectName()))
+            QTest.mouseClick(process_community.button_next, Qt.LeftButton)
+
+        self.lp.call_later(15, close_dialog)
+        asyncio.async(exec_test())
+        self.lp.run_until_complete(open_dialog(process_community))
+        mock.delete_mock()
+
+if __name__ == '__main__':
+    logging.basicConfig( stream=sys.stderr )
+    logging.getLogger().setLevel( logging.DEBUG )
+    unittest.main()
diff --git a/src/cutecoin/tests/gui/transfer/__init__.py b/src/cutecoin/tests/gui/transfer/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/cutecoin/tests/gui/transfer/test_transfer.py b/src/cutecoin/tests/gui/transfer/test_transfer.py
new file mode 100644
index 0000000000000000000000000000000000000000..55452ccbbfe274193e90aa4d4b533674edb2a44e
--- /dev/null
+++ b/src/cutecoin/tests/gui/transfer/test_transfer.py
@@ -0,0 +1,98 @@
+import sys
+import unittest
+import asyncio
+import quamash
+import time
+import logging
+from ucoinpy.documents.peer import BMAEndpoint as PyBMAEndpoint
+from PyQt5.QtWidgets import QDialog, QDialogButtonBox
+from PyQt5.QtCore import QLocale, Qt
+from PyQt5.QtTest import QTest
+from cutecoin.tests.mocks.bma import nice_blockchain
+from cutecoin.tests.mocks.access_manager import MockNetworkAccessManager
+from cutecoin.core.registry.identities import IdentitiesRegistry
+from cutecoin.gui.transfer import TransferMoneyDialog
+from cutecoin.gui.password_asker import PasswordAskerDialog
+from cutecoin.core.app import Application
+from cutecoin.core import Account, Community, Wallet
+from cutecoin.core.net import Network, Node
+from cutecoin.core.net.endpoint import BMAEndpoint
+from cutecoin.core.net.api.bma.access import BmaAccess
+from cutecoin.tests import get_application
+from cutecoin.core.net.api import bma as qtbma
+
+
+class TestTransferDialog(unittest.TestCase):
+    def setUp(self):
+        self.qapplication = get_application()
+        self.network_manager = MockNetworkAccessManager()
+        QLocale.setDefault(QLocale("en_GB"))
+        self.lp = quamash.QEventLoop(self.qapplication)
+        asyncio.set_event_loop(self.lp)
+        self.identities_registry = IdentitiesRegistry({})
+
+        self.application = Application(self.qapplication, self.lp, self.network_manager, self.identities_registry)
+        self.application.preferences['notifications'] = False
+
+        self.endpoint = BMAEndpoint(PyBMAEndpoint("", "127.0.0.1", "", 50000))
+        self.node = Node(self.network_manager, "test_currency", [self.endpoint],
+                         "", "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk",
+                         qtbma.blockchain.Block.null_value, Node.ONLINE,
+                         time.time(), {}, "ucoin", "0.14.0", 0)
+        self.network = Network.create(self.network_manager, self.node)
+        self.bma_access = BmaAccess.create(self.network)
+        self.community = Community("test_currency", self.network, self.bma_access)
+
+        self.wallet = Wallet(0, "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+                             "Wallet 1", self.identities_registry)
+
+        # Salt/password : "testcutecoin/testcutecoin"
+        # Pubkey : 7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ
+        self.account = Account("testcutecoin", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+                               "john", [self.community], [self.wallet], [], self.identities_registry)
+
+        self.password_asker = PasswordAskerDialog(self.account)
+        self.password_asker.password = "testcutecoin"
+        self.password_asker.remember = True
+
+    def tearDown(self):
+        try:
+            self.lp.close()
+        finally:
+            asyncio.set_event_loop(None)
+
+    def test_transfer_nice_community(self):
+        mock = nice_blockchain.get_mock()
+        time.sleep(2)
+        logging.debug(mock.pretend_url)
+        self.network_manager.set_mock_path(mock.pretend_url)
+        transfer_dialog = TransferMoneyDialog(self.application,
+                                                   self.account,
+                                                   self.password_asker)
+
+        @asyncio.coroutine
+        def open_dialog(certification_dialog):
+            result = yield from certification_dialog.async_exec()
+            self.assertEqual(result, QDialog.Rejected)
+
+        def close_dialog():
+            if transfer_dialog.isVisible():
+                transfer_dialog.close()
+
+        @asyncio.coroutine
+        def exec_test():
+            yield from asyncio.sleep(1)
+            QTest.mouseClick(transfer_dialog.radio_pubkey, Qt.LeftButton)
+            QTest.keyClicks(transfer_dialog.edit_pubkey, "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn")
+            QTest.mouseClick(transfer_dialog.button_box.button(QDialogButtonBox.Cancel), Qt.LeftButton)
+
+        self.lp.call_later(15, close_dialog)
+        asyncio.async(exec_test())
+        self.lp.run_until_complete(open_dialog(transfer_dialog))
+        mock.delete_mock()
+
+
+if __name__ == '__main__':
+    logging.basicConfig(stream=sys.stderr)
+    logging.getLogger().setLevel(logging.DEBUG)
+    unittest.main()
diff --git a/src/cutecoin/tests/gui/wot_tab/__init__.py b/src/cutecoin/tests/gui/wot_tab/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..39ab2a0b56350baad834cb7fb0cfecb8223e1fcd
--- /dev/null
+++ b/src/cutecoin/tests/gui/wot_tab/__init__.py
@@ -0,0 +1 @@
+__author__ = 'inso'
diff --git a/src/cutecoin/tests/gui/wot_tab/test_wot_tab.py b/src/cutecoin/tests/gui/wot_tab/test_wot_tab.py
new file mode 100644
index 0000000000000000000000000000000000000000..ce6584278c161b0e5e7e208d5a020142682961ee
--- /dev/null
+++ b/src/cutecoin/tests/gui/wot_tab/test_wot_tab.py
@@ -0,0 +1,99 @@
+import sys
+import unittest
+import asyncio
+import quamash
+import logging
+import time
+from ucoinpy.documents.peer import BMAEndpoint as PyBMAEndpoint
+from PyQt5.QtWidgets import QDialog
+from PyQt5.QtCore import QLocale, Qt
+from PyQt5.QtTest import QTest
+from cutecoin.core.net.api import bma as qtbma
+from cutecoin.tests.mocks.bma import nice_blockchain
+from cutecoin.tests.mocks.access_manager import MockNetworkAccessManager
+from cutecoin.core.registry.identities import IdentitiesRegistry
+from cutecoin.gui.wot_tab import WotTabWidget
+from cutecoin.gui.password_asker import PasswordAskerDialog
+from cutecoin.core.app import Application
+from cutecoin.core import Account, Community, Wallet
+from cutecoin.core.net import Network, Node
+from cutecoin.core.net.endpoint import BMAEndpoint
+from cutecoin.core.net.api.bma.access import BmaAccess
+from cutecoin.tests import get_application
+
+
+class TestIdentitiesTable(unittest.TestCase):
+    def setUp(self):
+        self.qapplication = get_application()
+        self.network_manager = MockNetworkAccessManager()
+        QLocale.setDefault(QLocale("en_GB"))
+        self.lp = quamash.QEventLoop(self.qapplication)
+        asyncio.set_event_loop(self.lp)
+        self.identities_registry = IdentitiesRegistry()
+
+        self.application = Application(self.qapplication, self.lp, self.network_manager, self.identities_registry)
+        self.application.preferences['notifications'] = False
+
+        self.endpoint = BMAEndpoint(PyBMAEndpoint("", "127.0.0.1", "", 50000))
+        self.node = Node(self.network_manager, "test_currency", [self.endpoint],
+                         "", "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk",
+                         qtbma.blockchain.Block.null_value, Node.ONLINE,
+                         time.time(), {}, "ucoin", "0.14.0", 0)
+        self.network = Network.create(self.network_manager, self.node)
+        self.bma_access = BmaAccess.create(self.network)
+        self.community = Community("test_currency", self.network, self.bma_access)
+
+        self.wallet = Wallet(0, "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+                             "Wallet 1", self.identities_registry)
+
+        # Salt/password : "testcutecoin/testcutecoin"
+        # Pubkey : 7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ
+        self.account = Account("testcutecoin", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+                               "john", [self.community], [self.wallet], [], self.identities_registry)
+
+        self.password_asker = PasswordAskerDialog(self.account)
+        self.password_asker.password = "testcutecoin"
+        self.password_asker.remember = True
+
+    def tearDown(self):
+        try:
+            self.lp.close()
+        finally:
+            asyncio.set_event_loop(None)
+
+    def test_empty_wot_tab(self):
+        mock = nice_blockchain.get_mock()
+        time.sleep(2)
+        logging.debug(mock.pretend_url)
+        self.network_manager.set_mock_path(mock.pretend_url)
+        wot_tab = WotTabWidget(self.application)
+        future = asyncio.Future()
+
+        def open_widget():
+            wot_tab.show()
+            return future
+
+        @asyncio.coroutine
+        def async_open_widget():
+            yield from open_widget()
+
+        def close_dialog():
+            if wot_tab.isVisible():
+                wot_tab.close()
+            future.set_result(True)
+
+        @asyncio.coroutine
+        def exec_test():
+            yield from asyncio.sleep(1)
+            self.assertTrue(wot_tab.isVisible())
+            self.lp.call_soon(close_dialog)
+
+        asyncio.async(exec_test())
+        self.lp.call_later(15, close_dialog)
+        self.lp.run_until_complete(async_open_widget())
+        mock.delete_mock()
+
+if __name__ == '__main__':
+    logging.basicConfig( stream=sys.stderr )
+    logging.getLogger().setLevel( logging.DEBUG )
+    unittest.main()
diff --git a/src/cutecoin/tests/mocks/__init__.py b/src/cutecoin/tests/mocks/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..7e4cdeb7cb59ef2876f24361d303fcc281ec4ef8
--- /dev/null
+++ b/src/cutecoin/tests/mocks/__init__.py
@@ -0,0 +1 @@
+__author__ = 'ggoinvic'
diff --git a/src/cutecoin/tests/mocks/access_manager.py b/src/cutecoin/tests/mocks/access_manager.py
new file mode 100644
index 0000000000000000000000000000000000000000..754909841f6dd3e102e5a06d75d0beead89310c3
--- /dev/null
+++ b/src/cutecoin/tests/mocks/access_manager.py
@@ -0,0 +1,27 @@
+from PyQt5.QtNetwork import QNetworkAccessManager
+from PyQt5.QtCore import QUrl
+
+class MockNetworkAccessManager(QNetworkAccessManager):
+    def __init__(self):
+        super().__init__()
+        self.mock_path = ""
+
+    def set_mock_path(self, mock_url):
+        url = QUrl(mock_url)
+        self.mock_path = url.path()
+
+    def get(self, request):
+        url = request.url()
+        path = url.path()
+        path = self.mock_path + path
+        url.setPath(path)
+        request.setUrl(url)
+        return super().get(request)
+
+    def post(self, request, post_data):
+        url = request.url()
+        path = url.path()
+        path = self.mock_path + path
+        url.setPath(path)
+        request.setUrl(url)
+        return super().post(request, post_data)
\ No newline at end of file
diff --git a/src/cutecoin/tests/mocks/bma/__init__.py b/src/cutecoin/tests/mocks/bma/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..7e4cdeb7cb59ef2876f24361d303fcc281ec4ef8
--- /dev/null
+++ b/src/cutecoin/tests/mocks/bma/__init__.py
@@ -0,0 +1 @@
+__author__ = 'ggoinvic'
diff --git a/src/cutecoin/tests/mocks/bma/init_new_community.py b/src/cutecoin/tests/mocks/bma/init_new_community.py
new file mode 100644
index 0000000000000000000000000000000000000000..cb4700e37e42d8ef03668902e64cf690dd8ae5a6
--- /dev/null
+++ b/src/cutecoin/tests/mocks/bma/init_new_community.py
@@ -0,0 +1,146 @@
+from pretenders.client.http import HTTPMock
+from pretenders.common.constants import FOREVER
+
+bma_peering = b"""{
+  "version": 1,
+  "currency": "test_currency",
+  "endpoints": [
+    "BASIC_MERKLED_API localhost 127.0.0.1 50000"
+  ],
+  "status": "UP",
+  "block": "30152-00003E7F9234E7542FCF669B69B0F84FF79CCCD3",
+  "signature": "cXuqZuDfyHvxYAEUkPH1TQ1M+8YNDpj8kiHGYi3LIaMqEdVqwVc4yQYGivjxFMYyngRfxXkyvqBKZA6rKOulCA==",
+  "raw": "Version: 1\\nType: Peer\\nCurrency: meta_brouzouf\\nPublicKey: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\\nBlock: 30152-00003E7F9234E7542FCF669B69B0F84FF79CCCD3\\nEndpoints:\\nBASIC_MERKLED_API localhost 127.0.0.1 50000\\n",
+  "pubkey": "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk"
+}"""
+
+bma_lookup_test_john = b"""{
+  "partial": false,
+  "results": [
+    {
+      "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+      "uids": [
+        {
+          "uid": "john",
+          "meta": {
+            "timestamp": 1441130831
+          },
+          "self": "ZrHK0cCqrxWReROK0ciiSb45+dRphJa68qFaSjdve8bBdnGAu7+DIu0d+u/fXrNRXuObihOKMBIawaIVPNHqDw==",
+          "others": []
+        }
+      ],
+      "signed": []
+    }
+  ]
+}"""
+
+bma_lookup_test_doe = b"""{
+  "partial": false,
+  "results": [
+    {
+      "pubkey": "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn",
+      "uids": [
+        {
+          "uid": "doe",
+          "meta": {
+            "timestamp": 1441130831
+          },
+          "self": "cIkHPQQ5+xTb4cKWv85rcYcZT+E3GDtX8B2nCK9Vs12p2Yz4bVaZiMvBBwisAAy2WBOaqHS3ydpXGtADchOICw==",
+          "others": []
+        }
+      ],
+      "signed": []
+    }
+  ]
+}"""
+
+bma_lookup_test_patrick = b"""{
+  "partial": false,
+  "results": [
+    {
+      "pubkey": "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn",
+      "uids": [
+        {
+          "uid": "patrick",
+          "meta": {
+            "timestamp": 1441130831
+          },
+          "self": "QNX2HDAxcHawc47TnMqb5/ou2lwa+zYOyeNk0a52dQDJX/NWmeTzGfTjdCtjpXmSCuPSg0F1mOnLQVd60xAzDA==",
+          "others": []
+        }
+      ],
+      "signed": []
+    }
+  ]
+}"""
+
+
+def get_mock():
+    mock = HTTPMock('127.0.0.1', 50000)
+
+    mock.when('GET /network/peering')\
+        .reply(body=bma_peering,
+                times=FOREVER,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /blockchain/block/0')\
+        .reply(body=b"Block not found",
+               status=404,
+               times=FOREVER,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /blockchain/current')\
+        .reply(body=b"Block not found",
+               status=404,
+               times=FOREVER,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /wot/certifiers-of/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ')\
+            .reply(body=b"No member matching this pubkey or uid",
+                status=404,
+                times=1,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /wot/lookup/john')\
+            .reply(body=bma_lookup_test_john,
+                status=200,
+                times=1,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /wot/lookup/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ')\
+            .reply(body=bma_lookup_test_john,
+                status=200,
+                times=1,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /wot/lookup/doe')\
+            .reply(body=bma_lookup_test_doe,
+                status=200,
+                times=1,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /wot/lookup/FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn')\
+            .reply(body=bma_lookup_test_doe,
+                status=200,
+                times=1,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /wot/lookup/patrick')\
+            .reply(body=bma_lookup_test_patrick,
+                status=200,
+                times=1,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /wot/lookup/FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn')\
+            .reply(body=bma_lookup_test_patrick,
+                status=200,
+                times=1,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('POST /wot/add.*')\
+        .reply(body=b"{}",
+               status=200,
+               times=FOREVER,
+               headers={'Content-Type': 'application/json'})
+
+    return mock
diff --git a/src/cutecoin/tests/mocks/bma/new_blockchain.py b/src/cutecoin/tests/mocks/bma/new_blockchain.py
new file mode 100644
index 0000000000000000000000000000000000000000..fe43d5d23588847d02cb084c47eb42aa6c9f71de
--- /dev/null
+++ b/src/cutecoin/tests/mocks/bma/new_blockchain.py
@@ -0,0 +1,69 @@
+from pretenders.client.http import HTTPMock
+from pretenders.common.constants import FOREVER
+
+bma_peering = b"""{
+  "version": 1,
+  "currency": "test_currency",
+  "endpoints": [
+    "BASIC_MERKLED_API localhost 127.0.0.1 50000"
+  ],
+  "status": "UP",
+  "block": "30152-00003E7F9234E7542FCF669B69B0F84FF79CCCD3",
+  "signature": "cXuqZuDfyHvxYAEUkPH1TQ1M+8YNDpj8kiHGYi3LIaMqEdVqwVc4yQYGivjxFMYyngRfxXkyvqBKZA6rKOulCA==",
+  "raw": "Version: 1\\nType: Peer\\nCurrency: meta_brouzouf\\nPublicKey: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\\nBlock: 30152-00003E7F9234E7542FCF669B69B0F84FF79CCCD3\\nEndpoints:\\nBASIC_MERKLED_API localhost 127.0.0.1 50000\\n",
+  "pubkey": "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk"
+}"""
+
+bma_wot_add = b"""{
+  "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+  "uids": [
+    {
+      "uid": "test",
+      "meta": {
+        "timestamp": 1409990782
+      },
+      "self": "J3G9oM5AKYZNLAB5Wx499w61NuUoS57JVccTShUbGpCMjCqj9yXXqNq7dyZpDWA6BxipsiaMZhujMeBfCznzyci",
+      "others": [
+      ]
+    }
+  ]
+}"""
+
+def get_mock():
+    mock = HTTPMock('127.0.0.1', 50000)
+
+    mock.when('GET /network/peering')\
+        .reply(body=bma_peering,
+                times=FOREVER,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /blockchain/block/0')\
+        .reply(body=b"Block not found",
+               status=404,
+               times=FOREVER,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /blockchain/current')\
+        .reply(body=b"Block not found",
+               status=404,
+               times=FOREVER,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /wot/certifiers-of/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ')\
+            .reply(body=b"No member matching this pubkey or uid",
+                status=404,
+                times=1,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /wot/lookup/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ')\
+            .reply(body=b"No member matching this pubkey or uid",
+                status=404,
+                times=1,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('POST /wot/add.*')\
+        .reply(body=bma_wot_add,
+               status=200,
+               times=FOREVER,
+               headers={'Content-Type': 'application/json'})
+    return mock
diff --git a/src/cutecoin/tests/mocks/bma/nice_blockchain.py b/src/cutecoin/tests/mocks/bma/nice_blockchain.py
new file mode 100644
index 0000000000000000000000000000000000000000..76a77edfcc009182df832f6fb04bfc32685b132e
--- /dev/null
+++ b/src/cutecoin/tests/mocks/bma/nice_blockchain.py
@@ -0,0 +1,348 @@
+import json
+from pretenders.client.http import HTTPMock
+from pretenders.common.constants import FOREVER
+
+bma_peering = {
+  "version": 1,
+  "currency": "test_currency",
+  "endpoints": [
+    "BASIC_MERKLED_API localhost 127.0.0.1 50000"
+  ],
+  "status": "UP",
+  "block": "30152-00003E7F9234E7542FCF669B69B0F84FF79CCCD3",
+  "signature": "cXuqZuDfyHvxYAEUkPH1TQ1M+8YNDpj8kiHGYi3LIaMqEdVqwVc4yQYGivjxFMYyngRfxXkyvqBKZA6rKOulCA==",
+  "raw": "Version: 1\nType: Peer\nCurrency: meta_brouzouf\nPublicKey: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\nBlock: 30152-00003E7F9234E7542FCF669B69B0F84FF79CCCD3\nEndpoints:\nBASIC_MERKLED_API localhost 127.0.0.1 50000\n",
+  "pubkey": "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk"
+}
+
+bma_lookup_john = {
+  "partial": False,
+  "results": [
+    {
+      "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+      "uids": [
+        {
+          "uid": "john",
+          "meta": {
+            "timestamp": 1441130831
+          },
+          "self": "ZrHK0cCqrxWReROK0ciiSb45+dRphJa68qFaSjdve8bBdnGAu7+DIu0d+u/fXrNRXuObihOKMBIawaIVPNHqDw==",
+          "others": []
+        }
+      ],
+      "signed": []
+    }
+  ]
+}
+
+bma_lookup_doe = {
+  "partial": False,
+  "results": [
+    {
+      "pubkey": "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn",
+      "uids": [
+        {
+          "uid": "doe",
+          "meta": {
+            "timestamp": 1441130831
+          },
+          "self": "cIkHPQQ5+xTb4cKWv85rcYcZT+E3GDtX8B2nCK9Vs12p2Yz4bVaZiMvBBwisAAy2WBOaqHS3ydpXGtADchOICw==",
+          "others": []
+        }
+      ],
+      "signed": []
+    }
+  ]
+}
+
+bma_certifiers_of_john = {
+  "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+  "uid": "john",
+  "isMember": True,
+  "certifications": [
+  ]
+}
+
+bma_certified_by_john = {
+  "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+  "uid": "john",
+  "isMember": True,
+  "certifications": [
+  ]
+}
+
+bma_parameters = {
+    "currency": "test_currency",
+    "c": 0.1,
+    "dt": 86400,
+    "ud0": 100,
+    "sigDelay": 604800,
+    "sigValidity": 2629800,
+    "sigQty": 3,
+    "sigWoT": 3,
+    "msValidity": 2629800,
+    "stepMax": 3,
+    "medianTimeBlocks": 11,
+    "avgGenTime": 600,
+    "dtDiffEval": 20,
+    "blocksRot": 144,
+    "percentRot": 0.67
+}
+
+bma_blockchain_current = {
+    "version": 1,
+    "nonce": 6909,
+    "number": 15,
+    "powMin": 4,
+    "time": 1441618206,
+    "medianTime": 1441614759,
+    "membersCount": 20,
+    "monetaryMass": 11711349901120,
+    "currency": "test_currency",
+    "issuer": "EPs9qX7HmCDy6ptUoMLpTzbh9toHu4au488pBTU9DN6y",
+    "signature": "kz/34w1cG+8tYacuPXf3FPmsFwrvtWkwp1POLJuX1P0zYaB9Tuu7iyYJzMQS0Xa3vwuWRqfz+fgyoCGnBjBLBQ==",
+    "hash": "0000CB4E9CCDE6F579135331C97F13903E8B6E21",
+    "parameters": "",
+    "previousHash": "00003BDA844D77EEE7CF32A6C3C87F2ACBFCFCBB",
+    "previousIssuer": "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk",
+    "dividend": None,
+    "membersChanges": [ ],
+    "identities": [ ],
+    "joiners": [ ],
+    "actives": [ ],
+    "leavers": [ ],
+    "excluded": [ ],
+    "certifications": [ ],
+    "transactions": [ ],
+    "raw": "Version: 1\nType: Block\nCurrency: meta_brouzouf\nNonce: 6909\nNumber: 30898\nPoWMin: 4\nTime: 1441618206\nMedianTime: 1441614759\nIssuer: EPs9qX7HmCDy6ptUoMLpTzbh9toHu4au488pBTU9DN6y\nPreviousHash: 00003BDA844D77EEE7CF32A6C3C87F2ACBFCFCBB\nPreviousIssuer: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\nMembersCount: 20\nIdentities:\nJoiners:\nActives:\nLeavers:\nExcluded:\nCertifications:\nTransactions:\n"
+}
+
+# Sent 6, received 20 + 30
+bma_txhistory_john = {
+    "currency": "test_currency",
+    "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+    "history":
+    {
+        "sent":
+    [
+    {
+        "version": 1,
+        "issuers":
+        [
+            "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ"
+        ],
+        "inputs":
+        [
+            "0:D:1:000A8362AE0C1B8045569CE07735DE4C18E81586:8"
+        ],
+        "outputs":
+        [
+            "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ:2",
+            "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn:6"
+        ],
+        "comment": "",
+        "signatures":
+        [
+            "1Mn8q3K7N+R4GZEpAUm+XSyty1Uu+BuOy5t7BIRqgZcKqiaxfhAUfDBOcuk2i4TJy1oA5Rntby8hDN+cUCpvDg=="
+        ],
+        "hash": "5FB3CB80A982E2BDFBB3EA94673A74763F58CB2A",
+        "block_number": 2,
+        "time": 1421932545
+    },
+],
+"received":
+    [
+        {
+            "version": 1,
+            "issuers":
+            [
+                "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn"
+            ],
+            "inputs":
+            [
+                "0:D:1:000A8362AE0C1B8045569CE07735DE4C18E81586:8"
+            ],
+            "outputs":
+            [
+                "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn:2",
+                "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ:20"
+            ],
+            "comment": "",
+            "signatures":
+            [
+                "1Mn8q3K7N+R4GZEpAUm+XSyty1Uu+BuOy5t7BIRqgZcKqiaxfhAUfDBOcuk2i4TJy1oA5Rntby8hDN+cUCpvDg=="
+            ],
+            "hash": "5FB3CB80A982E2BDFBB3EA94673A74763F58CB2A",
+            "block_number": 2,
+            "time": 1421932545
+        },
+        {
+            "version": 1,
+            "issuers":
+            [
+                "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn"
+            ],
+            "inputs":
+            [
+                "0:D:1:000A8362AE0C1B8045569CE07735DE4C18E81586:8"
+            ],
+            "outputs":
+            [
+                "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn:5",
+                "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ:40"
+            ],
+            "comment": "",
+            "signatures":
+            [
+                "1Mn8q3K7N+R4GZEpAUm+XSyty1Uu+BuOy5t7BIRqgZcKqiaxfhAUfDBOcuk2i4TJy1oA5Rntby8hDN+cUCpvDg=="
+            ],
+            "hash": "5FB3CB80A982E2BDFBB3EA94673A74763F58CB2A",
+            "block_number": 12,
+            "time": 1421932454
+        }
+        ],
+        "sending": [ ],
+        "receiving": [ ]
+    }
+}
+
+bma_udhistory_john = {
+    "currency": "test_currency",
+    "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+    "history":
+{
+    "history":
+    [
+    {
+        "block_number": 2,
+        "consumed": False,
+        "time": 1435749971,
+        "amount": 5
+    },
+    {
+
+        "block_number": 10,
+        "consumed": False,
+        "time": 1435836032,
+        "amount": 10
+
+    }
+    ]
+}}
+
+bma_txsources_john = {
+    "currency": "test_currency",
+    "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+    "sources":
+[
+{
+    "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+    "type": "D",
+    "number": 2,
+    "fingerprint": "4A317E3D676E9800E1E92AA2A7255BCEEFF31185",
+    "amount": 7
+},
+    {
+    "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+    "type": "D",
+    "number": 4,
+    "fingerprint": "4A317E3D676E9800E1E92AA2A7255BCEEFF31185",
+    "amount": 9
+}
+]}
+
+
+def get_mock():
+    mock = HTTPMock('127.0.0.1', 50000)
+
+    mock.when('GET /network/peering')\
+        .reply(body=bytes(json.dumps(bma_peering), "utf-8"),
+                times=FOREVER,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /blockchain/parameters')\
+            .reply(body=bytes(json.dumps(bma_parameters), "utf-8"),
+                status=200,
+                times=FOREVER,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /blockchain/current')\
+            .reply(body=bytes(json.dumps(bma_blockchain_current), "utf-8"),
+                status=200,
+                times=FOREVER,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /blockchain/block/15')\
+            .reply(body=bytes(json.dumps(bma_blockchain_current), "utf-8"),
+                status=200,
+                times=FOREVER,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /tx/history/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ/blocks/0/99')\
+            .reply(body=bytes(json.dumps(bma_txhistory_john), "utf-8"),
+                status=200,
+                times=FOREVER,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /tx/sources/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ')\
+            .reply(body=bytes(json.dumps(bma_txsources_john), "utf-8"),
+                status=200,
+                times=FOREVER,
+                headers={'Content-Type': 'application/json'})
+
+
+    mock.when('GET /ud/history/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ')\
+            .reply(body=bytes(json.dumps(bma_udhistory_john), "utf-8"),
+                status=200,
+                times=FOREVER,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /wot/certifiers-of/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ')\
+            .reply(body=bytes(json.dumps(bma_certifiers_of_john), "utf-8"),
+                status=200,
+                times=FOREVER,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /wot/certified-by/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ')\
+            .reply(body=bytes(json.dumps(bma_certified_by_john), "utf-8"),
+                status=200,
+                times=FOREVER,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /wot/lookup/john')\
+            .reply(body=bytes(json.dumps(bma_lookup_john), "utf-8"),
+                status=200,
+                times=FOREVER,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /wot/lookup/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ')\
+            .reply(body=bytes(json.dumps(bma_lookup_john), "utf-8"),
+                status=200,
+                times=FOREVER,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /wot/lookup/doe')\
+            .reply(body=bytes(json.dumps(bma_lookup_doe), "utf-8"),
+                status=200,
+                times=1,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /wot/lookup/FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn')\
+            .reply(body=bytes(json.dumps(bma_lookup_doe), "utf-8"),
+                status=200,
+                times=FOREVER,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /wot/certifiers-of/FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn')\
+            .reply(body=b"No member matching this pubkey or uid",
+                status=404,
+                times=FOREVER,
+                headers={'Content-Type': 'application/json'})
+
+    mock.when('GET /blockchain/memberships/FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn')\
+            .reply(body=b"No member matching this pubkey or uid",
+                status=404,
+                times=FOREVER,
+                headers={'Content-Type': 'application/json'})
+
+    return mock
diff --git a/src/cutecoin/tests/qapp.py b/src/cutecoin/tests/qapp.py
index d3e1a8f657a8d8a72ca386ba3b2e8e7313d44fbb..75c314f569a977251e69d5c815009111d705d685 100644
--- a/src/cutecoin/tests/qapp.py
+++ b/src/cutecoin/tests/qapp.py
@@ -1,9 +1,10 @@
 
 _application_ = []
 
+
 def get_application():
     """Get the singleton QApplication"""
-    from PyQt5.QtWidgets import QApplication
+    from quamash import QApplication
     if not len(_application_):
         application = QApplication.instance()
         if not application:
diff --git a/src/cutecoin/tools/decorators.py b/src/cutecoin/tools/decorators.py
new file mode 100644
index 0000000000000000000000000000000000000000..3842dbd419aa04b4275fe5f303ac48a5e2d8b443
--- /dev/null
+++ b/src/cutecoin/tools/decorators.py
@@ -0,0 +1,34 @@
+import asyncio
+import functools
+import logging
+
+
+def cancel_once_task(object, fn):
+    if getattr(object, "__tasks", None):
+        tasks = getattr(object, "__tasks")
+        if fn.__name__ in tasks and not tasks[fn.__name__].done():
+            getattr(object, "__tasks")[fn.__name__].cancel()
+
+
+def once_at_a_time(fn):
+    @functools.wraps(fn)
+    def wrapper(*args, **kwargs):
+        if getattr(args[0], "__tasks", None) is None:
+            setattr(args[0], "__tasks", {})
+        if fn.__name__ in args[0].__tasks:
+            if not args[0].__tasks[fn.__name__].done():
+                args[0].__tasks[fn.__name__].cancel()
+        try:
+            args[0].__tasks[fn.__name__] = fn(*args, **kwargs)
+        except asyncio.CancelledError:
+            logging.debug("Cancelled asyncified : {0}".format(fn.__name__))
+        return args[0].__tasks[fn.__name__]
+    return wrapper
+
+
+def asyncify(fn):
+    @functools.wraps(fn)
+    def wrapper(*args, **kwargs):
+        return asyncio.async(asyncio.coroutine(fn)(*args, **kwargs))
+
+    return wrapper