diff --git a/doc/uml/api.png b/doc/uml/api.png
new file mode 100644
index 0000000000000000000000000000000000000000..a7e3336901352dc647ce916c06bc2eb880eae469
Binary files /dev/null and b/doc/uml/api.png differ
diff --git a/doc/uml/api.pu b/doc/uml/api.pu
new file mode 100644
index 0000000000000000000000000000000000000000..f4a6ca46ace9b1302ecc225a51a719b5e9698648
--- /dev/null
+++ b/doc/uml/api.pu
@@ -0,0 +1,21 @@
+@startuml
+
+package api {
+	package api.bma {
+		class BMADataAccess {
+			{static} _cache
+			{static} _request(req : Request, network)
+			{static} _post(req : Request, network)
+			{static} _broadcast(req : Request, network)
+		}
+		BMADataAccess ..> api.bma.API
+	}
+	package api.es {
+			class ESDataAccess {
+			}
+			ESDataAccess ..> api.es.API
+	}
+
+}
+
+@enduml
\ No newline at end of file
diff --git a/doc/uml/core-classes.png b/doc/uml/core-classes.png
new file mode 100644
index 0000000000000000000000000000000000000000..000636eb518c8e441bb799c053286adc6ede60d0
Binary files /dev/null and b/doc/uml/core-classes.png differ
diff --git a/doc/uml/core-classes.pu b/doc/uml/core-classes.pu
new file mode 100644
index 0000000000000000000000000000000000000000..fc8d1e6d972241369d76c3d582a79dc3d6f28762
--- /dev/null
+++ b/doc/uml/core-classes.pu
@@ -0,0 +1,101 @@
+@startuml
+
+package core {
+	class App {
+	-- Signals --
+	current_account_changed(str : account_name)
+	data_changed()
+	-- Slots --
+	-- Properties --
+	current_account
+	accounts
+	-- Methods --
+	}
+	App --* Account : accounts
+
+	class Account {
+	-- Signals --
+	wallets_changed(int : nb_wallets)
+	community_added(int : index)
+	community_removed(int : index)
+	data_changed()
+	-- Slots --
+	-- Properties --
+	communities
+	wallets
+	-- Methods --
+	}
+	Account "1" --* "*" Wallet
+	Account "1" --* "*" Community
+
+	class Wallet {
+		-- Signals --
+	money_received(Transfer)
+	money_sent(Transfer)
+	name_changed(str : new_name
+	data_changed()
+	-- Slots --
+	-- Properties --
+	transfers
+	-- Methods --
+	}
+	Wallet "1" --* "*" Transfer
+
+	class Transfer {
+	-- Signals --
+	state_changed(int : new_state)
+	-- Slots --
+	-- Properties --
+	-- Methods --
+	}
+
+	class Community {
+	-- Signals --
+	members_changed()
+	data_changed()
+	-- Slots --
+	-- Properties --
+	network
+	-- Methods --
+
+	}
+	App --> Identity
+	class Identity {
+		{static} _identities
+		{static} load(data : dict)
+		{static} lookup(search : str)
+	}
+
+}
+
+
+package net {
+	class Network {
+	-- Signals --
+	node_found(int : index)
+	node_removed(int : index)
+	block_found(int : block_number)
+	-- Slots --
+	-- Properties --
+	nodes
+	root_nodes
+	-- Methods --
+	}
+	Community "1" --* "1" Network
+	Network "1" --* "*" Node
+
+	class Node {
+	-- Signals --
+	changed()
+	-- Slots --
+	-- Properties --
+	endpoints
+	pubkey
+	uid
+	block
+	state
+	-- Methods --
+	}
+
+}
+@enduml
\ No newline at end of file
diff --git a/doc/uml/cutecoin.png b/doc/uml/cutecoin.png
new file mode 100644
index 0000000000000000000000000000000000000000..59780e445fce620ad5f355c3d3f8ae1a95c92025
Binary files /dev/null and b/doc/uml/cutecoin.png differ
diff --git a/doc/uml/cutecoin.pu b/doc/uml/cutecoin.pu
new file mode 100644
index 0000000000000000000000000000000000000000..d79f67dfb4614935631fd76663cdd922aac6b841
--- /dev/null
+++ b/doc/uml/cutecoin.pu
@@ -0,0 +1,36 @@
+@startuml
+
+!include core-classes.pu
+!include gui-classes.pu
+!include models-classes.pu
+!include api.pu
+
+MainWindow "1" --> "1" App
+
+CertificationDialog --> Community
+TransferDialog --> Community
+
+CurrencyTab "1" --> "1" Community
+
+CommunityTab -right-> IdentitiesFilterProxyModel
+NetworkTab -right-> NetworkFilterProxyModel
+WalletTab -right-> WalletsFilterProxyModel
+
+WalletsFilterProxyModel -up-> Wallet
+NetworkFilterProxyModel -up-> Network
+TxHistoryFilterProxyModel -up-> Transfer
+
+ConfigureAccountDialog --> CommunitiesListModel
+ConfigureCommunityDialog --> RootNodesTableModel
+
+ConfigureAccountDialog --> Account
+ConfigureCommunityDialog --> Community
+
+Account ..> BMADataAccess
+Community ..> BMADataAccess
+Wallet ..> BMADataAccess
+Transfer ..> BMADataAccess
+Identity ..> BMADataAccess
+BMADataAccess .left.> Network
+
+@enduml
\ No newline at end of file
diff --git a/doc/uml/gui-classes.png b/doc/uml/gui-classes.png
new file mode 100644
index 0000000000000000000000000000000000000000..7df50d51d4ae74fb4f99c2b47eac4b31cc633b15
Binary files /dev/null and b/doc/uml/gui-classes.png differ
diff --git a/doc/uml/gui-classes.pu b/doc/uml/gui-classes.pu
new file mode 100644
index 0000000000000000000000000000000000000000..f8a0bc964fc2dd6a5714d56dab6da971bdd5e2cd
--- /dev/null
+++ b/doc/uml/gui-classes.pu
@@ -0,0 +1,58 @@
+@startuml
+
+
+package gui {
+		class MainWindow {
+		}
+		MainWindow "1" --* "*" CurrencyTab
+
+		class CurrencyTab {
+		}
+		CurrencyTab "1" --* "1" CommunityTab
+		CurrencyTab "1" --* "1" WalletTab
+		CurrencyTab "1" --* "1" InformationsTab
+		CurrencyTab "1" --* "1" TransactionsTab
+
+		class CommunityTab {
+		}
+
+		CommunityTab "1" --* "1" IdentitiesTab
+		CommunityTab "1" --* "1" WotTab
+
+		class WalletTab {
+		}
+
+		class InformationsTab {
+		}
+
+		class TransactionsTab {
+		}
+
+		class NetworkTab {
+		}
+
+		CurrencyTab "1" --* "1" NetworkTab
+
+		class IdentitiesTab {
+		}
+
+		class WotTab {
+		}
+		package dialogs {
+		class CertificationDialog
+		class TransferDialog
+		class ContactDialog
+		class ConfigureAccountDialog
+		class ConfigureCommunityDialog
+		}
+
+	MainWindow --> CertificationDialog
+	MainWindow --> TransferDialog
+	MainWindow --> ContactDialog
+	MainWindow --> ConfigureAccountDialog
+	ConfigureAccountDialog --> ConfigureCommunityDialog
+
+		class Wot
+		WotTab --> Wot
+}
+@enduml
\ No newline at end of file
diff --git a/doc/uml/models-classes.png b/doc/uml/models-classes.png
new file mode 100644
index 0000000000000000000000000000000000000000..54fec65a2ab178127054ae952f4b55b7e0afbc52
Binary files /dev/null and b/doc/uml/models-classes.png differ
diff --git a/doc/uml/models-classes.pu b/doc/uml/models-classes.pu
new file mode 100644
index 0000000000000000000000000000000000000000..1650739d5d4c65bfa48ba299c543b4d019cde42b
--- /dev/null
+++ b/doc/uml/models-classes.pu
@@ -0,0 +1,39 @@
+@startuml
+
+package models {
+	class WalletsFilterProxyModel {
+	}
+
+	WalletsFilterProxyModel --> WalletsTableModel : source
+
+	class WalletsTableModel {
+	}
+
+	class IdentitiesFilterProxyModel {
+	}
+	IdentitiesFilterProxyModel --> IdentitiesTableModel : source
+
+	class IdentitiesTableModel {
+	}
+
+	class NetworkFilterProxyModel {
+	}
+	NetworkFilterProxyModel --> NetworkTableModel : source
+
+	class NetworkTableModel {
+	}
+
+	class TxHistoryFilterProxyModel {
+	}
+	TxHistoryFilterProxyModel --> TxHistoryTableModel : source
+	class TxHistoryTableModel {
+	}
+
+	class CommunitiesListModel {
+	}
+
+	class RootNodesTableModel {
+	}
+}
+
+@enduml
\ No newline at end of file
diff --git a/doc/uml/network.png b/doc/uml/network.png
new file mode 100644
index 0000000000000000000000000000000000000000..853e39c21f10c5fabcb74d702194ce1822209727
Binary files /dev/null and b/doc/uml/network.png differ
diff --git a/doc/uml/network.pu b/doc/uml/network.pu
new file mode 100644
index 0000000000000000000000000000000000000000..d89859f85bb60f8291a322f6bab241ccc3cd0a02
--- /dev/null
+++ b/doc/uml/network.pu
@@ -0,0 +1,36 @@
+@startuml
+
+Network -->o Node : Connect to node_received()
+Network -> Node : Starts network discovery
+activate Node
+Node -> QNetworkManager : HTTP GET peering/peers?leaves=true
+create QNetworkReply
+QNetworkManager -> QNetworkReply : Instantiate
+Node <- QNetworkManager : QNetworkReply
+Node -->o QNetworkReply : Connect to finished()
+Network <- Node
+deactivate Node
+... Request is processed ...
+Node <-- QNetworkReply : finished()
+destroy QNetworkReply
+alt "root" hash changed
+loop "for all leaves changed"
+activate Node
+Node -> QNetworkManager : HTTP GET peering/peers/leaf=leaf_hash
+create QNetworkReply
+QNetworkManager -> QNetworkReply : Instantiate
+Node <- QNetworkManager : QNetworkReply
+Node -->o QNetworkReply : Connect to finished()
+end
+end
+... Requests is processed ...
+Node <-- QNetworkReply : finished()
+destroy QNetworkReply
+Network <-- Node : node_received()
+ref over Network
+New node is instanciated
+if pubkey not known yet.
+It starts it's own
+network discovery
+end ref
+@enduml
\ No newline at end of file
diff --git a/doc/uml/requests.png b/doc/uml/requests.png
new file mode 100644
index 0000000000000000000000000000000000000000..d629a6789802e9eadb3f092a198497c02b4ddcc2
Binary files /dev/null and b/doc/uml/requests.png differ
diff --git a/doc/uml/requests.pu b/doc/uml/requests.pu
new file mode 100644
index 0000000000000000000000000000000000000000..8ea91136f68aba9771cf9f438f89790f508b4341
--- /dev/null
+++ b/doc/uml/requests.pu
@@ -0,0 +1,50 @@
+@startuml
+
+QModel -->o "Core Component" : Connect to data_changed()
+QModel -> "Core Component" : Data access
+activate "Core Component"
+"Core Component" -> Community : Request data
+Community -> Cache : Request cache
+ref over Cache
+Data is obsolete
+(new block mined
+since last caching)
+end ref
+Cache -> QNetworkManager : HTTP GET
+create QNetworkReply
+QNetworkManager -> QNetworkReply : Instantiate
+Cache <- QNetworkManager : QNetworkReply
+create ReceiverSlot
+Cache -> ReceiverSlot : Instantiate Slot
+QNetworkReply o<-- ReceiverSlot : Connect to finished()
+Community <- Cache : Cached data
+"Core Component" <- Community : Cached data
+"Core Component" -> "Core Component" : Compute data
+QModel <- "Core Component" : Data
+deactivate "Core Component"
+
+...Network request is processed...
+
+ReceiverSlot <-- QNetworkReply  : finished()
+activate ReceiverSlot
+ReceiverSlot -> Cache : Update cache data
+ReceiverSlot -> "Core Component" : emit data_changed()
+deactivate ReceiverSlot
+destroy ReceiverSlot
+destroy QNetworkReply
+|||
+QModel <-- "Core Component" : data_changed()
+QModel -> "Core Component" : Data access
+activate "Core Component"
+ref over "Core Component", Community
+Community is requested again,
+and last cached data are returned
+No new block mined, so no HTTP GET
+initialized between cache
+and QNetworkManager
+end ref
+QModel <- "Core Component" : Data
+deactivate "Core Component"
+
+
+@enduml
\ No newline at end of file
diff --git a/doc/uml/tx_lifecycle.png b/doc/uml/tx_lifecycle.png
index 0e7061b3438870f7c6a7c4fae11a191f971e9234..ff35f12c2605e32c5e03428e10e77b0ddfb9e1e1 100644
Binary files a/doc/uml/tx_lifecycle.png and b/doc/uml/tx_lifecycle.png differ
diff --git a/lib/ucoinpy/documents/block.py b/lib/ucoinpy/documents/block.py
index 58a1b3bf8e9d29543fbd65b956b9bc144d0b2f04..dd17cb2f7e52f772c422eb4b93a3618943ddb29a 100644
--- a/lib/ucoinpy/documents/block.py
+++ b/lib/ucoinpy/documents/block.py
@@ -293,4 +293,4 @@ PreviousIssuer: {1}\n".format(self.prev_hash, self.prev_issuer)
         for transaction in self.transactions:
             doc += "{0}\n".format(transaction.compact())
 
-        return doc
+        return doc
\ No newline at end of file
diff --git a/src/cutecoin/core/account.py b/src/cutecoin/core/account.py
index 165adb6419c96281bc188e42e749855b7e52077b..0471dea12bd4475b3925703eceda7ddeeaeb5ade 100644
--- a/src/cutecoin/core/account.py
+++ b/src/cutecoin/core/account.py
@@ -41,14 +41,21 @@ def relative(units, community):
     :param cutecoin.core.community.Community community: Community instance
     :return: float
     """
-    # fixme: the value "community.nb_members" is not up to date, luckyly the good value is in "community.get_ud_block()['membersCount']"
     # calculate ud(t+1)
-    ud = math.ceil(
-        max(community.dividend,
-            community.parameters['c'] * community.monetary_mass / community.get_ud_block()['membersCount'])
-    )
-    relative_value = units / float(ud)
-    return relative_value
+    ud_block = community.get_ud_block()
+    if ud_block:
+        ud = math.ceil(
+            max(community.dividend(),
+                float(0) if ud_block['membersCount'] == 0 else
+                community.parameters['c'] * community.monetary_mass / ud_block['membersCount']))
+
+        if ud == 0:
+            return float(0)
+        else:
+            relative_value = units / float(ud)
+            return relative_value
+    else:
+        return float(0)
 
 
 def quantitative_zerosum(units, community):
@@ -111,6 +118,8 @@ class Account(QObject):
     )
 
     loading_progressed = pyqtSignal(int, int)
+    inner_data_changed = pyqtSignal()
+    wallets_changed = pyqtSignal()
 
     def __init__(self, salt, pubkey, name, communities, wallets, contacts):
         '''
@@ -153,9 +162,10 @@ class Account(QObject):
         return account
 
     @classmethod
-    def load(cls, json_data):
+    def load(cls, network_manager, json_data):
         '''
         Factory method to create an Account object from its json view.
+        :rtype : cutecoin.core.account.Account
         :param dict json_data: The account view as a json dict
         :return: A new account object created from the json datas
         '''
@@ -174,7 +184,7 @@ class Account(QObject):
 
         communities = []
         for data in json_data['communities']:
-            community = Community.load(data)
+            community = Community.load(network_manager, data)
             communities.append(community)
 
         account = cls(salt, pubkey, name, communities, wallets,
@@ -282,6 +292,7 @@ class Account(QObject):
                 self.wallets.append(wallet)
         else:
             self.wallets = self.wallets[:size]
+        self.wallets_changed.emit()
 
     def certify(self, password, community, pubkey):
         """
diff --git a/src/cutecoin/core/app.py b/src/cutecoin/core/app.py
index ca266b27eb0dc05e0d6f04c784917fe53e29826d..3a5e5ad60b153ea6724ce6fc66c24bd628c0733d 100644
--- a/src/cutecoin/core/app.py
+++ b/src/cutecoin/core/app.py
@@ -19,7 +19,6 @@ from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply, QNetworkReques
 from . import config
 from .account import Account
 from . import person
-from .watching.monitor import Monitor
 from .. import __version__
 from ..tools.exceptions import NameAlreadyExists, BadAccountFile
 
@@ -44,13 +43,11 @@ class Application(QObject):
         super().__init__()
         self.accounts = {}
         self.current_account = None
-        self.monitor = None
         self.available_version = (True,
                                   __version__,
                                   "")
         config.parse_arguments(argv)
         self._network_manager = QNetworkAccessManager()
-        self._network_manager.finished.connect(self.read_available_version)
         self.preferences = {'account': "",
                             'lang': 'en_GB',
                             'ref': 0
@@ -126,13 +123,9 @@ class Application(QObject):
             self.loading_progressed.emit(value, maximum)
 
         if self.current_account is not None:
-            if self.monitor:
-                self.monitor.stop_watching()
             self.save_cache(self.current_account)
         account.loading_progressed.connect(progressing)
         account.refresh_cache()
-        self.monitor = Monitor(account)
-        self.monitor.prepare_watching()
         self.current_account = account
 
     def load(self):
@@ -178,7 +171,7 @@ class Application(QObject):
                                     account_name, 'properties')
         with open(account_path, 'r') as json_data:
             data = json.load(json_data)
-            account = Account.load(data)
+            account = Account.load(self._network_manager, data)
             self.load_cache(account)
             self.accounts[account_name] = account
 
@@ -189,9 +182,9 @@ class Application(QObject):
         :param account: The account object to load the cache
         '''
         for community in account.communities:
-            community_path = os.path.join(config.parameters['home'],
+            bma_path = os.path.join(config.parameters['home'],
                                         account.name, '__cache__',
-                                        community.currency)
+                                        community.currency + '_bma')
 
             network_path = os.path.join(config.parameters['home'],
                                         account.name, '__cache__',
@@ -202,17 +195,17 @@ class Application(QObject):
                     data = json.load(json_data)
                 if 'version' in data and data['version'] == __version__:
                     logging.debug("Merging network : {0}".format(data))
-                    community.load_merge_network(data['network'])
+                    community.network.merge_with_json(data['network'])
                 else:
                     os.remove(network_path)
 
-            if os.path.exists(community_path):
-                with open(community_path, 'r') as json_data:
+            if os.path.exists(bma_path):
+                with open(bma_path, 'r') as json_data:
                     data = json.load(json_data)
                 if 'version' in data and data['version'] == __version__:
-                    community.load_cache(data)
+                    community.bma_access.load_from_json(data['cache'])
                 else:
-                    os.remove(community_path)
+                    os.remove(bma_path)
 
         for wallet in account.wallets:
             wallet_path = os.path.join(config.parameters['home'],
@@ -319,9 +312,9 @@ class Application(QObject):
             self.save_wallet(account, wallet)
 
         for community in account.communities:
-            community_path = os.path.join(config.parameters['home'],
+            bma_path = os.path.join(config.parameters['home'],
                                         account.name, '__cache__',
-                                        community.currency)
+                                        community.currency + '_bma')
 
             network_path = os.path.join(config.parameters['home'],
                                         account.name, '__cache__',
@@ -329,12 +322,12 @@ class Application(QObject):
 
             with open(network_path, 'w') as outfile:
                 data = dict()
-                data['network'] = community.jsonify_network()
+                data['network'] = community.network.jsonify()
                 data['version'] = __version__
                 json.dump(data, outfile, indent=4, sort_keys=True)
 
-            with open(community_path, 'w') as outfile:
-                data = community.jsonify_cache()
+            with open(bma_path, 'w') as outfile:
+                data['cache'] = community.bma_access.jsonify()
                 data['version'] = __version__
                 json.dump(data, outfile, indent=4, sort_keys=True)
 
@@ -402,11 +395,13 @@ class Application(QObject):
     def get_last_version(self):
         url = QUrl("https://api.github.com/repos/ucoin-io/cutecoin/releases")
         request = QNetworkRequest(url)
-        self._network_manager.get(request)
+        reply = self._network_manager.get(request)
+        reply.finished.connect(self.read_available_version)
 
     @pyqtSlot(QNetworkReply)
-    def read_available_version(self, reply):
+    def read_available_version(self):
         latest = None
+        reply = self.sender()
         releases = reply.readAll().data().decode('utf-8')
         logging.debug(releases)
         if reply.error() == QNetworkReply.NoError:
diff --git a/src/cutecoin/core/community.py b/src/cutecoin/core/community.py
index be5e70adf47c298e1c9ad62eafcad290fb0669ef..3857d6a2e94b1653d50fe9a6e2f871dc7553c50a 100644
--- a/src/cutecoin/core/community.py
+++ b/src/cutecoin/core/community.py
@@ -4,200 +4,104 @@ Created on 1 févr. 2014
 @author: inso
 '''
 
-from PyQt5.QtCore import QObject, pyqtSignal
-from ucoinpy.api import bma
-from ucoinpy.documents.block import Block
-from ..tools.exceptions import NoPeerAvailable
-from .net.node import Node
-from .net.network import Network
 import logging
-import inspect
 import hashlib
 import re
 import time
-from requests.exceptions import RequestException
-
-
-class Cache():
-    _saved_requests = [str(bma.blockchain.Block), str(bma.blockchain.Parameters)]
-
-    def __init__(self, community):
-        '''
-        Init an empty cache
-        '''
-        self.latest_block = 0
-        self.community = community
-        self.data = {}
-
-    def load_from_json(self, data):
-        '''
-        Put data in the cache from json datas.
-
-        :param dict data: The cache in json format
-        '''
-        self.data = {}
-        for entry in data['cache']:
-            key = entry['key']
-            cache_key = (key[0], key[1], key[2], key[3], key[4])
-            self.data[cache_key] = entry['value']
 
-        self.latest_block = data['latest_block']
-
-    def jsonify(self):
-        '''
-        Get the cache in json format
-
-        :return: The cache as a dict in json format
-        '''
-        data = {k: self.data[k] for k in self.data.keys()}
-        entries = []
-        for d in data:
-            entries.append({'key': d,
-                            'value': data[d]})
-        return {'latest_block': self.latest_block,
-                'cache': entries}
-
-    def refresh(self):
-        '''
-        Refreshing the cache just clears every last requests which
-        cannot be saved because they can change from one block to another.
-        '''
-        logging.debug("Refresh : {0}/{1}".format(self.latest_block,
-                                                 self.community.network.latest_block))
-        if self.latest_block < self.community.network.latest_block:
-            self.latest_block = self.community.network.latest_block
-            self.data = {k: self.data[k] for k in self.data.keys()
-                       if k[0] in Cache._saved_requests}
-
-    def request(self, request, req_args={}, get_args={}):
-        '''
-        Send a cached request to a community.
-        If the request was already sent in current block, return last value get.
+from PyQt5.QtCore import QObject, pyqtSignal
+from requests.exceptions import RequestException
 
-        :param request: The request bma class
-        :param req_args: The arguments passed to the request constructor
-        :param get_args: The arguments passed to the requests __get__ method
-        '''
-        cache_key = (str(request),
-                     str(tuple(frozenset(sorted(req_args.keys())))),
-                     str(tuple(frozenset(sorted(req_args.values())))),
-                     str(tuple(frozenset(sorted(get_args.keys())))),
-                     str(tuple(frozenset(sorted(get_args.values())))))
-
-        if cache_key not in self.data.keys():
-            result = self.community.request(request, req_args, get_args,
-                                         cached=False)
-            # For block 0, we should have a different behaviour
-            # Community members and certifications
-            # Should be requested without caching
-            self.data[cache_key] = result
-            return self.data[cache_key]
-        else:
-            return self.data[cache_key]
+from ucoinpy.documents.block import Block
+from ..tools.exceptions import NoPeerAvailable
+from .net.network import Network
+from .net.api import bma as qtbma
+from .net.api.bma.access import BmaAccess
 
 
 class Community(QObject):
-    '''
+    """
     A community is a group of nodes using the same currency.
 
     .. 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(int)
 
-    def __init__(self, currency, network):
-        '''
+    def __init__(self, currency, network, bma_access):
+        """
         Initialize community attributes with a currency and a network.
 
         :param str currency: The currency name of the community.
-        :param network: The network of the community
+        :param cutecoin.core.net.network.Network network: The network of the community
+        :param cutecoin.core.net.api.bma.access.BmaAccess bma_access: The BMA Access object
 
         .. warning:: The community object should be created using its factory
         class methods.
-        '''
+        """
         super().__init__()
         self.currency = currency
         self._network = network
-        self._cache = Cache(self)
-        self._cache.refresh()
+        self._bma_access = bma_access
 
     @classmethod
     def create(cls, node):
-        '''
+        """
         Create a community from its first node.
 
         :param node: The first Node of the community
-        '''
+        """
         network = Network.create(node)
-        community = cls(node.currency, network)
+        bma_access = BmaAccess.create(network)
+        community = cls(node.currency, network, bma_access)
         logging.debug("Creating community")
         return community
 
     @classmethod
-    def load(cls, json_data):
-        '''
+    def load(cls, network_manager, json_data):
+        """
         Load a community from json
 
         :param dict json_data: The community as a dict in json format
-        '''
+        """
         currency = json_data['currency']
-        network = Network.from_json(currency, json_data['peers'])
-        community = cls(currency, network)
+        network = Network.from_json(network_manager, currency, json_data['peers'])
+        bma_access = BmaAccess.create(network)
+        community = cls(currency, network, bma_access)
         return community
 
-    def load_merge_network(self, json_data):
-        '''
-        Load the last state of the network.
-        This network is merged with the network currently
-        known network.
-
-        :param dict json_data:
-        '''
-        self._network.merge_with_json(json_data)
-
-    def load_cache(self, json_data):
-        '''
+    def load_cache(self, bma_access_cache, network_cache):
+        """
         Load the community cache.
 
-        :param dict json_data: The community as a dict in json format.
-        '''
-        self._cache.load_from_json(json_data)
-
-    def jsonify_cache(self):
-        '''
-        Get the cache jsonified.
-
-        :return: The cache as a dict in json format.
-        '''
-        return self._cache.jsonify()
-
-    def jsonify_network(self):
-        '''
-        Get the network jsonified.
-        '''
-        return self._network.jsonify()
+        :param dict bma_access_cache: The BmaAccess cache in json
+        :param dict network_cache: The network cache in json
+        """
+        self._bma_access.load_from_json(bma_access_cache)
+        self._network.merge_with_json(network_cache)
 
     @property
     def name(self):
-        '''
+        """
         The community name is its currency name.
 
         :return: The community name
-        '''
+        """
         return self.currency
 
     def __eq__(self, other):
-        '''
+        """
         :return: True if this community has the same currency name as the other one.
-        '''
+        """
         return (other.currency == self.currency)
 
     @property
     def short_currency(self):
-        '''
+        """
         Format the currency name to a short one
 
         :return: The currency name in a shot format.
-        '''
+        """
         words = re.split('[_\W]+', self.currency)
         shortened = ""
         if len(words) > 1:
@@ -210,22 +114,22 @@ class Community(QObject):
 
     @property
     def currency_symbol(self):
-        '''
+        """
         Format the currency name to a symbol one.
 
         :return: The currency name as a utf-8 circled symbol.
-        '''
+        """
         letter = self.currency[0]
         u = ord('\u24B6') + ord(letter) - ord('A')
         return chr(u)
 
-    @property
+    #@property
     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()
         if block:
             return block['dividend']
@@ -233,32 +137,32 @@ class Community(QObject):
             return 1
 
     def get_ud_block(self, x=0):
-        '''
+        """
         Get a block with universal dividend
 
         :param int x: Get the 'x' older block with UD in it
         :return: The last block with universal dividend.
-        '''
-        blocks = self.request(bma.blockchain.UD)['result']['blocks']
+        """
+        blocks = self.bma_access.get(self, qtbma.blockchain.UD)['result']['blocks']
         if len(blocks) > 0:
             block_number = blocks[len(blocks)-(1+x)]
-            block = self.request(bma.blockchain.Block,
+            block = self.bma_access.get(self, qtbma.blockchain.Block,
                                  req_args={'number': block_number})
             return block
         else:
-            return False
+            return None
 
     @property
     def monetary_mass(self):
-        '''
+        """
         Get the community monetary mass
 
         :return: The monetary mass value
-        '''
+        """
         try:
             # Get cached block by block number
             block_number = self.network.latest_block
-            block = self.request(bma.blockchain.Block,
+            block = self.bma_access.get(self, qtbma.blockchain.Block,
                                  req_args={'number': block_number})
             return block['monetaryMass']
         except ValueError as e:
@@ -269,15 +173,15 @@ class Community(QObject):
 
     @property
     def nb_members(self):
-        '''
+        """
         Get the community members number
 
         :return: The community members number
-        '''
+        """
         try:
             # Get cached block by block number
             block_number = self.network.latest_block
-            block = self.request(bma.blockchain.Block,
+            block = self.bma_access.get(qtbma.blockchain.Block,
                                  req_args={'number': block_number})
             return block['membersCount']
         except ValueError as e:
@@ -288,29 +192,30 @@ class Community(QObject):
 
     @property
     def network(self):
-        '''
+        """
         Get the community network instance.
 
         :return: The community network instance.
-        '''
+        :rtype: cutecoin.core.net.network.Network
+        """
         return self._network
 
-    def network_quality(self):
-        '''
-        Get a ratio of the synced nodes vs the rest
-        '''
-        synced = len(self._network.synced_nodes)
-        #online = len(self._network.online_nodes)
-        total = len(self._network.nodes)
-        ratio_synced = synced / total
-        return ratio_synced
+    @property
+    def bma_access(self):
+        """
+        Get the community bma_access instance
+
+        :return: The community bma_access instace
+        :rtype: cutecoin.core.net.api.bma.access.BmaAccess
+        """
+        return self._bma_access
 
     @property
     def parameters(self):
-        '''
+        """
         Return community parameters in bma format
-        '''
-        return self.request(bma.blockchain.Parameters)
+        """
+        return self.bma_access.get(self, qtbma.blockchain.Parameters)
 
     def certification_expired(self, certtime):
         '''
@@ -341,14 +246,12 @@ class Community(QObject):
         :param int number: The block number. If none, returns current block.
         '''
         if number is None:
-            data = self.request(bma.blockchain.Current)
+            data = self.bma_access.get(self, qtbma.blockchain.Current)
         else:
             logging.debug("Requesting block {0}".format(number))
-            data = self.request(bma.blockchain.Block,
+            data = self.bma_access.get(self, qtbma.blockchain.Block,
                                 req_args={'number': number})
-
-        return Block.from_signed_raw("{0}{1}\n".format(data['raw'],
-                                                       data['signature']))
+        return data
 
     def current_blockid(self):
         '''
@@ -357,7 +260,7 @@ class Community(QObject):
         :return: The current block ID as [NUMBER-HASH] format.
         '''
         try:
-            block = self.request(bma.blockchain.Current, cached=False)
+            block = self.bma_access.get(self, qtbma.blockchain.Current, cached=False)
             signed_raw = "{0}{1}\n".format(block['raw'], block['signature'])
             block_hash = hashlib.sha1(signed_raw.encode("ascii")).hexdigest().upper()
             block_number = block['number']
@@ -375,7 +278,7 @@ class Community(QObject):
 
         :return: All members pubkeys.
         '''
-        memberships = self.request(bma.wot.Members)
+        memberships = self.bma_access.get(self, qtbma.wot.Members)
         return [m['pubkey'] for m in memberships["results"]]
 
     def refresh_cache(self):
@@ -384,42 +287,6 @@ class Community(QObject):
         '''
         self._cache.refresh()
 
-    def request(self, request, req_args={}, get_args={}, cached=True):
-        '''
-        Start a request to the community.
-
-        :param request: A ucoinpy bma request class
-        :param req_args: Arguments to pass to the request constructor
-        :param get_args: Arguments to pass to the request __get__ method
-        :return: The returned data
-        '''
-        if cached:
-            return self._cache.request(request, req_args, get_args)
-        else:
-            nodes = self._network.synced_nodes
-            for node in nodes:
-                try:
-                    req = request(node.endpoint.conn_handler(), **req_args)
-                    data = req.get(**get_args)
-
-                    if inspect.isgenerator(data):
-                        generated = []
-                        for d in data:
-                            generated.append(d)
-                        return generated
-                    else:
-                        return data
-                except ValueError as e:
-                    if '502' in str(e):
-                        continue
-                    else:
-                        raise
-                except RequestException as e:
-                    logging.debug("Error : {1} : {0}".format(str(e),
-                                                             str(request)))
-                    continue
-        raise NoPeerAvailable(self.currency, len(nodes))
-
     def post(self, request, req_args={}, post_args={}):
         '''
         Post data to a community.
diff --git a/src/cutecoin/core/net/__init__.py b/src/cutecoin/core/net/__init__.py
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..39ab2a0b56350baad834cb7fb0cfecb8223e1fcd 100644
--- a/src/cutecoin/core/net/__init__.py
+++ b/src/cutecoin/core/net/__init__.py
@@ -0,0 +1 @@
+__author__ = 'inso'
diff --git a/src/cutecoin/core/watching/__init__.py b/src/cutecoin/core/net/api/__init__.py
similarity index 100%
rename from src/cutecoin/core/watching/__init__.py
rename to src/cutecoin/core/net/api/__init__.py
diff --git a/src/cutecoin/core/net/api/bma/__init__.py b/src/cutecoin/core/net/api/bma/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..ce3f0b46dbb87fa4204dba32cf7df8764bbe5b03
--- /dev/null
+++ b/src/cutecoin/core/net/api/bma/__init__.py
@@ -0,0 +1,128 @@
+
+
+__all__ = ['api']
+
+from PyQt5.QtNetwork import QNetworkRequest
+from PyQt5.QtCore import QUrl, QUrlQuery
+import logging
+
+logger = logging.getLogger("ucoin")
+
+
+class ConnectionHandler(object):
+    """Helper class used by other API classes to ease passing server connection information."""
+
+    def __init__(self, network_manager, server, port):
+        """
+        Arguments:
+        - `server`: server hostname
+        - `port`: port number
+        """
+
+        self.network_manager = network_manager
+        self.server = server
+        self.port = port
+
+    def __str__(self):
+        return 'connection info: %s:%d' % (self.server, self.port)
+
+
+class API(object):
+    """APIRequest is a class used as an interface. The intermediate derivated classes are the modules and the leaf classes are the API requests."""
+
+    def __init__(self, conn_handler, module):
+        """
+        Asks a module in order to create the url used then by derivated classes.
+
+        Arguments:
+        - `module`: module name
+        - `connection_handler`: connection handler
+        """
+
+        self.module = module
+        self.conn_handler = conn_handler
+        self.headers = {}
+
+    def reverse_url(self, path):
+        """
+        Reverses the url using self.url and path given in parameter.
+
+        Arguments:
+        - `path`: the request path
+        """
+
+        server, port = self.conn_handler.server, self.conn_handler.port
+
+        url = 'http://%s:%d/%s' % (server, port, self.module)
+        return url + path
+
+    def get(self, **kwargs):
+        """wrapper of overloaded __get__ method."""
+
+        return self.__get__(**kwargs)
+
+    def post(self, **kwargs):
+        """wrapper of overloaded __post__ method."""
+
+        logger.debug('do some work with')
+
+        data = self.__post__(**kwargs)
+
+        logger.debug('and send back')
+
+        return data
+
+    def __get__(self, **kwargs):
+        """interface purpose for GET request"""
+
+        pass
+
+    def __post__(self, **kwargs):
+        """interface purpose for POST request"""
+
+        pass
+
+    def requests_get(self, path, **kwargs):
+        """
+        Requests GET wrapper in order to use API parameters.
+
+        Arguments:
+        - `path`: the request path
+        """
+        query = QUrlQuery()
+        for k,v in kwargs.items():
+            query.addQueryItem(k, v);
+        url = QUrl(self.reverse_url(path))
+        url.setQuery(query)
+        request = QNetworkRequest(url)
+        logging.debug(url.toString())
+        reply = self.conn_handler.network_manager.get(request)
+
+        return reply
+
+    def requests_post(self, path, **kwargs):
+        """
+        Requests POST wrapper in order to use API parameters.
+
+        Arguments:
+        - `path`: the request path
+        """
+        if 'self_' in kwargs:
+            kwargs['self'] = kwargs.pop('self_')
+
+        logging.debug("POST : {0}".format(kwargs))
+        post_data = QUrlQuery()
+        for k,v in kwargs.items():
+            post_data.addQueryItem(k, v)
+        url = QUrl(self.reverse_url(path))
+        url.setQuery(post_data)
+
+        request = QNetworkRequest(url)
+        request.setHeader(QNetworkRequest.ContentTypeHeader,
+            "application/x-www-form-urlencoded")
+        reply = self.conn_handler.network_manager.post(request,
+                             post_data.toString(QUrl.FullyEncoded).toUtf8())
+
+        return reply
+
+from . import network, blockchain, tx, wot
diff --git a/src/cutecoin/core/net/api/bma/access.py b/src/cutecoin/core/net/api/bma/access.py
new file mode 100644
index 0000000000000000000000000000000000000000..4c7fc64aec18dc62a5f43aee2678077c979ed3af
--- /dev/null
+++ b/src/cutecoin/core/net/api/bma/access.py
@@ -0,0 +1,153 @@
+from PyQt5.QtCore import QObject, pyqtSlot
+from PyQt5.QtNetwork import QNetworkReply
+from . import blockchain, network, node, tx, wot, ConnectionHandler
+from .....tools.exceptions import NoPeerAvailable
+import logging
+import json
+import random
+
+class BmaAccess(QObject):
+    '''
+    This class is used to access BMA API.
+    '''
+
+    __saved_requests = [str(blockchain.Block), str(blockchain.Parameters)]
+
+    def __init__(self, data, network):
+        """
+        Constructor of a network
+
+        :param dict data: The data present in this cache
+        :param cutecoin.core.net.network.Network network: The network used to connect
+        """
+        super().__init__()
+        self._data = data
+        self._network = network
+
+    @classmethod
+    def create(cls, network):
+        '''
+        Initialize a new BMAAccess object with empty data.
+
+        :param cutecoin.core.net.network.Network network:
+        :return: A new BmaAccess object
+        :rtype: cutecoin.core.net.api.bma.access.BmaAccess
+        '''
+        return cls({}, network)
+
+    @property
+    def data(self):
+        return self._data.copy()
+
+    def load_from_json(self, json_data):
+        '''
+        Put data in the cache from json datas.
+
+        :param dict data: The cache in json format
+        '''
+        data = {}
+        for entry in json_data:
+            key = entry['key']
+            cache_key = (key[0], key[1], key[2], key[3], key[4])
+            data[cache_key] = entry['value']
+        self._data = data
+
+    def jsonify(self):
+        '''
+        Get the cache in json format
+
+        :return: The cache as a dict in json format
+        '''
+        data = {k: self._data[k] for k in self._data.keys()}
+        entries = []
+        for d in data:
+            entries.append({'key': d,
+                            'value': data[d]})
+        return entries
+
+    def get(self, caller, request, req_args={}, get_args={}):
+        """
+        Get Json data from the specified URL
+        :rtype : dict
+        """
+        cache_key = (str(request),
+                     str(tuple(frozenset(sorted(req_args.keys())))),
+                     str(tuple(frozenset(sorted(req_args.values())))),
+                     str(tuple(frozenset(sorted(get_args.keys())))),
+                     str(tuple(frozenset(sorted(get_args.values())))))
+
+        if cache_key in self._data.keys():
+            need_reload = False
+            if 'metadata' in self._data[cache_key]:
+                if str(request) not in BmaAccess.__saved_requests \
+                   and self._data[cache_key]['metadata']['block'] < self._network.latest_block:
+                    need_reload = True
+            else:
+                need_reload = True
+            ret_data = self._data[cache_key]['value']
+        else:
+            need_reload = True
+            ret_data = request.null_value
+
+        if need_reload:
+            #Move to network nstead of community
+            #after removing qthreads
+            reply = self.request(request, req_args, get_args)
+            reply.finished.connect(lambda:
+                                     self.handle_reply(caller, request, req_args, get_args))
+        return ret_data
+
+    def request(self, request, req_args={}, get_args={}):
+        '''
+        Start a request to the network.
+
+        :param request: A bma request class calling for data
+        :param req_args: Arguments to pass to the request constructor
+        :param get_args: Arguments to pass to the request __get__ method
+        :return: The returned data if cached = True else return the QNetworkReply
+        '''
+        nodes = self._network.synced_nodes
+        if len(nodes) > 0:
+            node = random.choice(nodes)
+            server = node.endpoint.conn_handler().server
+            port = node.endpoint.conn_handler().port
+            conn_handler = ConnectionHandler(self._network.network_manager, server, port)
+            req = request(conn_handler, **req_args)
+            reply = req.get(**get_args)
+            return reply
+        else:
+            raise NoPeerAvailable(self.currency, len(nodes))
+
+    @pyqtSlot(int, dict, dict, QObject)
+    def handle_reply(self, caller, request, req_args, get_args):
+        reply = self.sender()
+        #logging.debug("Handling QtNetworkReply for {0}".format(str(request)))
+        if reply.error() == QNetworkReply.NoError:
+            cache_key = (str(request),
+                         str(tuple(frozenset(sorted(req_args.keys())))),
+                         str(tuple(frozenset(sorted(req_args.values())))),
+                         str(tuple(frozenset(sorted(get_args.keys())))),
+                         str(tuple(frozenset(sorted(get_args.values())))))
+            strdata = bytes(reply.readAll()).decode('utf-8')
+            #logging.debug("Data in reply : {0}".format(strdata))
+
+            if cache_key not in self._data:
+                self._data[cache_key] = {}
+
+            if 'metadata' not in self._data[cache_key]:
+                self._data[cache_key]['metadata'] = {}
+            self._data[cache_key]['metadata']['block'] = self._network.latest_block
+
+            change = False
+            if 'value' in self._data[cache_key]:
+                if self._data[cache_key]['value'] != json.loads(strdata):
+                    change = True
+            else:
+                change = True
+
+            if change == True:
+                self._data[cache_key]['value'] = json.loads(strdata)
+                caller.inner_data_changed.emit(request)
+        else:
+            logging.debug("Error in reply : {0}".format(reply.error()))
+            self.community.qtrequest(caller, request, req_args, get_args)
diff --git a/src/cutecoin/core/net/api/bma/blockchain/__init__.py b/src/cutecoin/core/net/api/bma/blockchain/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..6952dc6d8232fb31eb6cb376dcdb790febd83b35
--- /dev/null
+++ b/src/cutecoin/core/net/api/bma/blockchain/__init__.py
@@ -0,0 +1,232 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Caner Candan <caner@candan.fr>, http://caner.candan.fr
+#
+
+from .. import API, logging
+
+logger = logging.getLogger("ucoin/blockchain")
+
+
+class Blockchain(API):
+    def __init__(self, conn_handler, module='blockchain'):
+        super(Blockchain, self).__init__(conn_handler, module)
+
+
+class Parameters(Blockchain):
+    """GET the blockchain parameters used by this node."""
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/parameters', **kwargs)
+
+    null_value = {
+                'currency': "",
+                'c': 0,
+                'dt': 0,
+                'ud0': 0,
+                'sigDelay': 0,
+                'sigValidity': 0,
+                'sigQty': 0,
+                'sigWoT': 0,
+                'msValidity': 0,
+                'stepMax': 0,
+                'medianTimeBlocks': 0,
+                'avgGenTime': 0,
+                'dtDiffEval': 0,
+                'blocksRot': 0,
+                'percentRot': 0
+            }
+
+
+class Membership(Blockchain):
+    """GET/POST a Membership document."""
+    def __init__(self, conn_handler, search=None):
+        super().__init__(conn_handler)
+        self.search = search
+
+    def __post__(self, **kwargs):
+        assert 'membership' in kwargs
+
+        return self.requests_post('/membership', **kwargs)
+
+    def __get__(self, **kwargs):
+        assert self.search is not None
+        return self.requests_get('/memberships/%s' % self.search, **kwargs)
+
+
+class Block(Blockchain):
+    """GET/POST a block from/to the blockchain."""
+    null_value = {
+                "version": 1,
+                "nonce": 0,
+                "number": -1,
+                "powMin": 0,
+                "time": 0,
+                "medianTime": 0,
+                "membersCount": 0,
+                "monetaryMass": 0,
+                "currency": "",
+                "issuer": "",
+                "signature": "",
+                "hash": "",
+                "previousHash": "",
+                "previousIssuer": "",
+                "dividend": 0,
+                "membersChanges": [ ],
+                "identities": [],
+                "joiners": [],
+                "actives": [],
+                "leavers": [],
+                "excluded": [],
+                "certifications": [],
+                "transactions": [],
+                "raw": ""
+            }
+
+    def __init__(self, conn_handler, number=None):
+        """
+        Use the number parameter in order to select a block number.
+
+        Arguments:
+        - `number`: block number to select
+        """
+
+        super(Block, self).__init__(conn_handler)
+
+        self.number = number
+
+    def __get__(self, **kwargs):
+        assert self.number is not None
+        return self.requests_get('/block/%d' % self.number, **kwargs)
+
+    def __post__(self, **kwargs):
+        assert 'block' in kwargs
+        assert 'signature' in kwargs
+
+        return self.requests_post('/block', **kwargs)
+
+
+class Current(Blockchain):
+    """GET, same as block/[number], but return last accepted block."""
+    null_value = {
+                "version": 1,
+                "nonce": 0,
+                "number": -1,
+                "powMin": 0,
+                "time": 0,
+                "medianTime": 0,
+                "membersCount": 0,
+                "monetaryMass": 0,
+                "currency": "",
+                "issuer": "",
+                "signature": "",
+                "hash": "",
+                "previousHash": None,
+                "previousIssuer": None,
+                "dividend": None,
+                "membersChanges": [ ],
+                "identities": [],
+                "joiners": [],
+                "actives": [],
+                "leavers": [],
+                "excluded": [],
+                "certifications": [],
+                "transactions": [],
+                "raw": ""
+            }
+    def __get__(self, **kwargs):
+        return self.requests_get('/current', **kwargs)
+
+
+class Hardship(Blockchain):
+    """GET hardship level for given member's fingerprint for writing next block."""
+
+    def __init__(self, conn_handler, fingerprint):
+        """
+        Use the number parameter in order to select a block number.
+
+        Arguments:
+        - `fingerprint`: member fingerprint
+        """
+
+        super(Hardship, self).__init__(conn_handler)
+
+        self.fingerprint = fingerprint
+
+    def __get__(self, **kwargs):
+        assert self.fingerprint is not None
+        return self.requests_get('/hardship/%s' % self.fingerprint.upper(), **kwargs)
+
+
+class Newcomers(Blockchain):
+    """GET, return block numbers containing newcomers."""
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/with/newcomers', **kwargs)
+
+
+class Certifications(Blockchain):
+    """GET, return block numbers containing certifications."""
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/with/certs', **kwargs)
+
+
+class Joiners(Blockchain):
+    """GET, return block numbers containing joiners."""
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/with/joiners', **kwargs)
+
+
+class Actives(Blockchain):
+    """GET, return block numbers containing actives."""
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/with/actives', **kwargs)
+
+
+class Leavers(Blockchain):
+    """GET, return block numbers containing leavers."""
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/with/leavers', **kwargs)
+
+
+class Excluded(Blockchain):
+    """GET, return block numbers containing excluded."""
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/with/excluded', **kwargs)
+
+
+class UD(Blockchain):
+    """GET, return block numbers containing universal dividend."""
+    null_value = {
+                "result": {
+                "blocks": []
+                }
+            }
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/with/ud', **kwargs)
+
+
+class TX(Blockchain):
+    """GET, return block numbers containing transactions."""
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/with/tx', **kwargs)
diff --git a/src/cutecoin/core/net/api/bma/network/__init__.py b/src/cutecoin/core/net/api/bma/network/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..252219946af9fd6471dd6f20bf3f95659173d19c
--- /dev/null
+++ b/src/cutecoin/core/net/api/bma/network/__init__.py
@@ -0,0 +1,35 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Caner Candan <caner@candan.fr>, http://caner.candan.fr
+#
+
+from .. import API, logging
+
+logger = logging.getLogger("ucoin/network")
+
+
+class Network(API):
+    def __init__(self, conn_handler, module='network'):
+        super(Network, self).__init__(conn_handler, module)
+
+
+class Peering(Network):
+    """GET peering information about a peer."""
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/peering', **kwargs)
+
+from . import peering
diff --git a/src/cutecoin/core/net/api/bma/network/peering/__init__.py b/src/cutecoin/core/net/api/bma/network/peering/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..8da405735be29d99eaea8c590d6c328b3d95a954
--- /dev/null
+++ b/src/cutecoin/core/net/api/bma/network/peering/__init__.py
@@ -0,0 +1,51 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Caner Candan <caner@candan.fr>, http://caner.candan.fr
+#
+
+from .. import Network, logging
+
+logger = logging.getLogger("ucoin/network/peering")
+
+
+class Base(Network):
+    def __init__(self, conn_handler):
+        super(Base, self).__init__(conn_handler, 'network/peering')
+
+
+class Peers(Base):
+    """GET peering entries of every node inside the currency network."""
+
+    def __get__(self, **kwargs):
+        """creates a generator with one peering entry per iteration."""
+
+        return self.requests_get('/peers', **kwargs)
+
+    def __post__(self, **kwargs):
+        assert 'entry' in kwargs
+        assert 'signature' in kwargs
+
+        return self.requests_post('/peers', **kwargs)
+
+
+class Status(Base):
+    """POST a network status document to this node in order notify of its status."""
+
+    def __post__(self, **kwargs):
+        assert 'status' in kwargs
+        assert 'signature' in kwargs
+
+        return self.requests_post('/status', **kwargs)
diff --git a/src/cutecoin/core/net/api/bma/node/__init__.py b/src/cutecoin/core/net/api/bma/node/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..975a14649861f5cf8e10069f7dba6e7be06cc6ad
--- /dev/null
+++ b/src/cutecoin/core/net/api/bma/node/__init__.py
@@ -0,0 +1,36 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Caner Candan <caner@candan.fr>, http://caner.candan.fr
+#
+
+from .. import API, logging
+
+logger = logging.getLogger("ucoin/node")
+
+class Node(API):
+    def __init__(self, connection_handler, module='node'):
+        super(Node, self).__init__(connection_handler, module)
+
+
+class Summary(Node):
+    """GET Certification data over a member."""
+
+    def __init__(self, connection_handler, module='node'):
+        super(Summary, self).__init__(connection_handler, module)
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/summary', **kwargs)
+
diff --git a/src/cutecoin/core/net/api/bma/tx/__init__.py b/src/cutecoin/core/net/api/bma/tx/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..4bfc3cf4755224f5e8cd3af43374f60a27253f54
--- /dev/null
+++ b/src/cutecoin/core/net/api/bma/tx/__init__.py
@@ -0,0 +1,55 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Caner Candan <caner@candan.fr>, http://caner.candan.fr
+#
+
+from .. import API, logging
+
+logger = logging.getLogger("ucoin/tx")
+
+
+class Tx(API):
+    def __init__(self, conn_handler, module='tx'):
+        super(Tx, self).__init__(conn_handler, module)
+
+
+class Process(Tx):
+    """POST a transaction."""
+
+    def __post__(self, **kwargs):
+        assert 'transaction' in kwargs
+
+        return self.requests_post('/process', **kwargs)
+
+
+class Sources(Tx):
+    """Get transaction sources."""
+
+    null_value = {
+                "currency": "",
+                "pubkey": "",
+                "sources":
+                [
+                ]
+            }
+
+    def __init__(self, conn_handler, pubkey, module='tx'):
+        super(Tx, self).__init__(conn_handler, module)
+        self.pubkey = pubkey
+
+    def __get__(self, **kwargs):
+        assert self.pubkey is not None
+        return self.requests_get('/sources/%s' % self.pubkey, **kwargs)
diff --git a/src/cutecoin/core/net/api/bma/wot/__init__.py b/src/cutecoin/core/net/api/bma/wot/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..9eb01e13d3ed26459adcb3fd5c0b877af3c36b37
--- /dev/null
+++ b/src/cutecoin/core/net/api/bma/wot/__init__.py
@@ -0,0 +1,107 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Caner Candan <caner@candan.fr>, http://caner.candan.fr
+#
+
+from .. import API, logging
+
+logger = logging.getLogger("ucoin/wot")
+
+
+class WOT(API):
+    def __init__(self, conn_handler, module='wot'):
+        super(WOT, self).__init__(conn_handler, module)
+
+
+class Add(WOT):
+    """POST Public key data."""
+
+    def __post__(self, **kwargs):
+        assert 'pubkey' in kwargs
+        assert 'self_' in kwargs
+        assert 'other' in kwargs
+
+        return self.requests_post('/add', **kwargs)
+
+
+class Lookup(WOT):
+    """GET Public key data."""
+
+    def __init__(self, conn_handler, search, module='wot'):
+        super(WOT, self).__init__(conn_handler, module)
+
+        self.search = search
+
+    def __get__(self, **kwargs):
+        assert self.search is not None
+
+        return self.requests_get('/lookup/%s' % self.search, **kwargs)
+
+
+class CertifiersOf(WOT):
+    """GET Certification data over a member."""
+    null_value = \
+        {
+            "pubkey": "",
+            "uid": "",
+            "isMember": False,
+            "certifications": []
+        }
+
+    def __init__(self, conn_handler, search, module='wot'):
+        super(WOT, self).__init__(conn_handler, module)
+
+        self.search = search
+
+    def __get__(self, **kwargs):
+        assert self.search is not None
+
+        return self.requests_get('/certifiers-of/%s' % self.search, **kwargs)
+
+
+class CertifiedBy(WOT):
+    """GET Certification data from a member."""
+    null_value = \
+        {
+            "pubkey": "",
+            "uid": "",
+            "isMember": False,
+            "certifications": []
+        }
+
+    def __init__(self, conn_handler, search, module='wot'):
+        super(WOT, self).__init__(conn_handler, module)
+
+        self.search = search
+
+    def __get__(self, **kwargs):
+        assert self.search is not None
+
+        return self.requests_get('/certified-by/%s' % self.search, **kwargs)
+
+
+class Members(WOT):
+    """GET List all current members of the Web of Trust."""
+
+    null_value = \
+        {
+            "results": []
+        }
+    def __init__(self, conn_handler, module='wot'):
+        super(WOT, self).__init__(conn_handler, module)
+
+    def __get__(self, **kwargs):
+        return self.requests_get('/members', **kwargs)
diff --git a/src/cutecoin/core/net/network.py b/src/cutecoin/core/net/network.py
index 32602d00be232c4ac90ff9f491561d834aace8dc..b12932d325b578e7890a39908bc946a5c6b80252 100644
--- a/src/cutecoin/core/net/network.py
+++ b/src/cutecoin/core/net/network.py
@@ -1,27 +1,26 @@
 '''
-Created on 24 feb. 2015
+Created on 24 févr. 2015
 
 @author: inso
 '''
-from .node import Node
+from cutecoin.core.net.node import Node
 
 import logging
 import time
+from ucoinpy.documents.peer import Peer
 
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QMutex, QCoreApplication
-from ..watching.watcher import Watcher
+from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QCoreApplication, QTimer
 
 
-class Network(Watcher):
-    """
+class Network(QObject):
+    '''
     A network is managing nodes polling and crawling of a
     given community.
-    """
+    '''
     nodes_changed = pyqtSignal()
     new_block_mined = pyqtSignal(int)
-    stopped_perpetual_crawling = pyqtSignal()
 
-    def __init__(self, currency, nodes):
+    def __init__(self, network_manager, currency, nodes):
         '''
         Constructor of a network
 
@@ -31,15 +30,17 @@ class Network(Watcher):
         super().__init__()
         self._root_nodes = nodes
         self._nodes = []
-        self._mutex = QMutex()
+        for n in nodes:
+            self.add_node(n)
         self.currency = currency
-        self.nodes = nodes
         self._must_crawl = False
         self._is_perpetual = False
+        self.network_manager = network_manager
         self._block_found = self.latest_block
+        self._timer = QTimer()
 
     @classmethod
-    def create(cls, node):
+    def create(cls, network_manager, node):
         '''
         Create a new network with one knew node
         Crawls the nodes from the first node to build the
@@ -48,7 +49,7 @@ class Network(Watcher):
         :param node: The first knew node of the network
         '''
         nodes = [node]
-        network = cls(node.currency, nodes)
+        network = cls(network_manager, node.currency, nodes)
         return network
 
     def merge_with_json(self, json_data):
@@ -59,7 +60,7 @@ class Network(Watcher):
         :param dict json_data: Nodes in json format
         '''
         for data in json_data:
-            node = Node.from_json(self.currency, data)
+            node = Node.from_json(self.network_manager, self.currency, data)
             if node.pubkey not in [n.pubkey for n in self.nodes]:
                 self.add_node(node)
                 logging.debug("Loading : {:}".format(data['pubkey']))
@@ -71,7 +72,7 @@ class Network(Watcher):
                     other_node.state = node.state
 
     @classmethod
-    def from_json(cls, currency, json_data):
+    def from_json(cls, network_manager, currency, json_data):
         '''
         Load a network from a configured community
 
@@ -80,9 +81,9 @@ class Network(Watcher):
         '''
         nodes = []
         for data in json_data:
-            node = Node.from_json(currency, data)
+            node = Node.from_json(network_manager, currency, data)
             nodes.append(node)
-        network = cls(currency, nodes)
+        network = cls(network_manager, currency, nodes)
         return network
 
     def jsonify(self):
@@ -96,6 +97,16 @@ class Network(Watcher):
             data.append(node.jsonify())
         return data
 
+    @property
+    def quality(self):
+        '''
+        Get a ratio of the synced nodes vs the rest
+        '''
+        synced = len(self.synced_nodes)
+        total = len(self.nodes)
+        ratio_synced = synced / total
+        return ratio_synced
+
     def stop_crawling(self):
         '''
         Stop network nodes crawling.
@@ -113,10 +124,6 @@ class Network(Watcher):
         '''
         Get nodes which are in the ONLINE state.
         '''
-        latest = self.latest_block
-        for n in self._nodes:
-            if n.state in (Node.ONLINE, Node.DESYNCED):
-                n.check_sync(latest)
         return [n for n in self.nodes if n.state == Node.ONLINE]
 
     @property
@@ -140,25 +147,6 @@ class Network(Watcher):
         '''
         return self._root_nodes
 
-    @nodes.setter
-    def nodes(self, new_nodes):
-        '''
-        Set new nodes
-        '''
-        self._mutex.lock()
-        try:
-            for n in self.nodes:
-                try:
-                    n.disconnect()
-                except TypeError:
-                    logging.debug("Error disconnecting node {0}".format(n.pubkey[:5]))
-
-            self._nodes = []
-            for n in new_nodes:
-                self.add_node(n)
-        finally:
-            self._mutex.unlock()
-
     @property
     def latest_block(self):
         '''
@@ -172,7 +160,8 @@ class Network(Watcher):
         '''
         self._nodes.append(node)
         node.changed.connect(self.handle_change)
-        logging.debug("{:} connected".format(node.pubkey))
+        node.neighbour_found.connect(self.handle_new_node)
+        logging.debug("{:} connected".format(node.pubkey[:5]))
 
     def add_root_node(self, node):
         '''
@@ -200,91 +189,42 @@ class Network(Watcher):
         node = self.nodes[index]
         return self._root_nodes.index(node)
 
-    def moveToThread(self, thread):
-        for n in self.nodes:
-            n.moveToThread(thread)
-        super().moveToThread(thread)
-
-    def watch(self):
-        self.stopped_perpetual_crawling.connect(self.watching_stopped)
-        self.start_perpetual_crawling()
-
-    def stop(self):
-        self.stop_crawling()
-
-    def start_perpetual_crawling(self):
+    def discover_network(self):
         '''
         Start crawling which never stops.
         To stop this crawling, call "stop_crawling" method.
         '''
-        self._must_crawl = True
-        while self.continue_crawling():
-            emit_change = False
-            nodes = self.crawling(interval=2)
-
-            new_inlines = [n.endpoint.inline() for n in nodes]
-            last_inlines = [n.endpoint.inline() for n in self.nodes]
-
-            hash_new_nodes = str(tuple(frozenset(sorted(new_inlines))))
-            hash_last_nodes = str(tuple(frozenset(sorted(last_inlines))))
-            if hash_new_nodes != hash_last_nodes:
-                logging.debug("Nodes changed...")
-                self.nodes = nodes
-                emit_change = True
-
-            for node in self.nodes:
-                if node.last_change + 3600 < time.time() and \
-                    node.state in (Node.OFFLINE, Node.CORRUPTED):
-                    try:
-                        node.changed.disconnect()
-                    except TypeError:
-                        logging.debug("Error : {0} not connected".format(node.pubkey))
-                    self.nodes.remove(node)
-                    emit_change = True
-
-            if emit_change:
-                self.nodes_changed.emit()
-            QCoreApplication.processEvents()
-
-        self.stopped_perpetual_crawling.emit()
+        if not self.continue_crawling():
+            return
+        for (i, node) in enumerate(self.nodes):
+            if not self.continue_crawling():
+                return
+
+            if node == self.nodes[-1]:
+                QTimer.singleShot((i+1)*10000, self.discover_network)
+            QTimer.singleShot(i*10000, node.refresh)
+
+    @pyqtSlot(Peer)
+    def handle_new_node(self, peer):
+        logging.debug("New node found : {0}".format(peer.pubkey[:5]))
+        pubkeys = [n.pubkey for n in self.nodes]
+        if peer.pubkey not in pubkeys:
+            node = Node.from_peer(self.network_manager, self.currency, peer)
+            self.add_node(node)
+            self.nodes_changed.emit()
 
     @pyqtSlot()
     def handle_change(self):
         node = self.sender()
-        logging.debug("Handle change")
         if node.state in (Node.ONLINE, Node.DESYNCED):
             node.check_sync(self.latest_block)
+        else:
+            if node.last_change + 3600 < time.time():
+                self.nodes.remove(node)
+                self.nodes_changed.emit()
+
         logging.debug("{0} -> {1}".format(self.latest_block, self.latest_block))
         if self._block_found < self.latest_block:
-            self._block_found = self.latest_block
             logging.debug("New block found : {0}".format(self.latest_block))
+            self._block_found = self.latest_block
             self.new_block_mined.emit(self.latest_block)
-
-        QCoreApplication.processEvents()
-        logging.debug("Syncing : {0} : last changed {1} : unsynced : {2}".format(node.pubkey[:5],
-                                                        node.last_change, time.time() - node.last_change))
-
-        self.nodes_changed.emit()
-
-    def crawling(self, interval=0):
-        '''
-        One network crawling.
-
-        :param int interval: The interval between two nodes request.
-        '''
-        nodes = []
-        traversed_pubkeys = []
-        knew_pubkeys = [n.pubkey for n in self.nodes]
-        for n in self.nodes:
-            logging.debug(traversed_pubkeys)
-            logging.debug("Peering : next to read : {0} : {1}".format(n.pubkey,
-                          (n.pubkey not in traversed_pubkeys)))
-            if self.continue_crawling():
-                n.peering_traversal(knew_pubkeys, nodes,
-                                    traversed_pubkeys, interval,
-                                    self.continue_crawling)
-                QCoreApplication.processEvents()
-                time.sleep(interval)
-
-        logging.debug("Nodes found : {0}".format(nodes))
-        return nodes
diff --git a/src/cutecoin/core/net/node.py b/src/cutecoin/core/net/node.py
index c71bcce138130ea7b916c1a8ffa7a5d958db5f60..c2c162e4860f4080ebf03192c09b193acc389876 100644
--- a/src/cutecoin/core/net/node.py
+++ b/src/cutecoin/core/net/node.py
@@ -5,18 +5,20 @@ Created on 21 févr. 2015
 '''
 
 from ucoinpy.documents.peer import Peer, BMAEndpoint, Endpoint
-from ucoinpy.api import bma
-from ucoinpy.api.bma import ConnectionHandler
 from requests.exceptions import RequestException, ConnectionError
-from ...tools.exceptions import InvalidNodeCurrency, PersonNotFoundError
-from ..person import Person
+from cutecoin.tools.exceptions import InvalidNodeCurrency, PersonNotFoundError
+from cutecoin.core.person import Person
+from cutecoin.core.net.api import bma as qtbma
+from cutecoin.core.net.api.bma import ConnectionHandler
+
 import logging
 import time
 import ctypes
 import sys
+import json
 
-from PyQt5.QtCore import QObject, pyqtSignal
-
+from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot
+from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest
 
 class Node(QObject):
     '''
@@ -34,26 +36,29 @@ class Node(QObject):
     CORRUPTED = 4
 
     changed = pyqtSignal()
+    neighbour_found = pyqtSignal(Peer)
 
-    def __init__(self, currency, endpoints, uid, pubkey, block,
-                 state, last_change, software, version):
+    def __init__(self, network_manager, currency, endpoints, uid, pubkey, block,
+                 state, last_change, last_merkle, software, version):
         '''
         Constructor
         '''
         super().__init__()
+        self.network_manager = network_manager
         self._endpoints = endpoints
         self._uid = uid
         self._pubkey = pubkey
-        self._software = software
-        self._version = version
         self.block = block
         self._state = state
         self._neighbours = []
         self._currency = currency
         self._last_change = last_change
+        self._last_merkle = last_merkle
+        self._software = software
+        self._version = version
 
     @classmethod
-    def from_address(cls, currency, address, port):
+    def from_address(cls, network_manager, currency, address, port):
         '''
         Factory method to get a node from a given address
 
@@ -62,7 +67,7 @@ class Node(QObject):
         :param str address: The node address
         :param int port: The node port
         '''
-        peer_data = bma.network.Peering(ConnectionHandler(address, port)).get()
+        peer_data = qtbma.network.Peering(ConnectionHandler(network_manager, address, port)).get()
 
         peer = Peer.from_signed_raw("{0}{1}\n".format(peer_data['raw'],
                                                   peer_data['signature']))
@@ -71,13 +76,14 @@ class Node(QObject):
             if peer.currency != currency:
                 raise InvalidNodeCurrency(peer.currency, currency)
 
-        node = cls(peer.currency, peer.endpoints, "", peer.pubkey, 0,
-                   Node.ONLINE, time.time(), "", "")
+        node = cls(network_manager, peer.currency, peer.endpoints,
+                   "", peer.pubkey, 0, Node.ONLINE, time.time(),
+                   {'root': "", 'leaves': []})
         logging.debug("Node from address : {:}".format(str(node)))
         return node
 
     @classmethod
-    def from_peer(cls, currency, peer):
+    def from_peer(cls, network_manager, currency, peer):
         '''
         Factory method to get a node from a peer document.
 
@@ -89,21 +95,23 @@ class Node(QObject):
             if peer.currency != currency:
                 raise InvalidNodeCurrency(peer.currency, currency)
 
-        node = cls(peer.currency, peer.endpoints, "", "", 0,
-                   Node.ONLINE, time.time(), "", "")
+        node = cls(network_manager, peer.currency, peer.endpoints, "", "", 0,
+                   Node.ONLINE, time.time(),
+                   {'root': "", 'leaves': []},
+                   "", "")
         logging.debug("Node from peer : {:}".format(str(node)))
         return node
 
     @classmethod
-    def from_json(cls, currency, data):
+    def from_json(cls, network_manager, currency, data):
         endpoints = []
         uid = ""
         pubkey = ""
+        software = ""
+        version = ""
         block = 0
         last_change = time.time()
         state = Node.ONLINE
-        software = ''
-        version = ''
         logging.debug(data)
         for endpoint_data in data['endpoints']:
             endpoints.append(Endpoint.from_inline(endpoint_data))
@@ -125,21 +133,20 @@ class Node(QObject):
 
         if 'state' in data:
             state = data['state']
-        else:
-            logging.debug("Error : no state in node")
 
         if 'software' in data:
             software = data['software']
-        else:
-            logging.debug("Error : no software in node")
 
         if 'version' in data:
             version = data['version']
         else:
-            logging.debug("Error : no version in node")
+            logging.debug("Error : no state in node")
 
-        node = cls(currency, endpoints, uid, pubkey, block,
-                   state, last_change, software, version)
+        node = cls(network_manager, currency, endpoints,
+                   uid, pubkey, block,
+                   state, last_change,
+                   {'root': "", 'leaves': []},
+                   software, version)
         logging.debug("Node from json : {:}".format(str(node)))
         return node
 
@@ -161,9 +168,7 @@ class Node(QObject):
                 'currency': self._currency,
                 'state': self._state,
                 'last_change': self._last_change,
-                'block': self.block,
-                'software': self.software,
-                'version': self.version}
+                'block': self.block}
         endpoints = []
         for e in self._endpoints:
             endpoints.append(e.inline())
@@ -182,14 +187,6 @@ class Node(QObject):
     def block(self):
         return self._block
 
-    @property
-    def version(self):
-        return self._version
-
-    @property
-    def software(self):
-        return self._software
-
     @block.setter
     def block(self, new_block):
         self._block = new_block
@@ -214,182 +211,234 @@ class Node(QObject):
     def last_change(self):
         return self._last_change
 
+    @property
+    def software(self):
+        return self._software
+
+    @software.setter
+    def software(self, new_soft):
+        if self._software != new_soft:
+            self._software = new_soft
+            self.changed.emit()
+
+    @property
+    def version(self):
+        return self._version
+
+    @version.setter
+    def version(self, new_version):
+        if self._version != new_version:
+            self._version = new_version
+            self.changed.emit()
+
     @last_change.setter
     def last_change(self, val):
-        #logging.debug("{:} | Changed state : {:}".format(self.pubkey[:5],val))
+        logging.debug("{:} | Changed state : {:}".format(self.pubkey[:5],
+                                                         val))
         self._last_change = val
 
     @state.setter
     def state(self, new_state):
-        #logging.debug("{:} | Last state : {:} / new state : {:}".format(self.pubkey[:5],self.state, new_state))
+        logging.debug("{:} | Last state : {:} / new state : {:}".format(self.pubkey[:5],
+                                                                        self.state, new_state))
         if self._state != new_state:
             self.last_change = time.time()
         self._state = new_state
 
     def check_sync(self, block):
-        #logging.debug("Check sync")
+        logging.debug("Check sync")
         if self.block < block:
             self.state = Node.DESYNCED
         else:
             self.state = Node.ONLINE
 
-    def _request_uid(self):
-        uid = ""
-        try:
-            data = bma.wot.Lookup(self.endpoint.conn_handler(), self.pubkey).get()
-            timestamp = 0
-            for result in data['results']:
-                if result["pubkey"] == self.pubkey:
-                    uids = result['uids']
-                    for uid in uids:
-                        if uid["meta"]["timestamp"] > timestamp:
-                            timestamp = uid["meta"]["timestamp"]
-                            uid = uid["uid"]
-        except ValueError as e:
-            if '404' in str(e):
-                logging.debug("Error : node uid not found : {0}".format(self.pubkey))
-                uid = ""
-        return uid
-
-    def refresh_state(self):
-        logging.debug("Refresh state")
-        emit_change = False
-        try:
-            informations = bma.network.Peering(self.endpoint.conn_handler()).get()
-            node_pubkey = informations["pubkey"]
-            try:
-                block = bma.blockchain.Current(self.endpoint.conn_handler()).get()
-                block_number = block["number"]
-            except ValueError as e:
-                if '404' in str(e):
-                    block_number = 0
-
-            peers_data = bma.network.peering.Peers(self.endpoint.conn_handler()).get()
-            neighbours = []
-            for p in peers_data:
-                peer = Peer.from_signed_raw("{0}{1}\n".format(p['value']['raw'],
-                                                            p['value']['signature']))
-                neighbours.append(peer.endpoints)
-            logging.debug("Found neighbours : {0}".format(len(neighbours)))
-
-            node_currency = informations["currency"]
-            node_uid = self._request_uid()
-
-            implementation = bma.node.Summary(self.endpoint.conn_handler()).get()
-            software = implementation["ucoin"]["software"]
-            version = implementation["ucoin"]["version"]
-
-            #If the nodes goes back online...
-            if self.state in (Node.OFFLINE, Node.CORRUPTED):
+    def check_noerror(self, error_code, status_code):
+        if error_code != QNetworkReply.NoError:
+            if self.state == Node.OFFLINE:
                 self.state = Node.ONLINE
-                logging.debug("Change : new state online")
-                emit_change = True
-        except ConnectionError as e:
-            logging.debug(str(e))
-
-            if self.state != Node.OFFLINE:
-                self.state = Node.OFFLINE
-                logging.debug("Change : new state offine")
-                emit_change = True
-            # Dirty hack to reload resolv.conf on linux
-            if 'Connection aborted' in str(e) and 'gaierror' in str(e):
-                logging.debug("Connection Aborted")
-                if 'linux' in sys.platform:
-                    try:
-                        libc = ctypes.CDLL('libc.so.6')
-                        res_init = getattr(libc, '__res_init')
-                        res_init(None)
-                    except:
-                        logging.error('Error calling libc.__res_init')
-        except RequestException as e:
-            logging.debug(str(e))
-            if self.state != Node.OFFLINE:
-                self.state = Node.OFFLINE
-                logging.debug("Change : new state offine")
-                emit_change = True
-
-        # If not is offline, do not refresh last data
-        if self.state != Node.OFFLINE:
-            # If not changed its currency, consider it corrupted
-            if node_currency != self._currency:
+            return False
+        if status_code == 503:
+            return False
+        return True
+
+    @pyqtSlot()
+    def refresh(self):
+        logging.debug("Refresh block")
+        self.refresh_block()
+        logging.debug("Refresh info")
+        self.refresh_informations()
+        logging.debug("Refresh uid")
+        self.refresh_uid()
+        logging.debug("Refresh peers")
+        self.refresh_peers()
+        logging.debug("Refresh summary")
+        self.refresh_summary()
+
+    def refresh_block(self):
+        conn_handler = ConnectionHandler(self.network_manager,
+                                         self.endpoint.conn_handler().server,
+                                         self.endpoint.conn_handler().port)
+
+        logging.debug("Requesting {0}".format(conn_handler))
+        reply = qtbma.blockchain.Current(conn_handler).get()
+
+        reply.finished.connect(self.handle_block_reply)
+
+    @pyqtSlot()
+    def handle_block_reply(self):
+        reply = self.sender()
+        status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
+
+        if self.check_noerror(reply.error(), status_code):
+            if status_code == 200:
+                strdata = bytes(reply.readAll()).decode('utf-8')
+                block_data = json.loads(strdata)
+                block_number = block_data['number']
+            elif status_code == 404:
+                block_number = 0
+
+            if block_number != self.block:
+                self.block = block_number
+                logging.debug("Changed block {0} -> {1}".format(self.block,
+                                                                     block_number))
+                self.changed.emit()
+
+        else:
+            logging.debug("Error in block reply")
+
+    def refresh_informations(self):
+        conn_handler = ConnectionHandler(self.network_manager,
+                                         self.endpoint.conn_handler().server,
+                                         self.endpoint.conn_handler().port)
+
+        peering_reply = qtbma.network.Peering(conn_handler).get()
+        peering_reply.finished.connect(self.handle_peering_reply)
+
+    @pyqtSlot()
+    def handle_peering_reply(self):
+        reply = self.sender()
+        status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
+
+        if self.check_noerror(reply.error(), status_code):
+            strdata = bytes(reply.readAll()).decode('utf-8')
+            peering_data = json.loads(strdata)
+            logging.debug(peering_data)
+            node_pubkey = peering_data["pubkey"]
+            node_currency = peering_data["currency"]
+
+            change = False
+            if node_pubkey != self.pubkey:
+                self._pubkey = node_pubkey
+                change = True
+
+            if node_currency != self.currency:
                 self.state = Node.CORRUPTED
                 logging.debug("Change : new state corrupted")
-                emit_change = True
-            else:
-                if block_number != self.block:
-                    logging.debug("Change : new block {0} -> {1}".format(self.block,
-                                                                         block_number))
-                    self.block = block_number
-                    logging.debug("Changed block {0} -> {1}".format(self.block,
-                                                                         block_number))
-                    emit_change = True
-
-                if node_pubkey != self._pubkey:
-                    logging.debug("Change : new pubkey {0} -> {1}".format(self._pubkey,
-                                                                          node_pubkey))
-                    self._pubkey = node_pubkey
-                    emit_change = True
-
-                if node_uid != self._uid:
-                    logging.debug("Change : new uid")
-                    self._uid = node_uid
-                    emit_change = True
-
-                if software != self._software:
-                    logging.debug("Change : new software")
-                    self._software = software
-                    emit_change = True
-
-                if version != self._version:
-                    logging.debug("Change : new version")
-                    self._version = version
-                    emit_change = True
-
-                logging.debug(neighbours)
-                new_inlines = [e.inline() for n in neighbours for e in n]
-                last_inlines = [e.inline() for n in self._neighbours for e in n]
-
-                hash_new_neighbours = hash(tuple(frozenset(sorted(new_inlines))))
-                hash_last_neighbours = hash(tuple(frozenset(sorted(last_inlines))))
-                if hash_new_neighbours != hash_last_neighbours:
-                    self._neighbours = neighbours
-                    logging.debug("Change : new neighbours {0} -> {1}".format(last_inlines,
-                                                                              new_inlines))
-                    emit_change = True
-
-        if emit_change:
-            self.changed.emit()
+                change = True
 
-    def peering_traversal(self, knew_pubkeys, found_nodes,
-                          traversed_pubkeys, interval,
-                          continue_crawling):
-        logging.debug("Read {0} peering".format(self.pubkey))
-        traversed_pubkeys.append(self.pubkey)
-        self.refresh_state()
-
-        if self.pubkey not in [n.pubkey for n in found_nodes]:
-            # if node is corrupted remove it
-            if self.state != Node.CORRUPTED:
-                logging.debug("Found : {0} node".format(self.pubkey))
-                found_nodes.append(self)
-            logging.debug(self.neighbours)
-            for n in self.neighbours:
-                try:
-                    e = next(e for e in n if type(e) is BMAEndpoint)
-                    peering = bma.network.Peering(e.conn_handler()).get()
-                except:
-                    continue
-                peer = Peer.from_signed_raw("{0}{1}\n".format(peering['raw'],
-                                                            peering['signature']))
-                if peer.pubkey not in traversed_pubkeys and \
-                    peer.pubkey not in knew_pubkeys and continue_crawling():
-                    node = Node.from_peer(self._currency, peer)
-                    logging.debug(traversed_pubkeys)
-                    logging.debug("Traversing : next to read : {0} : {1}".format(node.pubkey,
-                                  (node.pubkey not in traversed_pubkeys)))
-                    node.peering_traversal(knew_pubkeys, found_nodes,
-                                        traversed_pubkeys, interval, continue_crawling)
-                    time.sleep(interval)
+            if change:
+                self.changed.emit()
+        else:
+            logging.debug("Error in peering reply")
+
+    def refresh_summary(self):
+        conn_handler = ConnectionHandler(self.network_manager,
+                                         self.endpoint.conn_handler().server,
+                                         self.endpoint.conn_handler().port)
+
+        summary_reply = qtbma.node.Summary(conn_handler).get()
+        summary_reply.finished.connect(self.handle_summary_reply)
+
+    @pyqtSlot()
+    def handle_summary_reply(self):
+        reply = self.sender()
+        status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
+
+        if self.check_noerror(reply.error(), status_code):
+            strdata = bytes(reply.readAll()).decode('utf-8')
+            summary_data = json.loads(strdata)
+            self.software = summary_data["ucoin"]["software"]
+            self.version = summary_data["ucoin"]["version"]
+
+    def refresh_uid(self):
+        conn_handler = ConnectionHandler(self.network_manager,
+                                         self.endpoint.conn_handler().server,
+                                         self.endpoint.conn_handler().port)
+        uid_reply = qtbma.wot.Lookup(conn_handler, self.pubkey).get()
+        uid_reply.finished.connect(self.handle_uid_reply)
+        uid_reply.error.connect(lambda code: logging.debug("Error : {0}".format(code)))
+
+    @pyqtSlot()
+    def handle_uid_reply(self):
+        reply = self.sender()
+        status_code = reply.attribute( QNetworkRequest.HttpStatusCodeAttribute );
+
+        if self.check_noerror(reply.error(), status_code):
+            uid = ''
+            if status_code == 200:
+                strdata = bytes(reply.readAll()).decode('utf-8')
+                data = json.loads(strdata)
+                timestamp = 0
+                for result in data['results']:
+                    if result["pubkey"] == self.pubkey:
+                        uids = result['uids']
+                        for uid in uids:
+                            if uid["meta"]["timestamp"] > timestamp:
+                                timestamp = uid["meta"]["timestamp"]
+                                uid = uid["uid"]
+            elif status_code == 404:
+                logging.debug("UID not found")
+
+            if self._uid != uid:
+                self._uid = uid
+                self.changed.emit()
+        else:
+            logging.debug("error in uid reply")
+
+    def refresh_peers(self):
+        conn_handler = ConnectionHandler(self.network_manager,
+                                         self.endpoint.conn_handler().server,
+                                         self.endpoint.conn_handler().port)
+
+        reply = qtbma.network.peering.Peers(conn_handler).get(leaves='true')
+        reply.finished.connect(self.handle_peers_reply)
+        reply.error.connect(lambda code: logging.debug("Error : {0}".format(code)))
+
+    @pyqtSlot()
+    def handle_peers_reply(self):
+        reply = self.sender()
+        status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
+
+        if self.check_noerror(reply.error(), status_code):
+            strdata = bytes(reply.readAll()).decode('utf-8')
+            peers_data = json.loads(strdata)
+            if peers_data['root'] != self._last_merkle['root']:
+                leaves = [leaf for leaf in peers_data['leaves']
+                          if leaf not in self._last_merkle['leaves']]
+                for leaf_hash in leaves:
+                    conn_handler = ConnectionHandler(self.network_manager,
+                                                     self.endpoint.conn_handler().server,
+                                                     self.endpoint.conn_handler().port)
+                    leaf_reply = qtbma.network.peering.Peers(conn_handler).get(leaf=leaf_hash)
+                    leaf_reply.finished.connect(self.handle_leaf_reply)
+                self._last_merkle = {'root' : peers_data['root'],
+                                     'leaves': peers_data['leaves']}
+        else:
+            logging.debug("Error in peers reply")
+
+    @pyqtSlot()
+    def handle_leaf_reply(self):
+        reply = self.sender()
+        status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
+
+        if self.check_noerror(reply.error(), status_code):
+            strdata = bytes(reply.readAll()).decode('utf-8')
+            leaf_data = json.loads(strdata)
+            doc = Peer.from_signed_raw("{0}{1}\n".format(leaf_data['leaf']['value']['raw'],
+                                                        leaf_data['leaf']['value']['signature']))
+            self.neighbour_found.emit(doc)
+        else:
+            logging.debug("Error in leaf reply")
 
     def __str__(self):
         return ','.join([str(self.pubkey), str(self.endpoint.server), str(self.endpoint.port), str(self.block),
diff --git a/src/cutecoin/core/person.py b/src/cutecoin/core/person.py
index 276ef0e0fa752a4124bcb56051d9d26e0aa12c29..ac44769f48489a4b8e23ad27296717de4728b3b5 100644
--- a/src/cutecoin/core/person.py
+++ b/src/cutecoin/core/person.py
@@ -419,7 +419,7 @@ class Person(object):
 
     def membership_expiration_time(self, community):
         join_block = self.membership(community)['blockNumber']
-        join_date = community.get_block(join_block).mediantime
+        join_date = community.get_block(join_block)['medianTime']
         parameters = community.parameters
         expiration_date = join_date + parameters['sigValidity']
         current_time = time.time()
diff --git a/src/cutecoin/core/wallet.py b/src/cutecoin/core/wallet.py
index 415f05bc2abf81fcc7262f310b27d992a1c50b1f..ba53f61d0034d4b88529ae409b75a3e6c835f026 100644
--- a/src/cutecoin/core/wallet.py
+++ b/src/cutecoin/core/wallet.py
@@ -4,12 +4,10 @@ Created on 1 févr. 2014
 @author: inso
 '''
 
-from ucoinpy import PROTOCOL_VERSION
-from ucoinpy.api import bma
-from ucoinpy.documents.block import Block
 from ucoinpy.documents.transaction import InputSource, OutputSource, Transaction
 from ucoinpy.key import SigningKey
 
+from .net.api import bma as qtbma
 from ..tools.exceptions import NotEnoughMoneyError, NoPeerAvailable, PersonNotFoundError
 from .transfer import Transfer, Received
 from .person import Person
@@ -198,6 +196,7 @@ class Wallet(QObject):
     A wallet is used to manage money with a unique key.
     '''
 
+    inner_data_changed = pyqtSignal(int)
     refresh_progressed = pyqtSignal(int, int)
 
     def __init__(self, walletid, pubkey, name):
@@ -440,10 +439,10 @@ class Wallet(QObject):
         '''
         Get available sources in a given community
 
-        :param community: The community where we want available sources
+        :param cutecoin.core.community.Community community: The community where we want available sources
         :return: List of InputSource ucoinpy objects
         '''
-        data = community.request(bma.tx.Sources,
+        data = community.bma_access.get(self, qtbma.tx.Sources,
                                  req_args={'pubkey': self.pubkey})
         tx = []
         for s in data['sources']:
diff --git a/src/cutecoin/core/watching/blockchain.py b/src/cutecoin/core/watching/blockchain.py
deleted file mode 100644
index a1f6c46179912a2a1302525307b20c7fbb4283f1..0000000000000000000000000000000000000000
--- a/src/cutecoin/core/watching/blockchain.py
+++ /dev/null
@@ -1,63 +0,0 @@
-'''
-Created on 27 févr. 2015
-
-@author: inso
-'''
-
-import logging
-import time
-from requests.exceptions import RequestException
-from ...tools.exceptions import NoPeerAvailable
-from .watcher import Watcher
-from PyQt5.QtCore import pyqtSignal
-
-
-class BlockchainWatcher(Watcher):
-
-    new_transfers = pyqtSignal(list)
-    loading_progressed = pyqtSignal(int, int)
-
-    def __init__(self, account, community):
-        super().__init__()
-        self.account = account
-        self.community = community
-        self.time_to_wait = int(self.community.parameters['avgGenTime'] / 10)
-        self.exiting = False
-        self.last_block = self.community.network.latest_block
-
-    def watch(self):
-        loaded_wallets = 0
-        def progressing(value, maximum):
-            account_value = maximum * loaded_wallets + value
-            account_max = maximum * len(self.account.wallets)
-            self.loading_progressed.emit(account_value, account_max)
-
-        try:
-            received_list = []
-            block_number = self.community.network.latest_block
-            if self.last_block != block_number:
-
-                for w in self.account.wallets:
-                    w.refresh_progressed.connect(progressing)
-
-                if not self.exiting:
-                    self.community.refresh_cache()
-                for w in self.account.wallets:
-                    if not self.exiting:
-                        w.refresh_cache(self.community, received_list)
-                        loaded_wallets = loaded_wallets + 1
-
-                logging.debug("New block, {0} mined in {1}".format(block_number,
-                                                                   self.community.currency))
-                self.last_block = block_number
-                if len(received_list) > 0:
-                    self.new_transfers.emit(received_list)
-        except NoPeerAvailable:
-            pass
-        except RequestException as e:
-            self.error.emit("Cannot check new block : {0}".format(str(e)))
-        finally:
-            self.watching_stopped.emit()
-
-    def stop(self):
-        self.exiting = True
diff --git a/src/cutecoin/core/watching/monitor.py b/src/cutecoin/core/watching/monitor.py
deleted file mode 100644
index c7086527f3789b89555546f897e75a83ef512a05..0000000000000000000000000000000000000000
--- a/src/cutecoin/core/watching/monitor.py
+++ /dev/null
@@ -1,91 +0,0 @@
-'''
-Created on 18 mars 2015
-
-@author: inso
-'''
-
-from PyQt5.QtCore import QThread, Qt, QObject
-from .blockchain import BlockchainWatcher
-from .persons import PersonsWatcher
-import logging
-
-
-class Monitor(object):
-    '''
-    The monitor is managing watchers
-    '''
-
-    # Dirty hack to avoid GC on monitors
-    # GC was causing random crashes
-    # We will get rid of QThreads asap
-    #___dirty_monitors = []
-
-    def __init__(self, account):
-        '''
-        Constructor
-        '''
-        super().__init__()
-        self.account = account
-        self.threads_pool = []
-        self._blockchain_watchers = {}
-        self._network_watchers = {}
-        self._persons_watchers = {}
-        #Monitor.___dirty_monitors.append(self)
-
-    def blockchain_watcher(self, community):
-        return self._blockchain_watchers[community.name]
-
-    def network_watcher(self, community):
-        return self._networks[community.name]
-
-    def persons_watcher(self, community):
-        return self._persons_watchers[community.name]
-
-    def connect_watcher_to_thread(self, watcher):
-        thread = QThread()
-        watcher.moveToThread(thread)
-        thread.started.connect(watcher.watch)
-        watcher.watching_stopped.connect(thread.exit)
-
-        self.threads_pool.append(thread)
-
-    def prepare_watching(self):
-        for c in self.account.communities:
-            persons_watcher = PersonsWatcher(c)
-            self.connect_watcher_to_thread(persons_watcher)
-            self._persons_watchers[c.name] = persons_watcher
-
-            bc_watcher = BlockchainWatcher(self.account, c)
-            self.connect_watcher_to_thread(bc_watcher)
-            self._blockchain_watchers[c.name] = bc_watcher
-
-            self.connect_watcher_to_thread(c.network)
-            self._network_watchers[c.name] = c.network
-
-    def start_network_watchers(self):
-        for watcher in self._network_watchers.values():
-            watcher.thread().start()
-
-    def stop_watching(self):
-        for watcher in self._persons_watchers.values():
-            watcher.stop()
-            self.threads_pool.remove(watcher.thread())
-            watcher.deleteLater()
-            watcher.thread().deleteLater()
-
-        for watcher in self._blockchain_watchers.values():
-            watcher.stop()
-            self.threads_pool.remove(watcher.thread())
-            watcher.deleteLater()
-            watcher.thread().deleteLater()
-
-        for watcher in self._network_watchers.values():
-            watcher.stop()
-            self.threads_pool.remove(watcher.thread())
-            watcher.deleteLater()
-            watcher.thread().deleteLater()
-
-        self.threads_pool = []
-        self._blockchain_watchers = {}
-        self._network_watchers = {}
-        self._persons_watchers = {}
diff --git a/src/cutecoin/core/watching/persons.py b/src/cutecoin/core/watching/persons.py
deleted file mode 100644
index 6311acd524b39b8ed53ba3723ac7cac88c837daf..0000000000000000000000000000000000000000
--- a/src/cutecoin/core/watching/persons.py
+++ /dev/null
@@ -1,44 +0,0 @@
-'''
-Created on 27 févr. 2015
-
-@author: inso
-'''
-
-from PyQt5.QtCore import pyqtSignal
-from ..person import Person
-from .watcher import Watcher
-import logging
-
-
-class PersonsWatcher(Watcher):
-    '''
-    This will crawl the network to always
-    have up to date informations about the nodes
-    '''
-    person_changed = pyqtSignal(str)
-
-    def __init__(self, community):
-        super().__init__()
-        self.community = community
-        self.exiting = False
-
-    def watch(self):
-        logging.debug("Watching persons")
-        instances = Person._instances.copy()
-        for p in instances.values():
-            if not self.exiting:
-                for func in [Person.membership,
-                             Person.is_member,
-                             Person.certifiers_of,
-                             Person.certified_by,
-                             Person.published_uid]:
-                    if not self.exiting:
-                        if p.reload(func, self.community):
-                            logging.debug("Change detected on {0} about {1}".format(p.pubkey,
-                                                                                func.__name__))
-                        self.person_changed.emit(p.pubkey)
-        logging.debug("Finished watching persons")
-        self.watching_stopped.emit()
-
-    def stop(self):
-        self.exiting = True
\ No newline at end of file
diff --git a/src/cutecoin/core/watching/watcher.py b/src/cutecoin/core/watching/watcher.py
deleted file mode 100644
index ead092282525b64fd85e309c242b545320f191c6..0000000000000000000000000000000000000000
--- a/src/cutecoin/core/watching/watcher.py
+++ /dev/null
@@ -1,23 +0,0 @@
-'''
-Created on 20 mars 2015
-
-@author: inso
-'''
-
-from PyQt5.QtCore import QObject, pyqtSlot, pyqtSignal
-
-
-class Watcher(QObject):
-    watching_stopped = pyqtSignal()
-    error = pyqtSignal(str)
-
-    def __init__(self):
-        super().__init__()
-
-    @pyqtSlot()
-    def watch(self):
-        pass
-
-    @pyqtSlot()
-    def stop(self):
-        pass
diff --git a/src/cutecoin/gui/community_tab.py b/src/cutecoin/gui/community_tab.py
index 724b89957ab1cd00ae04802eb5816bf0c44bccf1..09c7b99dc595fc2a0ba18fb8c6a5d9ec487cfcd2 100644
--- a/src/cutecoin/gui/community_tab.py
+++ b/src/cutecoin/gui/community_tab.py
@@ -20,6 +20,7 @@ from . import toast
 from ..tools.exceptions import PersonNotFoundError, NoPeerAvailable
 from ..core.person import Person
 from ucoinpy.api import bma
+from ..core.net.api import bma as qtbma
 
 
 class CommunityTabWidget(QWidget, Ui_CommunityTabWidget):
@@ -41,7 +42,9 @@ class CommunityTabWidget(QWidget, Ui_CommunityTabWidget):
         self.setupUi(self)
         self.parent = parent
         self.community = community
+        self.community.inner_data_changed.connect(self.handle_change)
         self.account = account
+        self._last_search = ''
         self.password_asker = password_asker
         identities_model = IdentitiesTableModel(community)
         proxy = IdentitiesFilterProxyModel()
@@ -51,7 +54,6 @@ class CommunityTabWidget(QWidget, Ui_CommunityTabWidget):
         self.table_identities.customContextMenuRequested.connect(self.identity_context_menu)
         self.table_identities.sortByColumn(0, Qt.AscendingOrder)
         self.table_identities.resizeColumnsToContents()
-        app.monitor.persons_watcher(self.community).person_changed.connect(self.refresh_person)
 
         self.wot_tab = WotTabWidget(app, account, community, password_asker, self)
         self.tabs_information.addTab(self.wot_tab, QIcon(':/icons/wot_icon'), self.tr("Web of Trust"))
@@ -282,9 +284,15 @@ Revoking your UID can only success if it is not already validated by the network
         for identity in response['results']:
             persons.append(Person.lookup(identity['pubkey'], self.community))
 
+        self._last_search = 'text'
         self.edit_textsearch.clear()
         self.refresh(persons)
 
+    def handle_change(self, origin):
+        if origin == qtbma.wot.Members:
+            if self._last_search == 'members':
+                self.search_members()
+
     def search_members(self):
         """
         Search members of community and display found members
@@ -294,6 +302,8 @@ Revoking your UID can only success if it is not already validated by the network
         for p in pubkeys:
             persons.append(Person.lookup(p, self.community))
 
+        self._last_search = 'members'
+
         self.edit_textsearch.clear()
         self.refresh(persons)
 
@@ -301,6 +311,7 @@ Revoking your UID can only success if it is not already validated by the network
         """
         Search members of community and display found members
         """
+        self._last_search = 'direct_connections'
         self.refresh()
 
     def refresh(self, persons=None):
diff --git a/src/cutecoin/gui/currency_tab.py b/src/cutecoin/gui/currency_tab.py
index 65075002e172f422846c77fd412176d179eaba95..3badb34f0c12eabb56d435b19ed6a990572da627 100644
--- a/src/cutecoin/gui/currency_tab.py
+++ b/src/cutecoin/gui/currency_tab.py
@@ -59,10 +59,6 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget):
 
         self.community.network.new_block_mined.connect(self.refresh_block)
         self.community.network.nodes_changed.connect(self.refresh_status)
-        bc_watcher = self.app.monitor.blockchain_watcher(self.community)
-        bc_watcher.error.connect(self.display_error)
-        bc_watcher.watching_stopped.connect(self.refresh_data)
-        bc_watcher.new_transfers.connect(self.notify_transfers)
 
     def refresh(self):
         if self.app.current_account is None:
@@ -102,11 +98,11 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget):
                                     self.tr("Informations"))
 
             # fix bug refresh_nodes launch on destroyed NetworkTabWidget
