diff --git a/package.json b/package.json
index 7cb527ff0f8d3c6e13a864b19a750c50175cf740..678572ac51c10b99da62f3cc4d3b8f934f11d199 100644
--- a/package.json
+++ b/package.json
@@ -84,6 +84,7 @@
     "@bower_components/socket.io-client": "socketio/socket.io-client#^1.7.4",
     "@bower_components/ui-leaflet": "angular-ui/ui-leaflet#v2.0.0",
     "@bower_components/underscore": "jashkenas/underscore#1.10.2",
+    "@bower_components/jdenticon": "dmester/jdenticon#3.1.0",
     "through2": "^4.0.2",
     "uuid": "3.2.1"
   },
@@ -221,4 +222,4 @@
     "node": ">= 12.18.3",
     "yarn": ">= 1.22.0"
   }
-}
\ No newline at end of file
+}
diff --git a/www/index.html b/www/index.html
index 46371efd7619b330b10b4d6e1f6c2f9c6487083f..a1e5f71dc31b8c38060757869aa04e67b5c36bbb 100644
--- a/www/index.html
+++ b/www/index.html
@@ -80,6 +80,8 @@
     <script src="lib/socket.io-client/dist/socket.io.min.js"></script>
     <script src="lib/underscore/underscore-min.js"></script>
     <script src="lib/chart.js/dist/Chart.min.js"></script>
+    <script src="lib/jdenticon/dist/jdenticon.min.js"></script>
+
 
     <!-- ionic/angular js -->
     <script src="lib/ionic/js/ionic.min.js"></script>
