diff --git a/www/api/index.html b/www/api/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..0b0f2f6268eb862c8b1d1c9c6a3500b866d4d0c0
--- /dev/null
+++ b/www/api/index.html
@@ -0,0 +1,116 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, width=device-width, minimal-ui">
+  <meta name="apple-mobile-web-app-capable" content="yes">
+  <title>Cesium API</title>
+  <link rel="icon" href="../img/favicon.ico">
+
+  <!-- build:css dist_css/cesium.css -->
+  <link rel="stylesheet" type="text/css" href="../css/ionic.app.min.css">
+  <link rel="stylesheet" type="text/css" href="../css/style.css">
+  <link rel="stylesheet" type="text/css" href="../css/angular-image-crop.css">
+  <!--removeIf(device)-->
+  <link rel="stylesheet" type="text/css" href="../css/style-no-device.css">
+  <!--endRemoveIf(device)-->
+  <!-- endbuild -->
+
+</head>
+</head>
+<body ng-app="cesium-api" id="cesium-api" ng-strict-di="true">
+<ion-nav-view>
+  <h3 style="text-align: center; padding-top: 25px; "><b>Cesium API</b></h3>
+  <h4 style="text-align: center;">Loading...</h4>
+</ion-nav-view>
+
+<!-- build:js dist_js/vendor.js -->
+<!-- vendor js -->
+<script src="../js/vendor/moment.min.js"></script>
+<script src="../js/vendor/moment.fr.js"></script>
+<script src="../js/vendor/moment.nl.js"></script>
+<script src="../js/vendor/moment.es.js"></script>
+<script src="../js/vendor/numeral.js"></script>
+<script src="../js/vendor/numeral.fr.js"></script>
+<script src="../js/vendor/numeral.en.js"></script>
+<script src="../js/vendor/numeral.nl.js"></script>
+<script src="../js/vendor/numeral.es.js"></script>
+<script src="../js/vendor/socket-io.js"></script>
+<script src="../js/vendor/underscore.js"></script>
+
+<!-- ionic/angularjs js -->
+<script src="../lib/ionic/js/ionic.bundle.js"></script>
+<script src="../lib/ionic/js/ionic.material.js"></script>
+<script src="../lib/ionic/js/angular/angular-resource.js"></script>
+<script src="../lib/ionic/js/angular/angular-translate.js"></script>
+<script src="../lib/ionic/js/angular/angular-messages.js"></script>
+<script src="../lib/ionic/js/angular/angular-api.js"></script>
+<script src="../lib/ionic/js/angular/angular-cache.js"></script>
+<script src="../lib/ionic/js/angular/angular-screenmatch.min.js"></script>
+<script src="../lib/ionic/js/angular/angular-bind-notifier.min.js"></script>
+<script src="../lib/ionic/js/angular/angular-file-saver.bundle.js"></script>
+<script src="../lib/ionic/js/angular/angular-idle.js"></script>
+
+  <script src="../js/vendor/base58.js" async></script>
+  <!--removeIf(android)-->
+  <!--removeIf(ios)-->
+  <script src="../js/vendor/nacl_factory.js" async></script>
+  <script src="../js/vendor/scrypt-em.js" async></script>
+  <script src="../js/vendor/base64.js" async></script>
+  <!--endRemoveIf(ios)-->
+  <!--endRemoveIf(android)-->
+  <!--removeIf(no-device)-->
+  <script src="../js/vendor/sha256.min.js" async></script>
+  <script src="../js/vendor/ng-cordova.min.js"></script>
+  <!--endRemoveIf(no-device)-->
+
+<!-- endbuild -->
+
+<!--removeIf(no-device)-->
+<script src="../cordova.js"></script>
+<!--endRemoveIf(no-device)-->
+
+<!-- build:js dist_js/cesium.js -->
+<!-- services -->
+<script src="../dist/dist_js/app/services/settings-services.js"></script>
+<script src="../dist/dist_js/app/services/network-services.js"></script>
+<script src="../dist/dist_js/app/services/crypto-services.js"></script>
+<script src="../dist/dist_js/app/services/utils-services.js"></script>
+<script src="../dist/dist_js/app/services/cache-services.js"></script>
+<script src="../dist/dist_js/app/services/modal-services.js"></script>
+<script src="../dist/dist_js/app/services/http-services.js"></script>
+<script src="../dist/dist_js/app/services/storage-services.js"></script>
+<script src="../dist/dist_js/app/services/device-services.js"></script>
+<script src="../dist/dist_js/app/services/currency-services.js"></script>
+<script src="../dist/dist_js/app/services/bma-services.js"></script>
+<script src="../dist/dist_js/app/services/wot-services.js"></script>
+<script src="../dist/dist_js/app/services/tx-services.js"></script>
+<script src="../dist/dist_js/app/services/wallet-services.js"></script>
+<script src="../dist/dist_js/app/services/plugin-services.js"></script>
+<script src="../dist/dist_js/app/services.js"></script>
+
+<!-- entities -->
+<script src="../dist/dist_js/app/entities/peer.js"></script>
+<script src="../dist/dist_js/app/entities/block.js"></script>
+
+<!-- controllers -->
+<script src="../dist/dist_js/app/controllers/login-controllers.js"></script>
+<script src="../dist/dist_js/app/controllers/help-controllers.js"></script>
+
+<!-- templates -->
+<script src="../dist/dist_js/app/templates.js"></script>
+<script src="../dist/dist_js/app/translations.js"></script>
+
+<!-- App -->
+<script src="../dist/dist_js/app/api/app.js"></script>
+<script src="../dist/dist_js/app/directives.js"></script>
+<script src="../dist/dist_js/app/filters.js"></script>
+<script src="../dist/dist_js/app/platform.js"></script>
+<!-- endbuild -->
+
+<!-- build:js config.js -->
+<!-- config  -->
+<script src="../dist/dist_js/app/config.js"></script>
+<!-- endbuild -->
+</body>
+</html>
diff --git a/www/i18n/locale-fr-FR.json b/www/i18n/locale-fr-FR.json
index 142bc212fa329a76c28f16465dc61266df08eff2..ecf9836d30558c12ebc5c8d3d9ab6f92e26d436c 100644
--- a/www/i18n/locale-fr-FR.json
+++ b/www/i18n/locale-fr-FR.json
@@ -763,5 +763,49 @@
       "END_LOGIN": "Cette visite guidée est <b>terminée</b> !<br/><br/>Bonne continuation à vous, dans le nouveau monde de l'<b>économie libre</b> !",
       "END_NOT_LOGIN": "Cette visite guidée est <b>terminée</b> !<br/><br/>Si vous souhaitez rejoindre la monnaie {{currency|capitalize}}, il vous suffira de cliquer sur <b>{{'LOGIN.CREATE_ACCOUNT'|translate}}</b> ci-dessous."
     }
+  },
+  "API" :{
+    "COMMON": {
+      "LINK_DOC": "documentation API",
+      "LINK_DOC_HELP": "Documentation pour les développeurs"
+    },
+    "HOME": {
+      "TITLE": "Documentation API {{'COMMON.APP_NAME'|translate}}",
+      "MESSAGE": "Bienvenue dans la <b>documentation de l'API</b> {{'COMMON.APP_NAME'|translate}}.<br/>Connecter vos sites web à <a href=\"http://duniter.org\" target=\"_system\">Duniter</a> très simplement !",
+      "MESSAGE_SHORT": "Connecter vos sites à <a href=\"http://duniter.org\" target=\"_system\">Duniter</a> très simplement !",
+      "DOC_HEADER": "Services disponibles :"
+    },
+    "TRANSFER": {
+      "TITLE": "{{'COMMON.APP_NAME'|translate}} - Paiement en ligne",
+      "TITLE_SHORT": "Paiement en ligne",
+      "SUMMARY": "Récapitulatif de la commande :",
+      "AMOUNT": "Montant :",
+      "NAME": "Destinataire :",
+      "PUBKEY": "Clé publique du destinaire :",
+      "COMMENT": "Référence de la commande :",
+      "ERROR": {
+        "TRANSFER_FAILED": "Echec du paiement"
+      }
+    },
+    "DOC": {
+      "BTN_DEMO": "Démo",
+      "DESCRIPTION_DIVIDER": "Description",
+      "URL_DIVIDER": "URL d'accès",
+      "PARAMETERS_DIVIDER": "Options",
+      "AVAILABLE_PARAMETERS": "Voici la liste des options possibles :",
+      "SUCCEED": "<i class=\"icon ion-checkmark\"></i> Succès !",
+      "CANCELLED": "<i class=\"icon ion-close\"></i> Annulé par l'utilisateur",
+      "RESULT": "Résultat retourné par l'appel :",
+      "TRANSFER": {
+        "TITLE": "Paiements",
+        "DESCRIPTION": "Depuis un site (ex: vente en ligne) vous pouvez déléguer le paiement en monnaie libre à Cesium API. Pour cela, il vous suffit de déclencher l'ouveture d'un page sur l'adresse suivante :",
+        "PARAM_AMOUNT": "Montant",
+        "PARAM_AMOUNT_HELP": "Montant de la transaction (obligatoire)",
+        "PARAM_COMMENT_HELP": "Référence ou commentaire. Vous permettra par exemple d'identifier le paiement dans la BlockChain.",
+        "PARAM_NAME_HELP": "Le nom de votre site. Cela peut-etre un nom lisible (\"Mon site en ligne\"), ou encore une pseudo-adresse web (\"MonSite.com\").",
+        "PARAM_REDIRECT_URL_HELP": "URL de redirection",
+        "PARAM_CANCEL_URL_HELP": "URL en cas d'annulation"
+      }
+    }
   }
 }
diff --git a/www/index.html b/www/index.html
index 5d663eff96de0979b17fcdf2287f45b46a4737e8..d9df6c449fd429cb1f432a2013a49046f324482e 100644
--- a/www/index.html
+++ b/www/index.html
@@ -27,10 +27,13 @@
 </head>
 </head>
 <body ng-app="cesium" id="cesium" ng-strict-di="true" window-exit-unauth="true"
+
       ng-class="{'nobackdrop': $root.tour, 'expert-mode': $root.settings.expertMode}">
 <ion-nav-view>
-  <h3 style="text-align: center; padding-top: 25px; "><b>Cesium</b></h3>
-  <h4 style="text-align: center;">Chargement / Sobreprima / Loading...</h4>
+  <div class="loader">
+    <h3 style="text-align: center; padding-top: 25px; "><b>Cesium</b></h3>
+    <h4 style="text-align: center;"><i class="icon ion-load-a"></i></h4>
+  </div>
 </ion-nav-view>
 
 <!-- build:js dist_js/vendor.js -->
diff --git a/www/js/api/app.js b/www/js/api/app.js
new file mode 100644
index 0000000000000000000000000000000000000000..255c378407f10b73a358ecc071a8f9a5ef11742f
--- /dev/null
+++ b/www/js/api/app.js
@@ -0,0 +1,239 @@
+// Ionic Starter App
+
+// angular.module is a global place for creating, registering and retrieving Angular modules
+// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
+// the 2nd parameter is an array of 'requires'
+// 'starter.controllers' is found in controllers.js
+angular.module('cesium-api', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht.translate', 'ngApi', 'angular-cache', 'angular.screenmatch',
+  // removeIf(no-device)
+  'ngCordova',
+  // endRemoveIf(no-device)
+  'cesium.filters', 'cesium.config', 'cesium.platform', 'cesium.templates', 'cesium.translations', 'cesium.directives',
+  // API dependencies :
+  'cesium.services', 'cesium.login.controllers', 'cesium.help.controllers'
+])
+
+  .config(function($stateProvider, $urlRouterProvider) {
+    'ngInject';
+    $stateProvider
+
+      .state('app', {
+        url: "/app",
+        abstract: true,
+        templateUrl: "templates/api/menu.html",
+        controller: 'ApiCtrl'
+      })
+
+      .state('app.home', {
+        url: "/home?result&service&cancel",
+        views: {
+          'menuContent': {
+            templateUrl: "templates/api/home.html",
+            controller: 'ApiDocCtrl'
+          }
+        }
+      })
+
+      .state('api', {
+        url: "/v1",
+        abstract: true,
+        templateUrl: "templates/api/menu.html",
+        controller: 'ApiCtrl'
+      })
+
+      .state('api.transfer', {
+        url: "/payment/:pubkey?name&amount&udAmount&comment&redirect_url&cancel_url&demo",
+        views: {
+          'menuContent': {
+            templateUrl: "templates/api/transfer.html",
+            controller: 'ApiTransferCtrl'
+          }
+        }
+      });
+
+    // if none of the above states are matched, use this as the fallback
+    $urlRouterProvider.otherwise('/app/home');
+  })
+
+  .controller('ApiCtrl', function ($scope, $state, Modals){
+    'ngInject';
+
+
+    $scope.showAboutModal = function(e) {
+      e.preventDefault(); // avoid to open link href
+      Modals.showAbout();
+    };
+
+    $scope.showHome = function() {
+      $state.go('app.home') ;
+    };
+  })
+
+  .controller('ApiDocCtrl', function ($scope, $rootScope){
+    'ngInject';
+
+    $scope.transferData = {
+      demo: true,
+      amount: 100,
+      comment: 'REF-0111',
+      name: 'mon-site.com',
+      pubkey: 'G2CBgZBPLe6FSFUgpx2Jf1Aqsgta6iib3vmDRA1yLiqU',
+      redirect_url: $rootScope.rootPath + '#/app/home?result={comment}&service=payment',
+      cancel_url: $rootScope.rootPath + '#/app/home?cancel&service=payment'
+    };
+    $scope.result = {};
+
+    $scope.enter = function(e, state) {
+      $scope.result = {};
+      if (state.stateParams && state.stateParams.service) {
+        $scope.result.type = state.stateParams.service;
+      }
+      if (state.stateParams && state.stateParams.result) {
+        $scope.result.content = state.stateParams.result;
+      }
+      if (state.stateParams && state.stateParams.cancel) {
+        $scope.result.cancelled = true;
+      }
+    };
+    $scope.$on('$ionicView.enter', $scope.enter);
+
+  })
+
+  .controller('ApiTransferCtrl', function ($scope, $rootScope, $timeout, $controller, $state, $q, $translate, $filter,
+                                           BMA, UIUtils, csCurrency, csTx, csWallet){
+    'ngInject';
+
+    // Initialize the super class and extend it.
+    angular.extend(this, $controller('AuthCtrl', {$scope: $scope}));
+
+    $scope.loading = true;
+    $scope.transferData = {
+      amount: undefined,
+      comment: undefined,
+      pubkey: undefined,
+      name: undefined,
+      redirect_url: undefined,
+      cancel_url: undefined
+    };
+
+    $scope.enter = function(e, state) {
+      if (state.stateParams && state.stateParams.amount) {
+        $scope.transferData.amount  = parseFloat(state.stateParams.amount.replace(new RegExp('[.,]'), '.')).toFixed(2) * 100;
+      }
+      if (state.stateParams && state.stateParams.pubkey) {
+        $scope.transferData.pubkey = state.stateParams.pubkey;
+      }
+      if (state.stateParams && state.stateParams.name) {
+        $scope.transferData.name= state.stateParams.name;
+      }
+      if (state.stateParams && state.stateParams.comment) {
+        $scope.transferData.comment = state.stateParams.comment;
+      }
+      if (state.stateParams && state.stateParams.redirect_url) {
+        $scope.transferData.redirect_url = state.stateParams.redirect_url;
+      }
+      if (state.stateParams && state.stateParams.cancel_url) {
+        $scope.transferData.cancel_url = state.stateParams.cancel_url;
+      }
+      if (state.stateParams && state.stateParams.demo) {
+        $scope.demo = true;
+      }
+    };
+    $scope.$on('$ionicView.enter', $scope.enter);
+
+    function createDemoWallet() {
+      return {
+        start: function() {
+          return $q.when();
+        },
+        login: function() {
+          return $q.when({
+            uid: 'Demo',
+            pubkey: 'fakeDemoPublicKey'
+          });
+        },
+        transfer: function() {
+          return $q.when();
+        }
+      };
+    }
+
+    function onLogin(authData) {
+      if (!authData) return;
+
+      var wallet = $scope.demo ? createDemoWallet() : csWallet.instance('api', BMA);
+
+      UIUtils.loading.show();
+
+      wallet.start({skipRestore: true})
+        .then(function() {
+          return wallet.login({auth: true, authData: authData});
+        })
+        .then(function(walletData) {
+          $scope.login = true;
+
+          UIUtils.loading.hide();
+          return $scope.askTransferConfirm(walletData);
+        })
+        .then(function(confirm) {
+          if (!confirm) return;
+          // sent transfer
+          return UIUtils.loading.show()
+            .then(function(){
+              var amount = parseInt($scope.transferData.amount); // remove 2 decimals on quantitative mode
+              return wallet.transfer($scope.transferData.pubkey, amount, $scope.transferData.comment, false /*always quantitative mode*/);
+            })
+            .then(function() {
+              UIUtils.loading.hide();
+              return true; // sent
+            })
+            .catch(UIUtils.onError('API.TRANSFER.ERROR.TRANSFER_FAILED'));
+        })
+        .then(function(sent) {
+          if (sent && $scope.transferData.redirect_url) {
+            return $timeout(function () {
+              // if iframe: send to parent
+              if (window.top && window.top.location) {
+                window.top.location.href = $scope.transferData.redirect_url;
+              }
+              else if (parent && parent.document && parent.document.location) {
+                parent.document.location.href = $scope.transferData.redirect_url;
+              }
+              else {
+                window.location.assign($scope.transferData.redirect_url);
+              }
+            }, 3000);
+          }
+        });
+    }
+
+
+    $scope.askTransferConfirm = function(walletData) {
+      return $translate(['COMMON.UD', 'COMMON.EMPTY_PARENTHESIS'])
+        .then(function(translations) {
+          return $translate('CONFIRM.TRANSFER', {
+            from: walletData.isMember ? walletData.uid : $filter('formatPubkey')(walletData.pubkey),
+            to: $scope.transferData.name || $filter('formatPubkey')($scope.transferData.pubkey),
+            amount: $scope.transferData.amount / 100,
+            unit: $filter('abbreviate')($rootScope.currency.name),
+            comment: (!$scope.transferData.comment || $scope.transferData.comment.trim().length === 0) ? translations['COMMON.EMPTY_PARENTHESIS'] : $scope.transferData.comment
+          });
+        })
+        .then(UIUtils.alert.confirm);
+    };
+
+    /* -- methods need by Login controller -- */
+
+    $scope.setForm = function(form) {
+      $scope.form = form;
+    };
+    $scope.closeModal = onLogin;
+
+  })
+
+  .run(function(csPlatform) {
+    'ngInject';
+
+    csPlatform.start();
+  })
+;
diff --git a/www/js/app.js b/www/js/app.js
index 6b52789d4e34b48fb4c896995d8fd3f6929ea8af..283c61b7ca7ba7c839d8c96909b560f092e78cb8 100644
--- a/www/js/app.js
+++ b/www/js/app.js
@@ -12,80 +12,9 @@ angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht
   // removeIf(no-plugin)
   'cesium.plugins',
   // endRemoveIf(no-plugin)
-  'cesium.filters', 'cesium.config', 'cesium.platform', 'cesium.controllers', 'cesium.templates', 'cesium.translations'
+  'cesium.filters', 'cesium.config', 'cesium.platform', 'cesium.controllers', 'cesium.templates', 'cesium.translations', 'cesium.components', 'cesium.directives'
   ])
 
-  // Translation i18n
-  .config(function ($translateProvider, csConfig) {
-    'ngInject';
-
-    $translateProvider
-    .uniformLanguageTag('bcp47')
-    .determinePreferredLanguage()
-    // Cela fait bugger les placeholder (pb d'affichage des accents en FR)
-    //.useSanitizeValueStrategy('sanitize')
-    .useSanitizeValueStrategy(null)
-    .fallbackLanguage([csConfig.fallbackLanguage ? csConfig.fallbackLanguage : 'en'])
-    .useLoaderCache(true);
-  })
-
-  .config(function($httpProvider, csConfig) {
-    'ngInject';
-
-    // Set default timeout
-    $httpProvider.defaults.timeout = !!csConfig.TIMEOUT ? csConfig.TIMEOUT : 4000 /* default timeout */;
-
-    //Enable cross domain calls
-    $httpProvider.defaults.useXDomain = true;
-
-    //Remove the header used to identify ajax call  that would prevent CORS from working
-    delete $httpProvider.defaults.headers.common['X-Requested-With'];
-
-    // removeIf(no-device)
-    // Group http request response processing (better performance when many request)
-    $httpProvider.useApplyAsync(true);
-    // endRemoveIf(no-device)
-  })
-
-  .config(function($compileProvider, csConfig) {
-    'ngInject';
-
-    $compileProvider.debugInfoEnabled(!!csConfig.DEBUG);
-  })
-
-  .config(function($animateProvider) {
-    'ngInject';
-    $animateProvider.classNameFilter( /\banimate-/ );
-  })
-
-  // Configure cache (used by HTTP requests) default max age
-  .config(function (CacheFactoryProvider) {
-    angular.extend(CacheFactoryProvider.defaults, { maxAge: 60 * 1000 /*1min*/});
-  })
-
-  // Configure screen size detection
-  .config(function(screenmatchConfigProvider) {
-    screenmatchConfigProvider.config.rules = 'bootstrap';
-  })
-
-  .config(function($ionicConfigProvider) {
-    'ngInject';
-    // JS scrolling need for iOs (see http://blog.ionic.io/native-scrolling-in-ionic-a-tale-in-rhyme/)
-    var enableJsScrolling = ionic.Platform.isIOS();
-    $ionicConfigProvider.scrolling.jsScrolling(enableJsScrolling);
-
-    // Configure the view cache
-    $ionicConfigProvider.views.maxCache(5);
-  })
-
-  .config(function(IdleProvider, csConfig) {
-    'ngInject';
-
-    IdleProvider.idle(csConfig.logoutIdle||10*60/*10min*/);
-    IdleProvider.timeout(csConfig.logoutTimeout||15); // display warning during 15s
-  })
-
-
   // Override the automatic sync between location URL and state
   // (see watch event $locationChangeSuccess in the run() function bellow)
   .config(function ($urlRouterProvider) {
@@ -94,219 +23,114 @@ angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht
     $urlRouterProvider.deferIntercept();
   })
 
