diff --git a/www/i18n/locale-en.json b/www/i18n/locale-en.json
index 59d645d193544a65156663d05a4bdd020b78f697..07c762c952021e31d7e8c444b28c8148e183c7b9 100644
--- a/www/i18n/locale-en.json
+++ b/www/i18n/locale-en.json
@@ -305,8 +305,8 @@
     "SALT_NOT_CONFIRMED": "Must match previous phrase.",
     "SEND_IDENTITY_FAILED": "Error while trying to register.",
     "SEND_CERTIFICATION_FAILED": "Could not certify identity.",
-    "NEED_MEMBER_ACCOUNT_TO_CERTIFY": "You could not send certification, because your account is <b>not</b> a member account.",
-    "NEED_MEMBER_ACCOUNT_TO_CERTIFY_HAS_SELF": "You could not send certification now, because your are a member yet.<br/>Be patient ! ;-)",
+    "NEED_MEMBER_ACCOUNT_TO_CERTIFY": "You could not send certification, because your account is <b>not a member account</b>.",
+    "NEED_MEMBER_ACCOUNT_TO_CERTIFY_HAS_SELF": "You could not send certification now, because your are <b>not a member</b> yet.<br/><br/>You still need certification to become a member.",
     "NOT_MEMBER_FOR_CERTIFICATION": "Your account is not a member account yet.",
     "IDENTITY_TO_CERTIFY_HAS_NO_SELF": "This account could not be certified. No registration found, or need to renew.",
     "LOGIN_FAILED": "Error while sign in.",
diff --git a/www/i18n/locale-fr-FR.json b/www/i18n/locale-fr-FR.json
index 707dcc93728f18703531f9f0021f1fa97c56c575..728b44f53d93e674433f5cb62c576c68b92b3f29 100644
--- a/www/i18n/locale-fr-FR.json
+++ b/www/i18n/locale-fr-FR.json
@@ -306,7 +306,7 @@
     "SEND_IDENTITY_FAILED": "Echec de l'inscription.",
     "SEND_CERTIFICATION_FAILED": "Echec de la certification.",
     "NEED_MEMBER_ACCOUNT_TO_CERTIFY": "Vous ne pouvez pas effectuer de certification, car votre compte n'est <b>pas membre</b>.",
-    "NEED_MEMBER_ACCOUNT_TO_CERTIFY_HAS_SELF": "Vous ne pouvez pas certifier quelqu'un, car vous n'êtes pas encore devenu membre.<br/>Patience ! ;-)",
+    "NEED_MEMBER_ACCOUNT_TO_CERTIFY_HAS_SELF": "Vous ne pouvez pas effectuer de certification, car votre compte n'est <p>pas encore membre</b>.<br/><br/>Il vous manque encore des certification pour devenir membre.",
     "NOT_MEMBER_FOR_CERTIFICATION": "Votre compte n'est pas encore membre.",
     "IDENTITY_TO_CERTIFY_HAS_NO_SELF": "Compte non certifiable. Aucune demande d'adhésion n'a été faite, ou bien elle n'a pas été renouvellée.",
     "LOGIN_FAILED": "Erreur lors de l'authentification.",