-            logging.debug('Disconnect community.network.nodes_changed')
-            try:
-                self.community.network.nodes_changed.disconnect()
-            except TypeError:
-                logging.debug('No signals on community.network.nodes_changed')
+            #logging.debug('Disconnect community.network.nodes_changed')
+            #try:
+            #    self.community.network.nodes_changed.disconnect()
+            #except TypeError:
+            #    logging.debug('No signals on community.network.nodes_changed')
 
             self.tab_network = NetworkTabWidget(self.community)
             self.tabs_account.addTab(self.tab_network,
@@ -181,9 +177,9 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget):
         '''
         logging.debug("Refresh status")
         text = self.tr(" Block {0}").format(self.community.network.latest_block)
-        if self.community.network_quality() > 0.66:
+        if self.community.network.quality > 0.66:
             icon = '<img src=":/icons/connected" width="12" height="12"/>'
-        elif self.community.network_quality() > 0.33:
+        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"/>'
@@ -213,6 +209,7 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget):
             self.tab_wallets.refresh()
 
     def showEvent(self, event):
+        self.community.network.discover_network()
         self.refresh_status()
 
     def referential_changed(self):
diff --git a/src/cutecoin/gui/informations_tab.py b/src/cutecoin/gui/informations_tab.py
index d6e3661557752428b70c293d1d5909c00b9de576..e4c3c854285b4a3200f7b16819b719b2a008c115 100644
--- a/src/cutecoin/gui/informations_tab.py
+++ b/src/cutecoin/gui/informations_tab.py
@@ -64,6 +64,7 @@ class InformationsTabWidget(QWidget, Ui_InformationsTabWidget):
                 # display float values
                 localized_ud = QLocale().toString(ud, 'f', 6)
                 localized_mass_per_member = QLocale().toString(
+                    float(0) if block['membersCount'] <= 0 else
                     self.get_referential_diff_value(block['monetaryMass'] / block['membersCount']), 'f', 6
                 )
                 localized_monetary_mass = QLocale().toString(
@@ -93,6 +94,7 @@ class InformationsTabWidget(QWidget, Ui_InformationsTabWidget):
                     localized_mass_per_member,
                     self.tr('Monetary Mass per member M(t)/N(t) in'),
                     self.get_referential_diff_name(),
+                    float(0) if block_t_minus_1['membersCount'] == 0 else
                     block['dividend'] / (block_t_minus_1['monetaryMass'] / block_t_minus_1['membersCount']),
                     params['dt'] / 86400,
                     self.tr('Actual growth c = UD(t)/[M(t-1)/N(t-1)]'),
@@ -128,6 +130,7 @@ class InformationsTabWidget(QWidget, Ui_InformationsTabWidget):
                     float(
                         self.get_referential_diff_value(
                             math.ceil(
+                                float(0) if block['membersCount'] == 0 else
                                 max(block['dividend'], params['c'] * block['monetaryMass'] / block['membersCount'])
                             )
                         )
diff --git a/src/cutecoin/gui/mainwindow.py b/src/cutecoin/gui/mainwindow.py
index b44cafb29dfe137ed7877ba77c0302f1022c400b..7cca2b206465bed3721085ba23fef6f76553518c 100644
--- a/src/cutecoin/gui/mainwindow.py
+++ b/src/cutecoin/gui/mainwindow.py
@@ -189,7 +189,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
         except:
             logging.debug("Disconnect of app failed")
 
-        self.app.monitor.start_network_watchers()
         QApplication.processEvents()
 
     def open_transfer_money_dialog(self):
diff --git a/src/cutecoin/gui/transactions_tab.py b/src/cutecoin/gui/transactions_tab.py
index 4d6b382e5dc3e09eb5d71e15a5e2474460f4a132..f0c739e3cd7787b875dc3171b4aba636495beff5 100644
--- a/src/cutecoin/gui/transactions_tab.py
+++ b/src/cutecoin/gui/transactions_tab.py
@@ -39,7 +39,7 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget):
 
     def refresh(self):
         minimum_datetime = QDateTime()
-        minimum_datetime.setTime_t(self.community.get_block(1).mediantime)
+        minimum_datetime.setTime_t(self.community.get_block(1)['medianTime'])
         minimum_datetime.setTime(QTime(0, 0))
 
         self.date_from.setMinimumDateTime(minimum_datetime)
@@ -74,8 +74,6 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget):
             self.progressbar.setMaximum(maximum)
 
         self.progressbar.show()
-        blockchain_watcher = self.app.monitor.blockchain_watcher(self.community)
-        blockchain_watcher.loading_progressed.connect(progressing)
 
     def stop_progress(self):
         self.progressbar.hide()
diff --git a/src/cutecoin/gui/wallets_tab.py b/src/cutecoin/gui/wallets_tab.py
index 22cdc57472ee852dcde3b2f9bbac79f1f48ca34f..54654146570e0629a254c7c0d836df4497d6875c 100644
--- a/src/cutecoin/gui/wallets_tab.py
+++ b/src/cutecoin/gui/wallets_tab.py
@@ -47,7 +47,7 @@ class WalletsTabWidget(QWidget, Ui_WalletsTab):
             person = Person.lookup(self.account.pubkey, self.community)
             membership = person.membership(self.community)
             renew_block = membership['blockNumber']
-            last_renewal = self.community.get_block(renew_block).mediantime
+            last_renewal = self.community.get_block(renew_block)['medianTime']
             expiration = last_renewal + parameters['sigValidity']
         except MembershipNotFoundError:
             last_renewal = None
diff --git a/src/cutecoin/gui/wot_tab.py b/src/cutecoin/gui/wot_tab.py
index 4a9d5ddaa41d5b8c5b47bfa75abce725aead8ac3..b5be05f9c0113d27db6ce6e0f0973eb18ce6b87a 100644
--- a/src/cutecoin/gui/wot_tab.py
+++ b/src/cutecoin/gui/wot_tab.py
@@ -38,7 +38,6 @@ 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)
 
-        app.monitor.persons_watcher(community).person_changed.connect(self.handle_person_change)
         self.account = account
         self.community = community
         self.password_asker = password_asker
diff --git a/src/cutecoin/models/identities.py b/src/cutecoin/models/identities.py
index aa0692ea5fd66c8064106cb576b8e52747be4880..2548f2c923f3a6852bf561ee7fb29488b8a82748 100644
--- a/src/cutecoin/models/identities.py
+++ b/src/cutecoin/models/identities.py
@@ -100,7 +100,7 @@ class IdentitiesTableModel(QAbstractTableModel):
         try:
             join_block = person.membership(self.community)['blockNumber']
             try:
-                join_date = self.community.get_block(join_block).mediantime
+                join_date = self.community.get_block(join_block)['medianTime']
                 expiration_date = join_date + parameters['sigValidity']
             except NoPeerAvailable:
                 join_date = None
diff --git a/src/cutecoin/models/network.py b/src/cutecoin/models/network.py
index 4c43f07266bb30461b23ccdb5385b7289d478b5e..31c801ab12c9be818a69aa0e1bcbeea4d3fc05a3 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
-from ..tools.exceptions import NoPeerAvailable
-from ..core.net.node import Node
+
 from PyQt5.QtCore import QAbstractTableModel, Qt, QVariant, QSortFilterProxyModel
 from PyQt5.QtGui import QColor, QFont
 
+from ..tools.exceptions import NoPeerAvailable
+from cutecoin.core.net.node import Node
+
 
 class NetworkFilterProxyModel(QSortFilterProxyModel):
     def __init__(self, parent=None):
diff --git a/src/cutecoin/models/wallets.py b/src/cutecoin/models/wallets.py
index 56a59423e11120ae8ce78b82906d6b7c24938899..8815c9224810d429f89594161f37e5a3cd794299 100644
--- a/src/cutecoin/models/wallets.py
+++ b/src/cutecoin/models/wallets.py
@@ -4,7 +4,7 @@ Created on 8 févr. 2014
 @author: inso
 '''
 