-  .factory('$exceptionHandler', function() {
+  .run(function($rootScope, $translate, $state, $window, $urlRouter, ionicReady,
+                Device, UIUtils, $ionicConfig, PluginService, csPlatform, csWallet) {
     'ngInject';
 
-    return function(exception, cause) {
-      if (cause) console.error(exception, cause);
-      else console.error(exception);
-    };
-  })
-
-
-.run(function($rootScope, $translate, $state, $window, $urlRouter, ionicReady,
-              Device, UIUtils, $ionicConfig, PluginService, csPlatform, csWallet, csSettings, csConfig, csCurrency) {
-  'ngInject';
-
-  // Allow access to service data, from HTML templates
-  $rootScope.config = csConfig;
-  $rootScope.settings = csSettings.data;
-  $rootScope.currency = csCurrency.data;
-  $rootScope.walletData = csWallet.data;
-  $rootScope.device = Device;
+    // Allow access to service data, from HTML templates
+    $rootScope.walletData = csWallet.data;
 
-  // Compute the root path
-  var hashIndex = $window.location.href.indexOf('#');
-  $rootScope.rootPath = (hashIndex != -1) ? $window.location.href.substr(0, hashIndex) : $window.location.href;
-  console.debug('[app] Root path is [' + $rootScope.rootPath + ']');
+    // Must be done before any other $stateChangeStart listeners
+    csPlatform.disableChangeState();
 
-  // removeIf(device)
-  // -- Automatic redirection to HTTPS
-  if ((csConfig.httpsMode === true || csConfig.httpsMode == 'true' ||csConfig.httpsMode === 'force') &&
-    $window.location.protocol != 'https:') {
+    var preventStateChange = false; // usefull to avoid duplicate login, when a first page with auth
     $rootScope.$on('$stateChangeStart', function (event, next, nextParams, fromState) {
-      var path = 'https' + $rootScope.rootPath.substr(4) + $state.href(next, nextParams);
-      if (csConfig.httpsModeDebug) {
-        console.debug('[app] [httpsMode] --- Should redirect to: ' + path);
-        // continue
-      }
-      else {
-        $window.location.href = path;
-      }
-    });
-  }
-  // endRemoveIf(device)
-
-  // Must be done before any other $stateChangeStart listeners
-  csPlatform.disableChangeState();
-
-  var preventStateChange = false; // usefull to avoid duplicate login, when a first page with auth
-  $rootScope.$on('$stateChangeStart', function (event, next, nextParams, fromState) {
-    if (event.defaultPrevented) return;
+      if (event.defaultPrevented) return;
 
-    var skip = !next.data || $rootScope.tour || event.currentScope.tour; // disabled for help tour
-    if (skip) return;
+      var skip = !next.data || $rootScope.tour || event.currentScope.tour; // disabled for help tour
+      if (skip) return;
 
-    if (preventStateChange) {
-      event.preventDefault();
-      return;
-    }
-
-    var options;
-
-    // removeIf(android)
-    // removeIf(ios)
-    // removeIf(firefoxos)
-    // -- Automatic redirection to large state (if define) (keep this code for platforms web and ubuntu build)
-    if (next.data.large && !UIUtils.screen.isSmall()) {
-      event.preventDefault();
-      $state.go(next.data.large, nextParams);
-      return;
-    }
-    // endRemoveIf(firefoxos)
-    // endRemoveIf(ios)
-    // endRemoveIf(android)
+      if (preventStateChange) {
+        event.preventDefault();
+        return;
+      }
 
-    // If state need auth
-    if (next.data.auth && !csWallet.isAuth()) {
-      event.preventDefault();
-      options = next.data.minData ? {minData: true} : undefined;
-      preventStateChange = true;
-      return csWallet.auth(options)
-        .then(function() {
-          preventStateChange = false;
-          return $state.go(next.name, nextParams);
-        })
-        .catch(function(err) {
-          preventStateChange = false;
-          // If cancel, redirect to home, if no current state
-          if (err == 'CANCELLED' && !$state.current.name) {
-            return $state.go('app.home');
-          }
-        });
-    }
+      var options;
 
-    // If state need login
-    else if (next.data.login && !csWallet.isLogin()) {
-      event.preventDefault();
-      options = next.data.minData ? {minData: true} : undefined;
-      preventStateChange = true;
-      return csWallet.login(options)
-        .then(function() {
-          preventStateChange = false;
-          return $state.go(next.name, nextParams);
-        })
-        .catch(function(err) {
-          preventStateChange = false;
-          // If cancel, redirect to home, if no current state
-          if (err == 'CANCELLED' && !$state.current.name) {
-            return $state.go('app.home');
-          }
-        });
-    }
+      // removeIf(android)
+      // removeIf(ios)
+      // removeIf(firefoxos)
+      // -- Automatic redirection to large state (if define) (keep this code for platforms web and ubuntu build)
+      if (next.data.large && !UIUtils.screen.isSmall()) {
+        event.preventDefault();
+        $state.go(next.data.large, nextParams);
+        return;
+      }
+      // endRemoveIf(firefoxos)
+      // endRemoveIf(ios)
+      // endRemoveIf(android)
 
-    // If state need login or auth, make sure to load wallet data
-    else if (next.data.login || next.data.auth)  {
-      options = next.data.minData ? {minData: true} : undefined;
-      if (!csWallet.isDataLoaded(options)) {
+      // If state need auth
+      if (next.data.auth && !csWallet.isAuth()) {
         event.preventDefault();
-        return csWallet.loadData(options)
+        options = next.data.minData ? {minData: true} : undefined;
+        preventStateChange = true;
+        return csWallet.auth(options)
           .then(function() {
             preventStateChange = false;
             return $state.go(next.name, nextParams);
+          })
+          .catch(function(err) {
+            preventStateChange = false;
+            // If cancel, redirect to home, if no current state
+            if (err == 'CANCELLED' && !$state.current.name) {
+              return $state.go('app.home');
+            }
           });
       }
-    }
-  });
-
-  // Leave the current page, if auth was required to access it
-  csWallet.api.data.on.unauth($rootScope, function() {
-    if ($state.current && $state.current.data && $state.current.data.auth) {
-      $state.go('app.home');
-    }
-  });
 
-  // Prevent $urlRouter's default handler from firing (don't sync ui router)
-  $rootScope.$on('$locationChangeSuccess', function(event, newUrl, oldUrl) {
-    if ($state.current.data && $state.current.data.silentLocationChange === true) {
-      // Skipping propagation, because same URL, and state configured with 'silentLocationChange' options
-      var sameUrl = oldUrl && (oldUrl.split('?')[0] === newUrl.split('?')[0]);
-      if (sameUrl) event.preventDefault();
-    }
-  });
-  // Configures $urlRouter's listener *after* the previous listener
-  $urlRouter.listen();
-
-  // Start plugins eager services
-  PluginService.start();
-
-  // We use 'ionicReady()' instead of '$ionicPlatform.ready()', because this one is callable many times
-  ionicReady().then(function() {
-
-    // Keyboard
-    if (Device.keyboard.enable) {
-      // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
-      // for form inputs)
-      Device.keyboard.hideKeyboardAccessoryBar(true);
+      // If state need login
+      else if (next.data.login && !csWallet.isLogin()) {
+        event.preventDefault();
+        options = next.data.minData ? {minData: true} : undefined;
+        preventStateChange = true;
+        return csWallet.login(options)
+          .then(function() {
+            preventStateChange = false;
+            return $state.go(next.name, nextParams);
+          })
+          .catch(function(err) {
+            preventStateChange = false;
+            // If cancel, redirect to home, if no current state
+            if (err == 'CANCELLED' && !$state.current.name) {
+              return $state.go('app.home');
+            }
+          });
+      }
 
-      // iOS: do not push header up when opening keyboard
-      // (see http://ionicframework.com/docs/api/page/keyboard/)
-      if (ionic.Platform.isIOS()) {
-        Device.keyboard.disableScroll(true);
+      // If state need login or auth, make sure to load wallet data
+      else if (next.data.login || next.data.auth)  {
+        options = next.data.minData ? {minData: true} : undefined;
+        if (!csWallet.isDataLoaded(options)) {
+          event.preventDefault();
+          return csWallet.loadData(options)
+            .then(function() {
+              preventStateChange = false;
+              return $state.go(next.name, nextParams);
+            });
+        }
       }
-    }
+    });
 
-    // Ionic Platform Grade is not A, disabling views transitions
-    if (ionic.Platform.grade.toLowerCase() != 'a') {
-      console.info('[app] Disabling UI effects, because plateform\'s grade is [' + ionic.Platform.grade + ']');
-      UIUtils.setEffects(false);
-    }
+    // Leave the current page, if auth was required to access it
+    csWallet.api.data.on.unauth($rootScope, function() {
+      if ($state.current && $state.current.data && $state.current.data.auth) {
+        $state.go('app.home');
+      }
+    });
 
-    // Status bar style
-    if (window.StatusBar) {
-      // org.apache.cordova.statusbar required
-      StatusBar.styleDefault();
-    }
+    // Prevent $urlRouter's default handler from firing (don't sync ui router)
+    $rootScope.$on('$locationChangeSuccess', function(event, newUrl, oldUrl) {
+      if ($state.current.data && $state.current.data.silentLocationChange === true) {
+        // Skipping propagation, because same URL, and state configured with 'silentLocationChange' options
+        var sameUrl = oldUrl && (oldUrl.split('?')[0] === newUrl.split('?')[0]);
+        if (sameUrl) event.preventDefault();
+      }
+    });
+    // Configures $urlRouter's listener *after* the previous listener
+    $urlRouter.listen();
 
-    // Make sure platform is started
-    return csPlatform.ready();
-  });
-})
+    // Start plugins eager services
+    PluginService.start();
+  })
 ;
