diff --git a/src/js/entry/web.js b/src/js/entry/web.js index 82f2f47b4..d7502a98c 100644 --- a/src/js/entry/web.js +++ b/src/js/entry/web.js @@ -31,7 +31,7 @@ require('../services/rippletxt.service.js'); require('../services/federation.service.js'); require('../services/domainalias.service.js'); require('../services/history.service.js'); -require('../services/notifications.service.js'); +require('../services/api.service.js'); require('../services/authflow.service.js'); require('../services/blob.service.js'); @@ -58,7 +58,7 @@ var appDependencies = [ 'tracker', 'appManager', 'history', - 'notifications', + 'api', // ID Service related services 'blob', 'authflow', diff --git a/src/js/services/api.service.js b/src/js/services/api.service.js new file mode 100644 index 000000000..1ffe916fb --- /dev/null +++ b/src/js/services/api.service.js @@ -0,0 +1,65 @@ +'use strict'; + +/** + * Backend API + * Interaction with Ripple Trade Backend REST API + */ + +var module = angular.module('api', []); + +module.factory('rpAPI', ['$http', '$q', function($http, $q) { + var rpAPI = {}; + var httpOptions = {}; + + rpAPI.setHttpOptions = function() { + httpOptions = { + headers: {'Authorization': 'Bearer ' + store.get('backend_token')}, + timeout: 8000 + }; + }; + + rpAPI.setHttpOptions(); + + rpAPI.getSubscription = function() { + return $http.get(Options.backend_url + '/api/subscription', httpOptions); + }; + + rpAPI.updateSubscription = function(subscription) { + return $http.put(Options.backend_url + '/api/subscription', subscription, httpOptions); + }; + + rpAPI.addTransaction = function(transaction, result, hash, submit_response_time) { + var request_body = { + transaction: transaction, + result: result, + hash: hash, + submit_response_time: submit_response_time + }; + + return $http.post(Options.backend_url + '/api/transactions', request_body, httpOptions); + }; + + rpAPI.getUserProfile = function() { + return $http.get(Options.backend_url + '/api/user', httpOptions); + }; + + rpAPI.getUserAccess = function() { + return $http.get(Options.backend_url + '/api/user/access', httpOptions).then(function(res) { + if (res.data.access === 'allowed') { + return 'allowed'; + } + + return $q.reject('denied'); + }); + }; + + rpAPI.getBlob = function() { + return $http.get(Options.backend_url + '/api/blob', httpOptions); + }; + + rpAPI.updateBlob = function(blobData) { + return $http.post(Options.backend_url + '/api/blob', blobData, httpOptions); + }; + + return rpAPI; +}]); diff --git a/src/js/services/blob.service.js b/src/js/services/blob.service.js index d963ebc97..48e9111d1 100644 --- a/src/js/services/blob.service.js +++ b/src/js/services/blob.service.js @@ -2,7 +2,7 @@ var module = angular.module('blob', []); -module.factory('rpBlob', ['$rootScope', '$http', '$q', function($scope, $http, $q) { +module.factory('rpBlob', ['$rootScope', '$q', 'rpAPI', function($scope, $q, api) { // Blob object class function BlobObj() { @@ -43,11 +43,7 @@ module.factory('rpBlob', ['$rootScope', '$http', '$q', function($scope, $http, $ BlobObj.prototype.init = function() { var self = this; - return $http.get( - Options.backend_url + '/api/blob', { - headers: {'Authorization': 'Bearer ' + store.get('backend_token')}, - timeout: 8000 - }).then(function(response) { + return api.getBlob().then(function(response) { if (!response.data || !response.data.data || !response.data.data.account_id) { return $q.reject('Could not retrieve blob'); } @@ -275,12 +271,8 @@ module.factory('rpBlob', ['$rootScope', '$http', '$q', function($scope, $http, $ blobData.encrypted_secret = this.encrypted_secret; blobData.data = this.data; - return $http.post( - Options.backend_url + '/api/blob', - blobData, { - headers: {'Authorization': 'Bearer ' + store.get('backend_token')}, - timeout: 8000 - }).then(function(response) { + return api.updateBlob(blobData) + .then(function(response) { if (!response.data) { return callback(new Error('Could not save blob')); } diff --git a/src/js/services/id.service.js b/src/js/services/id.service.js index d1719c01b..50c4ec83e 100644 --- a/src/js/services/id.service.js +++ b/src/js/services/id.service.js @@ -12,8 +12,8 @@ var webutil = require('../util/web'), var module = angular.module('id', ['authflow', 'blob']); module.factory( - 'rpId', ['$rootScope', '$location', '$route', '$routeParams', '$timeout', '$http', 'rpAuthFlow', 'rpBlob', '$q', - function($scope, $location, $route, $routeParams, $timeout, $http, $authflow, $blob, $q) { + 'rpId', ['$rootScope', '$location', '$route', '$routeParams', '$timeout', '$q', 'rpAuthFlow', 'rpBlob', 'rpAPI', + function($scope, $location, $route, $routeParams, $timeout, $q, authflow, blob, api) { /** * Identity manager * @@ -250,7 +250,7 @@ module.factory( Id.prototype.exists = function(username, callback) { username = Id.normalizeUsernameForDisplay(username); - $authflow.exists(Id.normalizeUsernameForInternals(username), function(err, data) { + authflow.exists(Id.normalizeUsernameForInternals(username), function(err, data) { if (!err && data) { // Blob found, new auth method callback(null, true); @@ -275,17 +275,19 @@ module.factory( } store.set('backend_token', backend_token); + // Update HTTP Options using new backend token value + api.setHttpOptions(); - var blobObj = new $blob(); + var blobObj = new blob(); // init returns a promise - blobObj.init().then(function(blob) { + blobObj.init().then(function(blobData) { // Ensure certain properties exist - $.extend(true, blob, Id.minimumBlob); + $.extend(true, blobData, Id.minimumBlob); - $scope.userBlob = blob; - self.setUsername(blob.ripple_name); - self.setAccount(blob.data.account_id); + $scope.userBlob = blobData; + self.setUsername(blobData.ripple_name); + self.setAccount(blobData.data.account_id); self.loginStatus = true; $scope.loginStatus = true; $scope.$broadcast('$blobUpdate'); @@ -323,22 +325,22 @@ module.factory( // self.loginStatus = true; // $scope.loginStatus = true; - var blobObj = new $blob(); + var blobObj = new blob(); // init returns a promise - blobObj.init().then(function(blob) { + blobObj.init().then(function(blobData) { // Ensure certain properties exist - $.extend(true, blob, Id.minimumBlob); + $.extend(true, blobData, Id.minimumBlob); - $scope.userBlob = blob; - self.setUsername(blob.ripple_name); - self.setAccount(blob.data.account_id); + $scope.userBlob = blobData; + self.setUsername(blobData.ripple_name); + self.setAccount(blobData.data.account_id); self.loginStatus = true; $scope.loginStatus = true; $scope.$broadcast('$blobUpdate'); store.set('ripple_known', true); - callback(null, blob); + callback(null, blobData); }, function(err) { callback(new Error(err)); @@ -365,14 +367,6 @@ module.factory( // location.href = location.protocol + '//' + location.hostname + port + location.pathname; }; - Id.prototype.getUserProfile = function() { - return $http.get( - Options.backend_url + '/api/user', - { - headers: {'Authorization': 'Bearer ' + store.get('backend_token')} - }); - }; - Id.prototype.unlock = function(username, password, callback) { // Callback is optional if ('function' !== typeof callback) { @@ -382,7 +376,7 @@ module.factory( // username = Id.normalizeUsernameForDisplay(username); // password = Id.normalizePassword(password); - $authflow.unlock(username, password, function(err, resp) { + authflow.unlock(username, password, function(err, resp) { if (err) { callback(err); return; diff --git a/src/js/services/notifications.service.js b/src/js/services/notifications.service.js deleted file mode 100644 index ec71edf00..000000000 --- a/src/js/services/notifications.service.js +++ /dev/null @@ -1,32 +0,0 @@ -'use strict'; - -/** - * Notifications - * Interaction with notifications REST API - */ - -var module = angular.module('notifications', []); - -module.factory('rpNotifications', ['$http', function($http) { - var rpNotifications = {}; - - rpNotifications.getSubscription = function() { - return $http.get( - Options.backend_url + '/api/subscription', - { - headers: {'Authorization': 'Bearer ' + store.get('backend_token')} - }); - }; - - rpNotifications.updateSubscription = function(subscription) { - return $http.put( - Options.backend_url + '/api/subscription', - subscription, - { - headers: {Authorization: 'Bearer ' + store.get('backend_token')} - } - ); - }; - - return rpNotifications; -}]); diff --git a/src/js/services/txqueue.service.js b/src/js/services/txqueue.service.js index e5ac669ec..20b68e98e 100644 --- a/src/js/services/txqueue.service.js +++ b/src/js/services/txqueue.service.js @@ -10,9 +10,9 @@ angular .module('txQueue', []) .service('rpTxQueue', rpTxQueue); -rpTxQueue.$inject = ['$rootScope', 'rpNetwork', 'rpKeychain', 'rpId']; +rpTxQueue.$inject = ['$rootScope', 'rpNetwork', 'rpKeychain', 'rpId', 'rpAPI']; -function rpTxQueue($scope, network, keychain, id) { +function rpTxQueue($scope, network, keychain, id, api) { return { addTransaction: addTransaction, checkQueue: checkQueue, @@ -47,7 +47,7 @@ function rpTxQueue($scope, network, keychain, id) { return; } $scope.userBlob.unshift('/clients/rippletradecom/txQueue', item); - } + }; if ($scope.userBlob.data && !$scope.userBlob.data.clients) { // there is bug in RippleLib with unshift operation - if @@ -76,8 +76,13 @@ function rpTxQueue($scope, network, keychain, id) { transaction.remote = network.remote; transaction.secret(secret); - // If account is funded submit the transaction right away - transaction.submit(); + api.getUserAccess().then(function(res) { + // If account is funded submit the transaction right away + transaction.submit(); + }, function(err2) { + // err + }); + }); } } @@ -112,7 +117,12 @@ function rpTxQueue($scope, network, keychain, id) { var tx = ripple.Transaction.from_json(item.tx_json); tx.remote = network.remote; tx.secret(secret); - tx.submit(); + + api.getUserAccess().then(function(res) { + tx.submit(); + }, function(err2) { + // err + }); }); self.emptyQueue(); diff --git a/src/js/tabs/brl.controller.js b/src/js/tabs/brl.controller.js index d761800ee..75c0dbfa5 100644 --- a/src/js/tabs/brl.controller.js +++ b/src/js/tabs/brl.controller.js @@ -13,13 +13,13 @@ BrlTab.prototype.mainMenu = 'fund'; BrlTab.prototype.angular = function (module) { - module.controller('BrlCtrl', ['$scope', 'rpId', 'rpAppManager', 'rpTracker', '$routeParams', 'rpKeychain', 'rpNetwork', '$timeout', - function ($scope, id, appManager, rpTracker, $routeParams, keychain, network, $timeout) { + module.controller('BrlCtrl', ['$scope', 'rpId', 'rpAppManager', 'rpTracker', '$routeParams', 'rpKeychain', 'rpNetwork', 'rpAPI', '$timeout', + function ($scope, id, appManager, rpTracker, $routeParams, keychain, network, api, $timeout) { $scope.toggle_instructions = function() { $scope.showInstructions = !$scope.showInstructions; - } + }; $scope.save_account = function () { @@ -59,6 +59,8 @@ BrlTab.prototype.angular = function (module) $scope.loading = false; $scope.editing = false; }); + + api.addTransaction(res.tx_json, {Status: 'success'}, res.tx_json.hash, new Date().toString()); }) .on('error', function (res) { setEngineStatus(res, false); @@ -71,6 +73,8 @@ BrlTab.prototype.angular = function (module) $scope.editing = false; }); }); + + api.addTransaction(res.tx_json, {Status: 'error'}, res.tx_json.hash, new Date().toString()); }); function setEngineStatus(res, accepted) { @@ -116,9 +120,21 @@ BrlTab.prototype.angular = function (module) $scope.mode = 'granting'; tx.secret(secret); - tx.submit(); + api.getUserAccess().then(function(res) { + tx.submit(); + }, function(err2) { + console.log('error', err2); + setImmediate(function () { + $scope.$apply(function () { + $scope.mode = 'error'; + + $scope.loading = false; + $scope.editing = false; + }); + }); + }); }); }; diff --git a/src/js/tabs/btc.controller.js b/src/js/tabs/btc.controller.js index a6fa64dd0..def3b0750 100644 --- a/src/js/tabs/btc.controller.js +++ b/src/js/tabs/btc.controller.js @@ -13,8 +13,8 @@ BtcTab.prototype.tabName = 'btc'; BtcTab.prototype.mainMenu = 'fund'; BtcTab.prototype.angular = function(module) { module.controller('BtcCtrl', [ - '$scope', 'rpId', 'rpAppManager', 'rpTracker', '$routeParams', 'rpNetwork', 'rpKeychain', - function($scope, id, appManager, rpTracker, $routeParams, network, keychain) { + '$scope', 'rpId', 'rpAppManager', 'rpTracker', '$routeParams', 'rpNetwork', 'rpKeychain', 'rpAPI', + function($scope, id, appManager, rpTracker, $routeParams, network, keychain, api) { $scope.accountLines = {}; $scope.showComponent = []; $scope.showInstructions = false; @@ -155,6 +155,8 @@ BtcTab.prototype.angular = function(module) { module.controller('BtcCtrl', [ $scope.btcLoading = false; $scope.btcediting = false; }); + + api.addTransaction(res.tx_json, {Status: 'success'}, res.tx_json.hash, new Date().toString()); }) .on('error', function (res) { setEngineStatus(res, false); @@ -167,6 +169,8 @@ BtcTab.prototype.angular = function(module) { module.controller('BtcCtrl', [ $scope.btcediting = false; }); }); + + api.addTransaction(res.tx_json, {Status: 'error'}, res.tx_json.hash, new Date().toString()); }); function setEngineStatus(res, accepted) { @@ -212,8 +216,20 @@ BtcTab.prototype.angular = function(module) { module.controller('BtcCtrl', [ $scope.btcMode = 'granting'; tx.secret(secret); - tx.submit(); + api.getUserAccess().then(function(res) { + tx.submit(); + }, function(err2) { + console.log('error', err2); + setImmediate(function () { + $scope.$apply(function() { + $scope.btcMode = 'error'; + + $scope.btcLoading = false; + $scope.btcediting = false; + }); + }); + }); }); diff --git a/src/js/tabs/cad.controller.js b/src/js/tabs/cad.controller.js index 173374950..32baa21ff 100644 --- a/src/js/tabs/cad.controller.js +++ b/src/js/tabs/cad.controller.js @@ -55,6 +55,8 @@ CadTab.prototype.angular = function(module) { $scope.loading = false; $scope.editing = false; }); + + api.addTransaction(res.tx_json, {Status: 'success'}, res.tx_json.hash, new Date().toString()); }) .on('error', function(res) { setEngineStatus(res, false); @@ -67,6 +69,8 @@ CadTab.prototype.angular = function(module) { $scope.editing = false; }); }); + + api.addTransaction(res.tx_json, {Status: 'error'}, res.tx_json.hash, new Date().toString()); }); function setEngineStatus(res, accepted) { @@ -109,7 +113,20 @@ CadTab.prototype.angular = function(module) { } $scope.mode = 'granting'; tx.secret(secret); - tx.submit(); + + api.getUserAccess().then(function(res) { + tx.submit(); + }, function(err2) { + console.log('error', err2); + setImmediate(function() { + $scope.$apply(function() { + $scope.mode = 'error'; + + $scope.loading = false; + $scope.editing = false; + }); + }); + }); }); }; $scope.$watch('lines', function() { diff --git a/src/js/tabs/eur.controller.js b/src/js/tabs/eur.controller.js index f94e392a7..c5f181877 100644 --- a/src/js/tabs/eur.controller.js +++ b/src/js/tabs/eur.controller.js @@ -11,11 +11,11 @@ util.inherits(EurTab, Tab); EurTab.prototype.tabName = 'eur'; EurTab.prototype.mainMenu = 'fund'; -EurTab.prototype.angular = function (module) -{ +EurTab.prototype.angular = function(module) { - module.controller('EurCtrl', ['$scope', 'rpId', 'rpAppManager', 'rpTracker', '$routeParams', 'rpKeychain', 'rpNetwork', '$timeout', - function ($scope, id, appManager, rpTracker, $routeParams, keychain, $network, $timeout) + module.controller('EurCtrl', ['$scope', 'rpId', 'rpAppManager', 'rpTracker', '$routeParams', + 'rpKeychain', 'rpNetwork', 'rpAPI', '$timeout', + function ($scope, id, appManager, rpTracker, $routeParams, keychain, $network, api, $timeout) { $scope.toggle_instructions = function () { $scope.showInstructions = !$scope.showInstructions; @@ -23,7 +23,7 @@ EurTab.prototype.angular = function (module) $scope.toggle_gatehub_instructions = function() { $scope.show3Instructions = !$scope.show3Instructions; - } + }; $scope.save_account = function() { $scope.loading = true; @@ -62,6 +62,8 @@ EurTab.prototype.angular = function (module) $scope.loading = false; $scope.editing = false; }); + + api.addTransaction(res.tx_json, {Status: 'success'}, res.tx_json.hash, new Date().toString()); }) .on('error', function (res) { setEngineStatus(res, false); @@ -74,6 +76,8 @@ EurTab.prototype.angular = function (module) $scope.editing = false; }); }); + + api.addTransaction(res.tx_json, {Status: 'error'}, res.tx_json.hash, new Date().toString()); }); function setEngineStatus(res, accepted) { @@ -118,7 +122,21 @@ EurTab.prototype.angular = function (module) $scope.mode = 'granting'; tx.secret(secret); - tx.submit(); + + api.getUserAccess().then(function(res) { + tx.submit(); + }, function(err2) { + console.log('error', err2); + setImmediate(function () { + $scope.$apply(function () { + $scope.mode = 'error'; + + $scope.loading = false; + $scope.editing = false; + }); + }); + }); + }); }; @@ -158,6 +176,8 @@ EurTab.prototype.angular = function (module) $scope.eur3loading = false; }); + + api.addTransaction(res.tx_json, {Status: 'success'}, res.tx_json.hash, new Date().toString()); }) .on('error', function(res) { setEngineStatus(res, false); @@ -167,6 +187,8 @@ EurTab.prototype.angular = function (module) $scope.eur3loading = false; }); }); + + api.addTransaction(res.tx_json, {Status: 'error'}, res.tx_json.hash, new Date().toString()); }); function setEngineStatus(res, accepted) { @@ -209,7 +231,17 @@ EurTab.prototype.angular = function (module) } tx.secret(secret); - tx.submit(); + + api.getUserAccess().then(function (res) { + tx.submit(); + }, function (err2) { + console.log('error', err2); + setImmediate(function () { + $scope.$apply(function () { + $scope.eur3loading = false; + }); + }); + }); }); }; diff --git a/src/js/tabs/exchange.controller.js b/src/js/tabs/exchange.controller.js index bf3522b50..852b5891a 100644 --- a/src/js/tabs/exchange.controller.js +++ b/src/js/tabs/exchange.controller.js @@ -20,8 +20,8 @@ ExchangeTab.prototype.mainMenu = 'exchange'; ExchangeTab.prototype.angular = function (module) { module.controller('ExchangeCtrl', ['$scope', '$timeout', '$routeParams', - 'rpId', 'rpNetwork', 'rpTracker', 'rpKeychain', '$rootScope', '$location', - function ($scope, $timeout, $routeParams, id, network, rpTracker, keychain, $rootScope, $location) + 'rpId', 'rpNetwork', 'rpTracker', 'rpKeychain', 'rpAPI', '$rootScope', '$location', + function ($scope, $timeout, $routeParams, id, network, rpTracker, keychain, api, $rootScope, $location) { var pathUpdateTimeout; @@ -416,6 +416,8 @@ ExchangeTab.prototype.angular = function (module) Amount: amount.to_number(false) }; rpTracker.track('Convert order result', eventProp); + + api.addTransaction(res.tx_json, eventProp, res.tx_json.hash, new Date().toString()); } catch (err) { console.warn(err); } @@ -443,11 +445,22 @@ ExchangeTab.prototype.angular = function (module) Address: $scope.userBlob.data.account_id }; rpTracker.track('Convert order result', eventProp); + + api.addTransaction(res.tx_json, eventProp, res.tx_json.hash, new Date().toString()); } catch (err) { console.warn(err); } }); - tx.submit(); + + api.getUserAccess().then(function(res) { + tx.submit(); + }, function(err2) { + setImmediate(function () { + $scope.$apply(function () { + $scope.mode = 'rippleerror'; + }); + }); + }); $scope.mode = 'sending'; }; diff --git a/src/js/tabs/gold.controller.js b/src/js/tabs/gold.controller.js index 5e1ae6b12..b7b97342b 100644 --- a/src/js/tabs/gold.controller.js +++ b/src/js/tabs/gold.controller.js @@ -13,8 +13,9 @@ GoldTab.prototype.mainMenu = 'fund'; GoldTab.prototype.angular = function (module) { - module.controller('GoldCtrl', ['$scope', 'rpId', 'rpAppManager', 'rpTracker', '$routeParams', 'rpKeychain', 'rpNetwork', '$timeout', - function ($scope, id, appManager, rpTracker, $routeParams, keychain, network, $timeout) { + module.controller('GoldCtrl', ['$scope', 'rpId', 'rpAppManager', 'rpTracker', '$routeParams', + 'rpKeychain', 'rpNetwork', 'rpAPI', '$timeout', + function ($scope, id, appManager, rpTracker, $routeParams, keychain, network, api, $timeout) { $scope.toggle_instructions = function () { @@ -59,6 +60,8 @@ GoldTab.prototype.angular = function (module) $scope.loading = false; $scope.editing = false; }); + + api.addTransaction(res.tx_json, {Status: 'success'}, res.tx_json.hash, new Date().toString()); }) .on('error', function (res) { setEngineStatus(res, false); @@ -71,6 +74,8 @@ GoldTab.prototype.angular = function (module) $scope.editing = false; }); }); + + api.addTransaction(res.tx_json, {Status: 'error'}, res.tx_json.hash, new Date().toString()); }); function setEngineStatus(res, accepted) { @@ -116,8 +121,20 @@ GoldTab.prototype.angular = function (module) $scope.mode = 'granting'; tx.secret(secret); - tx.submit(); + api.getUserAccess().then(function(res) { + tx.submit(); + }, function(err2) { + console.log('error', err2); + setImmediate(function () { + $scope.$apply(function () { + $scope.mode = 'error'; + + $scope.loading = false; + $scope.editing = false; + }); + }); + }); }); diff --git a/src/js/tabs/jpy.controller.js b/src/js/tabs/jpy.controller.js index 9eb8b8c1c..c3ddda2a7 100644 --- a/src/js/tabs/jpy.controller.js +++ b/src/js/tabs/jpy.controller.js @@ -13,24 +13,25 @@ JpyTab.prototype.mainMenu = 'fund'; JpyTab.prototype.angular = function (module) { - module.controller('JpyCtrl', ['$scope', 'rpId', 'rpAppManager', 'rpTracker', '$routeParams', 'rpKeychain', 'rpNetwork', '$timeout', - function ($scope, id, appManager, rpTracker, $routeParams, keychain, network, $timeout) + module.controller('JpyCtrl', ['$scope', 'rpId', 'rpAppManager', 'rpTracker', + '$routeParams', 'rpKeychain', 'rpNetwork', 'rpAPI', '$timeout', + function ($scope, id, appManager, rpTracker, $routeParams, keychain, network, api, $timeout) { - $scope.toggle_instructions = function (){ + $scope.toggle_instructions = function () { $scope.showInstructions = !$scope.showInstructions; - } + }; - $scope.save_account = function (){ + $scope.save_account = function () { $scope.loading = true; var amount = ripple.Amount.from_human( Options.gateway_max_limit + ' ' + 'JPY', - {reference_date: new Date(+new Date() + 5*60000)} + {reference_date: new Date(+new Date() + 5 * 60000)} ); - amount.set_issuer("r94s8px6kSw1uZ1MV98dhSRTvc6VMPoPcN"); + amount.set_issuer('r94s8px6kSw1uZ1MV98dhSRTvc6VMPoPcN'); if (!amount.is_valid()) { // Invalid amount. Indicates a bug in one of the validators. @@ -59,6 +60,8 @@ JpyTab.prototype.angular = function (module) $scope.loading = false; $scope.editing = false; }); + + api.addTransaction(res.tx_json, {Status: 'success'}, res.tx_json.hash, new Date().toString()); }) .on('error', function (res) { setEngineStatus(res, false); @@ -71,6 +74,8 @@ JpyTab.prototype.angular = function (module) $scope.editing = false; }); }); + + api.addTransaction(res.tx_json, {Status: 'error'}, res.tx_json.hash, new Date().toString()); }); function setEngineStatus(res, accepted) { @@ -116,11 +121,21 @@ JpyTab.prototype.angular = function (module) $scope.mode = 'granting'; tx.secret(secret); - tx.submit(); + api.getUserAccess().then(function(res) { + tx.submit(); + }, function(err2) { + console.log('error', err2); + setImmediate(function () { + $scope.$apply(function () { + $scope.mode = 'error'; + $scope.loading = false; + $scope.editing = false; + }); + }); + }); }); - }; $scope.$watch('lines', function () { diff --git a/src/js/tabs/login.controller.js b/src/js/tabs/login.controller.js index b4bc3161a..bacf38f99 100644 --- a/src/js/tabs/login.controller.js +++ b/src/js/tabs/login.controller.js @@ -18,8 +18,8 @@ LoginTab.prototype.extraRoutes = [ ]; LoginTab.prototype.angular = function(module) { - module.controller('LoginCtrl', ['$scope', '$location', '$sce', 'rpTracker', 'rpId', - function($scope, $location, $sce, rpTracker, id) { + module.controller('LoginCtrl', ['$scope', '$location', '$sce', 'rpTracker', 'rpId', 'rpAPI', + function($scope, $location, $sce, tracker, id, api) { $scope.error = ''; $scope.loggingIn = false; @@ -50,7 +50,7 @@ LoginTab.prototype.angular = function(module) { return; } - id.getUserProfile().success(function(profile) { + api.getUserProfile().success(function(profile) { store.set('profile_status', profile.ids_status); store.set('profile_country', profile.country); @@ -66,7 +66,7 @@ LoginTab.prototype.angular = function(module) { $location.path('/balance').search(''); } - rpTracker.track('Login', { + tracker.track('Login', { 'Status': 'success' }); }); diff --git a/src/js/tabs/mxn.controller.js b/src/js/tabs/mxn.controller.js index e50bec462..59926b93f 100644 --- a/src/js/tabs/mxn.controller.js +++ b/src/js/tabs/mxn.controller.js @@ -13,8 +13,9 @@ MxnTab.prototype.mainMenu = 'fund'; MxnTab.prototype.angular = function (module) { - module.controller('MxnCtrl', ['$scope', 'rpId', 'rpAppManager', 'rpTracker', '$routeParams', 'rpKeychain', 'rpNetwork', '$timeout', - function ($scope, id, appManager, rpTracker, $routeParams, keychain, $network, $timeout) { + module.controller('MxnCtrl', ['$scope', 'rpId', 'rpAppManager', 'rpTracker', + '$routeParams', 'rpKeychain', 'rpNetwork', 'rpAPI', '$timeout', + function ($scope, id, appManager, rpTracker, $routeParams, keychain, $network, api, $timeout) { $scope.toggle_instructions = function () { $scope.showInstructions = !$scope.showInstructions; @@ -58,6 +59,8 @@ MxnTab.prototype.angular = function (module) $scope.loading = false; $scope.editing = false; }); + + api.addTransaction(res.tx_json, {Status: 'success'}, res.tx_json.hash, new Date().toString()); }) .on('error', function (res) { setEngineStatus(res, false); @@ -70,6 +73,8 @@ MxnTab.prototype.angular = function (module) $scope.editing = false; }); }); + + api.addTransaction(res.tx_json, {Status: 'error'}, res.tx_json.hash, new Date().toString()); }); function setEngineStatus(res, accepted) { @@ -115,11 +120,21 @@ MxnTab.prototype.angular = function (module) $scope.mode = 'granting'; tx.secret(secret); - tx.submit(); + api.getUserAccess().then(function(res) { + tx.submit(); + }, function(err2) { + console.log('error', err2); + setImmediate(function () { + $scope.$apply(function () { + $scope.mode = 'error'; + $scope.loading = false; + $scope.editing = false; + }); + }); + }); }); - }; $scope.$watch('lines', function () { diff --git a/src/js/tabs/notifications.controller.js b/src/js/tabs/notifications.controller.js index 2f1a4bc48..df17c85bd 100644 --- a/src/js/tabs/notifications.controller.js +++ b/src/js/tabs/notifications.controller.js @@ -13,9 +13,9 @@ NotificationsTab.prototype.tabName = 'notifications'; NotificationsTab.prototype.mainMenu = 'notifications'; NotificationsTab.prototype.angular = function(module) { - module.controller('NotificationsCtrl', ['$scope', '$window', 'rpId', 'rpNotifications', function($scope, $window, $id, $notifications) { - if (!$id.loginStatus) { - return $id.goId(); + module.controller('NotificationsCtrl', ['$scope', '$window', 'rpId', 'rpAPI', function($scope, $window, id, api) { + if (!id.loginStatus) { + return id.goId(); } $scope.settingsPage = 'notifications'; @@ -42,7 +42,7 @@ NotificationsTab.prototype.angular = function(module) { return; } - $notifications.getSubscription().success(function(data) { + api.getSubscription().success(function(data) { $scope.subscription = data; @@ -87,7 +87,7 @@ NotificationsTab.prototype.angular = function(module) { } }); - $notifications.updateSubscription($scope.subscription) + api.updateSubscription($scope.subscription) .success(function() { $scope.state.waitingForResponse = false; $scope.state.alert = 'saved_successfully'; diff --git a/src/js/tabs/send.controller.js b/src/js/tabs/send.controller.js index 6c28824e2..b7cae0dd2 100644 --- a/src/js/tabs/send.controller.js +++ b/src/js/tabs/send.controller.js @@ -23,10 +23,10 @@ SendTab.prototype.angular = function (module) { module.controller('SendCtrl', ['$scope', '$timeout', '$routeParams', 'rpId', 'rpNetwork', 'rpFederation', 'rpTracker', - 'rpKeychain', '$interval', + 'rpKeychain', 'rpAPI', '$interval', function ($scope, $timeout, $routeParams, id, network, federation, rpTracker, - keychain, $interval) + keychain, api, $interval) { var destUpdateTimeout, passwordUpdater, @@ -1095,6 +1095,8 @@ SendTab.prototype.angular = function (module) $scope.setEngineStatus(res, false); } else if (res.error === 'remoteError') { $scope.error_type = res.remote.error; + } else if (res === 'denied') { + $scope.error_type = 'unknown'; } else { $scope.error_type = 'unknown'; } @@ -1191,7 +1193,7 @@ SendTab.prototype.angular = function (module) tx.on('success', function (res) { $scope.onTransactionSuccess(res, tx); - rpTracker.track('Send result', { + var eventProp = { 'Status': 'success', 'Currency': $scope.send.currency_code, 'Address Type': $scope.send.federation ? 'federation' : 'ripple', @@ -1199,7 +1201,11 @@ SendTab.prototype.angular = function (module) 'Time': (+new Date() - +$scope.confirmedTime) / 1000, 'Address': $scope.userBlob.data.account_id, 'Transaction ID': res.tx_json.hash - }); + }; + + rpTracker.track('Send result', eventProp); + + api.addTransaction(res.tx_json, eventProp, res.tx_json.hash, new Date().toString()); if ($routeParams.return_url) { document.location.replace($routeParams.return_url); @@ -1213,7 +1219,7 @@ SendTab.prototype.angular = function (module) tx.on('error', function (res) { $scope.onTransactionError(res, tx); - rpTracker.track('Send result', { + var eventProp = { 'Status': 'error', 'Message': res.engine_result, 'Currency': $scope.send.currency_code, @@ -1222,14 +1228,23 @@ SendTab.prototype.angular = function (module) 'Time': (+new Date() - +$scope.confirmedTime) / 1000, 'Address': $scope.userBlob.account_id, 'Transaction ID': res.tx_json.hash - }); + }; + + rpTracker.track('Send result', eventProp); + + api.addTransaction(res.tx_json, eventProp, res.tx_json.hash, new Date().toString()); if ($routeParams.abort_url) { document.location.replace($routeParams.abort_url); } }); - tx.submit(); + api.getUserAccess().then(function(res) { + tx.submit(); + }, function(err2) { + $scope.onTransactionError(err2); + } + ); $scope.confirmedTime = new Date(); }; diff --git a/src/js/tabs/settingsgateway.controller.js b/src/js/tabs/settingsgateway.controller.js index 8f61d06ac..bdd018e41 100644 --- a/src/js/tabs/settingsgateway.controller.js +++ b/src/js/tabs/settingsgateway.controller.js @@ -16,8 +16,8 @@ SettingsGatewayTab.prototype.mainMenu = 'settingsgateway'; SettingsGatewayTab.prototype.angular = function(module) { - module.controller('SettingsGatewayCtrl', ['$scope', 'rpId', 'rpKeychain', 'rpNetwork', - function ($scope, id, keychain, network) + module.controller('SettingsGatewayCtrl', ['$scope', 'rpId', 'rpKeychain', 'rpNetwork', 'rpAPI', + function ($scope, id, keychain, network, api) { var xrpCurrency = Currency.from_json('XRP'); @@ -67,12 +67,16 @@ SettingsGatewayTab.prototype.angular = function(module) $scope.edit.defaultRippleFlagSaving = false; $scope.load_notification('defaultRippleUpdated'); }); + + api.addTransaction(res.tx_json, {Status: 'success'}, res.tx_json.hash, new Date().toString()); }); tx.on('error', function(res) { console.warn(res); $scope.$apply(function() { $scope.edit.defaultRippleFlagSaving = false; }); + + api.addTransaction(res.tx_json, {Status: 'error'}, res.tx_json.hash, new Date().toString()); }); keychain.requestSecret(id.account, id.username, function (err, secret) { @@ -83,7 +87,16 @@ SettingsGatewayTab.prototype.angular = function(module) return; } tx.secret(secret); - tx.submit(); + + api.getUserAccess().then(function(res) { + tx.submit(); + }, function(err2) { + console.warn(err2); + $scope.$apply(function() { + $scope.edit.defaultRippleFlagSaving = false; + }); + }); + }); } break; diff --git a/src/js/tabs/sgd.controller.js b/src/js/tabs/sgd.controller.js index f3ba2618d..2ea7707b3 100644 --- a/src/js/tabs/sgd.controller.js +++ b/src/js/tabs/sgd.controller.js @@ -11,8 +11,9 @@ SgdTab.prototype.tabName = 'sgd'; SgdTab.prototype.mainMenu = 'fund'; SgdTab.prototype.angular = function(module) { - module.controller('SgdCtrl', ['$scope', 'rpId', 'rpAppManager', 'rpTracker', '$routeParams', 'rpKeychain', 'rpNetwork', '$timeout', - function($scope, id, appManager, rpTracker, $routeParams, keychain, $network, $timeout) + module.controller('SgdCtrl', ['$scope', 'rpId', 'rpAppManager', 'rpTracker', '$routeParams', + 'rpKeychain', 'rpNetwork', 'rpAPI', '$timeout', + function($scope, id, appManager, rpTracker, $routeParams, keychain, $network, api, $timeout) { $scope.toggle_instructions = function() { $scope.showInstructions = !$scope.showInstructions; @@ -55,6 +56,8 @@ SgdTab.prototype.angular = function(module) { $scope.loading = false; $scope.editing = false; }); + + api.addTransaction(res.tx_json, {Status: 'success'}, res.tx_json.hash, new Date().toString()); }) .on('error', function(res) { setEngineStatus(res, false); @@ -67,6 +70,8 @@ SgdTab.prototype.angular = function(module) { $scope.editing = false; }); }); + + api.addTransaction(res.tx_json, {Status: 'error'}, res.tx_json.hash, new Date().toString()); }); function setEngineStatus(res, accepted) { @@ -109,7 +114,21 @@ SgdTab.prototype.angular = function(module) { } $scope.mode = 'granting'; tx.secret(secret); - tx.submit(); + + api.getUserAccess().then(function(res) { + tx.submit(); + }, function(err2) { + console.log('error', err2); + setImmediate(function() { + $scope.$apply(function() { + $scope.mode = 'error'; + + $scope.loading = false; + $scope.editing = false; + }); + }); + }); + }); }; $scope.$watch('lines', function() { diff --git a/src/js/tabs/su.controller.js b/src/js/tabs/su.controller.js index 42019448d..883b68271 100644 --- a/src/js/tabs/su.controller.js +++ b/src/js/tabs/su.controller.js @@ -17,8 +17,8 @@ SuTab.prototype.mainMenu = 'su'; SuTab.prototype.angular = function (module) { module.controller('SuCtrl', ['$scope', '$routeParams', 'rpId', - 'rpNetwork', 'rpDomainAlias', 'rpKeychain', - function ($scope, $routeParams, id, net, aliasService, keychain) + 'rpNetwork', 'rpDomainAlias', 'rpKeychain', 'rpAPI', + function ($scope, $routeParams, id, net, aliasService, keychain, api) { $scope.account = {}; @@ -41,8 +41,16 @@ SuTab.prototype.angular = function (module) tx.accountSet(id.account); tx.tx_json.Domain = sjcl.codec.hex.fromBits(sjcl.codec.utf8String.toBits($scope.account.domain)); - tx.on('success', function(){ + tx.on('success', function(res) { console.log('Cool!'); + + api.addTransaction(res.tx_json, {Status: 'success'}, res.tx_json.hash, new Date().toString()); + }); + + tx.on('error', function(res) { + console.log('Error!'); + + api.addTransaction(res.tx_json, {Status: 'error'}, res.tx_json.hash, new Date().toString()); }); keychain.requestSecret(id.account, id.username, function (err, secret) { @@ -50,7 +58,13 @@ SuTab.prototype.angular = function (module) if (err) return; tx.secret(secret); - tx.submit(); + + api.getUserAccess().then(function(res) { + tx.submit(); + }, function(err) { + console.log('Error!'); + }); + }); }; }]); diff --git a/src/js/tabs/trade.controller.js b/src/js/tabs/trade.controller.js index 96e6721a5..702a891c0 100644 --- a/src/js/tabs/trade.controller.js +++ b/src/js/tabs/trade.controller.js @@ -33,12 +33,14 @@ TradeTab.prototype.angular = function(module) TradeCtrl.$inject = ['rpBooks', '$scope', 'rpId', 'rpNetwork', '$routeParams', '$location', '$filter', 'rpTracker', 'rpKeychain', '$rootScope', - 'rpPopup', '$anchorScroll', '$timeout', '$templateRequest']; + 'rpPopup', 'rpAPI', '$anchorScroll', + '$timeout', '$templateRequest']; function TradeCtrl(books, $scope, id, network, $routeParams, $location, $filter, rpTracker, keychain, $rootScope, - popup, $anchorScroll, $timeout, $templateRequest) + popup, api, $anchorScroll, + $timeout, $templateRequest) { var timer; var cancelNotifTimeout = {}; @@ -277,7 +279,7 @@ TradeTab.prototype.angular = function(module) // but a two stage method is utilized instead to minimize the risk of the problem detected by the // qtyChangedOnDeleted function. (JIRA: RT-1214) } - } + }; // Step 1 of modification was successful, start 2nd of 2 transactions function createAfterCancel(qtyChanged) { @@ -533,7 +535,7 @@ TradeTab.prototype.angular = function(module) $scope.view_orders_history = function() { $location.url('/history?f=orders'); - } + }; /** * Happens when user clicks on 'Cancel all' in 'My Orders'. @@ -543,7 +545,7 @@ TradeTab.prototype.angular = function(module) _.each($scope.offers, function(offer, index) { $scope.cancel_order(offer.seq, false); }); - } + }; /** * Happens when user clicks on 'Cancel' in 'My Orders'. @@ -562,31 +564,47 @@ TradeTab.prototype.angular = function(module) tx.on('success', function(res) { if ($scope.offers[cancelOrder.seq]) $scope.offers[cancelOrder.seq].cancelling = false; + var eventProp; + if (modifying) { var qtyChanged = qtyChangedOnDeleted(res); if (successCb) successCb(qtyChanged); if (qtyChanged) { - rpTracker.track(MIXPNL_MODIFY_EVENT, { + eventProp = { 'Status': 'error', 'Message': 'Qty changed after cancel requested by client', 'Address': $scope.userBlob.data.account_id, 'Transaction ID': res.tx_json.hash - }); + }; + + rpTracker.track(MIXPNL_MODIFY_EVENT, eventProp); + } else { + eventProp = { + 'Status': 'success', + 'Message': 'Qty did not changed after cancel requested by client', + 'Address': $scope.userBlob.data.account_id, + 'Transaction ID': res.tx_json.hash + }; } - } - else { + } else { $scope.cancelOrder.seq = cancelOrder.seq; $rootScope.load_notification('cancel_success'); scrollToMessages(); - if (successCb) successCb(); + if (successCb) { + successCb(); + } - rpTracker.track('Trade order cancellation', { + eventProp = { 'Status': 'success', 'Address': $scope.userBlob.data.account_id - }); + }; + + rpTracker.track('Trade order cancellation', eventProp); } + + api.addTransaction(res.tx_json, eventProp, res.tx_json.hash, new Date().toString()); }); tx.on('error', function (err) { @@ -609,6 +627,8 @@ TradeTab.prototype.angular = function(module) if (modifying) rpTracker.track(MIXPNL_MODIFY_EVENT, eventProp); else rpTracker.track('Trade order cancellation', eventProp); + + api.addTransaction(err.tx_json, eventProp, err.tx_json.hash, new Date().toString()); }); keychain.requestSecret(id.account, id.username, function (err, secret) { @@ -619,11 +639,24 @@ TradeTab.prototype.angular = function(module) } tx.secret(secret); - tx.submit(); + + api.getUserAccess().then(function(res) { + tx.submit(); + }, function(err2) { + cancelOrder.cancelling = false; + cancelOrder.errorMsg = + 'Sorry, users from your region are not allowed to do transactions through Ripple Trade.'; + $rootScope.load_notification('cancel_error'); + + if (!$scope.$$phase) { + $scope.$apply(); + } + }); + }); cancelOrder.cancelling = true; - } + }; $scope.dismissCancelError = function() { $scope.cancelOrder.seq = null; @@ -632,7 +665,7 @@ TradeTab.prototype.angular = function(module) $scope.showNotification = function(type, status) { if (typeof status !== 'string') { - console.log("You must pass in a string for the status"); + console.log('You must pass in a string for the status'); return; } @@ -646,7 +679,7 @@ TradeTab.prototype.angular = function(module) $scope.notif[type] = 'clear'; }, 9000); cancelNotifTimeout[type]['finally'](function() { cancelNotifTimeout[type] = null; }); - } + }; /** @@ -720,12 +753,14 @@ TradeTab.prototype.angular = function(module) if (modifying) rpTracker.track(MIXPNL_MODIFY_EVENT, eventProp); else rpTracker.track('Trade order result', eventProp); + + api.addTransaction(res.tx_json, eventProp, res.tx_json.hash, new Date().toString()); }); tx.on('error', function (err) { setEngineStatus(err, false, type); - if (!modifying) $scope.reset_widget(type);; + if (!modifying) $scope.reset_widget(type); if (errorCb) errorCb(); @@ -742,6 +777,8 @@ TradeTab.prototype.angular = function(module) if (modifying) rpTracker.track(MIXPNL_MODIFY_EVENT, eventProp); else rpTracker.track('Trade order result', eventProp); + + api.addTransaction(err.tx_json, eventProp, err.tx_json.hash, new Date().toString()); }); keychain.requestSecret(id.account, id.username, function (err, secret) { @@ -753,7 +790,16 @@ TradeTab.prototype.angular = function(module) } tx.secret(secret); - tx.submit(); + + api.getUserAccess().then(function(res) { + tx.submit(); + }, function(err2) { + if (!modifying) $scope.reset_widget(type); + + if (!$scope.$$phase) { + $scope.$apply(); + } + }); }); @@ -1008,7 +1054,7 @@ TradeTab.prototype.angular = function(module) $scope.second_currency_selected = ''; $scope.second_issuer_selected = ''; $scope.adding_pair = true; - } + }; $scope.add_pair = function() { var formattedIssuerFirst = $scope.first_currency_selected === 'XRP' ? '' : '.' + $scope.first_issuer_selected; diff --git a/src/js/tabs/trust.controller.js b/src/js/tabs/trust.controller.js index 48aacf6f3..e1aa1c7c2 100644 --- a/src/js/tabs/trust.controller.js +++ b/src/js/tabs/trust.controller.js @@ -1,3 +1,5 @@ +'use strict'; + var util = require('util'); var webutil = require('../util/web'); var Tab = require('../client/tab').Tab; @@ -17,276 +19,293 @@ TrustTab.prototype.mainMenu = 'fund'; TrustTab.prototype.angular = function (module) { - module.controller('TrustCtrl', ['$scope', 'rpBooks', '$timeout', '$routeParams', 'rpId', - '$filter', 'rpNetwork', 'rpTracker', 'rpKeychain', - function ($scope, books, $timeout, $routeParams, id, - $filter, network, rpTracker, keychain) - { - - // Get all currencies from currencies.js, parse through to display only those with display: true - var displayCurrenciesOnly = []; - - $scope.trust = {}; - - // Trust line sorting - $scope.sorting = { - predicate: 'balance', - reverse: true, - sort: function(line){ - return $scope.sorting.predicate === 'currency' ? line.currency : line.balance.to_number(); - } - }; - - $scope.validation_pattern = /^0*(([1-9][0-9]*.?[0-9]*)|(.0*[1-9][0-9]*))$/; //Don't allow zero for new trust lines. - - $scope.reset = function () { - $scope.mode = 'main'; - var usdCurrency = Currency.from_human('USD'); - $scope.currency = usdCurrency.to_human({full_name:$scope.currencies_all_keyed[usdCurrency.get_iso()].name}); - $scope.addform_visible = false; - $scope.edituser = ''; - $scope.amount = Options.gateway_max_limit; - $scope.allowrippling = false; - $scope.counterparty = ''; - $scope.counterparty_view = ''; - $scope.counterparty_address = ''; - $scope.saveAddressName = ''; - $scope.error_account_reserve = false; - }; - - $scope.toggle_form = function () { - - if($scope.addform_visible) { - $scope.reset(); - } else { - $scope.addform_visible = true; - } - }; + module.controller('TrustCtrl', [ + '$scope', 'rpBooks', '$timeout', '$routeParams', 'rpId', + '$filter', 'rpNetwork', 'rpTracker', 'rpKeychain', 'rpAPI', + function($scope, books, $timeout, $routeParams, id, + $filter, network, rpTracker, keychain, api) { + + // Get all currencies from currencies.js, parse through to display only those with display: true + var displayCurrenciesOnly = []; + + $scope.trust = {}; + + // Trust line sorting + $scope.sorting = { + predicate: 'balance', + reverse: true, + sort: function(line) { + return $scope.sorting.predicate === 'currency' ? line.currency : line.balance.to_number(); + } + }; + //Don't allow zero for new trust lines. + $scope.validation_pattern = /^0*(([1-9][0-9]*.?[0-9]*)|(.0*[1-9][0-9]*))$/; - // User should not even be able to try granting a trust if the reserve is insufficient - $scope.$watch('account', function() { - // Check if account has DefaultRipple flag set - $scope.acctDefaultRippleFlag = ($scope.account.Flags & ripple.Remote.flags.account_root.DefaultRipple); + $scope.reset = function () { + $scope.mode = 'main'; + var usdCurrency = Currency.from_human('USD'); + $scope.currency = usdCurrency.to_human({full_name: $scope.currencies_all_keyed[usdCurrency.get_iso()].name}); + $scope.addform_visible = false; + $scope.edituser = ''; + $scope.amount = Options.gateway_max_limit; + $scope.allowrippling = false; + $scope.counterparty = ''; + $scope.counterparty_view = ''; + $scope.counterparty_address = ''; + $scope.saveAddressName = ''; + $scope.error_account_reserve = false; + }; + + $scope.toggle_form = function () { - $scope.can_add_trust = false; - if ($scope.account.Balance && $scope.account.reserve_to_add_trust) { - if (!$scope.account.reserve_to_add_trust.subtract($scope.account.Balance).is_positive() - || $.isEmptyObject($scope.lines)) - { - $scope.can_add_trust = true; + if ($scope.addform_visible) { + $scope.reset(); + } else { + $scope.addform_visible = true; } - } - }, true); - - $scope.$watch('counterparty', function() { - $scope.error_account_reserve = false; - $scope.contact = webutil.getContact($scope.userBlob.data.contacts,$scope.counterparty); - if ($scope.contact) { - $scope.counterparty_name = $scope.contact.name; - $scope.counterparty_address = $scope.contact.address; - } else { - $scope.counterparty_name = ''; - $scope.counterparty_address = $scope.counterparty; - } - }, true); - - /** - - * N2. Confirmation page - */ - $scope.grant = function () - { - // set variable to show throbber - $scope.verifying = true; - $scope.error_account_reserve = false; - // test if account is valid - network.remote.requestAccountInfo({account: $scope.counterparty_address}) - // if account is valid then just to confirm page - .on('success', function (m){ - $scope.$apply(function(){ - // hide throbber - $scope.verifying = false; - - $scope.lineCurrencyObj = Currency.from_human($scope.currency); - var matchedCurrency = $scope.lineCurrencyObj.has_interest() ? $scope.lineCurrencyObj.to_hex() : $scope.lineCurrencyObj.get_iso(); - var match = /^([a-zA-Z0-9]{3}|[A-Fa-f0-9]{40})\b/.exec(matchedCurrency); - - if (!match) { - // Currency code not recognized, should have been caught by - // form validator. - console.error('Currency code:', match, 'is not recognized'); - return; - } + }; - if (Options.advanced_feature_switch === false || $scope.amount === "") { - // $scope.amount = Number(ripple.Amount.consts.max_value); - $scope.amount = Options.gateway_max_limit; - } - var amount = ripple.Amount.from_human('' + $scope.amount + ' ' + $scope.lineCurrencyObj.to_hex(), {reference_date: new Date(+new Date() + 5*60000)}); + // User should not even be able to try granting a trust if the reserve is insufficient + $scope.$watch('account', function() { + // Check if account has DefaultRipple flag set + $scope.acctDefaultRippleFlag = ($scope.account.Flags & ripple.Remote.flags.account_root.DefaultRipple); - amount.set_issuer($scope.counterparty_address); - if (!amount.is_valid()) { - // Invalid amount. Indicates a bug in one of the validators. - return; - } + $scope.can_add_trust = false; + if ($scope.account.Balance && $scope.account.reserve_to_add_trust) { + if (!$scope.account.reserve_to_add_trust.subtract($scope.account.Balance).is_positive() + || $.isEmptyObject($scope.lines)) { + $scope.can_add_trust = true; + } + } + }, true); + + $scope.$watch('counterparty', function() { + $scope.error_account_reserve = false; + $scope.contact = webutil.getContact($scope.userBlob.data.contacts, $scope.counterparty); + if ($scope.contact) { + $scope.counterparty_name = $scope.contact.name; + $scope.counterparty_address = $scope.contact.address; + } else { + $scope.counterparty_name = ''; + $scope.counterparty_address = $scope.counterparty; + } + }, true); + + /** + + * N2. Confirmation page + */ + $scope.grant = function() { + // set variable to show throbber + $scope.verifying = true; + $scope.error_account_reserve = false; + // test if account is valid + network.remote.requestAccountInfo({account: $scope.counterparty_address}) + // if account is valid then just to confirm page + .on('success', function(m) { + $scope.$apply(function() { + // hide throbber + $scope.verifying = false; - $scope.amount_feedback = amount; - - $scope.confirm_wait = true; - $timeout(function () { - $scope.confirm_wait = false; - }, 1000, true); - - $scope.mode = 'confirm'; - - /** - * Warning messages - * - * - firstIssuer - * - sameIssuer - * - multipleIssuers - */ - // var currency = amount.currency().to_human({full_name:$scope.currencies_all_keyed[amount.currency().get_iso()].name}); - // var balance = $scope.balances[currency]; - // $scope.currencyWarning = false; - - // New trust on a currency or no rippling enabled - // if (!balance || !$scope.allowrippling) { - // $scope.currencyWarning = 'firstIssuer'; - // } - // else { - // Trust limit change - // for (var counterparty in balance.components) { - // if (counterparty === $scope.counterparty_address) - // $scope.currencyWarning = 'sameIssuer'; - // } + $scope.lineCurrencyObj = Currency.from_human($scope.currency); + var matchedCurrency = $scope.lineCurrencyObj.has_interest() ? + $scope.lineCurrencyObj.to_hex() : $scope.lineCurrencyObj.get_iso(); - // Multiple trusts on a same currency - // if (!$scope.currencyWarning) - // $scope.currencyWarning = 'multipleIssuers'; - // } - }); - }) - .on('error', function (m){ - setImmediate(function () { - $scope.$apply(function(){ - $scope.verifying = false; - $scope.error_account_reserve = true; - console.log('There was an error', m); - }); - }); - }) - .request(); - }; - - /** - * N3. Waiting for grant result page - */ - $scope.grant_confirmed = function () { - var amount = $scope.amount_feedback.to_json(); - var tx = network.remote.transaction(); - - // Add memo to tx - tx.addMemo('client', 'text/plain', 'rt' + $scope.version); - - - // Flags - tx - .rippleLineSet(id.account, amount) - .setFlags($scope.allowrippling ? 'ClearNoRipple' : 'NoRipple') - .on('proposed', function(res){ - $scope.$apply(function () { - setEngineStatus(res, false); - $scope.granted(tx.hash); + var match = /^([a-zA-Z0-9]{3}|[A-Fa-f0-9]{40})\b/.exec(matchedCurrency); - // Remember currency and increase order - var found; + if (!match) { + // Currency code not recognized, should have been caught by + // form validator. + console.error('Currency code:', match, 'is not recognized'); + return; + } - for (var i = 0; i < $scope.currencies_all.length; i++) { - if ($scope.currencies_all[i].value.toLowerCase() === $scope.amount_feedback.currency().get_iso().toLowerCase()) { - $scope.currencies_all[i].order++; - found = true; - break; + if (Options.advanced_feature_switch === false || $scope.amount === "") { + // $scope.amount = Number(ripple.Amount.consts.max_value); + $scope.amount = Options.gateway_max_limit; } - } - // // Removed feature until a permanent fix - // if (!found) { - // $scope.currencies_all.push({ - // 'name': currency, - // 'value': currency, - // 'order': 1 - // }); - // } - }); - }) - .on('success', function(res){ - $scope.$apply(function () { - setEngineStatus(res, true); - }); - }) - .on('error', function(res){ - setImmediate(function () { - $scope.$apply(function () { - $scope.mode = 'error'; + var amount = ripple.Amount.from_human( + '' + $scope.amount + ' ' + $scope.lineCurrencyObj.to_hex(), + {reference_date: new Date( + new Date() + 5 * 60000)}); + + amount.set_issuer($scope.counterparty_address); + if (!amount.is_valid()) { + // Invalid amount. Indicates a bug in one of the validators. + return; + } + + $scope.amount_feedback = amount; + + $scope.confirm_wait = true; + $timeout(function () { + $scope.confirm_wait = false; + }, 1000, true); + + $scope.mode = 'confirm'; + + /** + * Warning messages + * + * - firstIssuer + * - sameIssuer + * - multipleIssuers + */ + // var currency = amount.currency().to_human({full_name:$scope.currencies_all_keyed[amount.currency().get_iso()].name}); + // var balance = $scope.balances[currency]; + // $scope.currencyWarning = false; + + // New trust on a currency or no rippling enabled + // if (!balance || !$scope.allowrippling) { + // $scope.currencyWarning = 'firstIssuer'; + // } + // else { + // Trust limit change + // for (var counterparty in balance.components) { + // if (counterparty === $scope.counterparty_address) + // $scope.currencyWarning = 'sameIssuer'; + // } + + // Multiple trusts on a same currency + // if (!$scope.currencyWarning) + // $scope.currencyWarning = 'multipleIssuers'; + // } + }); + }) + .on('error', function (m) { + setImmediate(function () { + $scope.$apply(function() { + $scope.verifying = false; + $scope.error_account_reserve = true; + console.log('There was an error', m); + }); + }); + }) + .request(); + }; + + /** + * N3. Waiting for grant result page + */ + $scope.grant_confirmed = function () { + var amount = $scope.amount_feedback.to_json(); + var tx = network.remote.transaction(); + // Add memo to tx + tx.addMemo('client', 'text/plain', 'rt' + $scope.version); + + + // Flags + tx + .rippleLineSet(id.account, amount) + .setFlags($scope.allowrippling ? 'ClearNoRipple' : 'NoRipple') + .on('proposed', function(res) { + $scope.$apply(function () { setEngineStatus(res, false); + $scope.granted(tx.hash); - $scope.reset(); + // Remember currency and increase order + var found; + + for (var i = 0; i < $scope.currencies_all.length; i++) { + if ($scope.currencies_all[i].value.toLowerCase() === $scope.amount_feedback.currency().get_iso().toLowerCase()) { + $scope.currencies_all[i].order++; + found = true; + break; + } + } + // // Removed feature until a permanent fix + // if (!found) { + // $scope.currencies_all.push({ + // 'name': currency, + // 'value': currency, + // 'order': 1 + // }); + // } }); - }); - }) - ; + }) + .on('success', function(res) { + $scope.$apply(function() { + setEngineStatus(res, true); + }); + + api.addTransaction(res.tx_json, {Status: 'success'}, res.tx_json.hash, new Date().toString()); + }) + .on('error', function(res) { + setImmediate(function () { + $scope.$apply(function () { + $scope.mode = 'error'; - keychain.requestSecret(id.account, id.username, function (err, secret) { - // XXX Error handling - if (err) { - $scope.load_notification('unlock_failed'); + setEngineStatus(res, false); - $scope.reset(); - return; - } + $scope.reset(); - $scope.mode = 'granting'; + }); + }); - tx.secret(secret); - tx.submit(); + api.addTransaction(res.tx_json, {Status: 'error'}, res.tx_json.hash, new Date().toString()); + }) + ; - }); + keychain.requestSecret(id.account, id.username, function (err, secret) { + // XXX Error handling + if (err) { + $scope.load_notification('unlock_failed'); - $scope.toggle_form(); - }; - - /** - * N5. Granted page - */ - $scope.granted = function (hash) { - $scope.mode = 'granted'; - network.remote.on('transaction', handleAccountEvent); - - function handleAccountEvent(e) { - $scope.$apply(function () { - if (e.transaction.hash === hash) { - setEngineStatus(e, true); - network.remote.removeListener('transaction', handleAccountEvent); + $scope.reset(); + return; } + + $scope.mode = 'granting'; + + tx.secret(secret); + + api.getUserAccess().then(function(res) { + tx.submit(); + }, function(err2) { + setImmediate(function () { + $scope.$apply(function () { + $scope.mode = 'error'; + $scope.reset(); + }); + }); + }); + }); - } - $timeout(function(){ - $scope.mode = 'main'; - }, 10000); - }; + $scope.toggle_form(); + }; - function setEngineStatus(res, accepted) { - $scope.engine_result = res.engine_result; - $scope.engine_result_message = res.engine_result_message; - $scope.engine_status_accepted = accepted; + /** + * N5. Granted page + */ + $scope.granted = function (hash) { + $scope.mode = 'granted'; + network.remote.on('transaction', handleAccountEvent); + + function handleAccountEvent(e) { + $scope.$apply(function () { + if (e.transaction.hash === hash) { + setEngineStatus(e, true); + network.remote.removeListener('transaction', handleAccountEvent); + } + }); + } + + $timeout(function() { + $scope.mode = 'main'; + }, 10000); + }; + + function setEngineStatus(res, accepted) { + $scope.engine_result = res.engine_result; + $scope.engine_result_message = res.engine_result_message; + $scope.engine_status_accepted = accepted; - switch (res.engine_result.slice(0, 3)) { + switch (res.engine_result.slice(0, 3)) { case 'tes': $scope.tx_result = accepted ? 'cleared' : 'pending'; break; @@ -300,53 +319,53 @@ TrustTab.prototype.angular = function (module) $scope.tx_result = 'failed'; break; case 'tel': - $scope.tx_result = "local"; + $scope.tx_result = 'local'; break; case 'tep': console.warn('Unhandled engine status encountered!'); + } } - } - $scope.$watch('userBlob.data.contacts', function (contacts) { - $scope.counterparty_query = webutil.queryFromContacts(contacts); - }, true); + $scope.$watch('userBlob.data.contacts', function (contacts) { + $scope.counterparty_query = webutil.queryFromContacts(contacts); + }, true); - for (var i = 0; i < $scope.currencies_all.length; i++) { - if ($scope.currencies_all[i].display) { - displayCurrenciesOnly.push($scope.currencies_all[i]); + for (var i = 0; i < $scope.currencies_all.length; i++) { + if ($scope.currencies_all[i].display) { + displayCurrenciesOnly.push($scope.currencies_all[i]); + } } - } - $scope.currency_query = webutil.queryFromOptionsIncludingKeys(displayCurrenciesOnly); + $scope.currency_query = webutil.queryFromOptionsIncludingKeys(displayCurrenciesOnly); + + $scope.reset(); - $scope.reset(); + var updateAccountLines = function() { + var obj = {}; - var updateAccountLines = function() { - var obj = {}; + _.each($scope.lines, function(line) { - _.each($scope.lines, function(line){ + if ($scope.isSignificantLine(line)) { + if (!obj[line.currency]) { + obj[line.currency] = { components: [] }; + } - if ($scope.isSignificantLine(line)) { - if (!obj[line.currency]) { - obj[line.currency] = { components: [] }; + obj[line.currency].components.push(line); } + }); - obj[line.currency].components.push(line); - } - }); + $scope.accountLines = obj; + }; - $scope.accountLines = obj; - }; + $scope.$on('$balancesUpdate', function() { + updateAccountLines(); + }); - $scope.$on('$balancesUpdate', function(){ updateAccountLines(); - }); - - updateAccountLines(); }]); - module.controller('AccountRowCtrl', ['$scope', 'rpBooks', 'rpNetwork', 'rpId', 'rpKeychain', '$timeout', - function ($scope, books, network, id, keychain, $timeout) { + module.controller('AccountRowCtrl', ['$scope', 'rpBooks', 'rpNetwork', 'rpId', 'rpKeychain', 'rpAPi', '$timeout', + function ($scope, books, network, id, keychain, api, $timeout) { $scope.minVal = $scope.entry.components[0].limit_peer.to_human({rel_precision: 2}); // if($scope.minVal % 10 === 0) { // $scope.minVal = String($scope.minVal) + ".00"; @@ -363,26 +382,26 @@ TrustTab.prototype.angular = function (module) $scope.engine_status_accepted = accepted; switch (res.engine_result.slice(0, 3)) { - case 'tes': - $scope.tx_result = accepted ? 'cleared' : 'pending'; - break; - case 'tem': - $scope.tx_result = 'malformed'; - break; - case 'ter': - $scope.tx_result = 'failed'; - break; - case 'tec': - $scope.tx_result = 'failed'; - break; - case 'tel': - $scope.tx_result = "local"; - break; - case 'tep': - console.warn('Unhandled engine status encountered!'); + case 'tes': + $scope.tx_result = accepted ? 'cleared' : 'pending'; + break; + case 'tem': + $scope.tx_result = 'malformed'; + break; + case 'ter': + $scope.tx_result = 'failed'; + break; + case 'tec': + $scope.tx_result = 'failed'; + break; + case 'tel': + $scope.tx_result = 'local'; + break; + case 'tep': + console.warn('Unhandled engine status encountered!'); } } - + $scope.cancel = function () { $scope.editing = false; }; @@ -400,9 +419,9 @@ TrustTab.prototype.angular = function (module) var currency = Currency.from_human($scope.component.currency); - currency.to_human({full_name:$scope.currencies_all_keyed[currency.get_iso()]}) - ? $scope.trust.currency = currency.to_human({full_name:$scope.currencies_all_keyed[currency]}) - : $scope.trust.currency = currency.to_human({full_name:$scope.currencies_all_keyed[currency.get_iso()].name}); + currency.to_human({full_name: $scope.currencies_all_keyed[currency.get_iso()]}) + ? $scope.trust.currency = currency.to_human({full_name: $scope.currencies_all_keyed[currency]}) + : $scope.trust.currency = currency.to_human({full_name: $scope.currencies_all_keyed[currency.get_iso()].name}); // $scope.trust.currency = currency.to_human({full_name:$scope.currencies_all_keyed[currency.get_iso()].name}); $scope.trust.counterparty = $scope.component.account; @@ -410,25 +429,26 @@ TrustTab.prototype.angular = function (module) $scope.load_orderbook(); }; - $scope.delete_account = function() - { + $scope.delete_account = function() { $scope.trust.loading = true; $scope.load_notification('remove_gateway'); $scope.trust.state = 'removing'; var setSecretAndSubmit = function(tx) { tx - .on('proposed', function(res){ + .on('proposed', function(res) { $scope.$apply(function () { setEngineStatus(res, false); }); }) - .on('success', function(res){ + .on('success', function(res) { $scope.$apply(function () { setEngineStatus(res, true); }); + + api.addTransaction(res.tx_json, {Status: 'success'}, res.tx_json.hash, new Date().toString()); }) - .on('error', function(res){ + .on('error', function(res) { console.log('error', res); setImmediate(function () { $scope.$apply(function () { @@ -442,6 +462,8 @@ TrustTab.prototype.angular = function (module) $scope.trust.loading = false; }); }); + + api.addTransaction(res.tx_json, {Status: 'error'}, res.tx_json.hash, new Date().toString()); }); keychain.requestSecret(id.account, id.username, function (err, secret) { @@ -456,13 +478,23 @@ TrustTab.prototype.angular = function (module) } tx.secret(secret); - tx.submit(); + api.getUserAccess().then(function(res) { + tx.submit(); + }, function(err2) { + setImmediate(function() { + $scope.$apply(function () { + $scope.mode = 'error'; + $scope.trust.loading = false; + }); + }); + }); + }); }; var nullifyTrustLine = function(idAccount, lineCurrency, lineAccount) { var tx = network.remote.transaction(); - + // Add memo to tx tx.addMemo('client', 'text/plain', 'rt' + $scope.version); @@ -513,18 +545,23 @@ TrustTab.prototype.angular = function (module) tx.once('proposed', callback); }; - // $scope.counterparty inside the clearBalance callback function does not have counterparty in its scope, therefore, we need an immediate function to capture it. + // $scope.counterparty inside the clearBalance callback function does not have counterparty in its scope, + // therefore, we need an immediate function to capture it. if ($scope.trust.balance !== '0') { (function (counterparty) { - clearBalance(id.account, $scope.trust.counterparty, $scope.trust.currency, $scope.trust.balanceAmount, function(res) { - nullifyTrustLine(id.account, $scope.trust.currency, counterparty); - }); + clearBalance( + id.account, + $scope.trust.counterparty, + $scope.trust.currency, + $scope.trust.balanceAmount, + function(res) { + nullifyTrustLine(id.account, $scope.trust.currency, counterparty); + } + ); })($scope.trust.counterparty); - } - - else { + } else { nullifyTrustLine(id.account, $scope.trust.currency, $scope.trust.counterparty); } @@ -566,7 +603,7 @@ TrustTab.prototype.angular = function (module) var amount = ripple.Amount.from_human( $scope.trust.limit + ' ' + $scope.component.currency, - {reference_date: new Date(+new Date() + 5*60000)} + {reference_date: new Date(+new Date() + 5 * 60000)} ); amount.set_issuer($scope.component.account); @@ -586,12 +623,12 @@ TrustTab.prototype.angular = function (module) tx .rippleLineSet(id.account, amount) .setFlags($scope.trust.rippling ? 'ClearNoRipple' : 'NoRipple') - .on('proposed', function(res){ - $scope.$apply(function () { - setEngineStatus(res, false); + .on('proposed', function(res) { + $scope.$apply(function() { + setEngineStatus(res, false); }); }) - .on('success', function(res){ + .on('success', function(res) { $scope.$apply(function () { setEngineStatus(res, true); @@ -599,8 +636,10 @@ TrustTab.prototype.angular = function (module) $scope.editing = false; $scope.load_notification('changes_saved'); }); + + api.addTransaction(res.tx_json, {Status: 'success'}, res.tx_json.hash, new Date().toString()); }) - .on('error', function(res){ + .on('error', function(res) { setImmediate(function () { $scope.$apply(function () { $scope.mode = 'error'; @@ -615,6 +654,8 @@ TrustTab.prototype.angular = function (module) }); }); + + api.addTransaction(res.tx_json, {Status: 'error'}, res.tx_json.hash, new Date().toString()); }); @@ -632,7 +673,19 @@ TrustTab.prototype.angular = function (module) $scope.mode = 'granting'; tx.secret(secret); - tx.submit(); + + api.getUserAccess().then(function(res) { + tx.submit(); + }, function(err2) { + setImmediate(function () { + $scope.$apply(function () { + $scope.mode = 'error'; + + $scope.trust.loading = false; + $scope.editing = false; + }); + }); + }); }); }; @@ -642,19 +695,16 @@ TrustTab.prototype.angular = function (module) $scope.ripplingEnabled = function() { return !$scope.component.no_ripple; - } + }; $scope.showEnableRipplingWarningMessage = function() { return ($scope.isIncomingOnly() && !$scope.ripplingEnabled() && $scope.trust.rippling && $scope.trust.balance !== '0'); - } - + }; }]); }; - - module.exports = TrustTab; diff --git a/src/js/tabs/usd.controller.js b/src/js/tabs/usd.controller.js index 50343a8cc..5565283cb 100644 --- a/src/js/tabs/usd.controller.js +++ b/src/js/tabs/usd.controller.js @@ -17,23 +17,24 @@ UsdTab.prototype.extraRoutes = [ UsdTab.prototype.angular = function (module) { - module.controller('UsdCtrl', ['$scope', 'rpId', 'rpAppManager', 'rpTracker', '$routeParams', 'rpKeychain', 'rpNetwork', '$timeout', - function ($scope, id, appManager, rpTracker, $routeParams, keychain, network, $timeout) + module.controller('UsdCtrl', ['$scope', 'rpId', 'rpAppManager', 'rpTracker', + '$routeParams', 'rpKeychain', 'rpNetwork', 'rpAPI', '$timeout', + function ($scope, id, appManager, rpTracker, $routeParams, keychain, network, api, $timeout) { - $scope.toggle_instructions = function (){ + $scope.toggle_instructions = function() { $scope.showInstructions = !$scope.showInstructions; - } + }; - $scope.toggle_usd_instructions = function (){ + $scope.toggle_usd_instructions = function() { $scope.showUsdInstructions = !$scope.showUsdInstructions; - } + }; $scope.toggle_gatehub_instructions = function() { $scope.showUsd3Instructions = !$scope.showUsd3Instructions; - } + }; - $scope.save_account = function (){ + $scope.save_account = function() { $scope.loading = true; @@ -70,7 +71,9 @@ UsdTab.prototype.angular = function (module) $scope.loading = false; $scope.editing = false; }); - }) + + api.addTransaction(res.tx_json, {Status: 'success'}, res.tx_json.hash, new Date().toString()); + }) .on('error', function (res) { setEngineStatus(res, false); console.log('error', res); @@ -82,7 +85,9 @@ UsdTab.prototype.angular = function (module) $scope.editing = false; }); }); - }); + + api.addTransaction(res.tx_json, {Status: 'error'}, res.tx_json.hash, new Date().toString()); + }); function setEngineStatus(res, accepted) { $scope.engine_result = res.engine_result; @@ -127,20 +132,30 @@ UsdTab.prototype.angular = function (module) $scope.mode = 'granting'; tx.secret(secret); - tx.submit(); + api.getUserAccess().then(function(res) { + tx.submit(); + }, function(err2) { + console.log('error', err2); + setImmediate(function () { + $scope.$apply(function () { + $scope.mode = 'error'; + $scope.loading = false; + $scope.editing = false; + }); + }); + }); }); - }; - $scope.save_usd_account = function (){ + $scope.save_usd_account = function () { $scope.usdLoading = true; var amount = ripple.Amount.from_human( Options.gateway_max_limit + ' ' + 'USD', - {reference_date: new Date(+new Date() + 5*60000)} + {reference_date: new Date(+new Date() + 5 * 60000)} ); amount.set_issuer('rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'); @@ -159,7 +174,7 @@ UsdTab.prototype.angular = function (module) // Flags tx .rippleLineSet(id.account, amount) - .on('proposed', function(res){ + .on('proposed', function(res) { $scope.$apply(function () { setEngineStatus(res, false); }); @@ -171,7 +186,9 @@ UsdTab.prototype.angular = function (module) $scope.usdLoading = false; $scope.usdediting = false; }); - }) + + api.addTransaction(res.tx_json, {Status: 'success'}, res.tx_json.hash, new Date().toString()); + }) .on('error', function (res) { setEngineStatus(res, false); console.log('error', res); @@ -183,7 +200,9 @@ UsdTab.prototype.angular = function (module) $scope.usdediting = false; }); }); - }); + + api.addTransaction(res.tx_json, {Status: 'error'}, res.tx_json.hash, new Date().toString()); + }); function setEngineStatus(res, accepted) { $scope.usd_engine_result = res.engine_result; @@ -228,7 +247,21 @@ UsdTab.prototype.angular = function (module) $scope.usdMode = 'granting'; tx.secret(secret); - tx.submit(); + + api.getUserAccess().then(function(res) { + tx.submit(); + }, function(err2) { + console.log('error', err2); + setImmediate(function () { + $scope.$apply(function () { + $scope.usdMode = 'error'; + + $scope.usdLoading = false; + $scope.usdediting = false; + }); + }); + }); + }); }; @@ -267,6 +300,8 @@ UsdTab.prototype.angular = function (module) $scope.usd3Loading = false; }); + + api.addTransaction(res.tx_json, {Status: 'success'}, res.tx_json.hash, new Date().toString()); }) .on('error', function (res) { setEngineStatus(res, false); @@ -276,7 +311,9 @@ UsdTab.prototype.angular = function (module) $scope.usd3Loading = false; }); }); - }); + + api.addTransaction(res.tx_json, {Status: 'error'}, res.tx_json.hash, new Date().toString()); + }); function setEngineStatus(res, accepted) { $scope.usd3_engine_result = res.engine_result; @@ -318,7 +355,17 @@ UsdTab.prototype.angular = function (module) } tx.secret(secret); - tx.submit(); + + api.getUserAccess().then(function(res) { + tx.submit(); + }, function(err2) { + console.log('error', err2); + setImmediate(function () { + $scope.$apply(function () { + $scope.usd3Loading = false; + }); + }); + }); }); };