diff --git a/www/js/controllers/wallet-controllers.js b/www/js/controllers/wallet-controllers.js
index 9f9efad676c8326808bf2e7f959701b58fcac998..40a5bcd7ffbddee5fcfdb8be7c03be76a56aecde 100644
--- a/www/js/controllers/wallet-controllers.js
+++ b/www/js/controllers/wallet-controllers.js
@@ -103,7 +103,7 @@ function WalletController($scope, $rootScope, $q, $ionicPopup, $timeout, $state,
     return wallet.login()
       .then(function(walletData) {
         $scope.formData = walletData;
-        $scope.loading=false; // very important, to avoid TX to be display before wallet.currentUd is loaded
+        $scope.loading = false; // very important, to avoid TX to be display before wallet.currentUd is loaded
         $scope.updateView();
         $scope.addListeners();
 
diff --git a/www/js/controllers/wot-controllers.js b/www/js/controllers/wot-controllers.js
index 4f109795863360d862e3fc27cc79ae9892c4fcfc..2e3c8645cbce6135e9e9365fe764b0d19a36f2df 100644
--- a/www/js/controllers/wot-controllers.js
+++ b/www/js/controllers/wot-controllers.js
@@ -204,13 +204,13 @@ function WotLookupController($scope, $state, $q, $timeout, $focus, $location, $i
             $scope.doGetPending(0, undefined, true/*skipLocationUpdate*/);
           }
           // get new comers
-          else if (params.type == 'newcomers' || (!csConfig.initPhase && !params.type)) {
+          else if (params.type === 'newcomers' || (!csConfig.initPhase && !params.type)) {
             $scope.doGetNewcomers(0, undefined, true/*skipLocationUpdate*/);
           }
-          else if (params.type == 'pending') {
+          else if (params.type === 'pending') {
             $scope.doGetPending(0, undefined, true/*skipLocationUpdate*/);
           }
-          else if (params.type == 'wallets') {
+          else if (params.type === 'wallets') {
             $scope.doGetWallets(0, undefined, true/*skipLocationUpdate*/);
           }
 
@@ -263,7 +263,7 @@ function WotLookupController($scope, $state, $q, $timeout, $focus, $location, $i
         stateParams.q = text;
       }
     }
-    else if ($scope.search.type != 'last') {
+    else if ($scope.search.type !== 'last') {
       stateParams.type = $scope.search.type;
     }
 
@@ -295,7 +295,7 @@ function WotLookupController($scope, $state, $q, $timeout, $focus, $location, $i
     $scope.search.type = 'text';
     return csWot.search(text)
       .then(function(idties){
-        if ($scope.search.type != 'text') return; // could have change
+        if ($scope.search.type !== 'text') return; // could have change
         if ($scope.search.text.trim() !== text) return; // search text has changed before received response
 
         if ((!idties || !idties.length) && (BMA.regexp.PUBKEY.test(text) || BMA.regexp.PUBKEY_WITH_CHECKSUM.test(text))) {
@@ -366,7 +366,7 @@ function WotLookupController($scope, $state, $q, $timeout, $focus, $location, $i
 
     return searchFunction(offset, size)
       .then(function(res){
-        if ($scope.search.type != 'pending') return false; // could have change
+        if ($scope.search.type !== 'pending') return false; // could have change
         $scope.doDisplayResult(res && res.hits, offset, size, res && res.total);
         // Always disable "more" on initphase
         $scope.search.hasMore = !csCurrency.data.initPhase && $scope.search.hasMore;
@@ -397,7 +397,7 @@ function WotLookupController($scope, $state, $q, $timeout, $focus, $location, $i
 
     return csWallet.children.all()
       .then(function(children) {
-        if (!children || $scope.search.type != 'wallets') return false; // could have change
+        if (!children || $scope.search.type !== 'wallets') return false; // could have change
         var res = [csWallet].concat(children).reduce(function(res, wallet, index) {
           var item = {
             id: index,
diff --git a/www/js/directives.js b/www/js/directives.js
index e207a9262476cf31b7af36f58f8e8f45f5f91ff6..8f53b911f9690481c7a8221944d258e3ec3bcd61 100644
--- a/www/js/directives.js
+++ b/www/js/directives.js
@@ -213,6 +213,7 @@ angular.module('cesium.directives', [])
   // All this does is allow the message
   // to be sent when you tap return
   .directive('input', function($timeout) {
+    'ngInject';
     return {
       restrict: 'E',
       scope: {
@@ -250,7 +251,8 @@ angular.module('cesium.directives', [])
     };
   })
 
-  .directive('trustAsHtml', ['$sce', '$compile', '$parse', function($sce, $compile, $parse){
+  .directive('trustAsHtml', function($sce, $compile, $parse){
+    'ngInject';
     return {
       restrict: 'A',
       compile: function (tElement, tAttrs) {
@@ -272,12 +274,14 @@ angular.module('cesium.directives', [])
         };
       }
     };
-  }])
+  })
 
   /**
   * Close the current modal
   */
-  .directive('modalClose', ['$ionicHistory', '$timeout', function($ionicHistory, $timeout) {
+  .directive('modalClose', function($ionicHistory, $timeout) {
+    'ngInject';
+
     return {
       restrict: 'AC',
       link: function($scope, $element) {
@@ -302,12 +306,14 @@ angular.module('cesium.directives', [])
         });
       }
     };
-  }])
+  })
 
   /**
   * Plugin extension point (see services/plugin-services.js)
   */
   .directive('csExtensionPoint', function ($state, $compile, $controller, $templateCache, PluginService) {
+    'ngInject';
+
     var getTemplate = function(extensionPoint) {
       var template = extensionPoint.templateUrl ? $templateCache.get(extensionPoint.templateUrl) : extensionPoint.template;
       if (!template) {
@@ -353,6 +359,8 @@ angular.module('cesium.directives', [])
   })
 
   .directive('onReadFile', function ($parse) {
+    'ngInject';
+
     return {
       restrict: 'A',
       scope: false,
@@ -382,7 +390,8 @@ angular.module('cesium.directives', [])
     };
   })
 
-.directive("dropZone", function($parse) {
+  .directive("dropZone", function($parse) {
+    'ngInject';
     return {
       restrict: 'A',
       scope: false,
@@ -429,8 +438,8 @@ angular.module('cesium.directives', [])
 
 
   // See http://embed.plnkr.co/2vgnFe/
-  .directive('fileSelect', function ($parse) {
-    'use strict';
+  .directive('fileSelect', function($parse) {
+    'ngInject';
 
     return {
       restrict: 'A',
@@ -484,6 +493,8 @@ angular.module('cesium.directives', [])
   // Un-authenticate when window closed
   // see: https://stackoverflow.com/questions/28197316/javascript-or-angularjs-defer-browser-close-or-tab-close-between-refresh
   .directive('windowExitUnauth', function($window, csSettings, csWallet) {
+    'ngInject';
+
     return {
       restrict: 'AE',
       link: function(element, attrs){
@@ -497,4 +508,34 @@ angular.module('cesium.directives', [])
         });
       }
     };
+  })
+
+  // Jdenticon directive (to generate icon from a string)
+  // see:
+  .directive('jdenticon', function($parse) {
+    'ngInject';
+
+    return {
+      restrict: 'A',
+      scope: false,
+      template: '<canvas></canvas>',
+      transclude: false,
+      link: function (scope, element, attrs) {
+        var value = attrs.jdenticon;
+        var size = attrs.jdenticonSize || 54;
+        var canvas = element.children('canvas')[0];
+
+        if (!value) {
+          canvas.height = 0;
+          canvas.width = 0;
+        }
+        else {
+          canvas.height  = size;
+          canvas.width  = size;
+
+          var ctx = canvas.getContext("2d");
+          jdenticon.drawIcon(ctx, value, size);
+        }
+      }
+    };
   });
diff --git a/www/js/filters.js b/www/js/filters.js
index b38b0cc2b272db1874761a404512b8b0a8064097..64a4d063485a910da22d5cd4e23eb511899e0c33 100644
--- a/www/js/filters.js
+++ b/www/js/filters.js
@@ -80,6 +80,7 @@ angular.module('cesium.filters', ['cesium.config', 'cesium.platform', 'pascalpre
   })
 
   .filter('formatAmount', function(csConfig, csSettings, csCurrency, $filter) {
+    'ngInject';
     var pattern = '0,0.0' + Array(csConfig.decimalCount || 4).join('0');
     var patternBigNumber = '0,0.000 a';
     var currencySymbol = $filter('currencySymbol');
@@ -124,6 +125,7 @@ angular.module('cesium.filters', ['cesium.config', 'cesium.platform', 'pascalpre
   })
 
   .filter('formatAmountNoHtml', function(csConfig, csSettings, csCurrency, $filter) {
+    'ngInject';
     var minValue = 1 / Math.pow(10, csConfig.decimalCount || 4);
     var format = '0,0.0' + Array(csConfig.decimalCount || 4).join('0');
     var currencySymbol = $filter('currencySymbolNoHtml');
@@ -164,6 +166,7 @@ angular.module('cesium.filters', ['cesium.config', 'cesium.platform', 'pascalpre
   })
 
   .filter('currencySymbol', function(filterTranslations, $filter, csSettings) {
+    'ngInject';
     return function(input, useRelative) {
       if (!input) return '';
       return (angular.isDefined(useRelative) ? useRelative : csSettings.data.useRelative) ?
@@ -173,6 +176,7 @@ angular.module('cesium.filters', ['cesium.config', 'cesium.platform', 'pascalpre
   })
 
   .filter('currencySymbolNoHtml', function(filterTranslations, $filter, csSettings) {
+    'ngInject';
     return function(input, useRelative) {
       if (!input) return '';
       return (angular.isDefined(useRelative) ? useRelative : csSettings.data.useRelative) ?
@@ -182,6 +186,7 @@ angular.module('cesium.filters', ['cesium.config', 'cesium.platform', 'pascalpre
   })
 
   .filter('formatDecimal', function(csConfig, csCurrency) {
+    'ngInject';
     var minValue = 1 / Math.pow(10, csConfig.decimalCount || 4);
     var format = '0,0.0' + Array(csConfig.decimalCount || 4).join('0');
 
@@ -209,24 +214,28 @@ angular.module('cesium.filters', ['cesium.config', 'cesium.platform', 'pascalpre
   })
 
   .filter('formatDate', function(filterTranslations) {
+    'ngInject';
     return function(input) {
       return input ? moment.unix(parseInt(input)).local().format(filterTranslations.DATE_PATTERN || 'YYYY-MM-DD HH:mm') : '';
     };
   })
 
   .filter('formatDateShort', function(filterTranslations) {
+    'ngInject';
     return function(input) {
       return input ? moment.unix(parseInt(input)).local().format(filterTranslations.DATE_SHORT_PATTERN || 'YYYY-MM-DD') : '';
     };
   })
 
   .filter('formatDateMonth', function(filterTranslations) {
+    'ngInject';
     return function(input) {
       return input ? moment.unix(parseInt(input)).local().format(filterTranslations.DATE_MONTH_YEAR_PATTERN || 'MMM YY') : '';
     };
   })
 
   .filter('formatDateForFile', function(filterTranslations) {
+    'ngInject';
     return function(input) {
       return input ? moment.unix(parseInt(input)).local().format(filterTranslations.DATE_FILE_PATTERN || 'YYYY-MM-DD') : '';
     };
@@ -245,6 +254,7 @@ angular.module('cesium.filters', ['cesium.config', 'cesium.platform', 'pascalpre
   })
 
   .filter('formatFromNowAndDate', function(filterTranslations) {
+    'ngInject';
     return function(input, options) {
       var m = input && moment.unix(parseInt(input));
       return m && (m.fromNow() + (options && options.separator || ' | ') + m.local().format(filterTranslations.DATE_PATTERN || 'YYYY-MM-DD HH:mm')) || '';
@@ -265,6 +275,7 @@ angular.module('cesium.filters', ['cesium.config', 'cesium.platform', 'pascalpre
 
 
   .filter('formatDurationTime', function(filterTranslations) {
+    'ngInject';
     return function(input) {
       if (!input) return '';
       var sign = input && input < 0 ? '-' : '+';
@@ -305,12 +316,14 @@ angular.module('cesium.filters', ['cesium.config', 'cesium.platform', 'pascalpre
   /* -- median time (apply currency offset)-- */
 
   .filter('medianDate', function(filterTranslations) {
+    'ngInject';
     return function(input) {
       return input ? moment.unix(parseInt(input) + filterTranslations.MEDIAN_TIME_OFFSET).local().format(filterTranslations.DATE_PATTERN || 'YYYY-MM-DD HH:mm') : '';
     };
   })
 
   .filter('medianDateShort', function(filterTranslations) {
+    'ngInject';
     return function(input) {
       return input ? moment.unix(parseInt(input) + filterTranslations.MEDIAN_TIME_OFFSET).local().format(filterTranslations.DATE_SHORT_PATTERN || 'YYYY-MM-DD') : '';
     };
@@ -318,24 +331,28 @@ angular.module('cesium.filters', ['cesium.config', 'cesium.platform', 'pascalpre
 
 
   .filter('medianTime', function(filterTranslations) {
+    'ngInject';
     return function(input) {
       return input ? moment.unix(parseInt(input)+filterTranslations.MEDIAN_TIME_OFFSET).local().format('HH:mm') : '';
     };
   })
 
   .filter('medianFromNow', function(filterTranslations) {
+    'ngInject';
     return function(input) {
       return input ? moment.unix(parseInt(input) + filterTranslations.MEDIAN_TIME_OFFSET).fromNow() : '';
     };
   })
 
   .filter('medianFromNowShort', function(filterTranslations) {
+    'ngInject';
     return function(input) {
       return input ? moment.unix(parseInt(input)+filterTranslations.MEDIAN_TIME_OFFSET).fromNow(true) : '';
     };
   })
 
   .filter('medianFromNowAndDate', function(filterTranslations) {
+    'ngInject';
     return function(input, options) {
       var m = input && moment.unix(parseInt(input)+filterTranslations.MEDIAN_TIME_OFFSET);
       return m && (m.fromNow() + (options && options.separator || ' | ')  + m.local().format(filterTranslations.DATE_PATTERN || 'YYYY-MM-DD HH:mm')) || '';
@@ -390,12 +407,37 @@ angular.module('cesium.filters', ['cesium.config', 'cesium.platform', 'pascalpre
     };
   })
 
-  .filter('formatPubkey', function() {
-    return function(input) {
-      return input ? input.substr(0,8) : '';
+  .filter('formatPubkey', function(csCrypto) {
+    'ngInject';
+    return function(input, opts) {
+      if (!input || input.length < 43) return '';
+      var result = (!opts || opts.full !== true)
+        // See RFC0016
+        ? (input.substr(0,4)  + '…' + input.substr(input.length - 4))
+        : input;
+      // If given (e.g. already computed) use the existing CHK
+      if (opts && opts.checksum) {
+        result += ':' + opts.checksum;
+      }
+      // Crypto libs can be not loaded yet
+      else if (csCrypto.isStarted()){
+        result += ':' + csCrypto.util.pkChecksum(input);
+      }
+      return result;
     };
   })
 
+  .filter('pkChecksum', function(csCrypto) {
+    'ngInject';
+    return function(input, opts) {
+      if (!input || input.length < 43) return '';
+      if (opts && opts.prefix) {
+        return ':' + csCrypto.util.pkChecksum(input);
+      }
+      return csCrypto.util.pkChecksum(input);
+   };
+  })
+
   .filter('formatHash', function() {
     return function(input) {
       return input ? input.substr(0,4) + input.substr(input.length-4) : '';
@@ -444,6 +486,7 @@ angular.module('cesium.filters', ['cesium.config', 'cesium.platform', 'pascalpre
   })
 
   .filter('trustAsHtml', function($sce) {
+    'ngInject';
     return function(html) {
       return $sce.trustAsHtml(html);
     };
diff --git a/www/js/services/crypto-services.js b/www/js/services/crypto-services.js
index 044653204a68c72959ea20fd72c9c17e2fa2dd2d..5dc11633055f603c7cd92ea3ad1e86013c0f5a04 100644
--- a/www/js/services/crypto-services.js
+++ b/www/js/services/crypto-services.js
@@ -405,7 +405,7 @@ angular.module('cesium.crypto.services', ['cesium.utils.services'])
         var naclOptions = {};
         var scryptOptions = {};
         if (ionic.Platform.grade.toLowerCase()!='a') {
-          console.info('Reduce NaCl memory to 16mb,  because plateform grade is not [a] but [{0}]'.format(ionic.Platform.grade));
+          console.info('Reduce NaCl memory to 16mb,  because platform grade is not [a] but [{0}]'.format(ionic.Platform.grade));
           naclOptions.requested_total_memory = 16 * 1048576; // 16 Mo
         }
         var loadedLib = 0;
@@ -1007,6 +1007,15 @@ angular.module('cesium.crypto.services', ['cesium.utils.services'])
       BAD_CHECKSUM: 3002
     };
 
+    function ready() {
+      if (CryptoUtils.isLoaded()) return $q.when();
+      return $timeout(ready, 100);
+    }
+
+    function isStarted() {
+      return CryptoUtils.isLoaded();
+    }
+
     /* -- keyfile -- */
 
     function readKeyFile(file, options) {
@@ -1374,13 +1383,20 @@ angular.module('cesium.crypto.services', ['cesium.utils.services'])
       }
     }
 
+    /* -- Useful functions -- */
 
-
-    /* -- usefull methods -- */
-
+    /**
+     * Compute the pubkey checksum (see Duniter RFC0016)
+     */
     function pkChecksum(pubkey) {
-      var signPk_int8 = CryptoUtils.util.decode_base58(pubkey);
-      return CryptoUtils.util.encode_base58(CryptoUtils.util.crypto_hash_sha256(CryptoUtils.util.crypto_hash_sha256(signPk_int8))).substring(0,3);
+      // Remove leading '1' (see https://forum.duniter.org/t/format-de-checksum/7616)
+      var signPk_int8 = pubkey && pubkey.length === 44 && pubkey.charAt(0) === '1'
+        ? CryptoUtils.util.decode_base58(pubkey.substr(1))
+        : CryptoUtils.util.decode_base58(pubkey);
+      return CryptoUtils.util.encode_base58(
+        CryptoUtils.util.crypto_hash_sha256(
+          CryptoUtils.util.crypto_hash_sha256(signPk_int8))
+      ).substring(0,3);
     }
 
     /* -- box (pack/unpack a record) -- */
@@ -1562,6 +1578,8 @@ angular.module('cesium.crypto.services', ['cesium.utils.services'])
     return {
       errorCodes: errorCodes,
       constants: constants,
+      ready: ready,
+      isStarted: isStarted,
       // copy CryptoUtils
       util: angular.extend({
           pkChecksum: pkChecksum
diff --git a/www/js/services/device-services.js b/www/js/services/device-services.js
index a756a437d8d7cebc61b62fe65b6cd09aa61dc729..147c2f1be127e64905bfb0de5fcc6515dd9b45e1 100644
--- a/www/js/services/device-services.js
+++ b/www/js/services/device-services.js
@@ -14,7 +14,6 @@ angular.module('cesium.device.services', ['cesium.utils.services', 'cesium.setti
           MAX_HEIGHT: 400,
           MAX_WIDTH: 400
         },
-        that = this,
         api = new Api(this, "Device"),
         exports = {
           // workaround to quickly no is device or not (even before the ready() event)
diff --git a/www/js/services/wallet-services.js b/www/js/services/wallet-services.js
index 702c8f9d9033dec80fd9e56b500c2b50d7f60e4f..f392ccc0c94486484c70cd00edc5711790ae83d3 100644
--- a/www/js/services/wallet-services.js
+++ b/www/js/services/wallet-services.js
@@ -40,7 +40,8 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se
 
     resetData = function(init) {
       data.loaded = false;
-      data.pubkey= null;
+      data.pubkey = null;
+      data.checksum = null;
       data.qrcode=null;
 
       data.uid = null;
@@ -566,12 +567,12 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se
           var seckey = res[0];
           var pubkey = res[1];
           var uid = res[2];
-          if (!pubkey || pubkey == 'null') return;
+          if (!pubkey || pubkey === 'null') return;
 
           console.debug('[wallet] Restore {' + pubkey.substring(0, 8) + '} from local storage');
 
           var keypair;
-          if (seckey && seckey.length && seckey != 'null') {
+          if (seckey && seckey.length && seckey !== 'null') {
             try {
               keypair = {
                 signPk: CryptoUtils.util.decode_base58(pubkey),
@@ -887,27 +888,32 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se
         loadPromise,
 
         // Create the QR code
-        loadQrCode()
+        loadQrCode(),
+
+        // Compute the checksum (if need)
+        csCrypto.ready().then(function() {
+          data.checksum = data.checksum || csCrypto.util.pkChecksum(data.pubkey);
+        })
       ])
-        // Warn if wallet has been never used - see #167
         .then(function() {
-          var unused = isNeverUsed();
+
+          // Warn if wallet has been never used - see #167
+          var unused = alertIfUnusedWallet && isNeverUsed();
           var showAlert = alertIfUnusedWallet && !isNew() && unused === true;
           if (!showAlert) return true;
           return UIUtils.loading.hide()
-            .then(function() {
+            .then(function () {
               return UIUtils.alert.confirm('CONFIRM.LOGIN_UNUSED_WALLET', 'CONFIRM.LOGIN_UNUSED_WALLET_TITLE', {
                 cancelText: 'COMMON.BTN_CONTINUE',
                 okText: 'COMMON.BTN_RETRY'
               });
             })
-            .then(function(retry) {
+            .then(function (retry) {
               if (retry) {
-                return logout().then(function() {
+                return logout().then(function () {
                   throw 'RETRY';
                 });
-              }
-              else {
+              } else {
                 // Remembering to not ask for confirmation
                 if (csSettings.data.wallet.alertIfUnusedWallet) {
                   csSettings.data.wallet.alertIfUnusedWallet = false;
@@ -924,8 +930,7 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se
           if (confirm) {
             return data;
           }
-          else { // cancel
-
+          else { // user cancelled
             throw 'CANCELLED';
           }
         });
@@ -2082,7 +2087,7 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se
 
     newChildInstance =  function() {
       // Return max(id) + 1
-      var walletId = (data.children || []).reduce(function(res, wallet) {
+      var walletId = (data.children || []).reduce(function(res, wallet) {
           return Math.max(res, wallet.id);
         }, 0) + 1;
       return service.instance(walletId, BMA);
diff --git a/www/templates/wallet/view_wallet.html b/www/templates/wallet/view_wallet.html
index 04135d8cf557f01e7ee1e8081b48be7eee13989b..46e73710ec8d83e5b3379ad2d1015354714f21e2 100644
--- a/www/templates/wallet/view_wallet.html
+++ b/www/templates/wallet/view_wallet.html
@@ -130,12 +130,17 @@
 
           <!-- Public key -->
           <div id="helptip-wallet-pubkey"
-                class="item item-icon-left item-text-wrap ink"
+                class="item item-icon-left item-text-wrap item-icon-right ink"
                 on-hold="copy(formData.pubkey)"
-                copy-on-click="{{:rebind:formData.pubkey}}">
+                copy-on-click="{{:rebind:formData.pubkey|formatPubkey: {full: true, checksum: formData.checksum} }}">
             <i class="icon ion-key"></i>
             <span>{{:locale:'COMMON.PUBKEY'|translate}}</span>
-            <h4 id="pubkey" class="dark">{{:rebind:formData.pubkey}}</h4>
+            <h4 id="pubkey" class="dark">
+              {{:rebind:formData.pubkey|formatPubkey: {full: true, checksum: formData.checksum} }}
+            </h4>
+
+            <!-- icon of the pubkey -->
+            <i class="icon" ng-if=":rebind:formData.pubkey" jdenticon="{{:rebind:formData.pubkey}}" jdenticon-size="32"></i>
           </div>
 
           <!-- Uid + Registration date -->
diff --git a/www/templates/wot/item_content_identity.html b/www/templates/wot/item_content_identity.html
index 70b500fe41e24ae4421b563868f6bdaa9e3d3d49..02e29bcea0c447bd0719a1166adcf9e7fbac9cc7 100644
--- a/www/templates/wot/item_content_identity.html
+++ b/www/templates/wot/item_content_identity.html
@@ -10,13 +10,13 @@
     ng-class="{'pull-right': !smallscreen}"
     ng-if="::item.sigDate">
   <i class="ion-clock"></i>
-  {{::'WOT.LOOKUP.REGISTERED' | translate:item }}
+  {{:locale:'WOT.LOOKUP.REGISTERED' | translate:item }}
 </h4>
 <h4 class="gray"
     ng-class="{'pull-right': !smallscreen}"
     ng-if="item.memberDate">
   <i class="ion-clock"></i>
-  {{::'WOT.LOOKUP.MEMBER_FROM' | translate:item}}
+  {{:locale:'WOT.LOOKUP.MEMBER_FROM' | translate:item}}
 </h4>
 <h4 class="gray">
   <span class="positive" ng-if="::item.name && item.uid">
@@ -25,6 +25,7 @@
   </span>
   <b class="ion-key"></b>
   {{::item.pubkey | formatPubkey}}
+
   <span ng-if="::(!item.uid && !item.revoked)" class="assertive" translate>WOT.NOT_MEMBER_PARENTHESIS</span>
   <span ng-if="::item.revoked" class="assertive" translate>WOT.IDENTITY_REVOKED_PARENTHESIS</span>
 </h4>
diff --git a/www/templates/wot/lookup_form.html b/www/templates/wot/lookup_form.html
index 849b55fadb3235f69a72bcbdcea74d220a45652d..01a8005ffdc52851ee227c2c0905ecbc7ca3d1fe 100644
--- a/www/templates/wot/lookup_form.html
+++ b/www/templates/wot/lookup_form.html
@@ -1,4 +1,4 @@
-<div class="lookupForm">
+<div class="lookupForm" bind-notifier="{locale: $root.settings.locale.id}">
 
   <div class="item no-padding">
 
@@ -22,7 +22,7 @@
 
       <input type="text"
              class="visible-xs visible-sm"
-             placeholder="{{'WOT.SEARCH_HELP'|translate}}"
+             placeholder="{{:locale:'WOT.SEARCH_HELP'|translate}}"
              ng-model="search.text"
              ng-model-options="{ debounce: 650 }"
              ng-change="doSearch()"
@@ -30,7 +30,7 @@
              select-on-click>
       <input type="text"
              class="hidden-xs hidden-sm"
-             id="{{wotSearchTextId}}" placeholder="{{'WOT.SEARCH_HELP'|translate}}"
+             id="{{wotSearchTextId}}" placeholder="{{:locale:'WOT.SEARCH_HELP'|translate}}"
              ng-model="search.text"
              on-return="doSearchText()">
       <div class="helptip-anchor-center">
@@ -43,7 +43,7 @@
     ng-class="::{'hidden-xs hidden-sm': !showResultLabel}">
     <div class="pull-left" ng-if="!search.loading && showResultLabel">
       <ng-if ng-if="search.type=='newcomers'">
-        <h4 translate>WOT.LOOKUP.NEWCOMERS</h4>
+        <h4>{{:locale:'WOT.LOOKUP.NEWCOMERS'|translate}}</h4>
         <small class="gray no-padding" ng-if="search.total">{{'WOT.LOOKUP.NEWCOMERS_COUNT'|translate:{count: search.total} }}</small>
       </ng-if>
       <ng-if ng-if="search.type=='pending'">
@@ -51,7 +51,7 @@
         <small class="gray no-padding" ng-if="search.total">{{'WOT.LOOKUP.PENDING_COUNT'|translate:{count: search.total} }}</small>
       </ng-if>
       <h4 ng-if="search.type=='text'">
-        <span translate>COMMON.RESULTS_LIST</span>
+        <span>{{:locale:'COMMON.RESULTS_LIST'|translate}}</span>
         <small class="gray" ng-if="search.total">({{search.total}})</small>
       </h4>
     </div>
@@ -63,14 +63,14 @@
          ng-class="{'button-text-positive': search.type=='newcomers'}"
          ng-click="doGetNewcomers()">
         <i class="icon ion-person-stalker"></i>
-        {{'WOT.LOOKUP.BTN_NEWCOMERS' | translate}}
+        {{:locale:'WOT.LOOKUP.BTN_NEWCOMERS' | translate}}
       </a>
       <a ng-if="enableFilter"
          class="button button-text button-small ink"
          ng-class="{'button-text-positive': search.type=='pending'}"
          ng-click="doGetPending()" class="badge-balanced">
         <i class="icon ion-clock"></i>
-        {{'WOT.LOOKUP.BTN_PENDING' | translate}}
+        {{:locale:'WOT.LOOKUP.BTN_PENDING' | translate}}
       </a>
       <a ng-if="enableWallets"
          class="button button-text button-small ink"
@@ -78,7 +78,7 @@
          ng-click="doGetWallets()" class="badge-balanced">
         <i class="icon ion-card" style="left: -1px; top: 4px; position: relative; padding-left: 3px; padding-right: 3px;"></i>
         <b class="icon-secondary ion-card" style="left: 10px; top: -4px; font-size: 14px;"> </b>
-        {{'MENU.WALLETS' | translate}}
+        {{:locale:'MENU.WALLETS' | translate}}
       </a>
 
       <!-- Allow extension here -->
@@ -86,14 +86,14 @@
       &nbsp;
       <button class="button button-small button-stable ink"
               ng-click="doSearch()">
-        {{'COMMON.BTN_SEARCH' | translate}}
+        {{:locale:'COMMON.BTN_SEARCH' | translate}}
       </button>
 
       <button class="button button-small button-positive {{parameters.okType}} ink"
               ng-if="::allowMultiple"
               ng-disabled="!selection.length"
               ng-click="next()">
-        {{parameters.okText||'COMMON.BTN_NEXT' | translate}}
+        {{:locale:parameters.okText||'COMMON.BTN_NEXT' | translate}}
       </button>
     </div>
   </div>
@@ -105,9 +105,9 @@
 
   <ng-if ng-if="!search.loading">
     <div class="assertive padding" ng-if="!search.results.length">
-      <span ng-if="search.type=='text'" translate>COMMON.SEARCH_NO_RESULT</span>
-      <span ng-if="search.type=='pending'" translate>WOT.LOOKUP.NO_PENDING</span>
-      <span ng-if="search.type=='newcomers'" translate>WOT.LOOKUP.NO_NEWCOMERS</span>
+      <span ng-if="search.type=='text'">{{:locale:'COMMON.SEARCH_NO_RESULT'|translate}}</span>
+      <span ng-if="search.type=='pending'">{{:locale:'WOT.LOOKUP.NO_PENDING'|translate}}</span>
+      <span ng-if="search.type=='newcomers'">{{:locale:'WOT.LOOKUP.NO_NEWCOMERS'|translate}}</span>
     </div>
 
     <!-- simple selection + device -->
@@ -120,14 +120,14 @@
       <ng-repeat ng-repeat="item in search.results track by item.id">
         <div ng-if="::item.divider"
              class="item item-divider"
-             id="helptip-wot-search-result-{{$index}}">{{::('WOT.SEARCH.DIVIDER_' + item.index)|upper|translate}}</div>
+             id="helptip-wot-search-result-{{$index}}">{{:locale:('WOT.SEARCH.DIVIDER_' + item.index)|upper|translate}}</div>
         <ion-item
           ng-if="::!item.divider"
           id="helptip-wot-search-result-{{$index}}"
           class="item item-border-large item-avatar item-icon-right ink"
           ng-click="::select(item)">
 
-          <ng-include src="item.templateUrl || 'templates/wot/item_content_identity.html'"></ng-include>
+          <ng-include src="::item.templateUrl || 'templates/wot/item_content_identity.html'"></ng-include>
 
           <i class="icon ion-ios-arrow-right "></i>
           <ion-option-button
diff --git a/www/templates/wot/view_certifications.html b/www/templates/wot/view_certifications.html
index 2981a7d4b7fc5279b370938ed61c5cf5c4783338..2d3ae0a5b35a74dd3ba8cde8f27f95c87d446151 100644
--- a/www/templates/wot/view_certifications.html
+++ b/www/templates/wot/view_certifications.html
@@ -73,9 +73,14 @@
                 ng-class="{'positive': formData.isMember, 'gray': !formData.isMember}">
                 {{::formData.name||formData.uid}}
               </h4>
-              <h5 class="text-center gray">
-                <i class="icon ion-key"></i> {{formData.pubkey|formatPubkey}}
+              <h5 class="text-center gray row no-padding">
+                <div class="col">
+                  <i class="icon ion-key"></i> {{formData.pubkey|formatPubkey}}
+                </div>
+                <!-- icon of the pubkey -->
+                <div class="col" ng-if=":rebind:formData.pubkey" jdenticon="{{:rebind:formData.pubkey}}" jdenticon-size="32"></div>
               </h5>
+
               <h5 class="assertive">
                 <span ng-if="::(formData.name || formData.uid) && !formData.isMember && !revoked" translate>WOT.NOT_MEMBER_PARENTHESIS</span>
                 <b ng-if="::(formData.name || formData.uid) && !formData.isMember && revoked" translate>WOT.IDENTITY_REVOKED_PARENTHESIS</b>
diff --git a/www/templates/wot/view_identity.html b/www/templates/wot/view_identity.html
index 6c1b8328b19e3f9da305eb283e87cdb1fa802867..dd28c816f74e879273ae81df545c4b85d9203b21 100644
--- a/www/templates/wot/view_identity.html
+++ b/www/templates/wot/view_identity.html
@@ -89,12 +89,17 @@
         <span class="item item-divider" translate>WOT.GENERAL_DIVIDER</span>
 
         <!-- Pubkey -->
-        <ion-item class="item-icon-left item-text-wrap ink"
-                  copy-on-click="{{:rebind:formData.pubkey}}">
+        <div class="item item-icon-left item-text-wrap item-icon-right ink"
+                  ng-if=":rebind:formData.pubkey"
+                  on-hold="copy(formData.pubkey)"
+                  copy-on-click="{{:rebind:formData.pubkey|formatPubkey: {full: true } }}">
           <i class="icon ion-key"></i>
           <span translate>COMMON.PUBKEY</span>
-          <h4 id="pubkey" class="dark text-left">{{:rebind:formData.pubkey}}</h4>
-        </ion-item>
+          <h4 id="pubkey" class="dark text-left">{{:rebind:formData.pubkey|formatPubkey: {full: true } }}</h4>
+
+          <!-- icon of the pubkey -->
+          <i class="icon" jdenticon="{{::formData.pubkey}}" jdenticon-size="32"></i>
+        </div>
 
         <div class="item item-icon-left item-text-wrap"
               ng-if=":rebind:!formData.hasSelf">
diff --git a/yarn.lock b/yarn.lock
index 17097a320af00a8e242ce6ac0943ad3b1c2e0ae5..6875d8ebfcf06935fe33de9c7462d73feef62786 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -198,6 +198,12 @@
   version "0.0.0"
   resolved "https://codeload.github.com/driftyco/ionic-bower/tar.gz/816a8b26fae3e8305162eefe1114415503391be6"
 
+"@bower_components/jdenticon@dmester/jdenticon#3.1.0":
+  version "3.1.0"
+  resolved "https://codeload.github.com/dmester/jdenticon/tar.gz/54fb9c1d1d66d5eb6849583cca219ae6ab986ee5"
+  dependencies:
+    canvas-renderer "~2.2.0"
+
 "@bower_components/js-nacl@tonyg/js-nacl#1.3.2":
   version "1.3.2"
   resolved "https://codeload.github.com/tonyg/js-nacl/tar.gz/883f9d3cd9b6bbce84dc489ae4c2d87ffd653a18"
@@ -1889,6 +1895,13 @@ camelcase@^3.0.0:
   resolved "https://nexus.e-is.pro/nexus/content/repositories/npmjs/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a"
   integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo=
 
+canvas-renderer@~2.2.0:
+  version "2.2.0"
+  resolved "https://registry.npmjs.org/canvas-renderer/-/canvas-renderer-2.2.0.tgz#512151f5494aaac5270802fba22599785114716d"
+  integrity sha512-Itdq9pwXcs4IbbkRCXc7reeGBk6i6tlDtZTjE1yc+KvYkx1Mt3WLf6tidZ/Ixbm7Vmi+jpWKG0dRBor67x9yGw==
+  dependencies:
+    "@types/node" "*"
+
 caseless@~0.11.0:
   version "0.11.0"
   resolved "https://nexus.e-is.pro/nexus/content/repositories/npmjs/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7"