Merge pull request #6283 from cmgustavo/bug/coinbase-02
Coinbase (purchase flow): adds bitcoin fee to create transaction
This commit is contained in:
commit
883a7c763c
2 changed files with 111 additions and 62 deletions
|
|
@ -47,63 +47,74 @@ angular.module('copayApp.controllers').controller('buyCoinbaseController', funct
|
||||||
data.stateParams.amount,
|
data.stateParams.amount,
|
||||||
data.stateParams.currency);
|
data.stateParams.currency);
|
||||||
|
|
||||||
amount = parsedAmount.amount;
|
// Buy always in BTC
|
||||||
currency = parsedAmount.currency;
|
amount = (parsedAmount.amountSat / 100000000).toFixed(8);
|
||||||
|
currency = 'BTC';
|
||||||
|
|
||||||
$scope.amountUnitStr = parsedAmount.amountUnitStr;
|
$scope.amountUnitStr = parsedAmount.amountUnitStr;
|
||||||
|
|
||||||
$scope.network = coinbaseService.getNetwork();
|
ongoingProcess.set('calculatingFee', true);
|
||||||
$scope.wallets = profileService.getWallets({
|
coinbaseService.checkEnoughFundsForFee(amount, function(err) {
|
||||||
onlyComplete: true,
|
ongoingProcess.set('calculatingFee', false);
|
||||||
network: $scope.network
|
|
||||||
});
|
|
||||||
|
|
||||||
if (lodash.isEmpty($scope.wallets)) {
|
|
||||||
showErrorAndBack('No wallets available');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$scope.wallet = $scope.wallets[0]; // Default first wallet
|
|
||||||
|
|
||||||
ongoingProcess.set('connectingCoinbase', true);
|
|
||||||
coinbaseService.init(function(err, res) {
|
|
||||||
if (err) {
|
if (err) {
|
||||||
ongoingProcess.set('connectingCoinbase', false);
|
|
||||||
showErrorAndBack(err);
|
showErrorAndBack(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var accessToken = res.accessToken;
|
|
||||||
|
|
||||||
coinbaseService.buyPrice(accessToken, coinbaseService.getAvailableCurrency(), function(err, b) {
|
$scope.network = coinbaseService.getNetwork();
|
||||||
$scope.buyPrice = b.data || null;
|
$scope.wallets = profileService.getWallets({
|
||||||
|
onlyComplete: true,
|
||||||
|
network: $scope.network
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.paymentMethods = [];
|
if (lodash.isEmpty($scope.wallets)) {
|
||||||
$scope.selectedPaymentMethodId = { value : null };
|
showErrorAndBack('No wallets available');
|
||||||
coinbaseService.getPaymentMethods(accessToken, function(err, p) {
|
return;
|
||||||
|
}
|
||||||
|
$scope.wallet = $scope.wallets[0]; // Default first wallet
|
||||||
|
|
||||||
|
ongoingProcess.set('connectingCoinbase', true);
|
||||||
|
coinbaseService.init(function(err, res) {
|
||||||
if (err) {
|
if (err) {
|
||||||
ongoingProcess.set('connectingCoinbase', false);
|
ongoingProcess.set('connectingCoinbase', false);
|
||||||
showErrorAndBack(err);
|
showErrorAndBack(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var accessToken = res.accessToken;
|
||||||
|
|
||||||
var hasPrimary;
|
coinbaseService.buyPrice(accessToken, coinbaseService.getAvailableCurrency(), function(err, b) {
|
||||||
var pm;
|
$scope.buyPrice = b.data || null;
|
||||||
for(var i = 0; i < p.data.length; i++) {
|
});
|
||||||
pm = p.data[i];
|
|
||||||
if (pm.allow_buy) {
|
$scope.paymentMethods = [];
|
||||||
$scope.paymentMethods.push(pm);
|
$scope.selectedPaymentMethodId = { value : null };
|
||||||
|
coinbaseService.getPaymentMethods(accessToken, function(err, p) {
|
||||||
|
if (err) {
|
||||||
|
ongoingProcess.set('connectingCoinbase', false);
|
||||||
|
showErrorAndBack(err);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (pm.allow_buy && pm.primary_buy) {
|
|
||||||
hasPrimary = true;
|
var hasPrimary;
|
||||||
$scope.selectedPaymentMethodId.value = pm.id;
|
var pm;
|
||||||
|
for(var i = 0; i < p.data.length; i++) {
|
||||||
|
pm = p.data[i];
|
||||||
|
if (pm.allow_buy) {
|
||||||
|
$scope.paymentMethods.push(pm);
|
||||||
|
}
|
||||||
|
if (pm.allow_buy && pm.primary_buy) {
|
||||||
|
hasPrimary = true;
|
||||||
|
$scope.selectedPaymentMethodId.value = pm.id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (lodash.isEmpty($scope.paymentMethods)) {
|
||||||
if (lodash.isEmpty($scope.paymentMethods)) {
|
ongoingProcess.set('connectingCoinbase', false);
|
||||||
ongoingProcess.set('connectingCoinbase', false);
|
showErrorAndBack('No payment method available to buy');
|
||||||
showErrorAndBack('No payment method available to buy');
|
return;
|
||||||
return;
|
}
|
||||||
}
|
if (!hasPrimary) $scope.selectedPaymentMethodId.value = $scope.paymentMethods[0].id;
|
||||||
if (!hasPrimary) $scope.selectedPaymentMethodId.value = $scope.paymentMethods[0].id;
|
$scope.buyRequest();
|
||||||
$scope.buyRequest();
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -139,7 +150,7 @@ angular.module('copayApp.controllers').controller('buyCoinbaseController', funct
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.buyConfirm = function() {
|
$scope.buyConfirm = function() {
|
||||||
var message = 'Buy bitcoin for ' + amount + ' ' + currency;
|
var message = 'Buy bitcoin for ' + $scope.amountUnitStr;
|
||||||
var okText = 'Confirm';
|
var okText = 'Confirm';
|
||||||
var cancelText = 'Cancel';
|
var cancelText = 'Cancel';
|
||||||
popupService.showConfirm(null, message, okText, cancelText, function(ok) {
|
popupService.showConfirm(null, message, okText, cancelText, function(ok) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('copayApp.services').factory('coinbaseService', function($http, $log, $window, $filter, platformInfo, lodash, storageService, configService, appConfigService, txFormatService, buyAndSellService, $rootScope) {
|
angular.module('copayApp.services').factory('coinbaseService', function($http, $log, $window, $filter, platformInfo, lodash, storageService, configService, appConfigService, txFormatService, buyAndSellService, $rootScope, feeService) {
|
||||||
var root = {};
|
var root = {};
|
||||||
var credentials = {};
|
var credentials = {};
|
||||||
var isCordova = platformInfo.isCordova;
|
var isCordova = platformInfo.isCordova;
|
||||||
|
|
@ -107,6 +107,19 @@ angular.module('copayApp.services').factory('coinbaseService', function($http, $
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
root.checkEnoughFundsForFee = function(amount, cb) {
|
||||||
|
_getNetAmount(amount, function(err, reducedAmount) {
|
||||||
|
if (err) return cb(err);
|
||||||
|
|
||||||
|
// Check if transaction has enough funds to transfer bitcoin from Coinbase to Copay
|
||||||
|
if (reducedAmount < 0) {
|
||||||
|
return cb('Not enough funds for fee');
|
||||||
|
}
|
||||||
|
|
||||||
|
return cb();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
root.getSignupUrl = function() {
|
root.getSignupUrl = function() {
|
||||||
return credentials.HOST + '/signup';
|
return credentials.HOST + '/signup';
|
||||||
}
|
}
|
||||||
|
|
@ -153,6 +166,17 @@ angular.module('copayApp.services').factory('coinbaseService', function($http, $
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var _getNetAmount = function(amount, cb) {
|
||||||
|
// Fee Normal for a single transaction (450 bytes)
|
||||||
|
var txNormalFeeKB = 450 / 1000;
|
||||||
|
feeService.getFeeRate(null, 'normal', function(err, feePerKB) {
|
||||||
|
if (err) return cb(err);
|
||||||
|
var feeBTC = (feePerKB * txNormalFeeKB / 100000000).toFixed(8);
|
||||||
|
|
||||||
|
return cb(null, amount - feeBTC, feeBTC);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
var _refreshToken = function(refreshToken, cb) {
|
var _refreshToken = function(refreshToken, cb) {
|
||||||
var req = {
|
var req = {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|
@ -657,13 +681,7 @@ angular.module('copayApp.services').factory('coinbaseService', function($http, $
|
||||||
var _sendToWallet = function(tx, accessToken, accountId, coinbasePendingTransactions) {
|
var _sendToWallet = function(tx, accessToken, accountId, coinbasePendingTransactions) {
|
||||||
if (!tx) return;
|
if (!tx) return;
|
||||||
var desc = appConfigService.nameCase + ' Wallet';
|
var desc = appConfigService.nameCase + ' Wallet';
|
||||||
var data = {
|
_getNetAmount(tx.amount.amount, function(err, amountBTC, feeBTC) {
|
||||||
to: tx.toAddr,
|
|
||||||
amount: tx.amount.amount,
|
|
||||||
currency: tx.amount.currency,
|
|
||||||
description: desc
|
|
||||||
};
|
|
||||||
root.sendTo(accessToken, accountId, data, function(err, res) {
|
|
||||||
if (err) {
|
if (err) {
|
||||||
_savePendingTransaction(tx, {
|
_savePendingTransaction(tx, {
|
||||||
status: 'error',
|
status: 'error',
|
||||||
|
|
@ -672,8 +690,18 @@ angular.module('copayApp.services').factory('coinbaseService', function($http, $
|
||||||
if (err) $log.debug(err);
|
if (err) $log.debug(err);
|
||||||
_updateTxs(coinbasePendingTransactions);
|
_updateTxs(coinbasePendingTransactions);
|
||||||
});
|
});
|
||||||
} else {
|
return;
|
||||||
if (res.data && !res.data.id) {
|
}
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
to: tx.toAddr,
|
||||||
|
amount: amountBTC,
|
||||||
|
currency: tx.amount.currency,
|
||||||
|
description: desc,
|
||||||
|
fee: feeBTC
|
||||||
|
};
|
||||||
|
root.sendTo(accessToken, accountId, data, function(err, res) {
|
||||||
|
if (err) {
|
||||||
_savePendingTransaction(tx, {
|
_savePendingTransaction(tx, {
|
||||||
status: 'error',
|
status: 'error',
|
||||||
error: err
|
error: err
|
||||||
|
|
@ -681,19 +709,29 @@ angular.module('copayApp.services').factory('coinbaseService', function($http, $
|
||||||
if (err) $log.debug(err);
|
if (err) $log.debug(err);
|
||||||
_updateTxs(coinbasePendingTransactions);
|
_updateTxs(coinbasePendingTransactions);
|
||||||
});
|
});
|
||||||
return;
|
} else {
|
||||||
}
|
if (res.data && !res.data.id) {
|
||||||
root.getTransaction(accessToken, accountId, res.data.id, function(err, sendTx) {
|
_savePendingTransaction(tx, {
|
||||||
_savePendingTransaction(tx, {
|
status: 'error',
|
||||||
remove: true
|
error: err
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
_savePendingTransaction(sendTx.data, {}, function(err) {
|
|
||||||
if (err) $log.debug(err);
|
if (err) $log.debug(err);
|
||||||
_updateTxs(coinbasePendingTransactions);
|
_updateTxs(coinbasePendingTransactions);
|
||||||
});
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
root.getTransaction(accessToken, accountId, res.data.id, function(err, sendTx) {
|
||||||
|
_savePendingTransaction(tx, {
|
||||||
|
remove: true
|
||||||
|
}, function(err) {
|
||||||
|
_savePendingTransaction(sendTx.data, {}, function(err) {
|
||||||
|
if (err) $log.debug(err);
|
||||||
|
_updateTxs(coinbasePendingTransactions);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue