From 947111899d919d99d7e8f4c3f5e81222948414a8 Mon Sep 17 00:00:00 2001
From: ArnaudCerisier <arnaud.cerisier@gmail.com>
Date: Mon, 15 May 2017 11:33:07 +0200
Subject: [PATCH] [enh] Changing the registration process

---
 app/config.json                               |   6 +-
 scss/ionic.app.scss                           |   7 +-
 www/css/ionic.app.css                         |   6 +
 www/css/style.css                             |   5 +
 www/i18n/locale-en-GB.json                    |  21 +-
 www/i18n/locale-en.json                       |  21 +-
 www/i18n/locale-es-ES.json                    |  21 +-
 www/i18n/locale-fr-FR.json                    |  30 +-
 www/i18n/locale-nl-NL.json                    |  20 +-
 www/js/config.js                              |  32 +-
 www/js/controllers/app-controllers.js         |  41 +-
 www/js/controllers/join-controllers.js        | 184 ++++++--
 www/js/services/crypto-services.js            |   2 +-
 www/js/services/modal-services.js             |  12 +
 www/js/services/utils-services.js             |  24 +-
 www/js/services/wallet-services.js            | 154 +++----
 www/licence_g1.txt                            |  75 ++++
 www/templates/currency/items_wot.html         |   6 +
 www/templates/join/modal_join.html            | 281 +------------
 www/templates/join/modal_join_member.html     | 392 ++++++++++++++++++
 www/templates/join/modal_join_wallet.html     | 298 +++++++++++++
 .../wallet/slides/slides_revocation_1.html    |   4 +-
 22 files changed, 1164 insertions(+), 478 deletions(-)
 create mode 100644 www/licence_g1.txt
 create mode 100644 www/templates/join/modal_join_member.html
 create mode 100644 www/templates/join/modal_join_wallet.html