diff --git a/www/js/config.js b/www/js/config.js
index f9ebe07493171e815ff94ef620a5dfe997910972..72c97a39affb919946e7b6962a8d5882ed251d6e 100644
--- a/www/js/config.js
+++ b/www/js/config.js
@@ -10,39 +10,35 @@ angular.module("cesium.config", [])
 
 .constant("csConfig", {
 	"cacheTimeMs": 60000,
-	"fallbackLanguage": "fr-FR",
-	"defaultLanguage": "fr-FR",
-	"rememberMe": true,
+	"fallbackLanguage": "en",
+	"rememberMe": false,
 	"showUDHistory": false,
-	"timeout": 6000,
+	"timeout": 10000,
 	"timeWarningExpireMembership": 5184000,
 	"timeWarningExpire": 7776000,
 	"useLocalStorage": true,
 	"useRelative": true,
 	"initPhase": false,
 	"expertMode": false,
-	"decimalCount": 2,
+	"decimalCount": 4,
 	"helptip": {
 		"enable": true,
-		"installDocUrl": {
-			"fr-FR": "http://www.le-sou.org/devenir-noeud/",
-			"en": "https://github.com/duniter/duniter/blob/master/doc/install-a-node.md"
-		}
+		"installDocUrl": "https://github.com/duniter/duniter/blob/master/doc/install-a-node.md"
 	},
 	"node": {
-		"host": "duniter.le-sou.org",
-		"port": "9600"
+		"host": "cgeek.fr",
+		"port": "9330"
 	},
 	"plugins": {
 		"es": {
 			"enable": true,
-			"askEnable": true,
-			"host": "data.le-sou.org",
+			"askEnable": false,
+			"host": "data.duniter.fr",
 			"port": "80"
 		}
 	},
 	"version": "0.5.0",
-	"build": "2016-11-09T20:11:53.167Z",
+	"build": "2016-11-12T10:57:58.316Z",
 	"newIssueUrl": "https://github.com/duniter/cesium/issues/new?labels=bug"
 })
 
diff --git a/www/js/controllers/wot-controllers.js b/www/js/controllers/wot-controllers.js
index c0dbc9ccd7b2c6948bf2578727cb2c9b45df6c1f..7f8ca0a9981a06219b39c912bc98713f0f1a3c63 100644
--- a/www/js/controllers/wot-controllers.js
+++ b/www/js/controllers/wot-controllers.js
@@ -455,7 +455,10 @@ function WotCertificationsViewController($scope, $rootScope, $state, $timeout, $
       $scope.formData = identity;
       $scope.canCertify = $scope.formData.hasSelf && (!csWallet.isLogin() || (!csWallet.isUserPubkey(pubkey)));
       $scope.canSelectAndCertify = $scope.formData.hasSelf && csWallet.isUserPubkey(pubkey);
-      $scope.alreadyCertified = $scope.canCertify ? !!_.findWhere(identity.received_cert, { uid: csWallet.data.uid, valid: true }) : false;
+      $scope.alreadyCertified = $scope.canCertify ?
+        (!csWallet.isLogin() ||
+         !!_.findWhere(identity.received_cert, { pubkey: csWallet.data.pubkey, valid: true }) ||
+         !!_.findWhere(identity.received_cert_pending, { pubkey: csWallet.data.pubkey, valid: true })) : false;
 
       $scope.loading = false;
 
@@ -474,12 +477,34 @@ function WotCertificationsViewController($scope, $rootScope, $state, $timeout, $
   $scope.certify = function() {
     $scope.loadWallet()
     .then(function() {
+      UIUtils.loading.hide();
+
       if (!csConfig.initPhase && !$rootScope.walletData.isMember) {
         UIUtils.alert.error($rootScope.walletData.requirements.needSelf ?
           'ERROR.NEED_MEMBER_ACCOUNT_TO_CERTIFY' : 'ERROR.NEED_MEMBER_ACCOUNT_TO_CERTIFY_HAS_SELF');
         return;
       }
-      UIUtils.loading.hide();
+
+      // Check not already certified
+      var previousCert = _.findWhere($scope.formData.received_cert, { pubkey: csWallet.data.pubkey, valid: true});
+      if (previousCert) {
+        $translate('ERROR.IDENTITY_ALREADY_CERTIFY', previousCert)
+          .then(function(message) {
+            UIUtils.alert.error(message, 'ERROR.UNABLE_TO_CERTIFY_TITLE');
+          });
+        return;
+      }
+
+      // Check not pending certification
+      previousCert = _.findWhere($scope.formData.received_cert_pending, { pubkey: csWallet.data.pubkey, valid: true});
+      if (previousCert) {
+        $translate('ERROR.IDENTITY_ALREADY_CERTIFY_PENDING', previousCert)
+          .then(function(message) {
+            UIUtils.alert.error(message, 'ERROR.UNABLE_TO_CERTIFY_TITLE');
+          });
+        return;
+      }
+
       UIUtils.alert.confirm('CONFIRM.CERTIFY_RULES')
       .then(function(confirm){
         if (!confirm) {
@@ -489,10 +514,19 @@ function WotCertificationsViewController($scope, $rootScope, $state, $timeout, $
         csWallet.certify($scope.formData.uid,
                     $scope.formData.pubkey,
                     $scope.formData.timestamp,
-                    $scope.formData.sig)
-        .then(function() {
+                    $scope.formData.sig,
+                    $scope.formData.isMember,
+                    $scope.formData.wasMember)
+        .then(function(cert) {
           UIUtils.loading.hide();
-          UIUtils.alert.info('INFO.CERTIFICATION_DONE');
+          if (cert) {
+            cert.uid = csWallet.data.uid;
+            cert.pubkey = csWallet.data.pubkey;
+            cert.isMember = csWallet.data.isMember;
+            UIUtils.alert.info('INFO.CERTIFICATION_DONE');
+            $scope.formData.received_cert_pending.unshift(cert);
+            $scope.motionCertifications();
+          }
         })
         .catch(UIUtils.onError('ERROR.SEND_CERTIFICATION_FAILED'));
       });
@@ -506,7 +540,7 @@ function WotCertificationsViewController($scope, $rootScope, $state, $timeout, $
       .catch(UIUtils.onError('ERROR.LOGIN_FAILED'))
       .then(function() {
         if (!csConfig.initPhase && !$rootScope.walletData.isMember) {
-          UIUtils.alert.error($rootScope.walletData.requirements.needSelf ?
+          UIUtils.alert.error($rootScope.walletData.requirements.needSelf || $rootScope.walletData.requirements.needMembership ?
             'ERROR.NEED_MEMBER_ACCOUNT_TO_CERTIFY' : 'ERROR.NEED_MEMBER_ACCOUNT_TO_CERTIFY_HAS_SELF');
           return;
         }
@@ -536,7 +570,7 @@ function WotCertificationsViewController($scope, $rootScope, $state, $timeout, $
         }
 
         // Check not already certified
-        var previousCert = _.findWhere(identity.certifications, { uid: csWallet.data.uid, pending: false, valid: true});
+        var previousCert = _.findWhere(identity.received_cert, { pubkey: csWallet.data.pubkey, valid: true});
         if (previousCert) {
           $translate('ERROR.IDENTITY_ALREADY_CERTIFY', previousCert)
             .then(function(message) {
@@ -546,7 +580,7 @@ function WotCertificationsViewController($scope, $rootScope, $state, $timeout, $
         }
 
         // Check not pending certification
-        previousCert = _.findWhere(identity.certifications, { uid: csWallet.data.uid, pending: true, valid: true});
+        previousCert = _.findWhere(identity.received_cert_pending, { pubkey: csWallet.data.pubkey, valid: true});
         if (previousCert) {
           $translate('ERROR.IDENTITY_ALREADY_CERTIFY_PENDING', previousCert)
             .then(function(message) {
@@ -570,10 +604,16 @@ function WotCertificationsViewController($scope, $rootScope, $state, $timeout, $
             csWallet.certify(identity.uid,
               identity.pubkey,
               identity.timestamp,
-              identity.sig)
-              .then(function() {
+              identity.sig,
+              identity.isMember,
+              identity.wasMember)
+              .then(function(cert) {
                 UIUtils.loading.hide();
-                UIUtils.alert.info('INFO.CERTIFICATION_DONE');
+                if (cert) {
+                  UIUtils.alert.info('INFO.CERTIFICATION_DONE');
+                  $scope.formData.given_cert_pending.unshift(cert);
+                  $scope.motionGivenCertifications();
+                }
               })
               .catch(UIUtils.onError('ERROR.SEND_CERTIFICATION_FAILED'));
           });
diff --git a/www/js/services/wallet-services.js b/www/js/services/wallet-services.js
index 17d2277354527180776a39b827d5c28c281f5bc4..17052bf29c5b105ee7b30e2e0eebaf34ddc3f76c 100644
--- a/www/js/services/wallet-services.js
+++ b/www/js/services/wallet-services.js
@@ -196,6 +196,7 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
     isNeverUsed = function() {
       return !data.pubkey ||
         (!data.isMember &&
+        (!data.requirements || !data.requirements.pendingMembership) &&
          !data.tx.history.length &&
          !data.tx.pendings.length);
     },
@@ -329,7 +330,7 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
           data.blockUid = idty.meta.timestamp;
           // Add useful custom fields
           data.requirements.needSelf = false;
-          data.requirements.needMembership = (data.requirements.membershipExpiresIn === 0 &&
+          data.requirements.needMembership = (data.requirements.membershipExpiresIn <= 0 &&
                                               data.requirements.membershipPendingExpiresIn <= 0 );
           data.requirements.needRenew = (!data.requirements.needMembership &&
                                          data.requirements.membershipExpiresIn <= csSettings.data.timeWarningExpireMembership &&
@@ -343,7 +344,7 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
             }
             return count;
           }, 0) : 0;
-          data.isMember = !data.requirements.needSelf && !data.requirements.needMembership;
+          data.isMember = (data.requirements.membershipExpiresIn > 0);
 
           var blockParts = idty.meta.timestamp.split('-', 2);
           var blockNumber = parseInt(blockParts[0]);
@@ -354,9 +355,9 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
               data.sigDate = block.time;
 
               // Check if self has been done on a valid block
-              if (!data.isMember && blockNumber!== 0 && blockHash !== block.hash) {
+              if (!data.isMember && blockNumber !== 0 && blockHash !== block.hash) {
                 addEvent({type: 'error', message: 'ERROR.WALLET_INVALID_BLOCK_HASH'});
-                console.debug("Invalid membership for uid={0}: block hash not match a real block (block cancelled)".format(data.uid));
+                console.debug("Invalid membership for uid={0}: block hash changed".format(data.uid));
               }
               resolve();
             })
@@ -739,12 +740,16 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
             enable: true,
             fromTime: data.tx ? data.tx.fromTime : undefined // keep previous time
           },
-          sigStock: true
+          sigStock: true,
+          api: true
         };
       }
 
       var jobs = [];
 
+      // Reset events
+      data.events = [];
+
       // Get current UD
       if (options.currentUd) jobs.push(loadCurrentUD());
 
@@ -1223,85 +1228,91 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
     */
     membership = function(sideIn) {
       return function() {
-        return $q(function(resolve, reject) {
-          BMA.blockchain.current()
+        var membership;
+        return BMA.blockchain.current()
             .catch(function(err){
               // Special case for currency init (root block not exists): use fixed values
               if (err && err.ucode == BMA.errorCodes.NO_CURRENT_BLOCK) {
                 return {number: 0, hash: BMA.constants.ROOT_BLOCK_HASH};
               }
-              else {
-                throw err;
-              }
+              throw err;
             })
           .then(function(block) {
             // Create membership to sign
-             var membership = 'Version: 2\n' +
-                     'Type: Membership\n' +
-                     'Currency: ' + data.currency + '\n' +
-                     'Issuer: ' + data.pubkey + '\n' +
-                     'Block: ' + block.number + '-' + block.hash + '\n' +
-                     'Membership: ' + (!!sideIn ? "IN" : "OUT" ) + '\n' +
-                     'UserID: ' + data.uid + '\n' +
-                     'CertTS: ' + data.blockUid + '\n';
-
-            CryptoUtils.sign(membership, data.keypair)
-            .then(function(signature) {
-              var signedMembership = membership + signature + '\n';
-              // Send signed membership
-              BMA.blockchain.membership({membership: signedMembership})
-              .then(function(result) {
-                $timeout(function() {
-                  loadRequirements()
-                    .then(function() {
-                      finishLoadRequirements();
-                      resolve();
-                    })
-                    .catch(function(err){reject(err);});
-                }, 1000); // waiting for node to process membership doc
-              }).catch(function(err){reject(err);});
-            }).catch(function(err){reject(err);});
-          }).catch(function(err){reject(err);});
-        });
+            membership = 'Version: 2\n' +
+              'Type: Membership\n' +
+              'Currency: ' + data.currency + '\n' +
+              'Issuer: ' + data.pubkey + '\n' +
+              'Block: ' + block.number + '-' + block.hash + '\n' +
+              'Membership: ' + (!!sideIn ? "IN" : "OUT" ) + '\n' +
+              'UserID: ' + data.uid + '\n' +
+              'CertTS: ' + data.blockUid + '\n';
+
+            return CryptoUtils.sign(membership, data.keypair);
+          })
+          .then(function(signature) {
+            var signedMembership = membership + signature + '\n';
+            // Send signed membership
+            return BMA.blockchain.membership({membership: signedMembership});
+          })
+          .then(function() {
+            return $timeout(function() {
+              return loadRequirements();
+            }, 1000); // waiting for node to process membership doc
+          })
+          .then(function() {
+            finishLoadRequirements();
+          });
       };
     },
 
     /**
     * Send identity certification
     */
-    certify = function(uid, pubkey, timestamp, signature) {
-      return $q(function(resolve, reject) {
+    certify = function(uid, pubkey, timestamp, signature, isMember, wasMember) {
+      var current;
+      var cert;
 
-        BMA.blockchain.current()
+      return BMA.blockchain.current()
         .catch(function(err){
           // Special case for currency init (root block not exists): use fixed values
           if (err && err.ucode == BMA.errorCodes.NO_CURRENT_BLOCK) {
-            return {number: 0, hash: BMA.constants.ROOT_BLOCK_HASH};
+            return {number: 0, hash: BMA.constants.ROOT_BLOCK_HASH, medianTime: Math.trunc(new Date().getTime() / 1000)};
           }
-          reject(err);
+          throw err;
         })
         .then(function(block) {
+          current = block;
           // Create the self part to sign
-          var cert = 'Version: 2\n' +
-                     'Type: Certification\n' +
-                     'Currency: ' + data.currency + '\n' +
-                     'Issuer: ' + data.pubkey + '\n' +
-                     'IdtyIssuer: '+ pubkey + '\n' +
-                     'IdtyUniqueID: '+ uid + '\n' +
-                     'IdtyTimestamp: '+ timestamp + '\n' +
-                     'IdtySignature: '+ signature + '\n' +
-                     'CertTimestamp: '+ block.number + '-' + block.hash + '\n';
-
-          CryptoUtils.sign(cert, data.keypair)
-          .then(function(signature) {
-            var signedCert = cert + signature + '\n';
-            BMA.wot.certify({cert: signedCert})
-              .then(function(result) {
-                resolve(result);
-              }).catch(function(err){reject(err);});
-          }).catch(function(err){reject(err);});
-        }).catch(function(err){reject(err);});
-      });
+          cert = 'Version: 2\n' +
+            'Type: Certification\n' +
+            'Currency: ' + data.currency + '\n' +
+            'Issuer: ' + data.pubkey + '\n' +
+            'IdtyIssuer: ' + pubkey + '\n' +
+            'IdtyUniqueID: ' + uid + '\n' +
+            'IdtyTimestamp: ' + timestamp + '\n' +
+            'IdtySignature: ' + signature + '\n' +
+            'CertTimestamp: ' + block.number + '-' + block.hash + '\n';
+
+          return CryptoUtils.sign(cert, data.keypair);
+        })
+        .then(function(signature) {
+          var signedCert = cert + signature + '\n';
+          return BMA.wot.certify({cert: signedCert});
+        })
+        .then(function() {
+          return {
+            pubkey: pubkey,
+            uid: uid,
+            time: current.medianTime,
+            isMember: isMember,
+            wasMember: wasMember,
+            expiresIn: data.parameters.sigWindow,
+            pending: true,
+            block: current.number,
+            valid: true
+          };
+        });
     },
 
     addEvent = function(event) {
diff --git a/www/js/services/wot-services.js b/www/js/services/wot-services.js
index 79fc224573df6473c6553b6a1f076219812dc902..6cc428e5580f2a02f0326ac29e3f82df647ec5e7 100644
--- a/www/js/services/wot-services.js
+++ b/www/js/services/wot-services.js
@@ -83,8 +83,6 @@ angular.module('cesium.wot.services', ['ngResource', 'ngApi', 'cesium.bma.servic
                 canMembershipOut: false,
                 needRenew: false,
                 pendingMembership: false,
-                certificationCount: 0,
-                certifications: [],
                 needCertifications: false,
                 needCertificationCount: 0,
                 willNeedCertificationCount: 0
@@ -684,7 +682,7 @@ angular.module('cesium.wot.services', ['ngResource', 'ngApi', 'cesium.bma.servic
                     idty.sigDate = block.medianTime;
                     if (block.number !== 0 && idty.blockHash !== block.hash) {
                       addEvent(idty, {type:'error', message: 'ERROR.WOT_PENDING_INVALID_BLOCK_HASH'});
-                      console.debug("Invalid membership for uid={0}: block hash not match a real block (block cancelled)".format(idty.uid));
+                      console.debug("Invalid membership for uid={0}: block hash changed".format(idty.uid));
                     }
                   });
                 });
diff --git a/www/templates/wallet/view_wallet.html b/www/templates/wallet/view_wallet.html
index f55832356cd721fd138f59305b6d53d3bdbdfc84..d4e2eaa50f6750192cc3d781074ebd2d711cd28f 100644
--- a/www/templates/wallet/view_wallet.html
+++ b/www/templates/wallet/view_wallet.html
@@ -24,9 +24,8 @@
            ng-style="walletData.avatarStyle"
            ng-class="{'avatar-wallet': !walletData.avatarStyle && !walletData.isMember, 'avatar-member': !walletData.avatarStyle && walletData.isMember}">
         </i>
-        <h3 class="light" ng-if="walletData.name">{{walletData.name}}</h3>
-        <h3 class="light" ng-if="!walletData.name && walletData.isMember">{{walletData.uid}}</h3>
-        <h3 class="light" ng-if="!walletData.name && !walletData.isMember"><i class="icon ion-key"></i> {{walletData.pubkey | formatPubkey}}</h3>
+        <h3 class="light" ng-if="walletData.name || walletData.uid">{{walletData.name || walletData.uid}}</h3>
+        <h3 class="light" ng-if="!walletData.name && !walletData.uid"><i class="icon ion-key"></i> {{walletData.pubkey | formatPubkey}}</h3>
         <h4 class="light">
             <span ng-if="!$root.settings.useRelative">{{convertedBalance | formatInteger}} {{walletData.parameters.currency | abbreviate}}</span>
             <span ng-if="$root.settings.useRelative">{{convertedBalance | formatDecimal}} {{'COMMON.UD' | translate}}<sub>{{walletData.parameters.currency | abbreviate}}</sub></span>
@@ -83,7 +82,7 @@
         <!-- Certifications -->
         <a class="item item-icon-left item-icon-right item-text-wrap ink"
            id="helptip-wallet-certifications"
-           ng-if="walletData.isMember"
+           ng-if="walletData.isMember||walletData.requirements.pendingMembership"
            ng-click="showCertifications()">
           <i class="icon ion-ribbon-b"></i>
           <span clas="input-label">{{'ACCOUNT.CERTIFICATION_COUNT'|translate}}</span>