-from PyQt5.QtCore import QAbstractTableModel, QSortFilterProxyModel, Qt, QLocale
+from PyQt5.QtCore import QAbstractTableModel, QSortFilterProxyModel, Qt, QLocale, pyqtSlot
 
 
 class WalletsFilterProxyModel(QSortFilterProxyModel):
@@ -61,11 +61,18 @@ class WalletsTableModel(QAbstractTableModel):
     '''
 
     def __init__(self, account, community, parent=None):
-        '''
-        Constructor
-        '''
+        """
+
+        :param list of cutecoin.core.wallet.Wallet wallets: The list of wallets to display
+        :param cutecoin.core.community.Community community: The community to show
+        :param PyQt5.QtCore.QObject parent: The parent widget
+        :return: The model
+        :rtype: WalletsTableModel
+        """
         super().__init__(parent)
         self.account = account
+        self.account.wallets_changed.connect(self.refresh_account_wallets)
+
         self.community = community
         self.columns_headers = (self.tr('Name'),
                                 self.tr('Amount'),
@@ -76,6 +83,25 @@ class WalletsTableModel(QAbstractTableModel):
     def wallets(self):
         return self.account.wallets
 
+    @pyqtSlot()
+    def refresh_account_wallets(self):
+        """
+        Change the current wallets, reconnect the slots
+        """
+        self.beginResetModel()
+        for w in self.account.wallets:
+            w.inner_data_changed.connect(lambda: self.refresh_wallet(w))
+        self.endResetModel()
+
+    def refresh_wallet(self, wallet):
+        """
+        Refresh the specified wallet value
+        :param cutecoin.core.wallet.Wallet wallet: The wallet to refresh
+        """
+        index = self.account.wallets.index(wallet)
+        if index > 0:
+            self.dataChanged.emit(index, index)
+
     def rowCount(self, parent):
         return len(self.wallets)