diff --git a/app/config.json b/app/config.json
index 8408c042d..3315785a0 100644
--- a/app/config.json
+++ b/app/config.json
@@ -132,12 +132,12 @@
       }
     },
     "node": {
-      "host": "gtest.duniter.org",
-      "port": 10900
+      "host": "localhost",
+      "port": 9600
     },
     "plugins":{
       "es": {
-        "enable": true,
+        "enable": false,
         "askEnable": false,
         "host": "localhost",
         "port": 9200,
diff --git a/scss/ionic.app.scss b/scss/ionic.app.scss
index 761630371..5884fbcb5 100644
--- a/scss/ionic.app.scss
+++ b/scss/ionic.app.scss
@@ -654,7 +654,12 @@ $screen-menu:                     845px;
 .button-text-stable {
   color: #b2b2b2 !important;
 }
-
+.popup-buttons .button.icon-right, 
+.popup-buttons .button.icon-left {
+  padding-left: 32px !important;
+  padding-right: 32px !important;
+  line-height: 42px;
+}
 /* ============
  Home page
 =============== */
diff --git a/www/css/ionic.app.css b/www/css/ionic.app.css
index f12bcce9c..5c5c5ec4e 100644
--- a/www/css/ionic.app.css
+++ b/www/css/ionic.app.css
@@ -14144,6 +14144,12 @@ a {
 .button-text-stable {
   color: #b2b2b2 !important; }
 
+.popup-buttons .button.icon-right,
+.popup-buttons .button.icon-left {
+  padding-left: 32px !important;
+  padding-right: 32px !important;
+  line-height: 42px; }
+
 /* ============
  Home page
 =============== */
diff --git a/www/css/style.css b/www/css/style.css
index bfee1d685..9b02869e0 100644
--- a/www/css/style.css
+++ b/www/css/style.css
@@ -37,6 +37,10 @@
   color: grey;
 }
 
+#modal-license {
+  color:rgb(0, 0, 0);
+}
+
 .bar .button.button-clear {
   font-size: 12px !important;
   font-weight: 300 !important;
@@ -205,3 +209,4 @@
 .item-block.item-block-empty.compacted {
   border-bottom: double 1px #eee !important;
 }
+
diff --git a/www/i18n/locale-en-GB.json b/www/i18n/locale-en-GB.json
index f9d3b2ec2..d4c409be3 100644
--- a/www/i18n/locale-en-GB.json
+++ b/www/i18n/locale-en-GB.json
@@ -35,6 +35,8 @@
     "BTN_OPTIONS": "Options",
     "BTN_HELP_TOUR": "Features tour",
     "BTN_HELP_TOUR_SCREEN": "Discover this screen",
+    "BTN_DOWNLOAD": "Download",
+    "BTN_MODIFY": "Modify",
     "DAYS": "days",
     "NO_ACCOUNT_QUESTION": "Not a member yet? Register now!",
     "SEARCH_NO_RESULT": "No result found",
@@ -396,8 +398,9 @@
       "LAST_SLIDE_CONGRATULATION": "You completed all required fields.<br/><b>You can send the account creation request</b>.<br/><br/>For information, the public key below identifies your future account.<br/>It can be communicated to third parties to receive their payment.<br/>Once your account has been approved, you can find this key under <b>{{'ACCOUNT.TITLE'|translate}}</b>.",
       "CONFIRMATION_MEMBER_ACCOUNT": "<b class=\"assertive\">Warning:</b> your secret identifier, password and pseudonym can not be changed.<br/><b>Make sure you always remember it!</b><br/><b>Are you sure</b> you want to send this account creation request?",
       "CONFIRMATION_WALLET_ACCOUNT": "<b class=\"assertive\">Warning:</b> your password and pseudonym can not be changed.<br/><b>Make sure you always remember it!</b><br/><b>Are you sure</b> you want to continue?",
-      "MSG_UID_ALREADY_USED": "This pseudonym is already used by an existing member.<br/>Please choose another one.",
-      "MSG_PUBKEY_ALREADY_USED": "Public key already used by an existing member.<br/>Please choose other connection parameters."
+      "PSEUDO_AVAILABLE": "This nickname is available",
+      "PSEUDO_NOT_AVAILABLE": "This nickname is not available",
+      "INFO_LICENSE": "To be able to adhere to the currency, we ask you to kindly read and accept this license."
     },
     "POPUP_REGISTER": {
       "TITLE": "Enter a pseudonym",
@@ -435,6 +438,7 @@
       "QUESTION_19": "What was your grand-father's job ?",
       "RECOVER_ID": "Recover your password",
       "REVOCATION": "Revocation ...",
+      "REVOCATION_SAVE": "revocation",
       "REVOKE" : "Revoke this identity",
       "REVOKE_WITH_FILE" : "Rekoke this identity with a file",
       "SAVE_ID": "Save your login",
@@ -531,7 +535,9 @@
     "SALT_OR_PASSWORD_NOT_CONFIRMED": "Wrong secret identifier or password ",
     "RECOVER_ID_FAILED": "Could not recover password",
     "LOAD_FILE_FAILED" : "Unable to load file",
-    "ONLY_TEXT_FILE": "You have to select a text file"
+    "ONLY_TEXT_FILE": "You have to select a text file",
+    "EXISTING_ACCOUNT": "Your identifiers correspond to an already existing account, whose <a ng-click=\"showHelpModal('pubkey')\">public key</a> is:",
+    "EXISTING_ACCOUNT_REQUEST": "Please modify your credentials so that they correspond to an unused account."
   },
   "INFO": {
     "POPUP_TITLE": "Information",
@@ -565,7 +571,12 @@
     "NOT_NEED_RENEW_MEMBERSHIP": "Your membership does not need to be renewed (it will only expire in {{membershipExpiresIn|formatDuration}}).<br/></br/><b>Are you sure you</b> want to renew your membership?",
     "SAVE_BEFORE_LEAVE": "Do you want to <b>save your changes</b> before leaving the page?",
     "SAVE_BEFORE_LEAVE_TITLE": "Changes not saved",
-    "LOGOUT": "Are you sure you want to logout?"
+    "LOGOUT": "Are you sure you want to logout?",
+    "LICENCE": "I declare that I have read and accepted the conditions of the license Äž1"
+  },
+  "DOWNLOAD": {
+    "POPUP_TITLE": "<b>Revocation file</b>",
+    "POPUP_REVOKE_MESSAGE": "The revocation file now needs to be retrieved by clicking on the button below.</br></br>The revocation file allows you to cancel your account (in the event of an account theft, A change of identifier, an incorrectly created account etc.), it is therefore<b> important to store it in place on.</b>"
   },
   "HELP": {
     "TITLE": "Online help",
@@ -577,7 +588,7 @@
     },
     "GLOSSARY": {
       "SECTION": "Glossary",
-      "PUBKEY_DEF": "A public key always identifies a wallet. It may identify a member.",
+      "PUBKEY_DEF": "A public key always identifies a wallet. It may identify a member. In Cesium it is calculated using the secret identifier and the password.",
       "MEMBER": "Member",
       "MEMBER_DEF": "A member is a real and living human, wishing to participate freely to the monitary community. The member will receive universal dividend, according to the period and amount as defined in the <span class=\"text-italic\">currency parameters</span>.",
       "CURRENCY_RULES": "Currency rules",
diff --git a/www/i18n/locale-en.json b/www/i18n/locale-en.json
index 227a2c7e6..904769939 100644
--- a/www/i18n/locale-en.json
+++ b/www/i18n/locale-en.json
@@ -35,6 +35,8 @@
     "BTN_OPTIONS": "Options",
     "BTN_HELP_TOUR": "Features tour",
     "BTN_HELP_TOUR_SCREEN": "Discover this screen",
+    "BTN_DOWNLOAD": "Download",
+    "BTN_MODIFY": "Modify",
     "DAYS": "days",
     "NO_ACCOUNT_QUESTION": "Not a member yet? Register now!",
     "SEARCH_NO_RESULT": "No result found",
@@ -396,8 +398,9 @@
       "LAST_SLIDE_CONGRATULATION": "You completed all required fields.<br/><b>You can send the account creation request</b>.<br/><br/>For information, the public key below identifies your future account.<br/>It can be communicated to third parties to receive their payment.<br/>Once your account has been approved, you can find this key under <b>{{'ACCOUNT.TITLE'|translate}}</b>.",
       "CONFIRMATION_MEMBER_ACCOUNT": "<b class=\"assertive\">Warning:</b> your secret identifier, password and pseudonym can not be changed.<br/><b>Make sure you always remember it!</b><br/><b>Are you sure</b> you want to send this account creation request?",
       "CONFIRMATION_WALLET_ACCOUNT": "<b class=\"assertive\">Warning:</b> your password and pseudonym can not be changed.<br/><b>Make sure you always remember it!</b><br/><b>Are you sure</b> you want to continue?",
-      "MSG_UID_ALREADY_USED": "This pseudonym is already used by an existing member.<br/>Please choose another one.",
-      "MSG_PUBKEY_ALREADY_USED": "Public key already used by an existing member.<br/>Please choose other connection parameters."
+      "PSEUDO_AVAILABLE": "This nickname is available",
+      "PSEUDO_NOT_AVAILABLE": "This nickname is not available",
+      "INFO_LICENSE": "To be able to adhere to the currency, we ask you to kindly read and accept this license."
     },
     "POPUP_REGISTER": {
       "TITLE": "Enter a pseudonym",
@@ -435,6 +438,7 @@
       "QUESTION_19": "What was your grand-father's job ?",
       "RECOVER_ID": "Recover your password",
       "REVOCATION": "Revocation ...",
+      "REVOCATION_SAVE": "revocation",
       "REVOKE" : "Revoke this identity",
       "REVOKE_WITH_FILE" : "Rekoke this identity with a file",
       "SAVE_ID": "Save your login",
@@ -531,7 +535,9 @@
     "SALT_OR_PASSWORD_NOT_CONFIRMED": "Wrong secret identifier or password ",
     "RECOVER_ID_FAILED": "Could not recover password",
     "LOAD_FILE_FAILED" : "Unable to load file",
-    "ONLY_TEXT_FILE": "You have to select a text file"
+    "ONLY_TEXT_FILE": "You have to select a text file",
+    "EXISTING_ACCOUNT": "Your identifiers correspond to an already existing account, whose <a ng-click=\"showHelpModal('pubkey')\">public key</a> is:",
+    "EXISTING_ACCOUNT_REQUEST": "Please modify your credentials so that they correspond to an unused account."
   },
   "INFO": {
     "POPUP_TITLE": "Information",
@@ -565,7 +571,12 @@
     "NOT_NEED_RENEW_MEMBERSHIP": "Your membership does not need to be renewed (it will only expire in {{membershipExpiresIn|formatDuration}}).<br/></br/><b>Are you sure you</b> want to renew your membership?",
     "SAVE_BEFORE_LEAVE": "Do you want to <b>save your changes</b> before leaving the page?",
     "SAVE_BEFORE_LEAVE_TITLE": "Changes not saved",
-    "LOGOUT": "Are you sure you want to logout?"
+    "LOGOUT": "Are you sure you want to logout?",
+    "LICENCE": "I declare that I have read and accepted the conditions of the license Äž1"
+  },
+  "DOWNLOAD": {
+    "POPUP_TITLE": "<b>Revocation file</b>",
+    "POPUP_REVOKE_MESSAGE": "The revocation file now needs to be retrieved by clicking on the button below.</br></br>The revocation file allows you to cancel your account (in the event of an account theft, A change of identifier, an incorrectly created account etc.), it is therefore<b> important to store it in place on.</b>"
   },
   "HELP": {
     "TITLE": "Online help",
@@ -577,7 +588,7 @@
     },
     "GLOSSARY": {
       "SECTION": "Glossary",
-      "PUBKEY_DEF": "A public key always identifies a wallet. It may identify a member.",
+      "PUBKEY_DEF": "A public key always identifies a wallet. It may identify a member. In Cesium it is calculated using the secret identifier and the password.",
       "MEMBER": "Member",
       "MEMBER_DEF": "A member is a real and living human, wishing to participate freely to the monitary community. The member will receive universal dividend, according to the period and amount as defined in the <span class=\"text-italic\">currency parameters</span>.",
       "CURRENCY_RULES": "Currency rules",
diff --git a/www/i18n/locale-es-ES.json b/www/i18n/locale-es-ES.json
index 5ebb46e6a..259f5e38e 100644
--- a/www/i18n/locale-es-ES.json
+++ b/www/i18n/locale-es-ES.json
@@ -35,6 +35,8 @@
     "BTN_OPTIONS": "Opciónes",
     "BTN_HELP_TOUR": "Visita guiada",
     "BTN_HELP_TOUR_SCREEN": "Descubrir esta pantalla",
+    "BTN_DOWNLOAD": "Descargar",
+    "BTN_MODIFY": "Cambio",
     "DAYS": "Dias",
     "NO_ACCOUNT_QUESTION": "Todavía no miembre ? Creer una cuenta !",
     "SEARCH_NO_RESULT": "Ninguno resultado encontrado",
@@ -381,8 +383,9 @@
       "LAST_SLIDE_CONGRATULATION": "<b>Bravo !</b> Ha introducido todas las informaciónes necesarias.<br/><b>Puede mandar la solicitud</b> de creación de su cuenta.</b><br/><br/>Por su información, la llave pública más abajo identificará su cuenta futura.<br/>Podrá estar comunicada a terceros para recibir sus pagos.<br/>Sin embargo, <b>no es útil</b> anotarla aquí.",
       "CONFIRMATION_MEMBER_ACCOUNT": "<b class=\"assertive\">Advertencia :</b> el identificador secreto, la contraseña y el seudónimo no podrán estar modificados.<br/><b>Asegurase siempre se los recordar !</b><br/><br/><b>Está usted seguro</b> querer mandar esta solicitud de inscripción ?",
       "CONFIRMATION_WALLET_ACCOUNT": "<b class=\"assertive\">Advertencia :</b> el identificador secreto y la contraseña no podrán estar modificados.<br/><b>Asegurase siempre se los recordar !</b><br/><br/><b>Está usted seguro</b> querer continuar con estos identificadores ?",
-      "MSG_UID_ALREADY_USED": "Seudónimo ya utilizado por una otra persona.<br/>Elige un otro por favor.",
-      "MSG_PUBKEY_ALREADY_USED": "Llave pública ya utilizada por una otra persona.<br/>Elige otros identificadores de conexión por favor."
+      "PSEUDO_AVAILABLE": "Este nombre está disponible",
+      "PSEUDO_NOT_AVAILABLE": "Este nombre de usuario no está disponible",
+      "INFO_LICENSE": "Para unirse a la moneda, le pedimos que leer y aceptar esta licencia."
     },
     "POPUP_REGISTER": {
       "TITLE": "Elige un seudónimo",
@@ -420,6 +423,7 @@
       "QUESTION_19": "Cuál fue el oficio de su abuelo ?",
       "RECOVER_ID": "Recuperar sus identificadores",
       "REVOCATION": "Revocación ...",
+      "REVOCATION_SAVE": "revocacion",
       "REVOKE": "Revocar esta identidad",
       "REVOKE_WITH_FILE": "Revocar una identidad a partir de un fichero",
       "SAVE_ID": "Salvar sus identificadores",
@@ -516,7 +520,9 @@
     "SALT_OR_PASSWORD_NOT_CONFIRMED": "Identificador secreto o contraseña incorrectos",
     "RECOVER_ID_FAILED": "Fracaso en la recuperación de los identificadores",
     "LOAD_FILE_FAILED" : "Fracaso en la carga del fichero",
-    "ONLY_TEXT_FILE": "Debe seleccionar un fichero texto"
+    "ONLY_TEXT_FILE": "Debe seleccionar un fichero texto",
+    "EXISTING_ACCOUNT": "Su contraseña corresponde a una cuenta existente, la <a ng-click=\"showHelpModal('pubkey')\">clave pública</a> es:",
+    "EXISTING_ACCOUNT_REQUEST": "Por favor, cambie su contraseña para que coincida con una cuenta sin usar."
   },
   "INFO": {
     "POPUP_TITLE": "Información",
@@ -550,7 +556,12 @@
     "NOT_NEED_RENEW_MEMBERSHIP": "Su adhesión no necesita estar renovada (solo va a caducar en {{membershipExpiresIn|formatDuration}}).<br/></br/><b>Está usted seguro</b> querer renovar su adhesión ?",
     "SAVE_BEFORE_LEAVE": "Quiere usted <b>guardar sus modificaciónes</b> antes dejar la página ?",
     "SAVE_BEFORE_LEAVE_TITLE": "Modificaciónes no registradas",
-    "LOGOUT": "Está usted seguro querer desconectarse ?"
+    "LOGOUT": "Está usted seguro querer desconectarse ?",
+    "LICENCE": "He leído y acepto las condiciones de la licencia G1"
+  },
+  "DOWNLOAD": {
+    "POPUP_TITLE": "<b>Revocación del archivo</b>",
+    "POPUP_REVOKE_MESSAGE": "Ahora tenemos que recuperar el archivo de revocación, puede descargarlo haciendo clic en el botón de abajo.</br></br>El archivo de revocación, se cancelará su cuenta (en caso de robo de cuenta, un cambio de identificador, una cuenta falsamente creado etc.), por lo que es<b> importante para almacenarlo en un lugar seguro.</b>"
   },
   "HELP": {
     "TITLE": "Ayuda en línea",
@@ -562,7 +573,7 @@
     },
     "GLOSSARY": {
       "SECTION": "Glosario",
-      "PUBKEY_DEF": "Una llave pública identifica un monedero. Puede identificar un miembro",
+      "PUBKEY_DEF": "Una llave pública identifica un monedero. Puede identificar un miembro. En Cesium se calcula con el identificador y la contraseña secreta.",
       "MEMBER": "Miembro",
       "MEMBER_DEF": "Un miembro es una persona humana física y viva, deseosa de participar libremente a la comunidad monetaria. Percibe un dividendo universal, dependiendo de un período y un importe como definido en las <span class=\"text-italic\">reglas de la moneda</span>",
       "CURRENCY_RULES": "Reglas de la moneda",
diff --git a/www/i18n/locale-fr-FR.json b/www/i18n/locale-fr-FR.json
index ebb2acbdb..e7a2652b6 100644
--- a/www/i18n/locale-fr-FR.json
+++ b/www/i18n/locale-fr-FR.json
@@ -35,6 +35,8 @@
     "BTN_OPTIONS": "Options",
     "BTN_HELP_TOUR": "Visite guidée",
     "BTN_HELP_TOUR_SCREEN": "Découvrir cet écran",
+    "BTN_DOWNLOAD": "Télécharger",
+    "BTN_MODIFY": "Modifier",
     "DAYS": "jours",
     "NO_ACCOUNT_QUESTION": "Pas de encore membre ? Créer un compte !",
     "SEARCH_NO_RESULT": "Aucun résultat trouvé",
@@ -396,8 +398,10 @@
       "LAST_SLIDE_CONGRATULATION": "<b>Bravo !</b> Vous avez saisi toutes les informations nécessaires.<br/><b>Vous pouvez envoyer la demande</b> de création de compte.</b><br/><br/>Pour information, la clé publique ci-dessous identifiera votre futur compte.<br/>Elle pourra être communiquée à des tiers pour recevoir leur paiement.<br/>Cependant, <b>il n'est pas utile</b> de la noter ici.",
       "CONFIRMATION_MEMBER_ACCOUNT": "<b class=\"assertive\">Avertissement :</b> l'identifiant secret, le mot de passe et le pseudonyme ne pourront plus être modifiés.<br/><b>Assurez-vous de toujours vous en rappeller !</b><br/><br/><b>Etes-vous sûr</b> de vouloir envoyer cette demande d'inscription ?",
       "CONFIRMATION_WALLET_ACCOUNT": "<b class=\"assertive\">Avertissement :</b> l'identifiant secret et le mot de passe ne pourront plus être modifiés.<br/><b>Assurez-vous de toujours vous en rappeller !</b><br/><br/><b>Etes-vous sûr</b> de vouloir continuer avec ces identifiants ?",
-      "MSG_UID_ALREADY_USED": "Pseudonyme déjà utilisé par quelqu'un d'autre.<br/>Veuillez en choisir un autre.",
-      "MSG_PUBKEY_ALREADY_USED": "Clé publique déjà utilisée par quelqu'un d'autre.<br/>Veuillez choisir d'autres identifiants de connexion."
+      "PSEUDO_AVAILABLE": "Ce pseudo est disponible",
+      "PSEUDO_NOT_AVAILABLE": "Ce pseudo n'est pas disponible",
+      "INFO_LICENSE": "Pour pouvoir adhérer à la monnaie, nous vous demandons de bien vouloir lire et accepter cette licence."
+
     },
     "POPUP_REGISTER": {
       "TITLE": "Choisissez un pseudonyme",
@@ -435,6 +439,7 @@
       "QUESTION_19": "Quel était le métier de votre grand-père ?",
       "RECOVER_ID": "Recupérer vos identifiants",
       "REVOCATION": "Révocation ...",
+      "REVOCATION_FILENAME": "revocation-{{uid}}-{{pubkey|formatPubkey}}-{{currency}}.txt",
       "REVOKE": "Révoquer cette identité",
       "REVOKE_WITH_FILE": "Révoquer une identité à partir d'un fichier",
       "SAVE_ID": "Sauvegarder vos identifiants",
@@ -523,15 +528,9 @@
     "UNABLE_TO_CERTIFY_TITLE": "Certification impossible",
     "LOAD_NEWCOMERS_FAILED": "Echec du chargement des nouveaux membres.",
     "LOAD_PENDING_FAILED": "Echec du chargement des inscriptions en attente.",
-    "ONLY_MEMBER_CAN_EXECUTE_THIS_ACTION": "Vous devez <b>être membre</b> pour pouvoir effectuer cette action.",
-    "ONLY_SELF_CAN_EXECUTE_THIS_ACTION": "Vous devez avoir <b>publié votre identité</b> pour pouvoir effectuer cette action.",
-    "GET_BLOCK_FAILED": "Echec de la récupération du bloc",
-    "INVALID_BLOCK_HASH": "Bloc non trouvé (hash différent)",
-    "REVOCATION_FAILED": "Echec de la révocation.",
-    "SALT_OR_PASSWORD_NOT_CONFIRMED": "Identifiant secret ou mot de passe incorrects",
-    "RECOVER_ID_FAILED": "Echec de la récupération des identifiants",
-    "LOAD_FILE_FAILED" : "Echec du chargement du fichier",
-    "ONLY_TEXT_FILE": "Vous devez selectionner un fichier texte"
+    "ONLY_MEMBER_CAN_EXECUTE_THIS_ACTION": "Vous devez <b>être membre</b> pour pouvoir effectuerTING",
+    "EXISTING_ACCOUNT": "Vos identifiants correspondent à un compte déjà existant, dont la <a ng-click=\"showHelpModal('pubkey')\">clef publique</a> est :",
+    "EXISTING_ACCOUNT_REQUEST": "Veuillez modifier vos identifiants afin qu'ils correspondent à un compte non utilisé."
   },
   "INFO": {
     "POPUP_TITLE": "Information",
@@ -565,7 +564,12 @@
     "NOT_NEED_RENEW_MEMBERSHIP": "Votre adhésion n'a pas besoin d'être renouvellée (elle n'expirera que dans {{membershipExpiresIn|formatDuration}}).<br/></br/><b>Etes-vous sûr</b> de vouloir renouveler votre adhésion ?",
     "SAVE_BEFORE_LEAVE": "Voulez-vous <b>sauvegarder vos modifications</b> avant de quitter la page ?",
     "SAVE_BEFORE_LEAVE_TITLE": "Modifications non enregistrées",
-    "LOGOUT": "Etes-vous de vouloir vous déconnecter ?"
+    "LOGOUT": "Etes-vous de vouloir vous déconnecter ?",
+    "LICENCE": "Je déclare avoir lu et accepté les conditions de la licence Ğ1"
+  },
+  "DOWNLOAD": {
+    "POPUP_TITLE": "<b>Fichier de révocation</b>",
+    "POPUP_REVOKE_MESSAGE": "Il faut maintenant récupérer le fichier de révocation, veuillez le télécharger en cliquant sur le boutton ci-dessous.</br></br> Le fichier de révocation permet d'annuler son compte (en cas d'un vol de compte, d'un changement d'identifiant, d'un compte créé à tort etc.), il est donc <b>important de le stocker en lieu sûr</b>."
   },
   "HELP": {
     "TITLE": "Aide en ligne",
@@ -577,7 +581,7 @@
     },
     "GLOSSARY": {
       "SECTION": "Glossaire",
-      "PUBKEY_DEF": "Une clé publique identifie un portefeuille de monnaie. Il peut identifier un membre",
+      "PUBKEY_DEF": "Une clé publique identifie un portefeuille de monnaie. Il peut identifier un membre. Dans Cesium elle est calculée grâce à l'identifiant secret et au mot de passe.",
       "MEMBER": "Membre",
       "MEMBER_DEF": "Un membre est une personne humaine physique et vivante, désireuse de participer librement à la communauté monétaire. Elle percoit un dividende universel, suivant une période et un montant tels que définis dans les <span class=\"text-italic\">règles de la monnaie</span>",
       "CURRENCY_RULES": "Règles de la monnaie",
diff --git a/www/i18n/locale-nl-NL.json b/www/i18n/locale-nl-NL.json
index 5e4b1199b..bb27b7ac1 100644
--- a/www/i18n/locale-nl-NL.json
+++ b/www/i18n/locale-nl-NL.json
@@ -35,6 +35,8 @@
     "BTN_OPTIONS": "Opties",
     "BTN_HELP_TOUR": "Rondleiding",
     "BTN_HELP_TOUR_SCREEN": "Ontdek dit scherm",
+    "BTN_DOWNLOAD": "Downloaden",
+    "BTN_MODIFY": "Bewerken",
     "DAYS": "dagen",
     "NO_ACCOUNT_QUESTION": "Nog geen lid? Registreer nu!",
     "SEARCH_NO_RESULT": "Geen resultaten",
@@ -335,8 +337,9 @@
       "LAST_SLIDE_CONGRATULATION": "Bravo! Je hebt alle verplichte velden ingevuld.<br/>Je kunt je <b>rekeningaanvraag verzenden</b>.<br/><br/>Ter informatie, de publieke sleutel hieronder identificeert je toekomstige rekening.<br/>Je kunt deze aan derde partijen communiceren om geld te ontvangen. Zodra je rekening geopend is, kun je de sleutel terugvinden onder <b>{{'ACCOUNT.TITLE'|translate}}</b>.",
       "CONFIRMATION_MEMBER_ACCOUNT": "<b class=\"assertive\">Waarschuwing:</b> je beveiligingszin, wachtwoord en pseudoniem kunnen hierna niet gewijzigd worden.<br/><b>Zorg dat ze goed onthoudt!</b><br/><b>Weet je zeker</b> dat je je persoonlijke rekeningaanvraag wil verzenden?",
       "CONFIRMATION_WALLET_ACCOUNT": "<b class=\"assertive\">Waarschuwing:</b> je wachtwoord en pseudoniem kunnen hierna niet gewijzigd worden.<br/><b>Zorg dat ze goed onthoudt!</b><br/><b>Weet je zeker</b> dat je deze portefeilleaanvraag wil verzenden?",
-      "MSG_UID_ALREADY_USED": "Deze pseudoniem is al in gebruik door een bestaand lid.<br/>Kies een andere.",
-      "MSG_PUBKEY_ALREADY_USED": "Publieke sleutel komt overeen met die van een bestaand lid.<br/>Kies andere verbindingsparameters."
+      "PSEUDO_AVAILABLE": "Deze naam is beschikbaar",
+      "PSEUDO_NOT_AVAILABLE": "Deze gebruikersnaam is niet beschikbaar",
+      "INFO_LICENSE": "Om de valuta te sluiten, vragen wij u om te lezen en deze licentie te accepteren."
     },
     "POPUP_REGISTER": {
       "TITLE": "Voer een pseudoniem in",
@@ -420,7 +423,9 @@
     "LOAD_NEWCOMERS_FAILED": "Unable to load new members.",
     "LOAD_PENDING_FAILED": "Unable to load pending registrations.",
     "ONLY_MEMBER_CAN_EXECUTE_THIS_ACTION": "You must <b>be a member</b> in order to perform this action.",
-    "ONLY_SELF_CAN_EXECUTE_THIS_ACTION": "You must have <b>published your identity</b> in order to perform this action."
+    "ONLY_SELF_CAN_EXECUTE_THIS_ACTION": "You must have <b>published your identity</b> in order to perform this action.",
+    "EXISTING_ACCOUNT": "Uw wachtwoord overeenkomen met een bestaande account, de <a ng-click=\"showHelpModal('pubkey')\">publieke sleutel</a> is:",
+    "EXISTING_ACCOUNT_REQUEST": "Gelieve uw wachtwoord wijzigen om een ongebruikte account."
   },
   "INFO": {
     "POPUP_TITLE": "Informatie",
@@ -448,7 +453,12 @@
     "REVOKE_IDENTITY_2": "Deze handeling is <b>niet terug te draaien</b>!<br/><br/><b>Weet je zeker</b> dat je door wil gaan?",
     "NOT_NEED_RENEW_MEMBERSHIP": "Je lidmaatschap hoeft niet verlengd te worden (het zal pas verlopen na {{membershipExpiresIn|formatDuration}}).<br/></br/><b>Weet je zeker</b> dat je een verlengingsaanvraag wil versturen?",
     "SAVE_BEFORE_LEAVE": "Wil je <b>je wijzigingen opslaan</b> voor je de pagina verlaat?",
-    "SAVE_BEFORE_LEAVE_TITLE": "Wijzigingen niet opgeslagen"
+    "SAVE_BEFORE_LEAVE_TITLE": "Wijzigingen niet opgeslagen",
+    "LICENCE": "Ik heb gelezen en geaccepteerd de voorwaarden van de vergunning G1"
+  },
+  "DOWNLOAD": {
+    "POPUP_TITLE": "<b>Intrekking File</b>",
+    "POPUP_REVOKE_MESSAGE": "We moeten nu herstellen van de herroeping bestand, dan kunt u downloaden door te klikken op de onderstaande knop.</br></br>De herroeping bestand zullen hun rekening (in het geval van de rekening van diefstal te annuleren, een verandering van de identifier, een ten onrechte gemaakte account etc.), dus het is<b> belangrijk om het op te slaan op een veilige plaats.</b>"
   },
   "HELP": {
     "TITLE": "Online help",
@@ -460,7 +470,7 @@
     },
     "GLOSSARY": {
       "SECTION": "Glossary",
-      "PUBKEY_DEF": "A public key always identifies a wallet. It may identify a member.",
+      "PUBKEY_DEF": "Een publieke sleutel identificeert altijd een portemonnee. Het kan een lid identificeren. In Cesium wordt berekend met de geheime ID en wachtwoord.",
       "MEMBER": "Member",
       "MEMBER_DEF": "A member is a real and living human, wishing to participate freely to the monitary community. The member will receive universal dividend, according to the period and amount as defined in the <span class=\"text-italic\">currency parameters</span>.",
       "CURRENCY_RULES": "Currency rules",
diff --git a/www/js/config.js b/www/js/config.js
index 1d6543f6e..1fc8fc211 100644
--- a/www/js/config.js
+++ b/www/js/config.js
@@ -10,33 +10,41 @@ angular.module("cesium.config", [])
 
 .constant("csConfig", {
 	"cacheTimeMs": 60000,
-	"fallbackLanguage": "en",
+	"fallbackLanguage": "fr-FR",
+	"defaultLanguage": "fr-FR",
 	"rememberMe": true,
 	"showUDHistory": false,
-	"timeout": 10000,
+	"timeout": 6000,
 	"timeWarningExpireMembership": 5184000,
 	"timeWarningExpire": 7776000,
 	"useLocalStorage": true,
-	"useRelative": false,
-	"initPhase": false,
+	"useRelative": true,
 	"expertMode": true,
 	"decimalCount": 2,
-	"httpsMode": false,
 	"helptip": {
 		"enable": false,
-		"installDocUrl": "https://github.com/duniter/duniter/blob/master/doc/install-a-node.md"
+		"installDocUrl": {
+			"fr-FR": "http://www.le-sou.org/devenir-noeud/",
+			"en": "https://github.com/duniter/duniter/blob/master/doc/install-a-node.md"
+		}
 	},
 	"node": {
-		"host": "g1.duniter.org",
-		"port": "443"
+		"host": "localhost",
+		"port": 9600
 	},
 	"plugins": {
 		"es": {
-			"enable": true,
+			"enable": false,
 			"askEnable": false,
 			"host": "localhost",
-			"port": "9200",
-			"wsPort": "9400"
+			"port": 9200,
+			"wsPort": 9400,
+			"notifications": {
+				"txSent": true,
+				"txReceived": true,
+				"certSent": true,
+				"certReceived": true
+			}
 		},
 		"graph": {
 			"enable": true
@@ -46,7 +54,7 @@ angular.module("cesium.config", [])
 		}
 	},
 	"version": "0.12.2",
-	"build": "2017-05-09T14:47:38.758Z",
+	"build": "2017-05-15T09:21:45.439Z",
 	"newIssueUrl": "https://github.com/duniter/cesium/issues/new?labels=bug"
 })
 
diff --git a/www/js/controllers/app-controllers.js b/www/js/controllers/app-controllers.js
index e2384e581..81328cc44 100644
--- a/www/js/controllers/app-controllers.js
+++ b/www/js/controllers/app-controllers.js
@@ -205,17 +205,22 @@ function AppController($scope, $rootScope, $state, $ionicSideMenuDelegate, $q, $
         // Warn if wallet has been never used - see #167
         var showAlert = !csConfig.initPhase && csWallet.isNeverUsed() && (!csSettings.data.wallet || csSettings.data.wallet.alertIfUnusedWallet);
         if (!showAlert) return walletData;
-        return UIUtils.loading.hide()
-          .then(function(){
-            return UIUtils.alert.confirm('CONFIRM.LOGIN_UNUSED_WALLET', 'CONFIRM.LOGIN_UNUSED_WALLET_TITLE',
-              {
-                okText: 'COMMON.BTN_CONTINUE'
-              });
-          })
-          .then(function(confirm) {
-            if (confirm) return walletData;
-            return csWallet.logout();
-          });
+        if($rootScope.accountType === "member"){
+          return UIUtils.loading.hide()
+            .then(function(){
+              return UIUtils.alert.confirm('CONFIRM.LOGIN_UNUSED_WALLET', 'CONFIRM.LOGIN_UNUSED_WALLET_TITLE',
+                {
+                  okText: 'COMMON.BTN_CONTINUE'
+                });
+            })
+            .then(function(confirm) {
+              if (confirm) return walletData;
+              return csWallet.logout();
+            });
+        }
+        else{
+          return walletData;
+        }
       })
 
       .then(function(walletData) {
@@ -392,7 +397,19 @@ function AppController($scope, $rootScope, $state, $ionicSideMenuDelegate, $q, $
 
   $scope.showJoinModal = function() {
     $scope.closeProfilePopover();
-    return Modals.showJoin();
+    return Modals.showJoin()
+    .then(function(res){
+      if (!res) return;
+      if (res === 'member'){
+        $rootScope.accountType = 'member';
+        Modals.showJoinMember();
+        $rootScope.startLicenceRead();
+      }
+      else if (res === 'wallet'){
+        $rootScope.accountType = 'wallet';
+        Modals.showJoinWallet();
+      }
+    }); 
   };
 
   $scope.showSettings = function() {
diff --git a/www/js/controllers/join-controllers.js b/www/js/controllers/join-controllers.js
index ec1c7ca49..690388360 100644
--- a/www/js/controllers/join-controllers.js
+++ b/www/js/controllers/join-controllers.js
@@ -1,4 +1,3 @@
-
 angular.module('cesium.join.controllers', ['cesium.services'])
 
   .config(function($stateProvider) {
@@ -36,7 +35,7 @@ function JoinController($timeout, Modals) {
 }
 
 
-function JoinModalController($scope, $state,  UIUtils, CryptoUtils, csSettings, Modals, csWallet, csCurrency, BMA) {
+function JoinModalController($scope, $state, $interval, $rootScope, UIUtils, CryptoUtils, csSettings, Modals, csWallet, csCurrency, BMA) {
   'ngInject';
 
   $scope.formData = {
@@ -54,8 +53,11 @@ function JoinModalController($scope, $state,  UIUtils, CryptoUtils, csSettings,
   $scope.search = {
     looking: true
   };
+
+  $scope.isLicenceRead = false;
   $scope.showUsername = false;
   $scope.showPassword = false;
+  $scope.formData.computing=false;
   $scope.smallscreen = UIUtils.screen.isSmall();
   $scope.userIdPattern = BMA.constants.regex.USER_ID;
 
@@ -98,6 +100,7 @@ function JoinModalController($scope, $state,  UIUtils, CryptoUtils, csSettings,
     .then(function(keypair) {
       $scope.formData.pubkey = CryptoUtils.util.encode_base58(keypair.signPk);
       $scope.formData.computing=false;
+      $scope.checkAccountAvailable();
     })
     .catch(function(err) {
       $scope.formData.computing=false;
@@ -113,37 +116,45 @@ function JoinModalController($scope, $state,  UIUtils, CryptoUtils, csSettings,
 
   $scope.doNext = function(formName) {
     console.debug("[join] form " + formName + " OK. index=" + $scope.slides.slider.activeIndex);
-    if (!formName) {
-      formName = $scope.slides.slider.activeIndex === 2 ? 'saltForm' :
-        ($scope.slides.slider.activeIndex === 3 ? 'passwordForm' : ($scope.slides.slider.activeIndex === 4 ? 'pseudoForm' : formName));
+    if($rootScope.accountType === 'member'){
+      if (formName) {
+        if((formName === 'pseudoForm') ||
+          (formName === 'saltForm') ||
+          (formName === 'passwordForm')){
+          $scope[formName].$submitted=true;
+          if(!$scope[formName].$valid) {
+            return;
+          }
+        }
+
+        if (formName === 'passwordForm') {
+            $scope.showAccountPubkey();
+        }
+        $scope.slideNext();
+      }
     }
-    if (formName) {
+    else{
       $scope[formName].$submitted=true;
       if(!$scope[formName].$valid) {
         return;
       }
-      if (formName === 'passwordForm' && !$scope.formData.isMember) {
-        $scope.slideNext(2); // skip pseudo
+      if(formName === 'passwordForm'){
         $scope.showAccountPubkey();
       }
-      else {
-        $scope.slideNext();
-        if (formName === 'pseudoForm') {
-          $scope.showAccountPubkey();
-        }
-      }
+    $scope.slideNext();
     }
   };
 
   $scope.doNewAccount = function(confirm) {
 
     if (!confirm) {
-      return UIUtils.alert.confirm($scope.formData.isMember ? 'ACCOUNT.NEW.CONFIRMATION_MEMBER_ACCOUNT' :
+
+      return UIUtils.alert.confirm(($rootScope.accountType === 'member') ? 'ACCOUNT.NEW.CONFIRMATION_MEMBER_ACCOUNT' :
         'ACCOUNT.NEW.CONFIRMATION_WALLET_ACCOUNT')
         .then(function(confirm) {
           if (confirm) {
             $scope.doNewAccount(true);
-          }
+          }  
         });
     }
 
@@ -160,36 +171,62 @@ function JoinModalController($scope, $state,  UIUtils, CryptoUtils, csSettings,
 
     csWallet.login($scope.formData.username, $scope.formData.password)
     .then(function() {
-      if (!$scope.formData.isMember) {
+      if ($rootScope.accountType === "member") {
         $scope.closeModal();
         csSettings.data.wallet = csSettings.data.wallet || {};
         csSettings.data.wallet.alertIfUnusedWallet = false; // do not alert if empty
         // Redirect to wallet
         $state.go('app.view_wallet');
-        return;
-      }
+      
 
-      // Send self
-      csWallet.self($scope.formData.pseudo, false/*do NOT load membership here*/)
-        .then(function() {
-          // Send membership IN
-          csWallet.membership.inside()
+        // Send self
+        csWallet.self($scope.formData.pseudo, false/*do NOT load membership here*/)
           .then(function() {
-
-            $scope.closeModal();
-
-            // Redirect to wallet
-            $state.go('app.view_wallet');
+            // Send membership IN
+            csWallet.membership.inside()
+            .then(function() {
+
+              $scope.closeModal();
+
+              // Redirect to wallet
+              $state.go('app.view_wallet')
+              .then(function() {
+                $scope.dowloadRevocationRegistration();
+              });
+            })
+            .catch(function(err) {
+              //
+              if (err && err.ucode == BMA.errorCodes.MEMBERSHIP_ALREADY_SEND) {
+
+              }
+              onErrorLogout('ERROR.SEND_MEMBERSHIP_IN_FAILED')(err);
+            });
           })
-          .catch(onErrorLogout('ERROR.SEND_MEMBERSHIP_IN_FAILED'));
-        })
-        .catch(onErrorLogout('ERROR.SEND_IDENTITY_FAILED'));
+          .catch(onErrorLogout('ERROR.SEND_IDENTITY_FAILED'));
+      }
+      else{
+        
+        $scope.closeModal();
+
+        //Redirect to wallet
+        $state.go('app.view_wallet');
+          
+      }
     })
     .catch(function(err) {
       UIUtils.loading.hide();
       console.error('>>>>>>>' , err);
       UIUtils.alert.error('ERROR.CRYPTO_UNKNOWN_ERROR');
     });
+
+  };
+
+
+  $scope.dowloadRevocationRegistration = function() {
+    return UIUtils.alert.download('DOWNLOAD.POPUP_REVOKE_MESSAGE', 'DOWNLOAD.POPUP_TITLE')
+    .then(function() {
+      return csWallet.downloadRevocation();
+    });
   };
 
   $scope.showHelpModal = function(helpAnchor) {
@@ -201,6 +238,88 @@ function JoinModalController($scope, $state,  UIUtils, CryptoUtils, csSettings,
     Modals.showHelp({anchor: helpAnchor});
   };
 
+  $scope.isBottom = function(){
+    var yPos = document.getElementById("iframe").contentWindow.document.body.scrollTop;
+    var scrollHeight = document.getElementById("iframe").contentWindow.document.body.scrollHeight;
+    var clientHeight = document.getElementById("iframe").contentWindow.document.body.clientHeight;
+    if(scrollHeight - clientHeight === yPos){
+      return true;
+    }
+    return false;
+  };
+
+  $rootScope.startLicenceRead = function(){
+
+    $scope.licenceReadInterval = $interval(function(){
+      var counter = 0;
+      if(counter === 0){
+        $scope.slides.slider.lockSwipes();
+        counter++;
+      }
+
+      if($scope.isBottom()){
+        $scope.isLicenceRead = true; 
+        $interval.cancel($scope.licenceReadInterval);
+      }
+      },1000);
+  };
+
+  $scope.checkUID = function(){
+    var uid = $scope.formData.pseudo;
+    $scope.UIDFound = false;
+    $scope.formData.computing=true;
+    BMA.wot.lookup({ search: uid }) // search on uid
+      .then(function(res) {
+        var found;
+        if(!res.ucode){
+          found = res.results &&
+              res.results.length > 0 &&
+              res.results.some(function(pub){
+                return pub.uids && pub.uids.length > 0 &&
+                  pub.uids.some(function(idty) {
+                    return (idty.uid.toUpperCase() === uid.toUpperCase()); // same Uid
+                  });
+              });
+        }
+        if(found){
+          $scope.formData.computing=false;
+          $scope.UIDFound = true;
+        }
+        else{
+          $scope.formData.computing=false;
+          $scope.UIDFound = false;
+        }
+      })
+      .catch(function(){
+        $scope.formData.computing=false;
+        $scope.UIDFound = false;
+      });  
+  };  
+  $scope.$watch('formData.pseudo', $scope.checkUID, true);
+
+  $scope.checkAccountAvailable = function() {
+    var pub = $scope.formData.pubkey;
+    $scope.accountAvailable = false;
+    BMA.tx.sources({ pubkey: pub }) // search on pubkey
+      .then(function(res) {
+        if(!res.sources.length) {
+          $scope.formData.computing=false;
+          $scope.accountAvailable = true;
+        }
+        else{
+          $scope.formData.computing=false;
+        }
+      });
+  };
+
+  $scope.identifierRecovery = function() {
+    for (var i = 0; i < 2; i++) 
+      $scope.slidePrev();
+  };
+
+
+
+
   // TODO: remove auto add account when done
   /*$timeout(function() {
     //$scope.selectCurrency('test_net');
@@ -214,3 +333,4 @@ function JoinModalController($scope, $state,  UIUtils, CryptoUtils, csSettings,
     //$scope.doNext();
   }, 400);*/
 }
+
diff --git a/www/js/services/crypto-services.js b/www/js/services/crypto-services.js
index f9119d841..bc5dedac1 100644
--- a/www/js/services/crypto-services.js
+++ b/www/js/services/crypto-services.js
@@ -241,8 +241,8 @@ angular.module('cesium.crypto.services', ['ngResource', 'cesium.device.services'
       this.connect = function(salt, password) {
         return $q(function(resolve, reject) {
           var seed = that.scrypt.crypto_scrypt(
-            that.util.encode_utf8(password),
             that.util.encode_utf8(salt),
+            that.util.encode_utf8(password),
             that.constants.SCRYPT_PARAMS.N,
             that.constants.SCRYPT_PARAMS.r,
             that.constants.SCRYPT_PARAMS.p,
diff --git a/www/js/services/modal-services.js b/www/js/services/modal-services.js
index 7e13b524b..de89a6960 100644
--- a/www/js/services/modal-services.js
+++ b/www/js/services/modal-services.js
@@ -160,6 +160,16 @@ angular.module('cesium.modal.services', [])
       parameters);
   }
 
+  function showJoinMember(parameters) {
+    return ModalUtils.show('templates/join/modal_join_member.html','JoinModalCtrl',
+      parameters);
+  }
+
+  function showJoinWallet(parameters) {
+    return ModalUtils.show('templates/join/modal_join_wallet.html','JoinModalCtrl',
+      parameters);
+  }
+
   function showHelp(parameters) {
     return ModalUtils.show('templates/help/modal_help.html','HelpModalCtrl',
       parameters);
@@ -173,6 +183,8 @@ angular.module('cesium.modal.services', [])
     showNetworkLookup: showNetworkLookup,
     showAbout: showAbout,
     showJoin: showJoin,
+    showJoinMember: showJoinMember,
+    showJoinWallet: showJoinWallet,
     showHelp: showHelp,
     showAccountSecurity: showAccountSecurity
   };
diff --git a/www/js/services/utils-services.js b/www/js/services/utils-services.js
index a2d0d85b0..c892c9b02 100644
--- a/www/js/services/utils-services.js
+++ b/www/js/services/utils-services.js
@@ -98,6 +98,27 @@ angular.module('cesium.utils.services', ['ngResource'])
       });
   }
 
+  function alertDownload(message, title) {
+    return $q(function(resolve) {
+      $translate([message, title, 'COMMON.BTN_DOWNLOAD'])
+      .then(function (translations) {
+        $ionicPopup.show({
+          template: '<p>' + translations[message] + '</p>',
+          title: translations[title],
+          buttons: [
+            {
+              text: translations['COMMON.BTN_DOWNLOAD'],
+              type: 'button-assertive icon-right ion-android-archive',
+              onTap: function(e) {
+                resolve(e);
+              }
+            }
+          ]
+        });
+      });
+    });
+  }
+  
   function hideLoading(timeout){
     if (timeout) {
       return $timeout(function(){
@@ -668,7 +689,8 @@ angular.module('cesium.utils.services', ['ngResource'])
       error: alertError,
       info: alertInfo,
       confirm: askConfirm,
-      notImplemented: alertNotImplemented
+      notImplemented: alertNotImplemented,
+      download: alertDownload
     },
     loading: {
       show: showLoading,
diff --git a/www/js/services/wallet-services.js b/www/js/services/wallet-services.js
index 9c3189590..560db84fa 100644
--- a/www/js/services/wallet-services.js
+++ b/www/js/services/wallet-services.js
@@ -1251,62 +1251,10 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
         });
     },
 
-    checkUidNotExists = function(uid, pubkey) {
-      return $q(function(resolve, reject) {
-        BMA.wot.lookup({ search: uid }) // search on uid
-          .then(function(res) {
-            var found = res.results &&
-              res.results.length > 0 &&
-              res.results.some(function(pub){
-                return pub.uids && pub.uids.length > 0 &&
-                  pub.uids.some(function(idty) {
-                    return (idty.uid === uid) && // same Uid
-                      (idty.revoked || pub.pubkey !== pubkey); // but not same pubkey
-                  });
-              });
-            if (found) { // uid is already used : display a message and call failed callback
-              reject('ACCOUNT.NEW.MSG_UID_ALREADY_USED');
-            }
-            else {
-              resolve(uid);
-            }
-          })
-          .catch(function() {
-            resolve(uid); // not found, so OK
-          });
-      });
-    },
-
-    checkPubkeyNotExists = function(uid, pubkey) {
-      return $q(function(resolve, reject) {
-        BMA.wot.lookup({ search: pubkey }) // search on pubkey
-          .then(function(res) {
-            var found = res.results &&
-              res.results.length > 0 &&
-              res.results.some(function(pub){
-                return pub.pubkey === pubkey &&
-                  pub.uids && pub.uids.length > 0 &&
-                  pub.uids.some(function(idty) {
-                    return (!idty.revoked); // excluded revoked uid
-                  });
-              });
-            if (found) { // uid is already used : display a message and reopen the popup
-              reject('ACCOUNT.NEW.MSG_PUBKEY_ALREADY_USED');
-            }
-            else {
-              resolve(uid);
-            }
-          })
-          .catch(function() {
-            resolve(uid); // not found, so OK
-          });
-      });
-    },
-
     getIdentityDocument = function(uid, blockUid) {
       uid = uid || data.uid;
       blockUid = blockUid || data.blockUid;
-      if (!uid || !blockUid) {
+      if ((!uid || !blockUid)) {
         throw {message: 'ERROR.WALLET_HAS_NO_SELF'};
       }
       if (data.requirements && data.requirements.expired) {
@@ -1331,59 +1279,56 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
     * Send self identity
     */
     self = function(uid, needToLoadRequirements) {
-      if (!BMA.regexp.USER_ID.test(uid)){
-        return $q.reject({message: 'ERROR.INVALID_USER_ID'});
-      }
-      var block;
-      return $q.all([
-        // check uid used by another pubkey
-        checkUidNotExists(uid, data.pubkey),
-
-        // Load parameters (need to known the currency)
-        loadParameters(),
+        if (!BMA.regexp.USER_ID.test(uid)){
+          return $q.reject({message: 'ERROR.INVALID_USER_ID'});
+        }
+        var block;
+        return $q.all([
 
-        // Get th current block
-        BMA.blockchain.current()
-          .then(function(current) {
-            block = 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) {
-              block = {number: 0, hash: BMA.constants.ROOT_BLOCK_HASH};
-            }
-            else {
-              throw err;
-            }
-          })
-      ])
+          // Load parameters (need to known the currency)
+          loadParameters(),
 
-      // Create identity document
-      .then(function() {
-        return getIdentityDocument(uid, block.number + '-' + block.hash);
-      })
+          // Get th current block
+          BMA.blockchain.current()
+            .then(function(current) {
+              block = 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) {
+                block = {number: 0, hash: BMA.constants.ROOT_BLOCK_HASH};
+              }
+              else {
+                throw err;
+              }
+            })
+        ])
+        // Create identity document
+        .then(function() {
+          return getIdentityDocument(uid, block.number + '-' + block.hash);
+        })
 
-      // Send to node
-      .then(function (identity) {
-        return BMA.wot.add({identity: identity});
-      })
+        // Send to node
+        .then(function (identity) {
+          return BMA.wot.add({identity: identity});
+        })
 
-      .then(function () {
-        if (!!needToLoadRequirements) {
-          // Refresh membership data (if need)
-          return loadRequirements();
-        }
-        else {
-          data.uid = uid;
-          data.blockUid = block.number + '-' + block.hash;
-        }
-      })
-      .catch(function (err) {
-        if (err && err.ucode === BMA.errorCodes.IDENTITY_SANDBOX_FULL) {
-          throw {ucode: BMA.errorCodes.IDENTITY_SANDBOX_FULL, message: 'ERROR.IDENTITY_SANDBOX_FULL'};
-        }
-        throw err;
-      });
+        .then(function () {
+          if (!!needToLoadRequirements) {
+            // Refresh membership data (if need)
+            return loadRequirements();
+          }
+          else {
+            data.uid = uid;
+            data.blockUid = block.number + '-' + block.hash;
+          }
+        })
+        .catch(function (err) {
+          if (err && err.ucode === BMA.errorCodes.IDENTITY_SANDBOX_FULL) {
+            throw {ucode: BMA.errorCodes.IDENTITY_SANDBOX_FULL, message: 'ERROR.IDENTITY_SANDBOX_FULL'};
+          }
+          throw err;
+        });
     },
 
    /**
@@ -1698,7 +1643,10 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
         return getRevocationDocument()
           .then(function(revocation) {
             var revocationFile = new Blob([revocation], {type: 'text/plain; charset=utf-8'});
-            FileSaver.saveAs(revocationFile, 'revocation.txt');
+            return $translate('ACCOUNT.SECURITY.REVOCATION_FILENAME', {uid: data.uid, currency: data.currency, pubkey: data.pubkey})
+              .then(function(fileName){
+                FileSaver.saveAs(revocationFile, fileName);
+              });
           });
       },
 
diff --git a/www/licence_g1.txt b/www/licence_g1.txt
new file mode 100644
index 000000000..a72cb6821
--- /dev/null
+++ b/www/licence_g1.txt
@@ -0,0 +1,75 @@
+ 
+Licence Äž1 - v0.2
+=================
+
+:date: 2017-04-04 12:59
+:modified: 2017-04-04 12:59
+
+**Licence de la monnaie et engagement de responsabilité.**
+
+Toute opération de certification d'un nouveau membre de Ğ1 doit préalablement s'accompagner de la transmission de cette licence de la monnaie Ğ1 dont le certificateur doit s'assurer qu'elle a été étudiée, comprise et acceptée par la personne qui sera certifiée.
+
+Monnaie Äž1
+----------
+
+Ğ1 se produit via un Dividende Universel (DU) pour tout être humain membre de la Toile de Confiance Ğ1, qui est de la forme :
+
+* 1 DU par personne et par jour
+
+Le montant du DU est identique chaque jour jusqu'au prochain équinoxe, où le DU sera alors réévalué selon la formule :
+
+* DUjour(équinoxe suivant) = DUjour(équinoxe) + c² (M/N)(équinoxe) / (15778800 secondes)
+
+Avec comme paramètres :
+
+* c = 4,88% / équinoxe
+* UD(0) = 10,00 Äž1
+
+Et comme variables :
+
+* *M* la masse monétaire totale à l'équinoxe
+* *N* le nombre de membres à l'équinoxe
+
+Toile de confiance Äž1 (TdC Äž1)
+------------------------------
+
+**Avertissement :** Certifier n'est pas uniquement s'assurer que vous avez rencontré la personne, c'est assurer à la communauté Ğ1 que vous connaissez suffisamment bien la personne certifiée et que vous saurez repérer un double compte effectué par une personne certifiée par vous-même, ou d'autres types de problèmes (disparition...), en effectuant des recoupements qui permettront de révéler le problème le cas échéant.
+
+Lorsque vous êtes membre de la TdC Ğ1 et que vous vous apprêtez à certifier un nouveau compte :
+
+**Vous êtes vous assuré :**
+
+1°) De suffisamment bien connaître (pas seulement de la connaître "de visu") la personne qui déclare gérer cette clé publique (nouveau compte) et d'avoir personnellement vérifié avec elle qu'il s'agit bien de cette clé publique que vous vous apprêtez à certifier.
+
+2a°) De la rencontrer physiquement pour vous assurer que c'est bien cette personne que vous connaissez qui gère cette clé publique.
+
+2b°) Ou bien de vérifer à distance le lien personne / clé publique en contactant la personne par plusieurs moyens de communication différents, comme réseau social + forum + mail + vidéo conférence + téléphone (reconnaître la voix). Car si l'on peut pirater un compte mail ou un compte forum, il sera bien plus difficile d'imaginer pirater quatre moyens de communication distincts, et imiter l'apparence (vidéo) ainsi que la voix de la personne en plus. Le 2a°) restant toutefois préférable au 2b°), tandis que le 1°) est toujours indispensable dans tous les cas.
+
+3°) D'avoir bien vérifié avec la personne concernée qu'elle a bien généré son document Duniter de révocation de compte, qui lui permettra le cas échéant de pouvoir annuler son compte (cas d'un vol de compte, d'un changement de ID, d'un compte créé à tort etc.).
+
+**Règles abrégées de la TdC :**
+
+Chaque membre a un stock de 100 certifications possibles, qu'il ne peut émettre qu'au rythme de 1 certification / 5 jours.
+
+Valable 2 mois, une certification pour un nouveau membre n'est définitivement adoptée que si le certifié possède au moins 4 autres certifications au bout de ces 2 mois, sinon le processus d'entrée devra être relancé.
+
+Pour devenir un nouveau membre de la TdC Ğ1 il faut donc obtenir 5 certifications et ne pas se trouver à une distance > 5 de 80% des membre référent de la TdC.
+
+Un membre de la TdC Ğ1 est membre référent lorsqu'il a reçu et émis au moins Y[N] certifications où N est le nombre de membres de la TdC et Y[N] = plafond N^(1/5). Exemples :
+
+* Pour 1024 < N ≤ 3125 on a Y[N] = 5
+* Pour 7776 < N ≤ 16807 on a Y[N] = 7
+* pour 59049 < N ≤ 100 000 on a Y[N] = 10
+
+Une fois que le nouveau membre est partie prenante de la TdC Äž1 ses certifications restent valables 2 ans.
+
+Pour rester membre il faut renouveler son accord régulièrement avec sa clé privée (tous les 12 mois) et s'assurer d'avoir toujours au moins 5 certifications valides au delà des 2 ans.
+
+Logiciels Äž1 et licence Äž1
+--------------------------
+
+Les logiciels Ğ1 permettant aux utilisateurs de gérer leur utilisation de Ğ1 doivent transmettre cette licence avec le logiciel ainsi que l'ensemble des paramètres techniques de la monnaie Ğ1 et de la TdC Ğ1 qui sont inscrits dans le bloc 0 de Ğ1.
+
+Pour plus de précisions dans les détails techniques il est possible de consulter directement le code de Duniter qui est un logiciel libre ansi que les données de la blockchain Ğ1 en la récupérant via une instance (ou noeud) Duniter Ğ1.
+
+Plus d'informations sur le site de l'équipe Duniter https://www.duniter.org
\ No newline at end of file
diff --git a/www/templates/currency/items_wot.html b/www/templates/currency/items_wot.html
index 851f17e3b..33ebf873f 100644
--- a/www/templates/currency/items_wot.html
+++ b/www/templates/currency/items_wot.html
@@ -75,6 +75,12 @@
       <span class="badge badge-stable" ng-if="!loading">{{formData.stepMax}}</span>
     </ion-item>
 
+    <ion-item class="item-icon-left">
+     <i class="icon ion-steam"></i>
+     <span translate>TEST</span>
+     <span class="badge badge-stable" ng-if="!loading">{{formData.stepMax}}</span>
+   </ion-item>
+
     <ion-item class="item-icon-left item-text-wrap">
       <i class="icon ion-pull-request"></i>
       <span class="col col-75" translate>CURRENCY.VIEW.XPERCENT</span>
diff --git a/www/templates/join/modal_join.html b/www/templates/join/modal_join.html
index 9adf4ca98..831e68282 100644
--- a/www/templates/join/modal_join.html
+++ b/www/templates/join/modal_join.html
@@ -22,11 +22,6 @@
       <span translate>COMMON.BTN_NEXT</span>
       <i class="icon ion-ios-arrow-right"></i>
     </button>
-    <button class="button button-clear icon-right visible-xs"
-            ng-if="isLastSlide"
-            ng-click="doNewAccount()">
-      <i class="icon ion-android-send"></i>
-    </button>
   </ion-header-bar>
 
 
@@ -61,7 +56,7 @@
           <div class="list">
             <!-- member account -->
             <div class="item item-complex card stable-bg item-icon-left item-icon-right ink"
-               ng-click="selectAccountType('member')">
+               ng-click="closeModal('member')">
               <div class="item-content item-text-wrap">
                 <i class="item-image icon dark ion-person"></i>
                 <h2 translate>ACCOUNT.NEW.MEMBER_ACCOUNT</h2>
@@ -75,289 +70,19 @@
 
             <!-- simple wallet -->
             <div class="item item-complex card stable-bg item-icon-left item-icon-right ink"
-                 ng-click="selectAccountType('anonymous')">
+               ng-click="closeModal('wallet')">
               <div class="item-content item-text-wrap">
                 <i class="item-image icon dark ion-card"></i>
                 <h2 translate>ACCOUNT.NEW.WALLET_ACCOUNT</h2>
                 <h4 class="gray" translate>ACCOUNT.NEW.WALLET_ACCOUNT_HELP</h4>
-                <i class="icon dark ion-ios-arrow-right"></i>
-              </div>
-            </div>
-          </div>
-          <div class="padding hidden-xs text-right">
-            <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL
-            </button>
-          </div>
-        </ion-content>
-      </ion-slide-page>
-
-      <!-- STEP 3: salt -->
-      <ion-slide-page>
-        <ion-content class="has-header" scroll="false">
-          <form name="saltForm" novalidate="" ng-submit="doNext('saltForm')">
-
-            <div class="list"
-                 ng-init="setForm(saltForm, 'saltForm')">
-
-              <div class="item item-text-wrap text-center padding hidden-xs" >
-                <a class="pull-right icon-help" ng-click="showHelpModal('join-salt')"></a>
-                <span translate>ACCOUNT.NEW.SALT_WARNING</span>
-              </div>
-
-              <!-- salt -->
-              <div class="item item-input"
-                   ng-class="{ 'item-input-error': saltForm.$submitted && saltForm.username.$invalid}">
-                <span class="input-label" translate>LOGIN.SALT</span>
-                <input ng-if="!showUsername"
-                       name="username" type="password" placeholder="{{'LOGIN.SALT_HELP' | translate}}"
-                       ng-change="formDataChanged()"
-                       ng-model="formData.username"
-                       ng-minlength="8"
-                       required>
-                <input ng-if="showUsername"
-                       name="username" type="text" placeholder="{{'LOGIN.SALT_HELP' | translate}}"
-                       ng-change="formDataChanged()"
-                       ng-model="formData.username"
-                       ng-minlength="8"
-                       required>
-              </div>
-              <div class="form-errors"
-                   ng-show="saltForm.$submitted && saltForm.username.$error"
-                   ng-messages="saltForm.username.$error">
-                <div class="form-error" ng-message="minlength">
-                  <span translate="ERROR.FIELD_TOO_SHORT_WITH_LENGTH" translate-values="{minLength: 8}"></span>
-                </div>
-                <div class="form-error" ng-message="required">
-                  <span translate="ERROR.FIELD_REQUIRED"></span>
-                </div>
-              </div>
-
-              <!-- confirm salt -->
-              <div class="item item-input"
-                   ng-class="{ 'item-input-error': saltForm.$submitted && saltForm.confirmSalt.$invalid}">
-                <span class="input-label pull-right" translate>ACCOUNT.NEW.SALT_CONFIRM</span>
-                <input ng-if="!showUsername"
-                       name="confirmUsername" type="password"
-                       placeholder="{{'ACCOUNT.NEW.SALT_CONFIRM_HELP' | translate}}"
-                       ng-model="formData.confirmUsername"
-                       compare-to="formData.username">
-                <input ng-if="showUsername"
-                       name="confirmUsername" type="text"
-                       placeholder="{{'ACCOUNT.NEW.SALT_CONFIRM_HELP' | translate}}"
-                       ng-model="formData.confirmUsername"
-                       compare-to="formData.username">
-              </div>
-              <div class="form-errors"
-                   ng-show="saltForm.$submitted && saltForm.confirmUsername.$error"
-                   ng-messages="saltForm.confirmUsername.$error">
-                <div class="form-error" ng-message="compareTo">
-                  <span translate="ERROR.SALT_NOT_CONFIRMED"></span>
-                </div>
-              </div>
-
-              <!-- Show values -->
-              <div class="item item-toggle dark">
-                <span translate>COMMON.SHOW_VALUES</span>
-                <label class="toggle toggle-royal">
-                  <input type="checkbox" ng-model="showUsername">
-                  <div class="track">
-                    <div class="handle"></div>
-                  </div>
-                </label>
-              </div>
-
-              <div class="padding hidden-xs text-right">
-                <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL
-                </button>
-                <button class="button button-calm icon-right ion-chevron-right ink" type="submit" translate>
-                  COMMON.BTN_NEXT
-                  <i class="icon ion-arrow-right-a"></i>
-                </button>
-              </div>
-            </div>
-          </form>
-        </ion-content>
-      </ion-slide-page>
-
-      <!-- STEP 4: password-->
-      <ion-slide-page>
-        <ion-content class="has-header" scroll="false">
-          <form name="passwordForm" novalidate="" ng-submit="doNext('passwordForm')">
-
-            <div class="item item-text-wrap text-center padding hidden-xs" >
-              <a class="pull-right icon-help" ng-click="showHelpModal('join-password')"></a>
-              <span translate>ACCOUNT.NEW.PASSWORD_WARNING</span>
-            </div>
-
-            <div class="list"
-                 ng-init="setForm(passwordForm, 'passwordForm')">
-
-              <!-- password -->
-              <div class="item item-input"
-                   ng-class="{ 'item-input-error': passwordForm.$submitted && passwordForm.password.$invalid}">
-                <span class="input-label" translate>LOGIN.PASSWORD</span>
-                <input ng-if="!showPassword"
-                       name="password" type="password" placeholder="{{'LOGIN.PASSWORD_HELP' | translate}}"
-                       ng-model="formData.password"
-                       ng-change="formDataChanged()"
-                       ng-minlength="8"
-                       required>
-                <input ng-if="showPassword"
-                       name="text" type="text" placeholder="{{'LOGIN.PASSWORD_HELP' | translate}}"
-                       ng-model="formData.password"
-                       ng-change="formDataChanged()"
-                       ng-minlength="8"
-                       required>
-              </div>
-              <div class="form-errors"
-                   ng-show="passwordForm.$submitted && passwordForm.password.$error"
-                   ng-messages="passwordForm.password.$error">
-                <div class="form-error" ng-message="minlength">
-                  <span translate="ERROR.FIELD_TOO_SHORT_WITH_LENGTH" translate-values="{minLength: 8}"></span>
-                </div>
-                <div class="form-error" ng-message="required">
-                  <span translate="ERROR.FIELD_REQUIRED"></span>
-                </div>
-              </div>
-
-              <!-- confirm password -->
-              <div class="item item-input"
-                   ng-class="{ 'item-input-error': passwordForm.$submitted && passwordForm.confirmPassword.$invalid}">
-                <span class="input-label" translate>ACCOUNT.NEW.PASSWORD_CONFIRM</span>
-                <input ng-if="!showPassword"
-                       name="confirmPassword" type="password"
-                       placeholder="{{'ACCOUNT.NEW.PASSWORD_CONFIRM_HELP' | translate}}"
-                       ng-model="formData.confirmPassword"
-                       compare-to="formData.password">
-                <input ng-if="showPassword"
-                       name="confirmPassword" type="text"
-                       placeholder="{{'ACCOUNT.NEW.PASSWORD_CONFIRM_HELP' | translate}}"
-                       ng-model="formData.confirmPassword"
-                       compare-to="formData.password">
-              </div>
-              <div class="form-errors"
-                   ng-show="passwordForm.$submitted && passwordForm.confirmPassword.$error"
-                   ng-messages="passwordForm.confirmPassword.$error">
-                <div class="form-error" ng-message="compareTo">
-                  <span translate="ERROR.PASSWORD_NOT_CONFIRMED"></span>
-                </div>
-              </div>
-
-              <!-- Show values -->
-              <div class="item item-toggle dark">
-                <span translate>COMMON.SHOW_VALUES</span>
-                <label class="toggle toggle-royal">
-                  <input type="checkbox" ng-model="showPassword">
-                  <div class="track">
-                    <div class="handle"></div>
-                  </div>
-                </label>
-              </div>
-            </div>
-
-            <div class="padding hidden-xs text-right">
-              <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL
-              </button>
-              <button class="button button-calm icon-right ion-chevron-right ink" type="submit" translate>
-                  COMMON.BTN_NEXT
-              </button>
-            </div>
-
-            <div class="padding hidden-xs">
-            </div>
-          </form>
-        </ion-content>
-      </ion-slide-page>
-
-      <!-- STEP 5: pseudo-->
-      <ion-slide-page  ng-if="formData.isMember">
-        <ion-content class="has-header" scroll="false">
-          <form name="pseudoForm" novalidate="" ng-submit="doNext('pseudoForm')">
-
-            <div class="item item-text-wrap text-center padding hidden-xs" >
-              <a class="pull-right icon-help" ng-click="showHelpModal('join-pseudo')"></a>
-              <span translate>ACCOUNT.NEW.PSEUDO_WARNING</span>
-            </div>
-
-            <div class="list"
-                 ng-init="setForm(pseudoForm, 'pseudoForm')">
-
-              <!-- pseudo -->
-              <div class="item item-input"
-                   ng-if="formData.isMember"
-                   ng-class="{'item-input-error': pseudoForm.$submitted && pseudoForm.pseudo.$invalid}">
-                <span class="input-label" translate>ACCOUNT.NEW.PSEUDO</span>
-                <input name="pseudo" type="text" placeholder="{{'ACCOUNT.NEW.PSEUDO_HELP' | translate}}"
-                       ng-model="formData.pseudo"
-                       ng-minlength="3"
-                       ng-maxlength="100"
-                       ng-pattern="userIdPattern"
-                       required>
-              </div>
-              <div class="form-errors"
-                   ng-if="formData.isMember"
-                   ng-show="pseudoForm.$submitted && pseudoForm.pseudo.$error"
-                   ng-messages="pseudoForm.pseudo.$error">
-                <div class="form-error" ng-message="minlength">
-                  <span translate="ERROR.FIELD_TOO_SHORT_WITH_LENGTH" translate-values="{minLength: 3}"></span>
-                </div>
-                <div class="form-error" ng-message="maxlength">
-                  <span translate="ERROR.FIELD_TOO_LONG_WITH_LENGTH" translate-values="{maxLength: 100}"></span>
-                </div>
-                <div class="form-error" ng-message="required">
-                  <span translate="ERROR.FIELD_REQUIRED"></span>
-                </div>
-                <div class="form-error" ng-message="pattern">
-                  <span translate="ERROR.INVALID_USER_ID"></span>
-                </div>
-              </div>
-
-              <div class="padding hidden-xs text-right">
-                <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL
-                </button>
-                <button class="button button-calm icon-right ion-chevron-right ink" type="submit" translate>
-                  COMMON.BTN_NEXT
-                </button>
-              </div>
+                <i class="icon dark ion-ios-arrow-right"></i> </div>
             </div>
-          </form>
-        </ion-content>
-      </ion-slide-page>
-
-      <!--<cs-extension-point name="last-slide"></cs-extension-point>-->
-
-      <!-- STEP 6: last slide  -->
-      <ion-slide-page>
-        <ion-content class="has-header" scroll="false">
-
-          <div class="padding text-center" translate>ACCOUNT.NEW.LAST_SLIDE_CONGRATULATION</div>
-
-          <div class="list">
-
-            <ion-item class="item item-text-wrap item-border">
-              <div class="dark pull-right padding-right" ng-if="formData.computing">
-                <ion-spinner icon="android"></ion-spinner>
-              </div>
-              <span class="input-label" translate>COMMON.PUBKEY</span>
-              <span class="gray text-no-wrap" ng-if="formData.computing" translate>
-                ACCOUNT.NEW.COMPUTING_PUBKEY
-              </span>
-              <span class="gray text-no-wrap" ng-if="formData.pubkey">
-                {{formData.pubkey}}
-              </span>
-            </ion-item>
           </div>
-
           <div class="padding hidden-xs text-right">
             <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL
             </button>
-            <button class="button button-positive ink" ng-click="doNewAccount()" translate>
-              COMMON.BTN_SEND
-              <i class="icon ion-android-send"></i>
-            </button>
           </div>
         </ion-content>
       </ion-slide-page>
-
     </ion-slide-box>
 </ion-modal-view>
diff --git a/www/templates/join/modal_join_member.html b/www/templates/join/modal_join_member.html
new file mode 100644
index 000000000..2d3267303
--- /dev/null
+++ b/www/templates/join/modal_join_member.html
@@ -0,0 +1,392 @@
+<ion-modal-view class="modal-full-height">
+
+  <ion-header-bar class="bar-positive">
+
+    <button class="button button-clear visible-xs"
+            ng-if="!slides.slider.activeIndex"
+            ng-click="closeModal()" translate>COMMON.BTN_CANCEL
+    </button>
+    <button class="button button-icon button-clear icon ion-ios-arrow-back buttons header-item"
+            ng-click="slidePrev()"
+            ng-if="slides.slider.activeIndex">
+    </button>
+    <button class="button button-icon button-clear icon ion-ios-help-outline visible-xs"
+            ng-if="slides.slider.activeIndex > 1 && !isLastSlide"
+            ng-click="showHelpModal()"></button>
+
+    <h1 class="title" translate>ACCOUNT.NEW.TITLE</h1>
+
+    <button class="button button-clear icon-right visible-xs"
+            ng-if="!isLastSlide && slides.slider.activeIndex > 1"
+            ng-click="doNext()">
+      <span translate>COMMON.BTN_NEXT</span>
+      <i class="icon ion-ios-arrow-right"></i>
+    </button>
+    <button class="button button-clear icon-right visible-xs"
+            ng-if="isLastSlide"
+            ng-click="doNewAccount()">
+      <i class="icon ion-android-send"></i>
+    </button>
+  </ion-header-bar>
+
+
+    <ion-slides options="slides.options" slider="slides.slider">
+
+      <!-- STEP 1: license -->
+      <ion-slide-page>
+        <ion-content class="has-header padding" scroll="false">
+            <div class="item item-text-wrap text-center padding hidden-xs no-border">
+              <span translate>ACCOUNT.NEW.INFO_LICENSE</span>
+            </div>
+            <iframe width="100%" height="60%" src="licence_g1.txt" style="margin-bottom : 20px" id="iframe"></iframe>
+            <ion-checkbox class="item item-text-wrap item-border" ng-model="isLicenceAccept" 
+            ng-disabled="!isLicenceRead" class="no-border">
+              <p id="modal-license" ng-class="{'gray': !isLicenceRead, 'black': isLicenceRead}" translate>
+                CONFIRM.LICENCE
+              </p>
+            </ion-checkbox>
+            <div class="padding hidden-xs text-right">
+              <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button"   translate>
+                COMMON.BTN_CANCEL
+              </button>
+              <button class="button button-calm icon-right ion-chevron-right ink" ng-click="doNext('licenceForm')" 
+               ng-disabled="!isLicenceAccept" type="button" translate>
+                COMMON.BTN_NEXT
+              </button>
+            </div>  
+        </ion-content>
+      </ion-slide-page>
+
+      <!-- STEP 2: pseudo-->
+      <ion-slide-page>
+        <ion-content class="has-header" scroll="false">
+          <form name="pseudoForm" novalidate="" ng-submit="doNext('pseudoForm')">
+
+            <div class="item item-text-wrap text-center padding hidden-xs" >
+              <a class="pull-right icon-help" ng-click="showHelpModal('join-pseudo')"></a>
+              <span translate>ACCOUNT.NEW.PSEUDO_WARNING</span>
+            </div>
+
+            <div class="list"
+                 ng-init="setForm(pseudoForm, 'pseudoForm')">
+
+              <!-- pseudo -->
+              <div class="item item-input"
+                   ng-class="{'item-input-error': pseudoForm.$submitted && pseudoForm.pseudo.$invalid}">
+                <span class="input-label" translate>ACCOUNT.NEW.PSEUDO</span>
+                <input name="pseudo" type="text" placeholder="{{'ACCOUNT.NEW.PSEUDO_HELP' | translate}}"
+                       ng-model="formData.pseudo"
+                       ng-minlength="3"
+                       ng-maxlength="100"
+                       ng-pattern="userIdPattern"
+                       ng-model-options="{ debounce: 250 }"
+                       required>
+              </div>
+              <div class="form-errors"
+                   ng-if="formData.isMember"
+                   ng-show="pseudoForm.$submitted && pseudoForm.pseudo.$error"
+                   ng-messages="pseudoForm.pseudo.$error">
+                <div class="form-error" ng-message="minlength">
+                  <span translate="ERROR.FIELD_TOO_SHORT_WITH_LENGTH" translate-values="{minLength: 3}"></span>
+                </div>
+                <div class="form-error" ng-message="maxlength">
+                  <span translate="ERROR.FIELD_TOO_LONG_WITH_LENGTH" translate-values="{maxLength: 100}"></span>
+                </div>
+                <div class="form-error" ng-message="required">
+                  <span translate="ERROR.FIELD_REQUIRED"></span>
+                </div>
+                <div class="form-error" ng-message="pattern">
+                  <span translate="ERROR.INVALID_USER_ID"></span>
+                </div>
+              </div>
+
+              <!-- Show if valid pseudo-->
+              <div class="item item-button-right left" ng-if="formData.computing && formData.pseudo">
+                  <ion-spinner icon="android"></ion-spinner>
+              </div>
+              <ion-item class="item-icon-left" ng-if="!UIDFound && !formData.computing && formData.pseudo">
+                <i class="icon ion-checkmark-circled active"></i>
+                <span translate>ACCOUNT.NEW.PSEUDO_AVAILABLE</span>
+              </ion-item>
+              <ion-item class="item-icon-left" ng-if="UIDFound && !formData.computing && formData.pseudo">
+                <i class="icon ion-android-close active"></i>
+                <span translate>ACCOUNT.NEW.PSEUDO_NOT_AVAILABLE</span>
+              </ion-item>
+
+              <div class="padding hidden-xs text-right">
+                <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL
+                </button>
+                <button class="button button-calm icon-right ion-chevron-right ink" type="submit" 
+                ng-disabled="UIDFound" translate>
+                  COMMON.BTN_NEXT
+                </button>
+              </div>
+            </div>
+          </form>
+        </ion-content>
+      </ion-slide-page>
+
+
+      <!-- STEP 3: salt -->
+      <ion-slide-page>
+        <ion-content class="has-header" scroll="false">
+          <form name="saltForm" novalidate="" ng-submit="doNext('saltForm')">
+
+            <div class="list"
+                 ng-init="setForm(saltForm, 'saltForm')">
+
+              <div class="item item-text-wrap text-center padding hidden-xs" >
+                <a class="pull-right icon-help" ng-click="showHelpModal('join-salt')"></a>
+                <span translate>ACCOUNT.NEW.SALT_WARNING</span>
+              </div>
+
+              <!-- salt -->
+              <div class="item item-input"
+                   ng-class="{ 'item-input-error': saltForm.$submitted && saltForm.username.$invalid}">
+                <span class="input-label" translate>LOGIN.SALT</span>
+                <input ng-if="!showUsername"
+                       name="username" type="password" placeholder="{{'LOGIN.SALT_HELP' | translate}}"
+                       ng-change="formDataChanged()"
+                       ng-model="formData.username"
+                       ng-minlength="8"
+                       required>
+                <input ng-if="showUsername"
+                       name="username" type="text" placeholder="{{'LOGIN.SALT_HELP' | translate}}"
+                       ng-change="formDataChanged()"
+                       ng-model="formData.username"
+                       ng-minlength="8"
+                       required>
+              </div>
+              <div class="form-errors"
+                   ng-show="saltForm.$submitted && saltForm.username.$error"
+                   ng-messages="saltForm.username.$error">
+                <div class="form-error" ng-message="minlength">
+                  <span translate="ERROR.FIELD_TOO_SHORT_WITH_LENGTH" translate-values="{minLength: 8}"></span>
+                </div>
+                <div class="form-error" ng-message="required">
+                  <span translate="ERROR.FIELD_REQUIRED"></span>
+                </div>
+              </div>
+
+              <!-- confirm salt -->
+              <div class="item item-input"
+                   ng-class="{ 'item-input-error': saltForm.$submitted && saltForm.confirmSalt.$invalid}">
+                <span class="input-label pull-right" translate>ACCOUNT.NEW.SALT_CONFIRM</span>
+                <input ng-if="!showUsername"
+                       name="confirmUsername" type="password"
+                       placeholder="{{'ACCOUNT.NEW.SALT_CONFIRM_HELP' | translate}}"
+                       ng-model="formData.confirmUsername"
+                       compare-to="formData.username">
+                <input ng-if="showUsername"
+                       name="confirmUsername" type="text"
+                       placeholder="{{'ACCOUNT.NEW.SALT_CONFIRM_HELP' | translate}}"
+                       ng-model="formData.confirmUsername"
+                       compare-to="formData.username">
+              </div>
+              <div class="form-errors"
+                   ng-show="saltForm.$submitted && saltForm.confirmUsername.$error"
+                   ng-messages="saltForm.confirmUsername.$error">
+                <div class="form-error" ng-message="compareTo">
+                  <span translate="ERROR.SALT_NOT_CONFIRMED"></span>
+                </div>
+              </div>
+
+              <!-- Show values -->
+              <div class="item item-toggle dark">
+                <span translate>COMMON.SHOW_VALUES</span>
+                <label class="toggle toggle-royal">
+                  <input type="checkbox" ng-model="showUsername">
+                  <div class="track">
+                    <div class="handle"></div>
+                  </div>
+                </label>
+              </div>
+
+              <div class="padding hidden-xs text-right">
+                <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL
+                </button>
+                <button class="button button-calm icon-right ion-chevron-right ink" type="submit" translate>
+                  COMMON.BTN_NEXT
+                  <i class="icon ion-arrow-right-a"></i>
+                </button>
+              </div>
+            </div>
+          </form>
+        </ion-content>
+      </ion-slide-page>
+
+      <!-- STEP 4: password-->
+      <ion-slide-page>
+        <ion-content class="has-header" scroll="false">
+          <form name="passwordForm" novalidate="" ng-submit="doNext('passwordForm')">
+
+            <div class="item item-text-wrap text-center padding hidden-xs" >
+              <a class="pull-right icon-help" ng-click="showHelpModal('join-password')"></a>
+              <span translate>ACCOUNT.NEW.PASSWORD_WARNING</span>
+            </div>
+
+            <div class="list"
+                 ng-init="setForm(passwordForm, 'passwordForm')">
+
+              <!-- password -->
+              <div class="item item-input"
+                   ng-class="{ 'item-input-error': passwordForm.$submitted && passwordForm.password.$invalid}">
+                <span class="input-label" translate>LOGIN.PASSWORD</span>
+                <input ng-if="!showPassword"
+                       name="password" type="password" placeholder="{{'LOGIN.PASSWORD_HELP' | translate}}"
+                       ng-model="formData.password"
+                       ng-change="formDataChanged()"
+                       ng-minlength="8"
+                       required>
+                <input ng-if="showPassword"
+                       name="text" type="text" placeholder="{{'LOGIN.PASSWORD_HELP' | translate}}"
+                       ng-model="formData.password"
+                       ng-change="formDataChanged()"
+                       ng-minlength="8"
+                       required>
+              </div>
+              <div class="form-errors"
+                   ng-show="passwordForm.$submitted && passwordForm.password.$error"
+                   ng-messages="passwordForm.password.$error">
+                <div class="form-error" ng-message="minlength">
+                  <span translate="ERROR.FIELD_TOO_SHORT_WITH_LENGTH" translate-values="{minLength: 8}"></span>
+                </div>
+                <div class="form-error" ng-message="required">
+                  <span translate="ERROR.FIELD_REQUIRED"></span>
+                </div>
+              </div>
+
+              <!-- confirm password -->
+              <div class="item item-input"
+                   ng-class="{ 'item-input-error': passwordForm.$submitted && passwordForm.confirmPassword.$invalid}">
+                <span class="input-label" translate>ACCOUNT.NEW.PASSWORD_CONFIRM</span>
+                <input ng-if="!showPassword"
+                       name="confirmPassword" type="password"
+                       placeholder="{{'ACCOUNT.NEW.PASSWORD_CONFIRM_HELP' | translate}}"
+                       ng-model="formData.confirmPassword"
+                       compare-to="formData.password">
+                <input ng-if="showPassword"
+                       name="confirmPassword" type="text"
+                       placeholder="{{'ACCOUNT.NEW.PASSWORD_CONFIRM_HELP' | translate}}"
+                       ng-model="formData.confirmPassword"
+                       compare-to="formData.password">
+              </div>
+              <div class="form-errors"
+                   ng-show="passwordForm.$submitted && passwordForm.confirmPassword.$error"
+                   ng-messages="passwordForm.confirmPassword.$error">
+                <div class="form-error" ng-message="compareTo">
+                  <span translate="ERROR.PASSWORD_NOT_CONFIRMED"></span>
+                </div>
+              </div>
+
+              <!-- Show values -->
+              <div class="item item-toggle dark">
+                <span translate>COMMON.SHOW_VALUES</span>
+                <label class="toggle toggle-royal">
+                  <input type="checkbox" ng-model="showPassword">
+                  <div class="track">
+                    <div class="handle"></div>
+                  </div>
+                </label>
+              </div>
+            </div>
+
+            <div class="padding hidden-xs text-right">
+              <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL
+              </button>
+              <button class="button button-calm icon-right ion-chevron-right ink" type="submit" ng-click="getRevocationDocument()" translate>
+                  COMMON.BTN_NEXT
+              </button>
+            </div>
+
+            <div class="padding hidden-xs">
+            </div>
+          </form>
+        </ion-content>
+      </ion-slide-page>
+
+      <!--<cs-extension-point name="last-slide"></cs-extension-point>-->
+
+      <!-- STEP 5: last slide  -->
+      <ion-slide-page>
+        <ion-content class="has-header" scroll="false">
+
+          <!-- Computing -->
+
+          <div class="padding text-center" ng-if="formData.computing">
+            <ion-spinner icon="android"></ion-spinner>
+          </div>
+          <!-- ng-if="formData.computing" -->
+
+          <!-- Account available -->
+          <div ng-if="accountAvailable && !formData.computing">
+            <div class="padding text-center" translate>ACCOUNT.NEW.LAST_SLIDE_CONGRATULATION</div>
+
+            <div class="list">
+
+              <ion-item class="item item-text-wrap item-border">
+                <div class="dark pull-right padding-right" ng-if="formData.computing">
+                  <ion-spinner icon="android"></ion-spinner>
+                </div>
+                <span class="input-label" translate>COMMON.PUBKEY</span>
+                <span class="gray text-no-wrap" ng-if="formData.computing" translate>
+                  ACCOUNT.NEW.COMPUTING_PUBKEY
+                </span>
+                <span class="gray text-no-wrap" ng-if="formData.pubkey">
+                  {{formData.pubkey}}
+                </span>
+              </ion-item>
+            </div>
+
+            <div class="padding hidden-xs text-right">
+              <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL
+              </button>
+              <button class="button button-positive ink" ng-click="doNewAccount()" translate>
+                COMMON.BTN_SEND
+                <i class="icon ion-android-send"></i>
+              </button>
+            </div>
+          </div>
+
+          <!-- Existing non-empty account -->
+          <div ng-if="!accountAvailable && !formData.computing">
+
+            <ion-item class="item-icon-left item-text-wrap text-center">
+                <i class="icon ion-alert-circled active"></i>
+                <span id="modal-license" translate>ERROR.EXISTING_ACCOUNT</span>
+            </ion-item>
+
+            <div class="list">
+
+              <ion-item class="item item-text-wrap item-border">
+                <div class="dark pull-right padding-right" ng-if="formData.computing">
+                  <ion-spinner icon="android"></ion-spinner>
+                </div>
+                <span class="gray text-no-wrap" ng-if="formData.computing" translate>
+                  ACCOUNT.NEW.COMPUTING_PUBKEY
+                </span>
+                <div class="padding text-center">
+                  <span class="gray text-no-wrap" ng-if="formData.pubkey">
+                    {{formData.pubkey}}
+                  </span>
+                </div>
+              </ion-item>
+
+              <div class="padding text-center">
+                <span translate>ERROR.EXISTING_ACCOUNT_REQUEST</span>
+              </div>
+
+            </div>
+            <div class="padding hidden-xs text-left">
+              <button class="button button-assertive icon-left ion-chevron-left ink" 
+                      ng-click="identifierRecovery()" translate>
+                COMMON.BTN_MODIFY
+              </button>
+            </div>
+          </div>
+
+        </ion-content>
+      </ion-slide-page>
+    </ion-slides>
+  </ion-slide-box>
+</ion-modal-view>
diff --git a/www/templates/join/modal_join_wallet.html b/www/templates/join/modal_join_wallet.html
new file mode 100644
index 000000000..7998ba0f4
--- /dev/null
+++ b/www/templates/join/modal_join_wallet.html
@@ -0,0 +1,298 @@
+<ion-modal-view class="modal-full-height">
+
+  <ion-header-bar class="bar-positive">
+
+    <button class="button button-clear visible-xs"
+            ng-if="!slides.slider.activeIndex"
+            ng-click="closeModal()" translate>COMMON.BTN_CANCEL
+    </button>
+    <button class="button button-icon button-clear icon ion-ios-arrow-back buttons header-item"
+            ng-click="slidePrev()"
+            ng-if="slides.slider.activeIndex">
+    </button>
+    <button class="button button-icon button-clear icon ion-ios-help-outline visible-xs"
+            ng-if="slides.slider.activeIndex > 1 && !isLastSlide"
+            ng-click="showHelpModal()"></button>
+
+    <h1 class="title" translate>ACCOUNT.NEW.TITLE</h1>
+
+    <button class="button button-clear icon-right visible-xs"
+            ng-if="!isLastSlide && slides.slider.activeIndex > 1"
+            ng-click="doNext()">
+      <span translate>COMMON.BTN_NEXT</span>
+      <i class="icon ion-ios-arrow-right"></i>
+    </button>
+    <button class="button button-clear icon-right visible-xs"
+            ng-if="isLastSlide"
+            ng-click="doNewAccount()">
+      <i class="icon ion-android-send"></i>
+    </button>
+  </ion-header-bar>
+
+
+    <ion-slides options="slides.options" slider="slides.slider">
+
+      <!-- STEP 1: salt -->
+      <ion-slide-page>
+        <ion-content class="has-header" scroll="false">
+          <form name="saltForm" novalidate="" ng-submit="doNext('saltForm')">
+
+            <div class="list"
+                 ng-init="setForm(saltForm, 'saltForm')">
+
+              <div class="item item-text-wrap text-center padding hidden-xs" >
+                <a class="pull-right icon-help" ng-click="showHelpModal('join-salt')"></a>
+                <span translate>ACCOUNT.NEW.SALT_WARNING</span>
+              </div>
+
+              <!-- salt -->
+              <div class="item item-input"
+                   ng-class="{ 'item-input-error': saltForm.$submitted && saltForm.username.$invalid}">
+                <span class="input-label" translate>LOGIN.SALT</span>
+                <input ng-if="!showUsername"
+                       name="username" type="password" placeholder="{{'LOGIN.SALT_HELP' | translate}}"
+                       ng-change="formDataChanged()"
+                       ng-model="formData.username"
+                       ng-minlength="8"
+                       required>
+                <input ng-if="showUsername"
+                       name="username" type="text" placeholder="{{'LOGIN.SALT_HELP' | translate}}"
+                       ng-change="formDataChanged()"
+                       ng-model="formData.username"
+                       ng-minlength="8"
+                       required>
+              </div>
+              <div class="form-errors"
+                   ng-show="saltForm.$submitted && saltForm.username.$error"
+                   ng-messages="saltForm.username.$error">
+                <div class="form-error" ng-message="minlength">
+                  <span translate="ERROR.FIELD_TOO_SHORT_WITH_LENGTH" translate-values="{minLength: 8}"></span>
+                </div>
+                <div class="form-error" ng-message="required">
+                  <span translate="ERROR.FIELD_REQUIRED"></span>
+                </div>
+              </div>
+
+              <!-- confirm salt -->
+              <div class="item item-input"
+                   ng-class="{ 'item-input-error': saltForm.$submitted && saltForm.confirmSalt.$invalid}">
+                <span class="input-label pull-right" translate>ACCOUNT.NEW.SALT_CONFIRM</span>
+                <input ng-if="!showUsername"
+                       name="confirmUsername" type="password"
+                       placeholder="{{'ACCOUNT.NEW.SALT_CONFIRM_HELP' | translate}}"
+                       ng-model="formData.confirmUsername"
+                       compare-to="formData.username">
+                <input ng-if="showUsername"
+                       name="confirmUsername" type="text"
+                       placeholder="{{'ACCOUNT.NEW.SALT_CONFIRM_HELP' | translate}}"
+                       ng-model="formData.confirmUsername"
+                       compare-to="formData.username">
+              </div>
+              <div class="form-errors"
+                   ng-show="saltForm.$submitted && saltForm.confirmUsername.$error"
+                   ng-messages="saltForm.confirmUsername.$error">
+                <div class="form-error" ng-message="compareTo">
+                  <span translate="ERROR.SALT_NOT_CONFIRMED"></span>
+                </div>
+              </div>
+
+              <!-- Show values -->
+              <div class="item item-toggle dark">
+                <span translate>COMMON.SHOW_VALUES</span>
+                <label class="toggle toggle-royal">
+                  <input type="checkbox" ng-model="showUsername">
+                  <div class="track">
+                    <div class="handle"></div>
+                  </div>
+                </label>
+              </div>
+
+              <div class="padding hidden-xs text-right">
+                <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL
+                </button>
+                <button class="button button-calm icon-right ion-chevron-right ink" type="submit" translate>
+                  COMMON.BTN_NEXT
+                  <i class="icon ion-arrow-right-a"></i>
+                </button>
+              </div>
+            </div>
+          </form>
+        </ion-content>
+      </ion-slide-page>
+
+      <!-- STEP 2: password-->
+      <ion-slide-page>
+        <ion-content class="has-header" scroll="false">
+          <form name="passwordForm" novalidate="" ng-submit="doNext('passwordForm')">
+
+            <div class="item item-text-wrap text-center padding hidden-xs" >
+              <a class="pull-right icon-help" ng-click="showHelpModal('join-password')"></a>
+              <span translate>ACCOUNT.NEW.PASSWORD_WARNING</span>
+            </div>
+
+            <div class="list"
+                 ng-init="setForm(passwordForm, 'passwordForm')">
+
+              <!-- password -->
+              <div class="item item-input"
+                   ng-class="{ 'item-input-error': passwordForm.$submitted && passwordForm.password.$invalid}">
+                <span class="input-label" translate>LOGIN.PASSWORD</span>
+                <input ng-if="!showPassword"
+                       name="password" type="password" placeholder="{{'LOGIN.PASSWORD_HELP' | translate}}"
+                       ng-model="formData.password"
+                       ng-change="formDataChanged()"
+                       ng-minlength="8"
+                       required>
+                <input ng-if="showPassword"
+                       name="text" type="text" placeholder="{{'LOGIN.PASSWORD_HELP' | translate}}"
+                       ng-model="formData.password"
+                       ng-change="formDataChanged()"
+                       ng-minlength="8"
+                       required>
+              </div>
+              <div class="form-errors"
+                   ng-show="passwordForm.$submitted && passwordForm.password.$error"
+                   ng-messages="passwordForm.password.$error">
+                <div class="form-error" ng-message="minlength">
+                  <span translate="ERROR.FIELD_TOO_SHORT_WITH_LENGTH" translate-values="{minLength: 8}"></span>
+                </div>
+                <div class="form-error" ng-message="required">
+                  <span translate="ERROR.FIELD_REQUIRED"></span>
+                </div>
+              </div>
+
+              <!-- confirm password -->
+              <div class="item item-input"
+                   ng-class="{ 'item-input-error': passwordForm.$submitted && passwordForm.confirmPassword.$invalid}">
+                <span class="input-label" translate>ACCOUNT.NEW.PASSWORD_CONFIRM</span>
+                <input ng-if="!showPassword"
+                       name="confirmPassword" type="password"
+                       placeholder="{{'ACCOUNT.NEW.PASSWORD_CONFIRM_HELP' | translate}}"
+                       ng-model="formData.confirmPassword"
+                       compare-to="formData.password">
+                <input ng-if="showPassword"
+                       name="confirmPassword" type="text"
+                       placeholder="{{'ACCOUNT.NEW.PASSWORD_CONFIRM_HELP' | translate}}"
+                       ng-model="formData.confirmPassword"
+                       compare-to="formData.password">
+              </div>
+              <div class="form-errors"
+                   ng-show="passwordForm.$submitted && passwordForm.confirmPassword.$error"
+                   ng-messages="passwordForm.confirmPassword.$error">
+                <div class="form-error" ng-message="compareTo">
+                  <span translate="ERROR.PASSWORD_NOT_CONFIRMED"></span>
+                </div>
+              </div>
+
+              <!-- Show values -->
+              <div class="item item-toggle dark">
+                <span translate>COMMON.SHOW_VALUES</span>
+                <label class="toggle toggle-royal">
+                  <input type="checkbox" ng-model="showPassword">
+                  <div class="track">
+                    <div class="handle"></div>
+                  </div>
+                </label>
+              </div>
+            </div>
+
+            <div class="padding hidden-xs text-right">
+              <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL
+              </button>
+              <button class="button button-calm icon-right ion-chevron-right ink" type="submit" translate>
+                  COMMON.BTN_NEXT
+              </button>
+            </div>
+
+            <div class="padding hidden-xs">
+            </div>
+          </form>
+        </ion-content>
+      </ion-slide-page>
+
+
+      <!--<cs-extension-point name="last-slide"></cs-extension-point>-->
+
+      <!-- STEP 3: last slide  -->
+      <ion-slide-page>
+        <ion-content class="has-header" scroll="false">
+
+          <!-- Computing -->
+
+          <div class="padding text-center" ng-if="formData.computing">
+            <ion-spinner icon="android"></ion-spinner>
+          </div>
+          <!-- ng-if="formData.computing" -->
+
+          <!-- Account available -->
+          <div ng-if="accountAvailable && !formData.computing">
+            <div class="padding text-center" translate>ACCOUNT.NEW.LAST_SLIDE_CONGRATULATION</div>
+
+            <div class="list">
+
+              <ion-item class="item item-text-wrap item-border">
+                <div class="dark pull-right padding-right" ng-if="formData.computing">
+                  <ion-spinner icon="android"></ion-spinner>
+                </div>
+                <span class="input-label" translate>COMMON.PUBKEY</span>
+                <span class="gray text-no-wrap" ng-if="formData.computing" translate>
+                  ACCOUNT.NEW.COMPUTING_PUBKEY
+                </span>
+                <span class="gray text-no-wrap" ng-if="formData.pubkey">
+                  {{formData.pubkey}}
+                </span>
+              </ion-item>
+            </div>
+
+            <div class="padding hidden-xs text-right">
+              <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL
+              </button>
+              <button class="button button-positive ink" ng-click="doNewAccount()" translate>
+                COMMON.BTN_SEND
+                <i class="icon ion-android-send"></i>
+              </button>
+            </div>
+          </div>
+
+          <!-- Existing non-empty account -->
+          <div ng-if="!accountAvailable && !formData.computing">
+
+            <ion-item class="item-icon-left item-text-wrap text-center">
+                <i class="icon ion-android-close active"></i>
+                <span id="modal-license" translate>ERROR.EXISTING_ACCOUNT</span>
+            </ion-item>
+
+
+            <div class="list">
+
+              <ion-item class="item item-text-wrap item-border">
+                <div class="dark pull-right padding-right" ng-if="formData.computing">
+                  <ion-spinner icon="android"></ion-spinner>
+                </div>
+                <span class="gray text-no-wrap" ng-if="formData.computing" translate>
+                  ACCOUNT.NEW.COMPUTING_PUBKEY
+                </span>
+                <div class="padding text-center">
+                  <span class="gray text-no-wrap" ng-if="formData.pubkey">
+                    {{formData.pubkey}}
+                  </span>
+                </div>
+              </ion-item>
+
+              <div class="padding text-center">
+                <span translate>ERROR.EXISTING_ACCOUNT_REQUEST</span>
+              </div>
+
+            </div>
+            <div class="padding hidden-xs text-left">
+              <button class="button button-assertive icon-left ion-chevron-left ink" 
+                      ng-click="identifierRecovery()" translate>
+                COMMON.BTN_MODIFY
+              </button>
+            </div>
+          </div>
+
+        </ion-content>
+      </ion-slide-page>
+  </ion-slide-box>
+</ion-modal-view>
diff --git a/www/templates/wallet/slides/slides_revocation_1.html b/www/templates/wallet/slides/slides_revocation_1.html
index 8d76ac730..5d427b37c 100644
--- a/www/templates/wallet/slides/slides_revocation_1.html
+++ b/www/templates/wallet/slides/slides_revocation_1.html
@@ -2,11 +2,11 @@
   <ion-content class="has-header padding">
     <h3 translate>ACCOUNT.SECURITY.REVOCATION</h3>
     <div class="list">
-      <div class="item card item-icon-right stable-bg padding ink dark"
+      <button class="item card item-icon-right stable-bg padding ink dark"
            ng-click="downloadRevokeFile()" ng-if="isLogin && hasSelf">
         <i class="icon ion-android-archive"></i>
         <span ng-bind-html="'ACCOUNT.SECURITY.DOWNLOAD_REVOKE' | translate"></span>
-      </div>
+      </button>
       <div class="item card item-icon-right stable-bg padding ink dark"
            ng-click="slideNext()">
         <i class="icon ion-ios-arrow-right"></i>
-- 
GitLab