diff --git a/src/js/controllers/amount.js b/src/js/controllers/amount.js index f4f8d9d72..51a42904d 100644 --- a/src/js/controllers/amount.js +++ b/src/js/controllers/amount.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('copayApp.controllers').controller('amountController', function($scope, $filter, $timeout, $ionicScrollDelegate, $ionicHistory, $ionicPopover, gettextCatalog, platformInfo, lodash, configService, rateService, $stateParams, $window, $state, $log, txFormatService, ongoingProcess, bitpayCardService, popupService, bwcError, payproService, profileService, bitcore, amazonService) { +angular.module('copayApp.controllers').controller('amountController', function($scope, $filter, $timeout, $ionicScrollDelegate, $ionicHistory, $ionicPopover, gettextCatalog, platformInfo, lodash, configService, rateService, $stateParams, $window, $state, $log, txFormatService, ongoingProcess, bitpayCardService, popupService, bwcError, payproService, profileService, bitcore, amazonService, glideraService) { var unitToSatoshi; var satToUnit; var unitDecimals; @@ -15,22 +15,34 @@ angular.module('copayApp.controllers').controller('amountController', function($ $scope.$on("$ionicView.beforeEnter", function(event, data) { $scope.isGiftCard = data.stateParams.isGiftCard; + + // Glidera parameters + $scope.isGlidera = data.stateParams.isGlidera; + $scope.glideraAccessToken = data.stateParams.glideraAccessToken; + + $scope.cardId = data.stateParams.cardId; $scope.showMenu = $ionicHistory.backView().stateName == 'tabs.send'; $scope.isWallet = data.stateParams.isWallet; - $scope.cardId = data.stateParams.cardId; $scope.toAddress = data.stateParams.toAddress; $scope.toName = data.stateParams.toName; $scope.toEmail = data.stateParams.toEmail; - $scope.showAlternativeAmount = !!$scope.cardId || !!$scope.isGiftCard; + $scope.showAlternativeAmount = !!$scope.cardId || !!$scope.isGiftCard || !!$scope.isGlidera; $scope.toColor = data.stateParams.toColor; $scope.customAmount = data.stateParams.customAmount; - if (!$scope.cardId && !$scope.isGiftCard && !data.stateParams.toAddress) { + if (!$scope.cardId && !$scope.isGiftCard && !$scope.isGlidera && !data.stateParams.toAddress) { $log.error('Bad params at amount') throw ('bad params'); } + glideraService.getLimits($scope.glideraAccessToken, function(err, limits) { + $scope.limits = limits; + $timeout(function() { + $scope.$apply(); + }); + }); + var reNr = /^[1234567890\.]$/; var reOp = /^[\*\+\-\/]$/; @@ -325,6 +337,13 @@ angular.module('copayApp.controllers').controller('amountController', function($ }, true); }); }); + } else if ($scope.isGlidera) { + var amount = $scope.showAlternativeAmount ? fromFiat(_amount) : _amount; + $state.transitionTo('tabs.buyandsell.glidera.confirm', { + toAmount: (amount * unitToSatoshi).toFixed(0), + isGlidera: $scope.isGlidera, + glideraAccessToken: $scope.glideraAccessToken + }); } else { var amount = $scope.showAlternativeAmount ? fromFiat(_amount) : _amount; if ($scope.customAmount) { diff --git a/src/js/controllers/buyGlidera.js b/src/js/controllers/buyGlidera.js deleted file mode 100644 index e15632185..000000000 --- a/src/js/controllers/buyGlidera.js +++ /dev/null @@ -1,146 +0,0 @@ -'use strict'; - -angular.module('copayApp.controllers').controller('buyGlideraController', - function($scope, $timeout, $log, profileService, walletService, glideraService, bwcError, lodash, ongoingProcess, popupService, gettextCatalog) { - - var wallet; - var self = this; - this.show2faCodeInput = null; - this.success = null; - $scope.network = glideraService.getEnvironment(); - - $scope.$on('Wallet/Changed', function(event, w) { - if (lodash.isEmpty(w)) { - $log.debug('No wallet provided'); - return; - } - wallet = w; - $log.debug('Wallet changed: ' + w.name); - }); - - $scope.update = function(opts) { - if (!$scope.token || !$scope.permissions) return; - $log.debug('Updating Glidera Account...'); - var accessToken = $scope.token; - var permissions = $scope.permissions; - - opts = opts || {}; - - glideraService.getStatus(accessToken, function(err, data) { - $scope.status = data; - }); - - glideraService.getLimits(accessToken, function(err, limits) { - $scope.limits = limits; - }); - - if (permissions.transaction_history) { - glideraService.getTransactions(accessToken, function(err, data) { - $scope.txs = data; - }); - } - - if (permissions.view_email_address && opts.fullUpdate) { - glideraService.getEmail(accessToken, function(err, data) { - $scope.email = data.email; - }); - } - if (permissions.personal_info && opts.fullUpdate) { - glideraService.getPersonalInfo(accessToken, function(err, data) { - $scope.personalInfo = data; - }); - } - }; - - this.getBuyPrice = function(token, price) { - var self = this; - if (!price || (price && !price.qty && !price.fiat)) { - this.buyPrice = null; - return; - } - this.gettingBuyPrice = true; - glideraService.buyPrice(token, price, function(err, buyPrice) { - self.gettingBuyPrice = false; - if (err) { - popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Could not get exchange information. Please, try again')); - return; - } - self.buyPrice = buyPrice; - }); - }; - - this.get2faCode = function(token) { - var self = this; - ongoingProcess.set('Sending 2FA code...', true); - $timeout(function() { - glideraService.get2faCode(token, function(err, sent) { - ongoingProcess.set('Sending 2FA code...', false); - if (err) { - popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Could not send confirmation code to your phone')); - return; - } - self.show2faCodeInput = sent; - }); - }, 100); - }; - - this.sendRequest = function(token, permissions, twoFaCode) { - var self = this; - ongoingProcess.set('Buying Bitcoin...', true); - $timeout(function() { - walletService.getAddress(wallet, false, function(err, walletAddr) { - if (err) { - ongoingProcess.set('Buying Bitcoin...', false); - popupService.showAlert(gettextCatalog.getString('Error'), bwcError.cb(err, 'Could not create address')); - return; - } - var data = { - destinationAddress: walletAddr, - qty: self.buyPrice.qty, - priceUuid: self.buyPrice.priceUuid, - useCurrentPrice: false, - ip: null - }; - glideraService.buy(token, twoFaCode, data, function(err, data) { - ongoingProcess.set('Buying Bitcoin...', false); - if (err) { - popupService.showAlert(gettextCatalog.getString('Error'), err); - return; - } - self.success = data; - $timeout(function() { - $scope.$digest(); - }); - }); - }); - }, 100); - }; - - $scope.$on("$ionicView.enter", function(event, data){ - $scope.token = null; - $scope.permissions = null; - $scope.email = null; - $scope.personalInfo = null; - $scope.txs = null; - $scope.status = null; - $scope.limits = null; - - ongoingProcess.set('connectingGlidera', true); - glideraService.init($scope.token, function(err, glidera) { - ongoingProcess.set('connectingGlidera'); - if (err || !glidera) { - if (err) popupService.showAlert(gettextCatalog.getString('Error'), err); - return; - } - $scope.token = glidera.token; - $scope.permissions = glidera.permissions; - $scope.update({fullUpdate: true}); - }); - - $scope.wallets = profileService.getWallets({ - network: $scope.network, - onlyComplete: true - }); - }); - - }); diff --git a/src/js/controllers/confirm.js b/src/js/controllers/confirm.js index 5c4d55499..79e20f2ff 100644 --- a/src/js/controllers/confirm.js +++ b/src/js/controllers/confirm.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('copayApp.controllers').controller('confirmController', function($rootScope, $scope, $interval, $filter, $timeout, $ionicScrollDelegate, gettextCatalog, walletService, platformInfo, lodash, configService, rateService, $stateParams, $window, $state, $log, profileService, bitcore, gettext, txFormatService, ongoingProcess, $ionicModal, popupService, $ionicHistory, $ionicConfig, payproService, feeService, amazonService) { +angular.module('copayApp.controllers').controller('confirmController', function($rootScope, $scope, $interval, $filter, $timeout, $ionicScrollDelegate, gettextCatalog, walletService, platformInfo, lodash, configService, rateService, $stateParams, $window, $state, $log, profileService, bitcore, gettext, txFormatService, ongoingProcess, $ionicModal, popupService, $ionicHistory, $ionicConfig, payproService, feeService, amazonService, glideraService, bwcError) { var cachedTxp = {}; var toAmount; var isChromeApp = platformInfo.isChromeApp; @@ -21,6 +21,10 @@ angular.module('copayApp.controllers').controller('confirmController', function( giftCardInvoiceTime = data.stateParams.giftCardInvoiceTime; giftCardUUID = data.stateParams.giftCardUUID; + // Glidera parameters + $scope.isGlidera = data.stateParams.isGlidera; + $scope.glideraAccessToken = data.stateParams.glideraAccessToken; + toAmount = data.stateParams.toAmount; cachedSendMax = {}; $scope.useSendMax = data.stateParams.useSendMax == 'true' ? true : false; @@ -42,7 +46,8 @@ angular.module('copayApp.controllers').controller('confirmController', function( var config = configService.getSync().wallet; $scope.feeLevel = config.settings && config.settings.feeLevel ? config.settings.feeLevel : 'normal'; - $scope.network = (new bitcore.Address($scope.toAddress)).network.name; + if ($scope.isGlidera) $scope.network = glideraService.getEnvironment(); + else $scope.network = (new bitcore.Address($scope.toAddress)).network.name; resetValues(); setwallets(); }); @@ -125,6 +130,8 @@ angular.module('copayApp.controllers').controller('confirmController', function( txFormatService.formatAlternativeStr(toAmount, function(v) { $scope.alternativeAmountStr = v; }); + if ($scope.isGlidera == 'buy') $scope.getBuyPrice(); + if ($scope.isGlidera == 'sell') $scope.getSellPrice(); }; function resetValues() { @@ -233,6 +240,7 @@ angular.module('copayApp.controllers').controller('confirmController', function( }); $scope.showWalletSelector = function() { + $scope.walletSelectorTitle = $scope.isGlidera == 'buy' ? 'Receive in' : $scope.isGlidera == 'sell' ? 'Sell From' : gettextCatalog.getString('Send from'); if (!$scope.useSendMax && ($scope.insufficientFunds || $scope.noMatchingWallet)) return; $scope.showWallets = true; }; @@ -309,6 +317,7 @@ angular.module('copayApp.controllers').controller('confirmController', function( $scope.wallet = wallet; $scope.fee = $scope.txp = null; + if ($scope.isGlidera) return; if (stop) { $timeout.cancel(stop); stop = null; @@ -415,6 +424,12 @@ angular.module('copayApp.controllers').controller('confirmController', function( }; $scope.approve = function(onSendStatusChange) { + + var wallet = $scope.wallet; + if (!wallet) { + return; + } + if ($scope.paypro && $scope.paymentExpired.value) { popupService.showAlert(null, gettextCatalog.getString('This bitcoin payment request has expired.')); $scope.sendStatus = ''; @@ -424,9 +439,45 @@ angular.module('copayApp.controllers').controller('confirmController', function( return; } - var wallet = $scope.wallet; - if (!wallet) { - return setSendError(gettextCatalog.getString('No wallet selected')); + if ($scope.isGlidera) { + $scope.get2faCode(function(err, sent) { + if (err) { + popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Could not send confirmation code to your phone')); + return; + } + if (sent) { + var title = gettextCatalog.getString("Please, enter the code below"); + var message = gettextCatalog.getString("A SMS containing a confirmation code was sent to your phone."); + popupService.showPrompt(title, message, null, function(twoFaCode) { + if (typeof twoFaCode == 'undefined') return; + if ($scope.isGlidera == 'buy') { + $scope.buyRequest(wallet, twoFaCode, function(err, data) { + if (err) { + popupService.showAlert(gettextCatalog.getString('Error'), err); + return; + } + $scope.sendStatus = 'success'; + $timeout(function() { + $scope.$digest(); + }); + }) + } + if ($scope.isGlidera == 'sell') { + $scope.sellRequest(wallet, twoFaCode, function(err, data) { + if (err) { + popupService.showAlert(gettextCatalog.getString('Error'), err); + return; + } + $scope.sendStatus = 'success'; + $timeout(function() { + $scope.$digest(); + }); + }) + } + }); + } + }); + return; } if (!wallet.canSign() && !wallet.isPrivKeyExternal()) { @@ -501,6 +552,7 @@ angular.module('copayApp.controllers').controller('confirmController', function( var previousView = $ionicHistory.viewHistory().backView && $ionicHistory.viewHistory().backView.stateName; var fromBitPayCard = previousView.match(/tabs.bitpayCard/) ? true : false; var fromAmazon = previousView.match(/tabs.giftcards.amazon/) ? true : false; + var fromGlidera = previousView.match(/tabs.buyandsell.glidera/) ? true : false; $ionicHistory.nextViewOptions({ disableAnimate: true @@ -525,6 +577,15 @@ angular.module('copayApp.controllers').controller('confirmController', function( cardClaimCode: $scope.amazonGiftCard ? $scope.amazonGiftCard.claimCode : null }); }); + } else if (fromGlidera) { + $ionicHistory.nextViewOptions({ + disableAnimate: true, + historyRoot: true + }); + $ionicHistory.clearHistory(); + $state.go('tabs.home').then(function() { + $state.transitionTo('tabs.buyandsell.glidera'); + }); } else { $ionicHistory.nextViewOptions({ disableAnimate: true, @@ -537,6 +598,162 @@ angular.module('copayApp.controllers').controller('confirmController', function( } }; + $scope.get2faCode = function(cb) { + ongoingProcess.set('sending2faCode', true); + $timeout(function() { + glideraService.get2faCode($scope.glideraAccessToken, function(err, sent) { + ongoingProcess.set('sending2faCode', false); + return cb(err, sent); + }); + }, 100); + }; + + $scope.buyRequest = function(wallet, twoFaCode, cb) { + ongoingProcess.set('buyingBitcoin', true); + $timeout(function() { + walletService.getAddress(wallet, false, function(err, walletAddr) { + if (err) { + ongoingProcess.set('buyingBitcoin', false); + popupService.showAlert(gettextCatalog.getString('Error'), bwcError.cb(err, 'Could not create address')); + return; + } + var data = { + destinationAddress: walletAddr, + qty: $scope.buyPrice.qty, + priceUuid: $scope.buyPrice.priceUuid, + useCurrentPrice: false, + ip: null + }; + glideraService.buy($scope.glideraAccessToken, twoFaCode, data, function(err, data) { + ongoingProcess.set('buyingBitcoin', false); + return cb(err, data); + }); + }); + }, 100); + }; + + $scope.sellRequest = function(wallet, twoFaCode, cb) { + var outputs = []; + var config = configService.getSync(); + var configWallet = config.wallet; + var walletSettings = configWallet.settings; + + ongoingProcess.set('creatingTx', true); + walletService.getAddress(wallet, null, function(err, refundAddress) { + if (!refundAddress) { + ongoingProcess.clear(); + popupService.showAlert(gettextCatalog.getString('Error'), bwcError.msg(err, 'Could not create address')); + return; + } + glideraService.getSellAddress($scope.glideraAccessToken, function(err, sellAddress) { + if (!sellAddress || err) { + ongoingProcess.clear(); + popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Could not get the destination bitcoin address')); + return; + } + var amount = parseInt(($scope.sellPrice.qty * 100000000).toFixed(0)); + var comment = 'Glidera transaction'; + + outputs.push({ + 'toAddress': sellAddress, + 'amount': amount, + 'message': comment + }); + + var txp = { + toAddress: sellAddress, + amount: amount, + outputs: outputs, + message: comment, + payProUrl: null, + excludeUnconfirmedUtxos: configWallet.spendUnconfirmed ? false : true, + feeLevel: walletSettings.feeLevel || 'normal', + customData: { + 'glideraToken': $scope.glideraAccessToken + } + }; + + walletService.createTx(wallet, txp, function(err, createdTxp) { + ongoingProcess.clear(); + if (err) { + popupService.showAlert(gettextCatalog.getString('Error'), err.message || bwcError.msg(err)); + return; + } + walletService.prepare(wallet, function(err, password) { + if (err) { + ongoingProcess.clear(); + popupService.showAlert(gettextCatalog.getString('Error'), err.message || bwcError.msg(err)); + return; + } + ongoingProcess.set('signingTx', true); + walletService.publishTx(wallet, createdTxp, function(err, publishedTxp) { + if (err) { + ongoingProcess.clear(); + popupService.showAlert(gettextCatalog.getString('Error'), err.message ||  bwcError.msg(err)); + return; + } + + walletService.signTx(wallet, publishedTxp, password, function(err, signedTxp) { + if (err) { + ongoingProcess.clear(); + popupService.showAlert(gettextCatalog.getString('Error'), err.message ||  bwcError.msg(err)); + walletService.removeTx(wallet, signedTxp, function(err) { + if (err) $log.debug(err); + }); + return; + } + var rawTx = signedTxp.raw; + var data = { + refundAddress: refundAddress, + signedTransaction: rawTx, + priceUuid: $scope.sellPrice.priceUuid, + useCurrentPrice: $scope.sellPrice.priceUuid ? false : true, + ip: null + }; + ongoingProcess.set('sellingBitcoin', true); + glideraService.sell($scope.glideraAccessToken, twoFaCode, data, function(err, data) { + ongoingProcess.clear(); + if (err) { + popupService.showAlert(gettextCatalog.getString('Error'), err.message ||  bwcError.msg(err)); + return; + } + return cb(err, data) + }); + }); + }); + }); + }); + }); + }); + } + + $scope.getBuyPrice = function() { + var satToBtc = 1 / 100000000; + var price = {}; + price.qty = (toAmount * satToBtc).toFixed(8); + glideraService.buyPrice($scope.glideraAccessToken, price, function(err, buyPrice) { + if (err) { + popupService.showAlert(gettextCatalog.getString('Error'), 'Could not get exchange information. Please, try again'); + return; + } + $scope.buyPrice = buyPrice; + }); + }; + + $scope.getSellPrice = function() { + var satToBtc = 1 / 100000000; + var price = {}; + price.qty = (toAmount * satToBtc).toFixed(8); + + glideraService.sellPrice($scope.glideraAccessToken, price, function(err, sellPrice) { + if (err) { + popupService.showAlert(gettextCatalog.getString('Error'), 'Could not get exchange information. Please, try again'); + return; + } + $scope.sellPrice = sellPrice; + }); + }; + function publishAndSign(wallet, txp, onSendStatusChange) { walletService.publishAndSign(wallet, txp, function(err, txp) { if (err) return setSendError(err); diff --git a/src/js/controllers/glidera.js b/src/js/controllers/glidera.js index f3fc9af6c..bb746274f 100644 --- a/src/js/controllers/glidera.js +++ b/src/js/controllers/glidera.js @@ -18,9 +18,11 @@ angular.module('copayApp.controllers').controller('glideraController', $scope.status = null; $scope.limits = null; + $scope.connectingGlidera = true; ongoingProcess.set('connectingGlidera', true); glideraService.init($scope.token, function(err, glidera) { ongoingProcess.set('connectingGlidera'); + $scope.connectingGlidera = false; if (err || !glidera) { if (err) popupService.showAlert(gettextCatalog.getString('Error'), err); return; @@ -67,11 +69,11 @@ angular.module('copayApp.controllers').controller('glideraController', } }; - this.getAuthenticateUrl = function() { + $scope.getAuthenticateUrl = function() { return glideraService.getOauthCodeUrl(); }; - this.submitOauthCode = function(code) { + $scope.submitOauthCode = function(code) { ongoingProcess.set('connectingGlidera', true); $timeout(function() { glideraService.getToken(code, function(err, data) { @@ -90,10 +92,7 @@ angular.module('copayApp.controllers').controller('glideraController', }, 100); }; - this.openTxModal = function(token, tx) { - var self = this; - - $scope.self = self; + $scope.openTxModal = function(token, tx) { $scope.tx = tx; glideraService.getTransaction(token, tx.transactionUuid, function(err, tx) { diff --git a/src/js/controllers/sellGlidera.js b/src/js/controllers/sellGlidera.js deleted file mode 100644 index be19a4298..000000000 --- a/src/js/controllers/sellGlidera.js +++ /dev/null @@ -1,219 +0,0 @@ -'use strict'; - -angular.module('copayApp.controllers').controller('sellGlideraController', - function($scope, $timeout, $log, profileService, glideraService, bwcError, lodash, walletService, configService, ongoingProcess, popupService, gettextCatalog) { - - var self = this; - this.data = {}; - this.show2faCodeInput = null; - this.success = null; - var wallet; - $scope.network = glideraService.getEnvironment(); - - $scope.$on('Wallet/Changed', function(event, w) { - if (lodash.isEmpty(w)) { - $log.debug('No wallet provided'); - return; - } - wallet = w; - $log.debug('Wallet changed: ' + w.name); - }); - - $scope.update = function(opts) { - if (!$scope.token || !$scope.permissions) return; - $log.debug('Updating Glidera Account...'); - var accessToken = $scope.token; - var permissions = $scope.permissions; - - opts = opts || {}; - - glideraService.getStatus(accessToken, function(err, data) { - $scope.status = data; - }); - - glideraService.getLimits(accessToken, function(err, limits) { - $scope.limits = limits; - }); - - if (permissions.transaction_history) { - glideraService.getTransactions(accessToken, function(err, data) { - $scope.txs = data; - }); - } - - if (permissions.view_email_address && opts.fullUpdate) { - glideraService.getEmail(accessToken, function(err, data) { - $scope.email = data.email; - }); - } - if (permissions.personal_info && opts.fullUpdate) { - glideraService.getPersonalInfo(accessToken, function(err, data) { - $scope.personalInfo = data; - }); - } - }; - - this.getSellPrice = function(token, price) { - var self = this; - if (!price || (price && !price.qty && !price.fiat)) { - self.sellPrice = null; - return; - } - self.gettingSellPrice = true; - glideraService.sellPrice(token, price, function(err, sellPrice) { - self.gettingSellPrice = false; - if (err) { - popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Could not get exchange information. Please, try again')); - return; - } - self.sellPrice = sellPrice; - }); - }; - - this.get2faCode = function(token) { - var self = this; - ongoingProcess.set('Sending 2FA code...', true); - $timeout(function() { - glideraService.get2faCode(token, function(err, sent) { - ongoingProcess.set('Sending 2FA code...', false); - if (err) { - popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Could not send confirmation code to your phone')); - } else { - self.show2faCodeInput = sent; - } - }); - }, 100); - }; - - this.createTx = function(token, permissions, twoFaCode) { - var self = this; - var outputs = []; - var config = configService.getSync(); - var configWallet = config.wallet; - var walletSettings = configWallet.settings; - - if (!wallet) { - popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('No wallet selected')); - return; - } - - ongoingProcess.set('creatingTx', true); - walletService.getAddress(wallet, null, function(err, refundAddress) { - if (!refundAddress) { - ongoingProcess.clear(); - popupService.showAlert(gettextCatalog.getString('Error'), bwcError.msg(err, 'Could not create address')); - return; - } - glideraService.getSellAddress(token, function(err, sellAddress) { - if (!sellAddress || err) { - ongoingProcess.clear(); - popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Could not get the destination bitcoin address')); - return; - } - var amount = parseInt((self.sellPrice.qty * 100000000).toFixed(0)); - var comment = 'Glidera transaction'; - - outputs.push({ - 'toAddress': sellAddress, - 'amount': amount, - 'message': comment - }); - - var txp = { - toAddress: sellAddress, - amount: amount, - outputs: outputs, - message: comment, - payProUrl: null, - excludeUnconfirmedUtxos: configWallet.spendUnconfirmed ? false : true, - feeLevel: walletSettings.feeLevel || 'normal', - customData: { - 'glideraToken': token - } - }; - - walletService.createTx(wallet, txp, function(err, createdTxp) { - ongoingProcess.clear(); - if (err) { - popupService.showAlert(gettextCatalog.getString('Error'), err.message || bwcError.msg(err)); - return; - } - walletService.prepare(wallet, function(err, password) { - if (err) { - ongoingProcess.clear(); - popupService.showAlert(gettextCatalog.getString('Error'), err.message || bwcError.msg(err)); - return; - } - ongoingProcess.set('signingTx', true); - walletService.publishTx(wallet, createdTxp, function(err, publishedTxp) { - if (err) { - ongoingProcess.clear(); - popupService.showAlert(gettextCatalog.getString('Error'), err.message || bwcError.msg(err)); - return; - } - - walletService.signTx(wallet, publishedTxp, password, function(err, signedTxp) { - if (err) { - ongoingProcess.clear(); - popupService.showAlert(gettextCatalog.getString('Error'), err.message || bwcError.msg(err)); - walletService.removeTx(wallet, signedTxp, function(err) { - if (err) $log.debug(err); - }); - return; - } - var rawTx = signedTxp.raw; - var data = { - refundAddress: refundAddress, - signedTransaction: rawTx, - priceUuid: self.sellPrice.priceUuid, - useCurrentPrice: self.sellPrice.priceUuid ? false : true, - ip: null - }; - ongoingProcess.set('Selling Bitcoin', true); - glideraService.sell(token, twoFaCode, data, function(err, data) { - ongoingProcess.clear(); - if (err) { - popupService.showAlert(gettextCatalog.getString('Error'), err.message || bwcError.msg(err)); - return; - } - self.success = data; - $timeout(function() { - $scope.$digest(); - }); - }); - }); - }); - }); - }); - }); - }); - }; - - $scope.$on("$ionicView.enter", function(event, data){ - $scope.token = null; - $scope.permissions = null; - $scope.email = null; - $scope.personalInfo = null; - $scope.txs = null; - $scope.status = null; - $scope.limits = null; - - ongoingProcess.set('connectingGlidera', true); - glideraService.init($scope.token, function(err, glidera) { - ongoingProcess.set('connectingGlidera'); - if (err || !glidera) { - if (err) popupService.showAlert(gettextCatalog.getString('Error'), err); - return; - } - $scope.token = glidera.token; - $scope.permissions = glidera.permissions; - $scope.update({fullUpdate: true}); - }); - - $scope.wallets = profileService.getWallets({ - network: $scope.network, - n: 1, - onlyComplete: true - }); - }); - }); diff --git a/src/js/directives/clickToAccept.js b/src/js/directives/clickToAccept.js index 36cfbaeb5..63257e235 100644 --- a/src/js/directives/clickToAccept.js +++ b/src/js/directives/clickToAccept.js @@ -8,10 +8,11 @@ angular.module('copayApp.directives') transclude: true, scope: { sendStatus: '=clickSendStatus', + wallet: '=hasWalletChosen' }, link: function(scope, element, attrs) { scope.$watch('sendStatus', function() { - if(scope.sendStatus !== 'success') { + if (scope.sendStatus !== 'success') { scope.displaySendStatus = scope.sendStatus; } }); diff --git a/src/js/directives/slideToAccept.js b/src/js/directives/slideToAccept.js index a396e2b0d..e57aaecff 100644 --- a/src/js/directives/slideToAccept.js +++ b/src/js/directives/slideToAccept.js @@ -8,7 +8,8 @@ angular.module('copayApp.directives') transclude: true, scope: { sendStatus: '=slideSendStatus', - onConfirm: '&slideOnConfirm' + onConfirm: '&slideOnConfirm', + wallet: '=hasWalletChosen' }, link: function(scope, element, attrs) { @@ -33,9 +34,9 @@ angular.module('copayApp.directives') scope.displaySendStatus = ''; scope.$watch('sendStatus', function() { - if(!scope.sendStatus) { + if (!scope.sendStatus) { reset(); - } else if(scope.sendStatus === 'success') { + } else if (scope.sendStatus === 'success') { scope.displaySendStatus = ''; $timeout(function() { reset(); @@ -51,19 +52,20 @@ angular.module('copayApp.directives') var startTime = currentEaseStartTime; var initialPct = fromPct; var distance = pct - fromPct; + function ease() { - if(startTime !== currentEaseStartTime) { + if (startTime !== currentEaseStartTime) { return; } $window.requestAnimationFrame(function() { var now = Date.now(); var elapsed = now - startTime; - var normalizedElapsedTime = elapsed/duration; + var normalizedElapsedTime = elapsed / duration; var newVal = easeFx(normalizedElapsedTime); - var newPct = newVal*distance + initialPct; + var newPct = newVal * distance + initialPct; animateFx(newPct); scope.$digest(); - if(elapsed < duration) { + if (elapsed < duration) { ease(); } else { deferred.resolve(); @@ -93,31 +95,33 @@ angular.module('copayApp.directives') function setNewSliderStyle(pct) { var knobWidthPct = getKnobWidthPercentage(); var translatePct = pct - knobWidthPct; - if(isSliding) { - translatePct += 0.35*pct; + if (isSliding) { + translatePct += 0.35 * pct; } scope.sliderStyle = getTransformStyle(translatePct); curSliderPct = pct; } function setNewBitcoinStyle(pct) { - var translatePct = -2.25*pct; + var translatePct = -2.25 * pct; scope.bitcoinStyle = getTransformStyle(translatePct); curBitcoinPct = pct; } function setNewTextStyle(pct) { - var translatePct = -0.1*pct; + var translatePct = -0.1 * pct; scope.textStyle = getTransformStyle(translatePct); curTextPct = pct; } function getTransformStyle(translatePct) { - return {'transform': 'translateX(' + translatePct + '%)'}; + return { + 'transform': 'translateX(' + translatePct + '%)' + }; } - function getKnobWidthPercentage() { - var knobWidthPct = (KNOB_WIDTH/elm.clientWidth)*100; + function getKnobWidthPercentage() { + var knobWidthPct = (KNOB_WIDTH / elm.clientWidth) * 100; return knobWidthPct; } @@ -175,8 +179,8 @@ angular.module('copayApp.directives') function getTouchXPosition($event) { var x; - if($event.touches || $event.changedTouches) { - if($event.touches.length) { + if ($event.touches || $event.changedTouches) { + if ($event.touches.length) { x = $event.touches[0].clientX; } else { x = $event.changedTouches[0].clientX; @@ -190,18 +194,18 @@ angular.module('copayApp.directives') function getSlidPercentage($event) { var x = getTouchXPosition($event); var width = elm.clientWidth; - var pct = (x/width)*100; - if(x >= width) { + var pct = (x / width) * 100; + if (x >= width) { pct = 100; } return pct; } scope.onTouchstart = function($event) { - if(scope.isSlidFully) { + if (scope.isSlidFully) { return; } - if(!isSliding) { + if (!isSliding) { var pct = getSlidPercentage($event); if (pct > MAX_SLIDE_START_PERCENTAGE) { jiggleSlider(); @@ -209,7 +213,7 @@ angular.module('copayApp.directives') } else { isSliding = true; var knobWidthPct = getKnobWidthPercentage(); - if(pct < knobWidthPct) { + if (pct < knobWidthPct) { pct = knobWidthPct; } pct += PERCENTAGE_BUMP; @@ -219,12 +223,12 @@ angular.module('copayApp.directives') }; scope.onTouchmove = function($event) { - if(!isSliding || scope.isSlidFully) { + if (!isSliding || scope.isSlidFully) { return; } var pct = getSlidPercentage($event); var knobWidthPct = getKnobWidthPercentage(); - if(pct < knobWidthPct) { + if (pct < knobWidthPct) { pct = knobWidthPct; } pct += PERCENTAGE_BUMP; @@ -233,11 +237,11 @@ angular.module('copayApp.directives') }; scope.onTouchend = function($event) { - if(scope.isSlidFully) { + if (scope.isSlidFully) { return; } var pct = getSlidPercentage($event); - if(isSliding && pct > FULLY_SLID_PERCENTAGE) { + if (isSliding && pct > FULLY_SLID_PERCENTAGE) { pct = 100; setSliderPosition(pct); alertSlidFully(); diff --git a/src/js/directives/walletSelector.js b/src/js/directives/walletSelector.js index 97149d528..c5dfff59a 100644 --- a/src/js/directives/walletSelector.js +++ b/src/js/directives/walletSelector.js @@ -7,6 +7,7 @@ angular.module('copayApp.directives') templateUrl: 'views/includes/walletSelector.html', transclude: true, scope: { + title: '=walletSelectorTitle', show: '=walletSelectorShow', wallets: '=walletSelectorWallets', selectedWallet: '=walletSelectorSelectedWallet', diff --git a/src/js/routes.js b/src/js/routes.js index 4ef27d0a8..278d24646 100644 --- a/src/js/routes.js +++ b/src/js/routes.js @@ -888,23 +888,21 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr } } }) - .state('tabs.buyandsell.glidera.buy', { - url: '/buy', + .state('tabs.buyandsell.glidera.amount', { + url: '/amount/:isGlidera/:glideraAccessToken', views: { 'tab-home@tabs': { - controller: 'buyGlideraController', - controllerAs: 'buy', - templateUrl: 'views/buyGlidera.html' + controller: 'amountController', + templateUrl: 'views/amount.html' } } }) - .state('tabs.buyandsell.glidera.sell', { - url: '/sell', + .state('tabs.buyandsell.glidera.confirm', { + url: '/confirm/:toAmount/:isGlidera/:glideraAccessToken', views: { 'tab-home@tabs': { - controller: 'sellGlideraController', - controllerAs: 'sell', - templateUrl: 'views/sellGlidera.html' + controller: 'confirmController', + templateUrl: 'views/confirm.html' } } }) diff --git a/src/js/services/glideraService.js b/src/js/services/glideraService.js index cf9083014..06e30cf14 100644 --- a/src/js/services/glideraService.js +++ b/src/js/services/glideraService.js @@ -192,8 +192,13 @@ angular.module('copayApp.services').factory('glideraService', function($http, $l }; root.get2faCode = function(token, cb) { - if (!token) return cb('Invalid Token'); + if (!token) { + $log.error('Glidera Sent 2FA code by SMS: ERROR Invalid Token'); + return cb('Invalid Token'); + } + $http(_get('/authentication/get2faCode', token)).then(function(data) { + $log.info('Glidera Sent 2FA code by SMS: SUCCESS'); return cb(null, data.status == 200 ? true : false); }, function(data) { diff --git a/src/js/services/onGoingProcess.js b/src/js/services/onGoingProcess.js index cdcb501d7..b543430ab 100644 --- a/src/js/services/onGoingProcess.js +++ b/src/js/services/onGoingProcess.js @@ -37,6 +37,9 @@ angular.module('copayApp.services').factory('ongoingProcess', function($log, $ti 'generatingNewAddress': gettext('Generating new address...'), 'gettingAddresses': gettext('Getting addresses...'), 'sendingByEmail': gettext('Preparing addresses...'), + 'sending2faCode': gettext('Sending 2FA code...'), + 'buyingBitcoin': gettext('Buying Bitcoin...'), + 'sellingBitcoin': gettext('Selling Bitcoin...') }; root.clear = function() { diff --git a/src/sass/views/amount.scss b/src/sass/views/amount.scss index 7c4c1681e..cc4bf24e3 100644 --- a/src/sass/views/amount.scss +++ b/src/sass/views/amount.scss @@ -37,7 +37,7 @@ position: absolute; top: 10px; } - .amount-pane-send { + .amount-pane-recipient { position: absolute; top: 95px; bottom: 0; @@ -68,7 +68,7 @@ } } } - .amount-pane-receive { + .amount-pane-no-recipient { position: absolute; top: 0; bottom: 0; @@ -84,6 +84,11 @@ padding-top: 10px; color: $dark-gray; font-weight: bold; + .limits { + margin-top: 10px; + color: $light-gray; + font-size: 12px; + } } } .amount { diff --git a/src/sass/views/includes/txp-details.scss b/src/sass/views/includes/txp-details.scss index 137573dae..5d1d0f9ea 100644 --- a/src/sass/views/includes/txp-details.scss +++ b/src/sass/views/includes/txp-details.scss @@ -245,4 +245,21 @@ color: rgba(58, 58, 58, .6); margin-bottom: 1.5rem; } + .glidera-success { + padding: 20px; + margin-top: 15px; + span { + font-size: 15px; + display: block; + } + } + .glidera-explanation { + padding: 0 1rem; + white-space: normal; + } + .glidera-description { + text-align: center; + font-size: 12px; + color: $mid-gray; + } } diff --git a/www/views/amount.html b/www/views/amount.html index 24c3b3f1e..c2d36dc12 100644 --- a/www/views/amount.html +++ b/www/views/amount.html @@ -14,14 +14,14 @@ -
+
Recipient
- +
@@ -36,12 +36,32 @@
-
+
Amount - (Purchase Amount is limited to USD 500 per day) + (Purchase Amount is limited to USD 500 per day) +
+
+ Daily buy limit: + {{limits.dailyBuy|currency:'':2}} {{limits.currency}} + (remaining {{limits.dailyBuyRemaining|currency:'':2}} {{limits.currency}}) +
+ Monthly buy limit: + {{limits.monthlyBuy|currency:'':2}} {{limits.currency}} + (remaining {{limits.monthlyBuyRemaining|currency:'':2}} {{limits.currency}}) +
+
+ Daily sell limit: + {{limits.dailySell|currency:'':2}} {{limits.currency}} + (remaining {{limits.dailySellRemaining|currency:'':2}} {{limits.currency}}) +
+ Monthly sell limit: + {{limits.monthlySell|currency:'':2}} {{limits.currency}} + (remaining {{limits.monthlySellRemaining|currency:'':2}} {{limits.currency}}) +
+
@@ -62,6 +82,7 @@
+
- - - - Buy - - - - -
- Testnet wallets only work with Glidera Sandbox Accounts -
- -
- Daily buy limit: - {{limits.dailyBuy|currency:'':2}} {{limits.currency}} - (remaining {{limits.dailyBuyRemaining|currency:'':2}} {{limits.currency}}) -
- Monthly buy limit: - {{limits.monthlyBuy|currency:'':2}} {{limits.currency}} - (remaining {{limits.monthlyBuyRemaining|currency:'':2}} {{limits.currency}}) -
- -
- - This operation was disabled because you have a pending first transaction - -
- -
- -
- -
- -
- - - -
- Buy - {{buy.buyPrice.subtotal|currency:'':2}} {{buy.buyPrice.currency}} in Bitcoin - {{buy.buyPrice.qty}} BTC - at {{buy.buyPrice.price}} {{buy.buyPrice.currency}}/BTC -
-
- (Enter the amount to get the exchange rate) -
- -
- ... -
- - -
-
-
-
-{{buy.buyPrice.subtotal|currency:'':2}} {{buy.buyPrice.currency}} → {{buy.buyPrice.qty}} BTC -

- A SMS containing a confirmation code was sent to your phone.
- Please, enter the code below -

-
-
- -
- -
-

- Fiat will be immediately withdrawn from your bank account. The bitcoins will be purchased and deposited to your wallet in 2-4 business days. -

-
-
-
-

Purchase initiated

-

- A transfer has been initiated from your bank account. Your bitcoins should arrive to your wallet in 2-4 business days. -

- - -
-
- diff --git a/www/views/confirm.html b/www/views/confirm.html index 5f5ebae63..df2d81bab 100644 --- a/www/views/confirm.html +++ b/www/views/confirm.html @@ -12,8 +12,10 @@
- Sending + Sending Sending maximum amount + Buying + Selling
{{displayAmount || '...'}} {{displayUnit}}
@@ -27,13 +29,16 @@ Expired
- To + To + From + To - +
+
@@ -51,7 +56,9 @@
- From + From + To + From
@@ -60,19 +67,47 @@
- + Add Memo {{description}} -
+
Fee: {{feeLevel}} {{fee || '...'}}
+
+ Information +
+
+ Buy {{buyPrice.subtotal|currency:'':2}} {{buyPrice.currency}} in Bitcoin at {{buyPrice.price}} {{buyPrice.currency}}/BTC +
+
+ Fiat will be immediately withdrawn from your bank account. +
+
+ The bitcoins will be purchased and deposited to "{{wallet.name || '...' }}" wallet in 2-4 business days. +
+
+
+
+ Information +
+
+ Sell {{sellPrice.subtotal|currency:'':2}} {{sellPrice.currency}} in Bitcoin at {{sellPrice.price|currency:'':2}} {{sellPrice.currency}}/BTC +
+
+ Fiat will be deposited in your bank account in 4-6 business days. +
+
+ Bitcoins will be immediately sent from your "{{wallet.name || '...' }}" wallet to Glidera. +
+
+
No wallets available
@@ -85,13 +120,16 @@ + click-send-status="sendStatus" + has-wallet-chosen="wallet"> Click to pay + slide-send-status="sendStatus" + has-wallet-chosen="wallet"> Slide to pay Payment Sent Proposal Created +
+ A transfer has been initiated from your bank account. Your bitcoins should arrive to your wallet in 2-4 business day + A transfer has been initiated to your bank account. Should arrive in 4-6 business days +
Glidera - +
Glidera is disabled for this application @@ -27,7 +27,7 @@

Connect your Glidera account to get started.

@@ -41,7 +41,7 @@
-
+ diff --git a/www/views/includes/clickToAccept.html b/www/views/includes/clickToAccept.html index cf555153b..ab24cfbd5 100644 --- a/www/views/includes/clickToAccept.html +++ b/www/views/includes/clickToAccept.html @@ -1,4 +1,4 @@ -
-
+
Payment Sent diff --git a/www/views/includes/walletSelector.html b/www/views/includes/walletSelector.html index 42ec0d772..5227c0b15 100644 --- a/www/views/includes/walletSelector.html +++ b/www/views/includes/walletSelector.html @@ -1,6 +1,6 @@ -
Send from
+
{{title}}
- - - - Sell - - - - -
- Testnet wallets only work with Glidera Sandbox Accounts -
- -
- Daily sell limit: - {{limits.dailySell|currency:'':2}} {{limits.currency}} - (remaining {{limits.dailySellRemaining|currency:'':2}} {{limits.currency}}) -
- Monthly sell limit: - {{limits.monthlySell|currency:'':2}} {{limits.currency}} - (remaining {{limits.monthlySellRemaining|currency:'':2}} {{limits.currency}}) -
- -
- - This operation was disabled because you have a pending first transaction - -
- -
- - - - - - -
- Sell - {{sell.sellPrice.subtotal|currency:'':2}} {{sell.sellPrice.currency}} in Bitcoin - {{sell.sellPrice.qty}} BTC - at {{sell.sellPrice.price|currency:'':2}} {{sell.sellPrice.currency}}/BTC - -
-
- (Enter the amount to get the exchange rate) -
- -
- ... -
- - - -
-
-
-{{sell.sellPrice.qty}} BTC → {{sell.sellPrice.subtotal|currency:'':2}} {{sell.sellPrice.currency}} -

- A SMS containing a confirmation code was sent to your phone.
- Please, enter the code below -

-
-
- -
- -
-

- Bitcoins will be immediately sent from your wallet to Glidera. Fiat will be deposited in your bank account in 4-6 business days. -

-
-
-
-

Sale initiated

-

- A transfer has been initiated to your bank account and should arrive in 4-6 business days. -

- - -
- -