-
-// Workaround to add "".startsWith() if not present
-if (typeof String.prototype.startsWith !== 'function') {
-  console.debug("Adding String.prototype.startsWith() -> was missing on this platform");
-  String.prototype.startsWith = function(prefix) {
-      return this.indexOf(prefix) === 0;
-  };
-}
-
-// Workaround to add "".startsWith() if not present
-if (typeof String.prototype.trim !== 'function') {
-  console.debug("Adding String.prototype.trim() -> was missing on this platform");
-  // Make sure we trim BOM and NBSP
-  var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
-  String.prototype.trim = function() {
-    return this.replace(rtrim, '');
-  };
-}
-
-// Workaround to add Math.trunc() if not present - fix #144
-if (Math && typeof Math.trunc !== 'function') {
-  console.debug("Adding Math.trunc() -> was missing on this platform");
-  Math.trunc = function(number) {
-    return (number - 0.5).toFixed();
-  };
-}
-
-// Workaround to add "".format() if not present
-if (typeof String.prototype.format !== 'function') {
-  console.debug("Adding String.prototype.format() -> was missing on this platform");
-  String.prototype.format = function() {
-    var args = arguments;
-    return this.replace(/{(\d+)}/g, function(match, number) {
-      return typeof args[number] != 'undefined' ? args[number] : match;
-    });
-  };
-}
diff --git a/www/js/components.js b/www/js/components.js
index 34ba027d79a9ba0411352e67e436d18094f133d7..2833ce11b83dd8c5401548c8ae65bb055e03db63 100644
--- a/www/js/components.js
+++ b/www/js/components.js
@@ -1,4 +1,4 @@
-angular.module('cesium')
+angular.module('cesium.components', [])
 
   .component('csBadgeCertification', {
     bindings: {
diff --git a/www/js/config.js b/www/js/config.js
index 91fc3fc15cf9928696a135e506f86cdcb3a881ba..87eb4df867a4ea586a64414dcd70d22b68672c76 100644
--- a/www/js/config.js
+++ b/www/js/config.js
@@ -11,6 +11,7 @@ angular.module("cesium.config", [])
 .constant("csConfig", {
 	"cacheTimeMs": 300000,
 	"fallbackLanguage": "en",
+  "debug": true,
 	"rememberMe": true,
 	"showUDHistory": false,
 	"timeout": 300000,
@@ -70,4 +71,4 @@ angular.module("cesium.config", [])
 	"newIssueUrl": "https://github.com/duniter/cesium/issues/new?labels=bug"
 })
 
-;
\ No newline at end of file
+;
diff --git a/www/js/controllers/app-controllers.js b/www/js/controllers/app-controllers.js
index bd968685f443b9fb994608ec3677cb608916f3a2..26323640c74a0dce72ceb3bf64769045fddbf024 100644
--- a/www/js/controllers/app-controllers.js
+++ b/www/js/controllers/app-controllers.js
@@ -1,14 +1,4 @@
-angular.module('cesium.app.controllers', ['ngIdle', 'cesium.platform', 'cesium.services'])
-
-  .config(function($httpProvider) {
-    'ngInject';
-
-    //Enable cross domain calls
-    $httpProvider.defaults.useXDomain = true;
-
-    //Remove the header used to identify ajax call  that would prevent CORS from working
-    delete $httpProvider.defaults.headers.common['X-Requested-With'];
-  })
+angular.module('cesium.app.controllers', ['cesium.platform', 'cesium.services'])
 
   .config(function($stateProvider, $urlRouterProvider) {
     'ngInject';
@@ -58,20 +48,10 @@ angular.module('cesium.app.controllers', ['ngIdle', 'cesium.platform', 'cesium.s
 
   .controller('PluginExtensionPointCtrl', PluginExtensionPointController)
 
-  .controller('EmptyModalCtrl', EmptyModalController)
 
-  .controller('AboutCtrl', AboutController)
 
 ;
 
-
-/**
- * Useful for modal with no controller (see Modal service)
- */
-function EmptyModalController($scope, parameters) {
-
-}
-
 /**
  * Useful controller that could be reuse in plugin, using $scope.extensionPoint for condition rendered in templates
  */
@@ -423,12 +403,6 @@ function AppController($scope, $rootScope, $state, $ionicSideMenuDelegate, $q, $
 }
 
 
-function AboutController($scope, csConfig) {
-  'ngInject';
-  $scope.config = csConfig;
-}
-
-
 function HomeController($scope, $state, $timeout, $ionicHistory, csPlatform, csCurrency) {
   'ngInject';
 
diff --git a/www/js/controllers/login-controllers.js b/www/js/controllers/login-controllers.js
index bb1bad1d9155c3b26e8ff5f7ba781ac7212e4f07..5184cbd4235bc3873262cd062d825f81fc56df29 100644
--- a/www/js/controllers/login-controllers.js
+++ b/www/js/controllers/login-controllers.js
@@ -3,6 +3,8 @@ angular.module('cesium.login.controllers', ['cesium.services'])
 
   .controller('LoginModalCtrl', LoginModalController)
 
+  .controller('AuthCtrl', AuthController)
+
 ;
 
 function LoginModalController($scope, $timeout, $q, $ionicPopover, CryptoUtils, UIUtils, BMA, Modals, csSettings, Device, parameters) {
@@ -417,3 +419,15 @@ function LoginModalController($scope, $timeout, $q, $ionicPopover, CryptoUtils,
     //$scope.form = {$valid:true};
   }, 900);*/
 }
+
+
+function AuthController($scope, $controller){
+
+  // Initialize the super class and extend it.
+  angular.extend(this, $controller('LoginModalCtrl', {$scope: $scope, parameters: {auth: true}}));
+
+  $scope.setForm = function(form) {
+    $scope.form = form;
+  };
+
+}
diff --git a/www/js/directives.js b/www/js/directives.js
index 1fe82e0fe59078a369afa73be23e8850b303ad48..f7f9c58e1f6e3c5632c43ca5760a2d751ed4ca4b 100644
--- a/www/js/directives.js
+++ b/www/js/directives.js
@@ -1,4 +1,4 @@
-angular.module('cesium')
+angular.module('cesium.directives', [])
 
   // Add new compare-to directive (need for form validation)
   .directive("compareTo", function() {
diff --git a/www/js/platform.js b/www/js/platform.js
index 2c9d9e1ef3328952987f647575058965584d6a45..e5db212f3824977fcbbaff1a33e6c473c4694663 100644
--- a/www/js/platform.js
+++ b/www/js/platform.js
@@ -1,5 +1,91 @@
 
-angular.module('cesium.platform', ['cesium.config', 'cesium.services'])
+angular.module('cesium.platform', ['ngIdle', 'cesium.config', 'cesium.services'])
+
+  // Translation i18n
+  .config(function ($translateProvider, csConfig) {
+    'ngInject';
+
+    $translateProvider
+      .uniformLanguageTag('bcp47')
+      .determinePreferredLanguage()
+      // Cela fait bugger les placeholder (pb d'affichage des accents en FR)
+      //.useSanitizeValueStrategy('sanitize')
+      .useSanitizeValueStrategy(null)
+      .fallbackLanguage([csConfig.fallbackLanguage ? csConfig.fallbackLanguage : 'en'])
+      .useLoaderCache(true);
+  })
+
+  .config(function($httpProvider, csConfig) {
+    'ngInject';
+
+    // Set default timeout
+    $httpProvider.defaults.timeout = !!csConfig.timeout ? csConfig.timeout : 300000 /* default timeout */;
+
+    //Enable cross domain calls
+    $httpProvider.defaults.useXDomain = true;
+
+    //Remove the header used to identify ajax call  that would prevent CORS from working
+    delete $httpProvider.defaults.headers.common['X-Requested-With'];
+
+    // removeIf(no-device)
+    // Group http request response processing (better performance when many request)
+    $httpProvider.useApplyAsync(true);
+    // endRemoveIf(no-device)
+  })
+
+
+  .config(function($compileProvider, csConfig) {
+    'ngInject';
+
+    $compileProvider.debugInfoEnabled(!!csConfig.debug);
+  })
+
+  .config(function($animateProvider) {
+    'ngInject';
+
+    $animateProvider.classNameFilter( /\banimate-/ );
+  })
+
+  // Configure cache (used by HTTP requests) default max age
+  .config(function (CacheFactoryProvider, csConfig) {
+    'ngInject';
+    angular.extend(CacheFactoryProvider.defaults, { maxAge: csConfig.cacheTimeMs || 60 * 1000 /*1min*/});
+  })
+
+  // Configure screen size detection
+  .config(function(screenmatchConfigProvider) {
+    'ngInject';
+
+    screenmatchConfigProvider.config.rules = 'bootstrap';
+  })
+
+  .config(function($ionicConfigProvider) {
+    'ngInject';
+
+    // JS scrolling need for iOs (see http://blog.ionic.io/native-scrolling-in-ionic-a-tale-in-rhyme/)
+    var enableJsScrolling = ionic.Platform.isIOS();
+    $ionicConfigProvider.scrolling.jsScrolling(enableJsScrolling);
+
+    // Configure the view cache
+    $ionicConfigProvider.views.maxCache(5);
+  })
+
+  .config(function(IdleProvider, csConfig) {
+    'ngInject';
+
+    IdleProvider.idle(csConfig.logoutIdle||10*60/*10min*/);
+    IdleProvider.timeout(csConfig.logoutTimeout||15); // display warning during 15s
+  })
+
+  .factory('$exceptionHandler', function() {
+    'ngInject';
+
+    return function(exception, cause) {
+      if (cause) console.error(exception, cause);
+      else console.error(exception);
+    };
+  })
+
 
   .factory('csPlatform', function (ionicReady, $rootScope, $q, $state, $translate, $timeout, UIUtils,
                                    BMA, Device, csHttp, csConfig, csSettings, csCurrency, csWallet) {
@@ -153,10 +239,10 @@ angular.module('cesium.platform', ['cesium.config', 'cesium.services'])
       BMA.stop();
 
       return $timeout(function() {
-          enableChangeState();
-          started = false;
-          startPromise = null;
-        }, 500);
+        enableChangeState();
+        started = false;
+        startPromise = null;
+      }, 500);
     }
 
     return  {
@@ -168,4 +254,108 @@ angular.module('cesium.platform', ['cesium.config', 'cesium.services'])
       stop: stop
     };
   })
+
+  .run(function($rootScope, $translate, $state, $window, $urlRouter, ionicReady,
+                Device, UIUtils, $ionicConfig, PluginService, csPlatform, csWallet, csSettings, csConfig, csCurrency) {
+    'ngInject';
+
+    // Allow access to service data, from HTML templates
+    $rootScope.config = csConfig;
+    $rootScope.settings = csSettings.data;
+    $rootScope.currency = csCurrency.data;
+    $rootScope.device = Device;
+
+    // Compute the root path
+    var hashIndex = $window.location.href.indexOf('#');
+    $rootScope.rootPath = (hashIndex != -1) ? $window.location.href.substr(0, hashIndex) : $window.location.href;
+    console.debug('[app] Root path is [' + $rootScope.rootPath + ']');
+
+    // removeIf(device)
+    // -- Automatic redirection to HTTPS
+    if ((csConfig.httpsMode === true || csConfig.httpsMode == 'true' ||csConfig.httpsMode === 'force') &&
+      $window.location.protocol != 'https:') {
+      $rootScope.$on('$stateChangeStart', function (event, next, nextParams, fromState) {
+        var path = 'https' + $rootScope.rootPath.substr(4) + $state.href(next, nextParams);
+        if (csConfig.httpsModeDebug) {
+          console.debug('[app] [httpsMode] --- Should redirect to: ' + path);
+          // continue
+        }
+        else {
+          $window.location.href = path;
+        }
+      });
+    }
+    // endRemoveIf(device)
+
+    // We use 'ionicReady()' instead of '$ionicPlatform.ready()', because this one is callable many times
+    ionicReady().then(function() {
+
+      // Keyboard
+      if (Device.keyboard.enable) {
+        // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
+        // for form inputs)
+        Device.keyboard.hideKeyboardAccessoryBar(true);
+
+        // iOS: do not push header up when opening keyboard
+        // (see http://ionicframework.com/docs/api/page/keyboard/)
+        if (ionic.Platform.isIOS()) {
+          Device.keyboard.disableScroll(true);
+        }
+      }
+
+      // Ionic Platform Grade is not A, disabling views transitions
+      if (ionic.Platform.grade.toLowerCase() != 'a') {
+        console.info('[app] Disabling UI effects, because plateform\'s grade is [' + ionic.Platform.grade + ']');
+        UIUtils.setEffects(false);
+      }
+
+      // Status bar style
+      if (window.StatusBar) {
+        // org.apache.cordova.statusbar required
+        StatusBar.styleDefault();
+      }
+
+      // Make sure platform is started
+      return csPlatform.ready();
+    });
+  })
+;
+
+// Workaround to add "".startsWith() if not present
+if (typeof String.prototype.startsWith !== 'function') {
+  console.debug("Adding String.prototype.startsWith() -> was missing on this platform");
+  String.prototype.startsWith = function(prefix) {
+    return this.indexOf(prefix) === 0;
+  };
+}
+
+// Workaround to add "".startsWith() if not present
+if (typeof String.prototype.trim !== 'function') {
+  console.debug("Adding String.prototype.trim() -> was missing on this platform");
+  // Make sure we trim BOM and NBSP
+  var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
+  String.prototype.trim = function() {
+    return this.replace(rtrim, '');
+  };
+}
+
+// Workaround to add Math.trunc() if not present - fix #144
+if (Math && typeof Math.trunc !== 'function') {
+  console.debug("Adding Math.trunc() -> was missing on this platform");
+  Math.trunc = function(number) {
+    return (number - 0.5).toFixed();
+  };
+}
+
+// Workaround to add "".format() if not present
+if (typeof String.prototype.format !== 'function') {
+  console.debug("Adding String.prototype.format() -> was missing on this platform");
+  String.prototype.format = function() {
+    var args = arguments;
+    return this.replace(/{(\d+)}/g, function(match, number) {
+      return typeof args[number] != 'undefined' ? args[number] : match;
+    });
+  };
+}
+
 ;
diff --git a/www/js/services/device-services.js b/www/js/services/device-services.js
index da81f75ecf0faa214f1518ad5c095d6515656bfa..8bfe85dec541b8114753febb0b0410719df13ec8 100644
--- a/www/js/services/device-services.js
+++ b/www/js/services/device-services.js
@@ -85,8 +85,8 @@ angular.module('cesium.device.services', ['cesium.utils.services', 'cesium.setti
         var deferred = $q.defer();
         cordova.plugins.barcodeScanner.scan(
           function(result) {
-            //console.log('bar code result');
-            //console.log(result);
+            console.log('bar code result');
+            console.log(result);
             if (!result.cancelled) {
               deferred.resolve(result.text); // make sure to convert into String
             }
@@ -94,7 +94,10 @@ angular.module('cesium.device.services', ['cesium.utils.services', 'cesium.setti
               deferred.resolve();
             }
           },
-          function(err) {deferred.reject(err);},
+          function(err) {
+            console.log('XXX -> ' + err);
+            deferred.reject(err);
+          },
           n);
         return deferred.promise;
       }
diff --git a/www/js/services/modal-services.js b/www/js/services/modal-services.js
index 5f0a1e6d5bbbfef5695fde84decb017d73142cc8..86d684c372ed44719b6fe9d2fa2b13002341942e 100644
--- a/www/js/services/modal-services.js
+++ b/www/js/services/modal-services.js
@@ -1,5 +1,11 @@
 angular.module('cesium.modal.services', [])
 
+// Useful for modal with no controller
+.controller('EmptyModalCtrl', function ($scope, parameters) {
+  'ngInject';
+
+})
+
 .factory('ModalUtils', function($ionicModal, $rootScope, $q, $injector, $controller, $timeout) {
   'ngInject';
 
@@ -156,7 +162,7 @@ angular.module('cesium.modal.services', [])
   }
 
   function showAbout(parameters) {
-    return ModalUtils.show('templates/modal_about.html','AboutCtrl',
+    return ModalUtils.show('templates/modal_about.html','EmptyModalCtrl',
       parameters);
   }
 
diff --git a/www/js/services/tx-services.js b/www/js/services/tx-services.js
index 59ccff35a677dd615b0e9641386e47e260ffc807..502303b8fa17385fc32fc913af8deb6c510c93a8 100644
--- a/www/js/services/tx-services.js
+++ b/www/js/services/tx-services.js
@@ -30,7 +30,8 @@ angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services',
             var sources = [];
             var lockedOutputs;
             var amount = tx.outputs.reduce(function(sum, output, noffset) {
-              var outputArray = output.split(':',3);
+              // FIXME duniter v1.4.13
+              var outputArray = (typeof output == 'string') ? output.split(':',3) : [output.amount,output.base,output.conditions];
               outputBase = parseInt(outputArray[1]);
               var outputAmount = powBase(parseInt(outputArray[0]), outputBase);
               var outputCondition = outputArray[2];
diff --git a/www/js/services/wallet-services.js b/www/js/services/wallet-services.js
index 37c171b21729b98b5b455b09895a30932c6c9d72..b0d835508127e0bb58399a298e1162b288c82255 100644
--- a/www/js/services/wallet-services.js
+++ b/www/js/services/wallet-services.js
@@ -119,7 +119,8 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se
       var keepAuth = csSettings.data.keepAuthIdle > 0;
 
       var authData;
-      return Modals.showLogin(options)
+      return (options && options.authData && $q.when(options.authData) ||
+        Modals.showLogin(options))
         .then(function(res){
           if (!res || !res.pubkey ||
              (!needLogin && res.pubkey !== data.pubkey) ||
@@ -184,7 +185,7 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se
           return keepAuth ? data : angular.merge({}, data, authData);
         })
         .catch(function(err) {
-          if (err == 'RETRY') {
+          if (err == 'RETRY' && (!options || !options.authData)) {
             return $timeout(function(){
               return login(options);
             }, 300);
@@ -1653,7 +1654,10 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se
       return $timeout(start, 200);
     }
 
-    function start() {
+    function start(options) {
+      options = options || {};
+      options.skipRestore =  angular.isDefined(options.skipRestore) ? options.skipRestore : false;
+
       console.debug('[wallet] Starting...');
       var now = new Date().getTime();
 
@@ -1661,21 +1665,19 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se
           csSettings.ready(),
           csCurrency.ready(),
           BMA.ready()
-        ])
+        ]);
 
-        // Restore
-        .then(restore)
+      // Restore
+      if (!options.skipRestore) startPromise = startPromise.then(restore);
 
-        // Emit ready event
-        .then(function() {
+      // Emit ready event
+      startPromise.then(function() {
           addListeners();
 
           console.debug('[wallet] Started in ' + (new Date().getTime() - now) + 'ms');
 
           started = true;
           startPromise = null;
-          startLoadOptions = null;
-
         })
         .then(function(){
           return data;
diff --git a/www/plugins/es/js/services/registry-services.js b/www/plugins/es/js/services/registry-services.js
index ff8294a0feaa98c2370b9b0258e20202c2f5ff06..8df998c0dbf5f74e5de0982b15723740d34875a4 100644
--- a/www/plugins/es/js/services/registry-services.js
+++ b/www/plugins/es/js/services/registry-services.js
@@ -17,7 +17,7 @@ angular.module('cesium.es.registry.services', ['ngResource', 'cesium.services',
         _internal: {},
       };
 
-    exports._internal.getCategories = esHttp.get('/registry/category/_search?sort=order&from=0&size=1000&_source=name,parent');
+    exports._internal.getCategories = esHttp.get('/page/category/_search?sort=order&from=0&size=1000&_source=name,parent');
 
     function getCategories() {
       if (exports._internal.categories && exports._internal.categories.length) {
@@ -46,7 +46,7 @@ angular.module('cesium.es.registry.services', ['ngResource', 'cesium.services',
         });
     }
 
-    exports._internal.getCategory = esHttp.get('/registry/category/:id');
+    exports._internal.getCategory = esHttp.get('/page/category/:id');
 
     function getCategory(params) {
       return exports._internal.getCategory(params)
@@ -88,10 +88,10 @@ angular.module('cesium.es.registry.services', ['ngResource', 'cesium.services',
       return record;
     }
 
-    exports._internal.searchText = esHttp.get('/registry/record/_search?q=:search');
-    exports._internal.search = esHttp.post('/registry/record/_search');
-    exports._internal.get = esHttp.get('/registry/record/:id');
-    exports._internal.getCommons = esHttp.get('/registry/record/:id?_source=' + fields.commons.join(','));
+    exports._internal.searchText = esHttp.get('/page/record/_search?q=:search');
+    exports._internal.search = esHttp.post('/page/record/_search');
+    exports._internal.get = esHttp.get('/page/record/:id');
+    exports._internal.getCommons = esHttp.get('/page/record/:id?_source=' + fields.commons.join(','));
 
     function search(request) {
       request = request || {};
@@ -164,20 +164,20 @@ angular.module('cesium.es.registry.services', ['ngResource', 'cesium.services',
     exports.record = {
         search: search,
         load: loadData,
-        add: esHttp.record.post('/registry/record'),
-        update: esHttp.record.post('/registry/record/:id/_update'),
+        add: esHttp.record.post('/page/record'),
+        update: esHttp.record.post('/page/record/:id/_update'),
         remove: esHttp.record.remove('registry', 'record'),
         fields: {
           commons: fields.commons
         },
         picture: {
-          all: esHttp.get('/registry/record/:id?_source=pictures')
+          all: esHttp.get('/page/record/:id?_source=pictures')
         },
         comment: esComment.instance('registry')
       };
     exports.currency = {
-        all: esHttp.get('/registry/currency/_search?_source=currencyName,peers.host,peers.port'),
-        get: esHttp.get('/registry/currency/:id/_source')
+        all: esHttp.get('/currency/record/_search?_source=currencyName,peers.host,peers.port'),
+        get: esHttp.get('/currency/record/:id/_source')
       };
     return exports;
   }
diff --git a/www/templates/api/doc.html b/www/templates/api/doc.html
new file mode 100644
index 0000000000000000000000000000000000000000..373bb0cf6cb02264d19f57e40ec2e184bcd9c67f
--- /dev/null
+++ b/www/templates/api/doc.html
@@ -0,0 +1,70 @@
+
+
+  <!-- transfer -->
+  <h2 class="padding" translate>API.DOC.TRANSFER.TITLE</h2>
+
+
+  <div class="list padding no-padding-xs no-padding-top">
+
+    <div class="item item-divider no-border">
+      <p translate>API.DOC.DESCRIPTION_DIVIDER</p>
+    </div>
+
+    <div class="item item-text-wrap">
+      <p translate>API.DOC.TRANSFER.DESCRIPTION</p>
+    </div>
+
+    <div class="item item-divider no-border">
+      <p translate>API.DOC.URL_DIVIDER</p>
+    </div>
+
+    <div class="item item-text-wrap">
+      <p class="gray text-right">
+        {{$root.rootPath}}#/v1/payment/:pubkey?amount=<span class="text-italic" translate>API.DOC.TRANSFER.PARAM_AMOUNT</span>
+      </p>
+    </div>
+
+    <div class="item item-divider no-border">
+      <p translate>API.DOC.PARAMETERS_DIVIDER</p>
+    </div>
+
+    <div class="item item-text-wrap">
+      <p translate>API.DOC.AVAILABLE_PARAMETERS</p>
+      <div class="row">
+        <div class="col col-20 text-italic">amount</div>
+        <div class="col" translate>API.DOC.TRANSFER.PARAM_AMOUNT_HELP</div>
+      </div>
+      <div class="row">
+        <div class="col col-20 text-italic">comment</div>
+        <div class="col" translate>API.DOC.TRANSFER.PARAM_COMMENT_HELP</div>
+      </div>
+      <div class="row">
+        <div class="col col-20 text-italic">name</div>
+        <div class="col" translate>API.DOC.TRANSFER.PARAM_NAME_HELP</div>
+      </div>
+      <div class="row">
+        <div class="col col-20 text-italic">redirect_url</div>
+        <div class="col" translate>API.DOC.TRANSFER.PARAM_REDIRECT_URL_HELP</div>
+      </div>
+      <div class="row">
+        <div class="col col-20 text-italic">cancel_url</div>
+        <div class="col" translate>API.DOC.TRANSFER.PARAM_CANCEL_URL_HELP</div>
+      </div>
+    </div>
+    <div class="item item-button-right">
+      <h2>&nbsp;</h2>
+      <a ui-sref="api.transfer(transferData)" class="button button-raised button-positive" translate>API.DOC.BTN_DEMO</a>
+    </div>
+
+
+    <!-- demo result -->
+    <div class="item item-text-wrap" ng-if="result.type === 'payment' && !result.cancelled">
+      <h2 class="text-right balanced" translate>API.DOC.SUCCEED</h2>
+      <h4 class="gray" translate>API.DOC.RESULT</h4>
+      <p class="balanced-100-bg padding dark"> {{result.content}}</p>
+    </div>
+    <div class="item item-text-wrap" ng-if="result.type === 'payment' && result.cancelled">
+      <h2 class="text-right assertive" translate>API.DOC.CANCELLED</h2>
+    </div>
+
+  </div>
diff --git a/www/templates/api/home.html b/www/templates/api/home.html
new file mode 100644
index 0000000000000000000000000000000000000000..15b4106a3ec2ab6c969b59c6bb972996df9ba525
--- /dev/null
+++ b/www/templates/api/home.html
@@ -0,0 +1,38 @@
+<ion-view  class="circle-bg-dark">
+  <ion-nav-title>
+    <span class="title visible-xs visible-sm" translate>API.HOME.TITLE</span>
+  </ion-nav-title>
+
+  <ion-content class=" has-header no-padding-xs positive-900-bg ">
+
+    <br class="hidden-xs"/>
+
+    <div class="light text-center" >
+      <h4 class="hidden-xs" translate>API.HOME.MESSAGE</h4>
+      <h4 class="visible-xs" translate>API.HOME.MESSAGE_SHORT</h4>
+    </div>
+
+    <br class="hidden-xs"/>
+
+    <div class="row no-padding-xs">
+      <div class="col col-20 hidden-xs hidden-sm">&nbsp;</div>
+      <div class="col ">
+
+        <div class="light-bg no-padding">
+          <!-- include documentation -->
+          <ng-include src="'templates/api/doc.html'"></ng-include>
+        </div>
+      </div>
+
+      <div class="col col-20 hidden-xs hidden-sm text-center" id="home" >
+        <div style="display: block; width: 100%;">
+          <div class="logo"></div>
+          <small class="light padding-top">v{{$root.config.version}}</small>
+        </div>
+      </div>
+    </div>
+
+  </ion-content>
+
+</ion-view>
+
diff --git a/www/templates/api/menu.html b/www/templates/api/menu.html
new file mode 100644
index 0000000000000000000000000000000000000000..a4751ae51b9578bd1b42556c6c873fc2c20ac5d7
--- /dev/null
+++ b/www/templates/api/menu.html
@@ -0,0 +1,18 @@
+<ion-side-menus bind-notifier="{locale:$root.settings.locale.id}">
+  <!-- HEADER -->
+  <ion-side-menu-content>
+    <ion-nav-bar class="bar-dark" title-align="left">
+      <ion-nav-back-button class="no-text">
+      </ion-nav-back-button>
+
+      <ion-nav-buttons side="left">
+      </ion-nav-buttons>
+      <ion-nav-buttons side="right" >
+      </ion-nav-buttons>
+    </ion-nav-bar>
+    <ion-nav-view name="menuContent"></ion-nav-view>
+
+  </ion-side-menu-content>
+
+
+</ion-side-menus>
diff --git a/www/templates/api/transfer.html b/www/templates/api/transfer.html
new file mode 100644
index 0000000000000000000000000000000000000000..01fc26567f15830a054bc17a7020f565c57864c1
--- /dev/null
+++ b/www/templates/api/transfer.html
@@ -0,0 +1,93 @@
+
+<ion-nav-view class="circle-bg-dark">
+  <ion-nav-title>
+    <h1 class="title" ng-bind-html="'API.TRANSFER.TITLE' | translate">
+    </h1>
+    <span class="visible-xs visible-sm" translate>API.TRANSFER.TITLE</span>
+  </ion-nav-title>
+
+  <ion-nav-buttons side="left">
+    <button class="button button-clear visible-xs" ng-click="closeModal()" translate>COMMON.BTN_CANCEL
+    </button>
+  </ion-nav-buttons>
+
+  <ion-nav-buttons side="right">
+    <button class="button button-icon button-clear icon ion-android-send visible-xs" ng-click="doLogin()">
+    </button>
+  </ion-nav-buttons>
+
+  <ion-content class=" has-header no-padding-xs positive-900-bg text-center">
+
+    <br class="hidden-xs"/>
+
+    <div class="row no-padding-xs">
+      <div class="col col-20 hidden-xs hidden-sm">
+        &nbsp;
+      </div>
+      <div class="col no-padding-xs">
+
+        <div class="light-bg">
+
+          <h2 class="padding-top">
+            <span class="hidden-xs" translate>API.TRANSFER.TITLE</span>
+            <span class="visible-xs" translate>API.TRANSFER.TITLE_SHORT</span>
+          </h2>
+
+          <ng-include src="'templates/login/form_login.html'"></ng-include>
+
+        </div>
+        <br class="hidden-xs"/>
+        <br class="hidden-xs"/>
+        <div class="list padding no-padding-xs light-bg expert-mode">
+          <div class="item">
+            <p translate>API.TRANSFER.SUMMARY</p>
+          </div>
+
+          <div class="item item-icon-left-padding item-tx no-border ">
+            <h2 translate>API.TRANSFER.AMOUNT</h2>
+            <div class="badge item-note badge-calm" ng-bind-html="transferData.amount|formatAmount:{useRelative: false, currency: $root.currency.name}"></div>
+            <div class="badge badge-secondary" ng-bind-html="transferData.amount|formatAmount:{useRelative: true, currency: $root.currency.name}"></div>
+          </div>
+          <div class="item item-icon-left-padding" ng-if="transferData.name">
+            <h2 translate>API.TRANSFER.NAME</h2>
+            <div class="badge item-note">
+              {{transferData.name}}
+            </div>
+          </div>
+          <div class="item item-icon-left-padding item-text-wrap">
+            <h2 translate>API.TRANSFER.PUBKEY</h2>
+            <div class="badge">
+              <br class="visible-xs"/>
+              {{transferData.pubkey}}
+            </div>
+          </div>
+
+          <div class="item item-icon-left-padding">
+            <h2 translate>API.TRANSFER.COMMENT</h2>
+            <div class="badge item-note">
+              {{transferData.comment}}
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="col col-20 hidden-xs hidden-sm text-center" id="home" >
+        <div style="display: block; width: 100%;">
+          <div class="logo text-center"></div>
+          <small class="light padding-top">v{{$root.config.version}}</small>
+        </div>
+      </div>
+    </div>
+
+    <p class="visible-xs visible-sm light padding-top">
+      {{'COMMON.APP_NAME'|translate}}
+      - <a href="#" ng-click="showAboutModal($event)">v{{$root.config.version}}</a>
+    </p>
+
+    <p class="hidden-xs hidden-sm gray padding-top">
+      {{'COMMON.APP_NAME'|translate}} v{{$root.config.version}}
+      - <a href="#" ng-click="showAboutModal($event)" title="{{'HOME.BTN_ABOUT'|translate}}">{{'HOME.BTN_ABOUT'|translate}}</a>
+      - <a ui-sref="app.home" target="_blank" title="{{'API.COMMON.LINK_DOC_HELP'|translate}}">{{'API.COMMON.LINK_DOC'|translate}}</a>
+    </p>
+
+  </ion-content>
+</ion-nav-view>
diff --git a/www/templates/login/form_login.html b/www/templates/login/form_login.html
new file mode 100644
index 0000000000000000000000000000000000000000..6c05dd7c25ae16d41753f0feb84f346c50d6064f
--- /dev/null
+++ b/www/templates/login/form_login.html
@@ -0,0 +1,76 @@
+
+  <form name="loginForm" novalidate="" ng-submit="doLogin()" autocomplete="off">
+
+   <div class="list padding no-padding-xs"
+         ng-init="setForm(loginForm)"
+         ng-switch on="formData.method">
+
+     <div class="item hidden-xs no-padding" ng-if="showMethods">
+       <div class="pull-right">
+          <a class="button button-text button-small-padding icon-right ink"
+             ng-click="showMethodsPopover($event)">
+            <i class="icon ion-wrench"></i>
+            {{'LOGIN.BTN_METHODS'| translate}}
+          </a>&nbsp;
+          <a class="button button-icon positive button-small-padding icon ion-ios-help-outline"
+            style="right: 8px;"
+            ng-click="showHelpModal('login-method')">
+          </a>
+       </div>
+     </div>
+
+      <!-- Form content, depending of the login method -->
+      <div ng-switch-when="SCRYPT_DEFAULT">
+        <ng-include src="'templates/login/form_scrypt.html'"></ng-include>
+      </div>
+      <div ng-switch-when="SCRYPT_ADVANCED">
+        <ng-include src="'templates/login/form_scrypt_advanced.html'"></ng-include>
+      </div>
+      <div ng-switch-when="PUBKEY">
+        <ng-include src="'templates/login/form_pubkey.html'"></ng-include>
+      </div>
+      <div ng-switch-when="FILE">
+        <ng-include src="'templates/login/form_file_import.html'"></ng-include>
+      </div>
+      <div ng-switch-default>
+        <ng-include src="'templates/login/form_scrypt.html'"></ng-include>
+      </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-positive ink" ng-class="{'button-assertive': isAuth, 'button-positive': !isAuth}" type="submit">
+        {{isAuth ? 'AUTH.BTN_AUTH' : 'COMMON.BTN_LOGIN' | translate}}
+      </button>
+    </div>
+
+    <div class="text-center no-padding visible-xs">
+      <br/>
+      <a ng-click="showMethodsPopover($event)">
+        <i class="ion-loop"></i>
+        <span translate>LOGIN.BTN_METHODS_DOTS</span>
+      </a>
+      <br/><br/>
+    </div>
+
+    <!-- Register ? -->
+    <ng-if ng-if="!isAuth">
+      <div class="text-center no-padding">
+        {{'LOGIN.NO_ACCOUNT_QUESTION'|translate}}
+        <br class="visible-xs"/>
+        <a ng-click="showJoinModal()" translate>
+          LOGIN.CREATE_ACCOUNT
+        </a>
+      </div>
+
+      <br class="visible-xs"/>
+
+      <div class="text-center no-padding">
+        <a ng-click="showAccountSecurityModal()" translate>
+          LOGIN.FORGOTTEN_ID
+        </a>
+      </div>
+    </ng-if>
+  </form>
diff --git a/www/templates/login/modal_login.html b/www/templates/login/modal_login.html
index f2258d6ed70d4ae43450d844699375c70a56ea87..20d59dd993450dde3a28c317383f3b602c7948a9 100644
--- a/www/templates/login/modal_login.html
+++ b/www/templates/login/modal_login.html
@@ -15,80 +15,6 @@
   </ion-header-bar>
 
   <ion-content>
-    <form name="loginForm" novalidate="" ng-submit="doLogin()" autocomplete="off">
-
-     <div class="list padding no-padding-xs"
-           ng-init="setForm(loginForm)"
-           ng-switch on="formData.method">
-
-       <div class="item hidden-xs no-padding" ng-if="showMethods">
-         <div class="pull-right">
-            <a class="button button-text button-small-padding icon-right ink"
-               ng-click="showMethodsPopover($event)">
-              <i class="icon ion-wrench"></i>
-              {{'LOGIN.BTN_METHODS'| translate}}
-            </a>&nbsp;
-            <a class="button button-icon positive button-small-padding icon ion-ios-help-outline"
-              style="right: 8px;"
-              ng-click="showHelpModal('login-method')">
-            </a>
-         </div>
-       </div>
-
-        <!-- Form content, depending of the login method -->
-        <div ng-switch-when="SCRYPT_DEFAULT">
-          <ng-include src="'templates/login/form_scrypt.html'"></ng-include>
-        </div>
-        <div ng-switch-when="SCRYPT_ADVANCED">
-          <ng-include src="'templates/login/form_scrypt_advanced.html'"></ng-include>
-        </div>
-        <div ng-switch-when="PUBKEY">
-          <ng-include src="'templates/login/form_pubkey.html'"></ng-include>
-        </div>
-        <div ng-switch-when="FILE">
-          <ng-include src="'templates/login/form_file_import.html'"></ng-include>
-        </div>
-        <div ng-switch-default>
-          <ng-include src="'templates/login/form_scrypt.html'"></ng-include>
-        </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-positive ink" ng-class="{'button-assertive': isAuth, 'button-positive': !isAuth}" type="submit">
-          {{isAuth ? 'AUTH.BTN_AUTH' : 'COMMON.BTN_LOGIN' | translate}}
-        </button>
-      </div>
-
-      <div class="text-center no-padding visible-xs">
-        <br/>
-        <a ng-click="showMethodsPopover($event)">
-          <i class="ion-loop"></i>
-          <span translate>LOGIN.BTN_METHODS_DOTS</span>
-        </a>
-        <br/><br/>
-      </div>
-
-      <!-- Register ? -->
-      <ng-if ng-if="!isAuth">
-        <div class="text-center no-padding">
-          {{'LOGIN.NO_ACCOUNT_QUESTION'|translate}}
-          <br class="visible-xs"/>
-          <a ng-click="showJoinModal()" translate>
-            LOGIN.CREATE_ACCOUNT
-          </a>
-        </div>
-
-        <br class="visible-xs"/>
-
-        <div class="text-center no-padding">
-          <a ng-click="showAccountSecurityModal()" translate>
-            LOGIN.FORGOTTEN_ID
-          </a>
-        </div>
-      </ng-if>
-    </form>
+    <ng-include src="'templates/login/form_login.html'"></ng-include>
   </ion-content>
 </ion-modal-view>
diff --git a/www/templates/modal_about.html b/www/templates/modal_about.html
index f915aac54586de7c7ea3c1070cf7edcbe073bc05..bc90dc6922adbd5cd70ca07083f0648f0ce6af48 100644
--- a/www/templates/modal_about.html
+++ b/www/templates/modal_about.html
@@ -10,8 +10,8 @@
     <div class="list item-wrap-text">
       <div class="item item-complex item-icon-left item-text-wrap">
         <div class="item-content">
-          <span>{{'COMMON.APP_NAME'|translate}}&nbsp;{{'COMMON.APP_VERSION'|translate:config}}</span>
-          <h3 ng-if="config.build" class="gray">{{'COMMON.APP_BUILD'|translate:config}}</h3>
+          <span>{{'COMMON.APP_NAME'|translate}}&nbsp;{{'COMMON.APP_VERSION'|translate:$root.config}}</span>
+          <h3 ng-if="$root.config.build" class="gray">{{'COMMON.APP_BUILD'|translate:$root.config}}</h3>
           <span translate>ABOUT.LICENSE</span>
         </div>
       </div>
@@ -46,7 +46,7 @@
           <h2>{{'ABOUT.DEV_WARNING'|translate}}</h2>
           <span translate>ABOUT.DEV_WARNING_MESSAGE</span>
           <br/>
-          <a href="{{config.newIssueUrl}}"
+          <a href="{{$root.config.newIssueUrl}}"
              target="_system"
              translate>ABOUT.REPORT_ISSUE</a>
         </div>