Refactor buying process

This commit is contained in:
Gustavo Maximiliano Cortez 2017-01-11 19:38:05 -03:00
commit e42d09574b
No known key found for this signature in database
GPG key ID: 15EDAD8D9F2EB1AF
8 changed files with 329 additions and 123 deletions

View file

@ -20,8 +20,8 @@ angular.module('copayApp.controllers').controller('amountController', function($
$scope.isGlidera = data.stateParams.isGlidera;
$scope.glideraAccessToken = data.stateParams.glideraAccessToken;
// Coinbase parameters
$scope.isCoinbase = data.stateParams.isCoinbase;
// Coinbase
$scope.coinbase = data.stateParams.coinbase;
$scope.cardId = data.stateParams.cardId;
$scope.showMenu = $ionicHistory.backView() && $ionicHistory.backView().stateName == 'tabs.send';
@ -30,13 +30,13 @@ angular.module('copayApp.controllers').controller('amountController', function($
$scope.toAddress = data.stateParams.toAddress;
$scope.toName = data.stateParams.toName;
$scope.toEmail = data.stateParams.toEmail;
$scope.showAlternativeAmount = !!$scope.cardId || !!$scope.isGiftCard || !!$scope.isGlidera || !!$scope.isCoinbase;
$scope.showAlternativeAmount = !!$scope.cardId || !!$scope.isGiftCard || !!$scope.isGlidera || !!$scope.coinbase;
$scope.toColor = data.stateParams.toColor;
$scope.showSendMax = false;
$scope.customAmount = data.stateParams.customAmount;
if (!$scope.cardId && !$scope.isGiftCard && !$scope.isGlidera && !$scope.isCoinbase && !data.stateParams.toAddress) {
if (!$scope.cardId && !$scope.isGiftCard && !$scope.isGlidera && !$scope.coinbase && !data.stateParams.toAddress) {
$log.error('Bad params at amount')
throw ('bad params');
}
@ -50,51 +50,6 @@ angular.module('copayApp.controllers').controller('amountController', function($
});
}
if ($scope.isCoinbase) {
var currency = 'USD';
coinbaseService.init(function(err, data) {
if ($scope.isCoinbase == 'buy') {
coinbaseService.buyPrice(data.accessToken, currency, function(err, b) {
$scope.coinbaseBuyPrice = b.data || null;
});
} else {
coinbaseService.sellPrice(data.accessToken, currency, function(err, s) {
$scope.coinbaseSellPrice = s.data || null;
});
var dataSrc = {
name: 'Received from ' + appConfigService.nameCase
};
coinbaseService.createAddress(data.accessToken, data.accountId, dataSrc, function(err, data) {
$scope.toAddress = data.data.address;
});
}
$scope.coinbasePaymentMethods = [];
$scope.coinbaseSelectedPaymentMethodId = { value : null };
coinbaseService.getPaymentMethods(data.accessToken, function(err, p) {
lodash.each(p.data, function(pm) {
if ($scope.isCoinbase == 'sell') {
if (pm.allow_sell) {
$scope.coinbasePaymentMethods.push(pm);
}
if (pm.allow_sell && pm.primary_sell) {
$scope.coinbaseSelectedPaymentMethodId.value = pm.id;
}
} else {
if (pm.allow_buy) {
$scope.coinbasePaymentMethods.push(pm);
}
if (pm.allow_buy && pm.primary_buy) {
$scope.coinbaseSelectedPaymentMethodId.value = pm.id;
}
}
});
});
});
}
var reNr = /^[1234567890\.]$/;
var reOp = /^[\*\+\-\/]$/;
@ -120,7 +75,11 @@ angular.module('copayApp.controllers').controller('amountController', function($
var config = configService.getSync().wallet.settings;
$scope.unitName = config.unitName;
$scope.alternativeIsoCode = !!$scope.cardId || !!$scope.isGiftCard ? 'USD' : config.alternativeIsoCode;
if (data.stateParams.currency) {
$scope.alternativeIsoCode = data.stateParams.currency;
} else {
$scope.alternativeIsoCode = !!$scope.cardId || !!$scope.isGiftCard ? 'USD' : config.alternativeIsoCode;
}
$scope.specificAmount = $scope.specificAlternativeAmount = '';
$scope.isCordova = platformInfo.isCordova;
unitToSatoshi = config.unitToSatoshi;
@ -398,29 +357,17 @@ angular.module('copayApp.controllers').controller('amountController', function($
isGlidera: $scope.isGlidera,
glideraAccessToken: $scope.glideraAccessToken
});
} else if ($scope.isCoinbase) {
if (lodash.isEmpty($scope.coinbaseSelectedPaymentMethodId.value)) {
popupService.showAlert(gettextCatalog.getString('Error'), 'No Payment Method Selected');
return;
}
if ($scope.isCoinbase == 'sell' && lodash.isEmpty($scope.toAddress)) {
popupService.showAlert(gettextCatalog.getString('Error'), 'No Destination Address');
return;
}
var amountUSD = $scope.showAlternativeAmount ? _amount : $filter('formatFiatAmount')(toFiat(_amount));
if (amountUSD < 1) {
popupService.showAlert(gettextCatalog.getString('Error'), 'Amount must be at least 1.00 USD');
} else if ($scope.coinbase) {
var amountAlternative = $scope.showAlternativeAmount ? _amount : $filter('formatFiatAmount')(toFiat(_amount));
if (amountAlternative < 1) {
popupService.showAlert(gettextCatalog.getString('Error'), 'Amount must be at least 1.00 ' + $scope.alternativeIsoCode);
return;
}
var amount = $scope.showAlternativeAmount ? fromFiat(_amount) : _amount;
$state.transitionTo('tabs.buyandsell.coinbase.confirm', {
toAmount: (amount * unitToSatoshi).toFixed(0),
toAddress: $scope.toAddress,
isCoinbase: $scope.isCoinbase,
coinbasePaymentMethodId: $scope.coinbaseSelectedPaymentMethodId.value,
coinbaseAmount: amountUSD,
coinbaseAmountCurrency: 'USD'
var goTo = 'tabs.buyandsell.coinbase.' + $scope.coinbase;
$state.transitionTo(goTo, {
amount: amountAlternative,
currency: $scope.alternativeIsoCode
});
} else {
var amount = $scope.showAlternativeAmount ? fromFiat(_amount) : _amount;

View file

@ -0,0 +1,166 @@
'use strict';
angular.module('copayApp.controllers').controller('buyCoinbaseController', function($scope, $log, $state, $timeout, $ionicHistory, lodash, coinbaseService, popupService, profileService, ongoingProcess, walletService) {
var amount;
var currency;
var initError = function(err) {
$log.error(err);
popupService.showAlert('Error', 'Could not connect to Coinbase', function() {
$ionicHistory.goBack();
});
};
$scope.$on("$ionicView.beforeEnter", function(event, data) {
amount = data.stateParams.amount;
currency = data.stateParams.currency;
$scope.network = coinbaseService.getNetwork();
$scope.wallets = profileService.getWallets({
onlyComplete: true,
network: $scope.network
});
$scope.wallet = $scope.wallets[0]; // Default first wallet
ongoingProcess.set('connectingCoinbase', true);
coinbaseService.init(function(err, res) {
if (err) {
ongoingProcess.set('connectingCoinbase', false);
initError(err);
return;
}
var accessToken = res.accessToken;
$scope.paymentMethods = [];
$scope.selectedPaymentMethodId = { value : null };
coinbaseService.getPaymentMethods(accessToken, function(err, p) {
if (err) {
ongoingProcess.set('connectingCoinbase', false);
initError(err);
return;
}
lodash.each(p.data, function(pm) {
if (pm.allow_buy) {
$scope.paymentMethods.push(pm);
}
if (pm.allow_buy && pm.primary_buy) {
$scope.selectedPaymentMethodId.value = pm.id;
$scope.buyRequest();
}
});
});
});
});
$scope.buyRequest = function() {
ongoingProcess.set('connectingCoinbase', true);
coinbaseService.init(function(err, res) {
if (err) {
ongoingProcess.set('connectingCoinbase', false);
initError(err);
return;
}
var accessToken = res.accessToken;
var accountId = res.accountId;
var dataSrc = {
amount: amount,
currency: currency,
payment_method: $scope.selectedPaymentMethodId.value
};
coinbaseService.buyRequest(accessToken, accountId, dataSrc, function(err, data) {
ongoingProcess.set('connectingCoinbase', false);
if (err) {
$log.error(err);
popupService.showAlert('Error', 'Could not create a buy request', function() {
$ionicHistory.goBack();
});
return;
}
$scope.buyRequestInfo = data.data;
});
});
};
$scope.buyConfirm = function() {
var message = 'Buy bitcoin for ' + amount + ' ' + currency;
var okText = 'Confirm';
var cancelText = 'Cancel';
popupService.showConfirm(null, message, okText, cancelText, function(ok) {
if (!ok) return;
ongoingProcess.set('buyingBitcoin', true);
coinbaseService.init(function(err, res) {
if (err) {
ongoingProcess.set('buyingBitcoin', false);
initError(err);
return;
}
var accessToken = res.accessToken;
var accountId = res.accountId;
coinbaseService.buyCommit(accessToken, accountId, $scope.buyRequestInfo.id, function(err, b) {
if (err) {
ongoingProcess.set('buyingBitcoin', false);
popupService.showAlert('Error', 'Could not complete purchase');
return;
}
var tx = b.data.transaction;
if (!tx) {
ongoingProcess.set('buyingBitcoin', false);
popupService.showAlert('Error', 'Transaction not found');
return;
}
$timeout(function() {
coinbaseService.getTransaction(accessToken, accountId, tx.id, function(err, updatedTx) {
if (err) {
ongoingProcess.set('buyingBitcoin', false);
popupService.showAlert('Error', 'Transaction error');
return;
}
walletService.getAddress($scope.wallet, false, function(err, walletAddr) {
if (err) {
ongoingProcess.set('buyingBitcoin', false);
popupService.showAlert('Error', err);
return;
}
updatedTx.data['toAddr'] = walletAddr;
updatedTx.data['status'] = 'pending'; // Forcing "pending" status to process later
$log.debug('Saving transaction to process later...');
coinbaseService.savePendingTransaction(updatedTx.data, {}, function(err) {
if (err) $log.debug(err);
ongoingProcess.set('buyingBitcoin', false);
$scope.buySuccess = updatedTx.data;
$timeout(function() {
$scope.$apply();
});
});
});
});
}, 8000);
});
});
});
};
$scope.showWalletSelector = function() {
$scope.walletSelectorTitle = ($scope.action) == 'buy' ? 'Receive in' : 'Sell From';
$scope.showWallets = true;
};
$scope.onWalletSelect = function(wallet) {
$scope.wallet = wallet;
};
$scope.goBackHome = function() {
$ionicHistory.nextViewOptions({
disableAnimate: true,
historyRoot: true
});
$ionicHistory.clearHistory();
$state.go('tabs.home').then(function() {
$state.transitionTo('tabs.buyandsell.coinbase');
});
};
});

View file

@ -6,6 +6,8 @@ angular.module('copayApp.controllers').controller('coinbaseController', function
var isCordova = platformInfo.isCordova;
var init = function() {
var config = configService.getSync().wallet.settings;
$scope.currency = getCurrency(config.alternativeIsoCode);
ongoingProcess.set('connectingCoinbase', true);
coinbaseService.init(function(err, data) {
ongoingProcess.set('connectingCoinbase', false);
@ -15,6 +17,15 @@ angular.module('copayApp.controllers').controller('coinbaseController', function
}
return;
}
// Show rates
coinbaseService.buyPrice(data.accessToken, $scope.currency, function(err, b) {
$scope.buyPrice = b.data || null;
});
coinbaseService.sellPrice(data.accessToken, $scope.currency, function(err, s) {
$scope.sellPrice = s.data || null;
});
// Updating accessToken and accountId
$timeout(function() {
$scope.accessToken = data.accessToken;
@ -25,6 +36,14 @@ angular.module('copayApp.controllers').controller('coinbaseController', function
});
};
var getCurrency = function(code) {
// ONLY "USD" and "EUR"
switch(code) {
case 'EUR' : return 'EUR';
default : return 'USD'
};
};
$scope.updateTransactions = function() {
$log.debug('Getting transactions...');
$scope.pendingTransactions = { data: {} };

View file

@ -942,41 +942,32 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
})
.state('tabs.buyandsell.coinbase.amount', {
url: '/amount/:isCoinbase',
views: {
'tab-home@tabs': {
controller: 'amountController',
templateUrl: 'views/amount.html'
}
url: '/amount/:coinbase/:currency',
views: {
'tab-home@tabs': {
controller: 'amountController',
templateUrl: 'views/amount.html'
}
})
.state('tabs.buyandsell.coinbase.confirm', {
url: '/confirm/:toAmount/:toAddress/:isCoinbase/:coinbasePaymentMethodId/:coinbaseAmount/:coinbaseAmountCurrency',
views: {
'tab-home@tabs': {
controller: 'confirmController',
templateUrl: 'views/confirm.html'
}
}
})
/*
.state('tabs.buyandsell.coinbase.buy', {
url: '/buy',
}
})
.state('tabs.buyandsell.coinbase.buy', {
url: '/buy/:amount/:currency',
views: {
'tab-home@tabs': {
controller: 'buyCoinbaseController',
controllerAs: 'buy',
templateUrl: 'views/buyCoinbase.html'
}
})
.state('tabs.buyandsell.coinbase.sell', {
url: '/sell',
}
})
.state('tabs.buyandsell.coinbase.sell', {
url: '/sell/:amount/:currency',
views: {
'tab-home@tabs': {
controller: 'sellCoinbaseController',
controllerAs: 'sell',
templateUrl: 'views/sellCoinbase.html'
}
})
*/
}
})
/*
*

View file

@ -394,7 +394,7 @@ angular.module('copayApp.services').factory('coinbaseService', function($http, $
amount: data.amount,
currency: data.currency,
payment_method: data.payment_method || null,
commit: false
commit: data.commit || false
};
$http(_post('/accounts/' + accountId + '/buys', token, data)).then(function(data) {
$log.info('Coinbase Buy Request: SUCCESS');