Adds bitcoin cash basic support (unit convertion, integrations, request specific amount, etc)

This commit is contained in:
Gustavo Maximiliano Cortez 2017-08-24 17:02:49 -03:00
commit 94363704ab
No known key found for this signature in database
GPG key ID: 15EDAD8D9F2EB1AF
24 changed files with 376 additions and 302 deletions

View file

@ -88,9 +88,9 @@ angular.module('copayApp.controllers').controller('addressesController', functio
$scope.lowWarning = resp.warning;
$scope.lowUtxosNb = resp.lowUtxos.length;
$scope.allUtxosNb = resp.allUtxos.length;
$scope.lowUtxosSum = txFormatService.formatAmountStr(lodash.sum(resp.lowUtxos || 0, 'satoshis'));
$scope.allUtxosSum = txFormatService.formatAmountStr(allSum);
$scope.minFee = txFormatService.formatAmountStr(resp.minFee || 0);
$scope.lowUtxosSum = txFormatService.formatAmountStr($scope.wallet, lodash.sum(resp.lowUtxos || 0, 'satoshis'));
$scope.allUtxosSum = txFormatService.formatAmountStr($scope.wallet, allSum);
$scope.minFee = txFormatService.formatAmountStr($scope.wallet, resp.minFee || 0);
$scope.minFeePer = per.toFixed(2) + '%';

View file

@ -21,6 +21,8 @@ angular.module('copayApp.controllers').controller('amountController', function($
$scope.nextStep = data.stateParams.nextStep;
$scope.currency = data.stateParams.currency;
$scope.forceCurrency = data.stateParams.forceCurrency;
$scope.forceChain = data.stateParams.forceChain || null;
$scope.chain = $scope.forceChain || data.stateParams.chain || 'BTC';
$scope.showMenu = $ionicHistory.backView() && ($ionicHistory.backView().stateName == 'tabs.send' ||
$ionicHistory.backView().stateName == 'tabs.bitpayCard');
@ -63,7 +65,6 @@ angular.module('copayApp.controllers').controller('amountController', function($
});
var config = configService.getSync().wallet.settings;
$scope.unitName = config.unitName;
if (data.stateParams.currency) {
$scope.alternativeIsoCode = data.stateParams.currency;
} else {
@ -124,6 +125,12 @@ angular.module('copayApp.controllers').controller('amountController', function($
}
};
$scope.toggleChain = function() {
if ($scope.forceCurrency || $scope.forceChain) return;
$scope.chain = $scope.chain == 'BTC' ? 'BCH' : 'BTC';
};
function checkFontSize() {
if ($scope.amount && $scope.amount.length >= SMALL_FONT_SIZE_LIMIT) $scope.smallFont = true;
else $scope.smallFont = false;
@ -227,7 +234,8 @@ angular.module('copayApp.controllers').controller('amountController', function($
$state.transitionTo($scope.nextStep, {
id: _id,
amount: $scope.useSendMax ? null : _amount,
currency: $scope.showAlternativeAmount ? $scope.alternativeIsoCode : $scope.unitName,
currency: $scope.showAlternativeAmount ? $scope.alternativeIsoCode : $scope.chain,
chain: $scope.chain,
useSendMax: $scope.useSendMax
});
} else {
@ -239,6 +247,7 @@ angular.module('copayApp.controllers').controller('amountController', function($
toName: $scope.toName,
toEmail: $scope.toEmail,
toColor: $scope.toColor,
chain: $scope.chain,
useSendMax: $scope.useSendMax
});
}

View file

@ -216,7 +216,7 @@ angular.module('copayApp.controllers').controller('buyAmazonController', functio
});
var initialize = function(wallet) {
var parsedAmount = txFormatService.parseAmount(amount, currency);
var parsedAmount = txFormatService.parseAmount(wallet, amount, currency);
$scope.currencyIsoCode = parsedAmount.currency;
$scope.amountUnitStr = parsedAmount.amountUnitStr;
var dataSrc = {
@ -260,7 +260,7 @@ angular.module('copayApp.controllers').controller('buyAmazonController', functio
invoiceUrl: invoice.url,
invoiceTime: invoice.invoiceTime
};
$scope.totalAmountStr = txFormatService.formatAmountStr(ctxp.amount);
$scope.totalAmountStr = txFormatService.formatAmountStr(wallet, ctxp.amount);
setTotalAmount(parsedAmount.amountSat, invoiceFeeSat, ctxp.fee);
});
});
@ -292,7 +292,8 @@ angular.module('copayApp.controllers').controller('buyAmazonController', functio
$scope.wallets = profileService.getWallets({
onlyComplete: true,
network: $scope.network,
hasFunds: true
hasFunds: true,
chain: 'BTC'
});
if (lodash.isEmpty($scope.wallets)) {
showErrorAndBack(null, gettextCatalog.getString('No wallets available'));

View file

@ -33,6 +33,52 @@ angular.module('copayApp.controllers').controller('buyCoinbaseController', funct
}
};
var processPaymentInfo = function() {
ongoingProcess.set('connectingCoinbase', true);
coinbaseService.init(function(err, res) {
if (err) {
ongoingProcess.set('connectingCoinbase', false);
showErrorAndBack(err);
return;
}
var accessToken = res.accessToken;
coinbaseService.buyPrice(accessToken, coinbaseService.getAvailableCurrency(), function(err, b) {
$scope.buyPrice = b.data || null;
});
$scope.paymentMethods = [];
$scope.selectedPaymentMethodId = { value : null };
coinbaseService.getPaymentMethods(accessToken, function(err, p) {
if (err) {
ongoingProcess.set('connectingCoinbase', false);
showErrorAndBack(err);
return;
}
var hasPrimary;
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)) {
ongoingProcess.set('connectingCoinbase', false);
showErrorAndBack('No payment method available to buy');
return;
}
if (!hasPrimary) $scope.selectedPaymentMethodId.value = $scope.paymentMethods[0].id;
$scope.buyRequest();
});
});
};
$scope.$on("$ionicView.beforeLeave", function(event, data) {
$ionicConfig.views.swipeBackEnabled(true);
});
@ -42,81 +88,22 @@ angular.module('copayApp.controllers').controller('buyCoinbaseController', funct
});
$scope.$on("$ionicView.beforeEnter", function(event, data) {
$scope.isFiat = data.stateParams.currency != 'bits' && data.stateParams.currency != 'BTC' ? true : false;
var parsedAmount = txFormatService.parseAmount(
data.stateParams.amount,
data.stateParams.currency);
$scope.isFiat = data.stateParams.currency != 'BCH' && data.stateParams.currency != 'BTC' ? true : false;
amount = data.stateParams.amount;
currency = data.stateParams.currency;
// Buy always in BTC
amount = (parsedAmount.amountSat / 100000000).toFixed(8);
currency = 'BTC';
$scope.amountUnitStr = parsedAmount.amountUnitStr;
ongoingProcess.set('calculatingFee', true);
coinbaseService.checkEnoughFundsForFee(amount, function(err) {
ongoingProcess.set('calculatingFee', false);
if (err) {
showErrorAndBack(err);
return;
}
$scope.network = coinbaseService.getNetwork();
$scope.wallets = profileService.getWallets({
onlyComplete: true,
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) {
ongoingProcess.set('connectingCoinbase', false);
showErrorAndBack(err);
return;
}
var accessToken = res.accessToken;
coinbaseService.buyPrice(accessToken, coinbaseService.getAvailableCurrency(), function(err, b) {
$scope.buyPrice = b.data || null;
});
$scope.paymentMethods = [];
$scope.selectedPaymentMethodId = { value : null };
coinbaseService.getPaymentMethods(accessToken, function(err, p) {
if (err) {
ongoingProcess.set('connectingCoinbase', false);
showErrorAndBack(err);
return;
}
var hasPrimary;
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)) {
ongoingProcess.set('connectingCoinbase', false);
showErrorAndBack('No payment method available to buy');
return;
}
if (!hasPrimary) $scope.selectedPaymentMethodId.value = $scope.paymentMethods[0].id;
$scope.buyRequest();
});
});
$scope.network = coinbaseService.getNetwork();
$scope.wallets = profileService.getWallets({
onlyComplete: true,
network: $scope.network,
chain: 'BTC'
});
if (lodash.isEmpty($scope.wallets)) {
showErrorAndBack('No wallets available');
return;
}
$scope.onWalletSelect($scope.wallets[0]); // Default first wallet
});
$scope.buyRequest = function() {
@ -248,6 +235,25 @@ angular.module('copayApp.controllers').controller('buyCoinbaseController', funct
$scope.onWalletSelect = function(wallet) {
$scope.wallet = wallet;
var parsedAmount = txFormatService.parseAmount(
wallet,
amount,
currency);
// Buy always in BTC
amount = (parsedAmount.amountSat / 100000000).toFixed(8);
currency = 'BTC';
$scope.amountUnitStr = parsedAmount.amountUnitStr;
ongoingProcess.set('calculatingFee', true);
coinbaseService.checkEnoughFundsForFee(amount, function(err) {
ongoingProcess.set('calculatingFee', false);
if (err) {
showErrorAndBack(err);
return;
}
processPaymentInfo();
});
};
$scope.goBackHome = function() {

View file

@ -35,36 +35,7 @@ angular.module('copayApp.controllers').controller('buyGlideraController', functi
}
};
$scope.$on("$ionicView.beforeLeave", function(event, data) {
$ionicConfig.views.swipeBackEnabled(true);
});
$scope.$on("$ionicView.enter", function(event, data) {
$ionicConfig.views.swipeBackEnabled(false);
});
$scope.$on("$ionicView.beforeEnter", function(event, data) {
$scope.isFiat = data.stateParams.currency != 'bits' && data.stateParams.currency != 'BTC' ? true : false;
var parsedAmount = txFormatService.parseAmount(
data.stateParams.amount,
data.stateParams.currency);
amount = parsedAmount.amount;
currency = parsedAmount.currency;
$scope.amountUnitStr = parsedAmount.amountUnitStr;
$scope.network = glideraService.getNetwork();
$scope.wallets = profileService.getWallets({
onlyComplete: true,
network: $scope.network
});
if (lodash.isEmpty($scope.wallets)) {
showErrorAndBack('No wallets available');
return;
}
$scope.wallet = $scope.wallets[0]; // Default first wallet
var processPaymentInfo = function() {
ongoingProcess.set('connectingGlidera', true);
glideraService.init(function(err, data) {
if (err) {
@ -88,6 +59,33 @@ angular.module('copayApp.controllers').controller('buyGlideraController', functi
$scope.buyInfo = buy;
});
});
};
$scope.$on("$ionicView.beforeLeave", function(event, data) {
$ionicConfig.views.swipeBackEnabled(true);
});
$scope.$on("$ionicView.enter", function(event, data) {
$ionicConfig.views.swipeBackEnabled(false);
});
$scope.$on("$ionicView.beforeEnter", function(event, data) {
$scope.isFiat = data.stateParams.currency != 'BCH' && data.stateParams.currency != 'BTC' ? true : false;
amount = data.stateParams.amount;
currency = data.stateParams.currency;
$scope.network = glideraService.getNetwork();
$scope.wallets = profileService.getWallets({
onlyComplete: true,
network: $scope.network,
chain: 'BTC'
});
if (lodash.isEmpty($scope.wallets)) {
showErrorAndBack('No wallets available');
return;
}
$scope.onWalletSelect($scope.wallets[0]); // Default first wallet
});
var ask2FaCode = function(mode, cb) {
@ -105,7 +103,7 @@ angular.module('copayApp.controllers').controller('buyGlideraController', functi
popupService.showPrompt(title, message, null, function(twoFaCode) {
if (typeof twoFaCode == 'undefined') return cb();
return cb(twoFaCode);
});
});
} else {
return cb();
}
@ -116,7 +114,7 @@ angular.module('copayApp.controllers').controller('buyGlideraController', functi
var okText = 'Confirm';
var cancelText = 'Cancel';
popupService.showConfirm(null, message, okText, cancelText, function(ok) {
if (!ok) return;
if (!ok) return;
ongoingProcess.set('buyingBitcoin', true, statusChangeHandler);
glideraService.get2faCode($scope.token, function(err, tfa) {
if (err) {
@ -162,6 +160,15 @@ angular.module('copayApp.controllers').controller('buyGlideraController', functi
$scope.onWalletSelect = function(wallet) {
$scope.wallet = wallet;
var parsedAmount = txFormatService.parseAmount(
wallet,
amount,
currency);
amount = parsedAmount.amount;
currency = parsedAmount.currency;
$scope.amountUnitStr = parsedAmount.amountUnitStr;
processPaymentInfo();
};
$scope.goBackHome = function() {

View file

@ -214,7 +214,7 @@ angular.module('copayApp.controllers').controller('buyMercadoLibreController', f
});
var initialize = function(wallet) {
var parsedAmount = txFormatService.parseAmount(amount, currency);
var parsedAmount = txFormatService.parseAmount(wallet, amount, currency);
$scope.currencyIsoCode = parsedAmount.currency;
$scope.amountUnitStr = parsedAmount.amountUnitStr;
var dataSrc = {
@ -258,7 +258,7 @@ angular.module('copayApp.controllers').controller('buyMercadoLibreController', f
invoiceUrl: invoice.url,
invoiceTime: invoice.invoiceTime
};
$scope.totalAmountStr = txFormatService.formatAmountStr(ctxp.amount);
$scope.totalAmountStr = txFormatService.formatAmountStr(wallet, ctxp.amount);
setTotalAmount(parsedAmount.amountSat, invoiceFeeSat, ctxp.fee);
});
});
@ -284,7 +284,8 @@ angular.module('copayApp.controllers').controller('buyMercadoLibreController', f
$scope.network = mercadoLibreService.getNetwork();
$scope.wallets = profileService.getWallets({
onlyComplete: true,
network: $scope.network
network: $scope.network,
chain: 'BTC'
});
if (lodash.isEmpty($scope.wallets)) {
showErrorAndBack(null, gettextCatalog.getString('No wallets available'));

View file

@ -69,14 +69,15 @@ angular.module('copayApp.controllers').controller('confirmController', function(
$scope.$on("$ionicView.beforeEnter", function(event, data) {
function setWalletSelector(network, minAmount, cb) {
function setWalletSelector(chain, network, minAmount, cb) {
// no min amount? (sendMax) => look for no empty wallets
minAmount = minAmount || 1;
$scope.wallets = profileService.getWallets({
onlyComplete: true,
network: network
network: network,
chain: chain
});
if (!$scope.wallets || !$scope.wallets.length) {
@ -137,6 +138,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
toEmail: data.stateParams.toEmail,
toColor: data.stateParams.toColor,
network: (new bitcore.Address(data.stateParams.toAddress)).network.name,
chain: data.stateParams.chain || 'BTC',
txp: {},
};
@ -146,23 +148,21 @@ angular.module('copayApp.controllers').controller('confirmController', function(
$scope.isWindowsPhoneApp = isWindowsPhoneApp;
$scope.showAddress = false;
updateTx(tx, null, {}, function() {
$scope.walletSelectorTitle = gettextCatalog.getString('Send from');
$scope.walletSelectorTitle = gettextCatalog.getString('Send from');
setWalletSelector(tx.network, tx.toAmount, function(err) {
if (err) {
return exitWithError('Could not update wallets');
}
if ($scope.wallets.length > 1) {
$scope.showWalletSelector();
} else if ($scope.wallets.length) {
setWallet($scope.wallets[0], tx);
}
});
setWalletSelector(tx.chain, tx.network, tx.toAmount, function(err) {
if (err) {
return exitWithError('Could not update wallets');
}
if ($scope.wallets.length > 1) {
$scope.showWalletSelector();
} else if ($scope.wallets.length) {
setWallet($scope.wallets[0], tx);
}
});
});
@ -238,7 +238,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
if (!tx.toAmount) return;
// Amount
tx.amountStr = txFormatService.formatAmountStr(tx.toAmount);
tx.amountStr = txFormatService.formatAmountStr(wallet, tx.toAmount);
tx.amountValueStr = tx.amountStr.split(' ')[0];
tx.amountUnitStr = tx.amountStr.split(' ')[1];
txFormatService.formatAlternativeStr(tx.toAmount, function(v) {
@ -280,7 +280,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
tx.sendMaxInfo = sendMaxInfo;
tx.toAmount = tx.sendMaxInfo.amount;
updateAmount();
showSendMaxWarning(sendMaxInfo);
showSendMaxWarning(wallet, sendMaxInfo);
}
// txp already generated for this wallet?
@ -292,7 +292,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
getTxp(lodash.clone(tx), wallet, opts.dryRun, function(err, txp) {
if (err) return cb(err);
txp.feeStr = txFormatService.formatAmountStr(txp.fee);
txp.feeStr = txFormatService.formatAmountStr(wallet, txp.fee);
txFormatService.formatAlternativeStr(txp.fee, function(v) {
txp.alternativeFeeStr = v;
});
@ -337,26 +337,26 @@ angular.module('copayApp.controllers').controller('confirmController', function(
};
function showSendMaxWarning(sendMaxInfo) {
function showSendMaxWarning(wallet, sendMaxInfo) {
function verifyExcludedUtxos() {
var warningMsg = [];
if (sendMaxInfo.utxosBelowFee > 0) {
warningMsg.push(gettextCatalog.getString("A total of {{amountBelowFeeStr}} were excluded. These funds come from UTXOs smaller than the network fee provided.", {
amountBelowFeeStr: txFormatService.formatAmountStr(sendMaxInfo.amountBelowFee)
amountBelowFeeStr: txFormatService.formatAmountStr(wallet, sendMaxInfo.amountBelowFee)
}));
}
if (sendMaxInfo.utxosAboveMaxSize > 0) {
warningMsg.push(gettextCatalog.getString("A total of {{amountAboveMaxSizeStr}} were excluded. The maximum size allowed for a transaction was exceeded.", {
amountAboveMaxSizeStr: txFormatService.formatAmountStr(sendMaxInfo.amountAboveMaxSize)
amountAboveMaxSizeStr: txFormatService.formatAmountStr(wallet, sendMaxInfo.amountAboveMaxSize)
}));
}
return warningMsg.join('\n');
};
var msg = gettextCatalog.getString("{{fee}} will be deducted for bitcoin networking fees.", {
fee: txFormatService.formatAmountStr(sendMaxInfo.fee)
fee: txFormatService.formatAmountStr(wallet, sendMaxInfo.fee)
});
var warningMsg = verifyExcludedUtxos();

View file

@ -15,7 +15,7 @@ angular.module('copayApp.controllers').controller('customAmountController', func
showErrorAndBack('Error', 'No wallet selected');
return;
}
$scope.showShareButton = platformInfo.isCordova ? (platformInfo.isIOS ? 'iOS' : 'Android') : null;
$scope.wallet = profileService.getWallet(walletId);
@ -25,11 +25,13 @@ angular.module('copayApp.controllers').controller('customAmountController', func
showErrorAndBack('Error', 'Could not get the address');
return;
}
$scope.address = addr;
$scope.chain = (data.stateParams.chain).toLowerCase();
var parsedAmount = txFormatService.parseAmount(
data.stateParams.amount,
$scope.wallet,
data.stateParams.amount,
data.stateParams.currency);
// Amount in USD or BTC
@ -37,16 +39,16 @@ angular.module('copayApp.controllers').controller('customAmountController', func
var currency = parsedAmount.currency;
$scope.amountUnitStr = parsedAmount.amountUnitStr;
if (currency != 'BTC') {
// Convert to BTC
if (currency != 'BTC' && currency != 'BCH') {
// Convert to BTC or BCH
var config = configService.getSync().wallet.settings;
var amountUnit = txFormatService.satToUnit(parsedAmount.amountSat);
var btcParsedAmount = txFormatService.parseAmount(amountUnit, config.unitName);
var btcParsedAmount = txFormatService.parseAmount($scope.wallet, amountUnit, $scope.wallet.chain);
$scope.amountBtc = btcParsedAmount.amount;
$scope.altAmountStr = btcParsedAmount.amountUnitStr;
} else {
$scope.amountBtc = amount; // BTC
$scope.amountBtc = amount; // BTC or BCH
$scope.altAmountStr = txFormatService.formatAlternativeStr(parsedAmount.amountSat);
}
});
@ -66,7 +68,7 @@ angular.module('copayApp.controllers').controller('customAmountController', func
}
$scope.copyToClipboard = function() {
return 'bitcoin:' + $scope.address + '?amount=' + $scope.amountBtc;
return 'bitcoin:' + $scope.address + '?amount=' + $scope.amountBtc + '&chain=' + $scope.chain;
};
});

View file

@ -219,7 +219,7 @@ angular.module('copayApp.controllers').controller('txpDetailsController', functi
copayerId: $scope.wallet.credentials.copayerId
});
$scope.tx = txFormatService.processTx(tx);
$scope.tx = txFormatService.processTx($scope.wallet, tx);
if (!action && tx.status == 'pending')
$scope.tx.pendingForUs = true;

View file

@ -34,124 +34,7 @@ angular.module('copayApp.controllers').controller('sellCoinbaseController', func
}, onSendStatusChange);
};
var checkTransaction = lodash.throttle(function(count, txp) {
$log.warn('Check if transaction has been received by Coinbase. Try ' + count + '/5');
// TX amount in BTC
var satToBtc = 1 / 100000000;
var amountBTC = (txp.amount * satToBtc).toFixed(8);
coinbaseService.init(function(err, res) {
if (err) {
$log.error(err);
checkTransaction(count, txp);
return;
}
var accessToken = res.accessToken;
var accountId = res.accountId;
var sellPrice = null;
coinbaseService.sellPrice(accessToken, coinbaseService.getAvailableCurrency(), function(err, sell) {
if (err) {
$log.debug(err);
checkTransaction(count, txp);
return;
}
sellPrice = sell.data;
coinbaseService.getTransactions(accessToken, accountId, function(err, ctxs) {
if (err) {
$log.debug(err);
checkTransaction(count, txp);
return;
}
var coinbaseTransactions = ctxs.data;
var txFound = false;
var ctx;
for(var i = 0; i < coinbaseTransactions.length; i++) {
ctx = coinbaseTransactions[i];
if (ctx.type == 'send' && ctx.from && ctx.amount.amount == amountBTC ) {
$log.warn('Transaction found!', ctx);
txFound = true;
$log.debug('Saving transaction to process later...');
ctx['payment_method'] = $scope.selectedPaymentMethodId.value;
ctx['status'] = 'pending'; // Forcing "pending" status to process later
ctx['price_sensitivity'] = $scope.selectedPriceSensitivity.data;
ctx['sell_price_amount'] = sellPrice ? sellPrice.amount : '';
ctx['sell_price_currency'] = sellPrice ? sellPrice.currency : 'USD';
ctx['description'] = appConfigService.nameCase + ' Wallet: ' + $scope.wallet.name;
coinbaseService.savePendingTransaction(ctx, null, function(err) {
ongoingProcess.set('sellingBitcoin', false, statusChangeHandler);
if (err) $log.debug(err);
});
return;
}
}
if (!txFound) {
// Transaction sent, but could not be verified by Coinbase.com
$log.warn('Transaction not found in Coinbase.');
if (count < 5) {
checkTransaction(count + 1, txp);
} else {
ongoingProcess.set('sellingBitcoin', false, statusChangeHandler);
showError('No transaction found');
return;
}
}
});
});
});
}, 8000, {
'leading': true
});
var statusChangeHandler = function (processName, showName, isOn) {
$log.debug('statusChangeHandler: ', processName, showName, isOn);
if ( processName == 'sellingBitcoin' && !isOn) {
$scope.sendStatus = 'success';
$timeout(function() {
$scope.$digest();
}, 100);
} else if (showName) {
$scope.sendStatus = showName;
}
};
$scope.$on("$ionicView.beforeLeave", function(event, data) {
$ionicConfig.views.swipeBackEnabled(true);
});
$scope.$on("$ionicView.enter", function(event, data) {
$ionicConfig.views.swipeBackEnabled(false);
});
$scope.$on("$ionicView.beforeEnter", function(event, data) {
$scope.isFiat = data.stateParams.currency != 'bits' && data.stateParams.currency != 'BTC' ? true : false;
var parsedAmount = txFormatService.parseAmount(
data.stateParams.amount,
data.stateParams.currency);
amount = parsedAmount.amount;
currency = parsedAmount.currency;
$scope.amountUnitStr = parsedAmount.amountUnitStr;
$scope.priceSensitivity = coinbaseService.priceSensitivity;
$scope.selectedPriceSensitivity = { data: coinbaseService.selectedPriceSensitivity };
$scope.network = coinbaseService.getNetwork();
$scope.wallets = profileService.getWallets({
m: 1, // Only 1-signature wallet
onlyComplete: true,
network: $scope.network,
hasFunds: true,
minAmount: parsedAmount.amountSat
});
if (lodash.isEmpty($scope.wallets)) {
showErrorAndBack('Insufficient funds');
return;
}
$scope.wallet = $scope.wallets[0]; // Default first wallet
var processPaymentInfo = function() {
ongoingProcess.set('connectingCoinbase', true);
coinbaseService.init(function(err, res) {
if (err) {
@ -193,7 +76,121 @@ angular.module('copayApp.controllers').controller('sellCoinbaseController', func
if (!hasPrimary) $scope.selectedPaymentMethodId.value = $scope.paymentMethods[0].id;
$scope.sellRequest();
});
});
});
};
var checkTransaction = lodash.throttle(function(count, txp) {
$log.warn('Check if transaction has been received by Coinbase. Try ' + count + '/5');
// TX amount in BTC
var satToBtc = 1 / 100000000;
var amountBTC = (txp.amount * satToBtc).toFixed(8);
coinbaseService.init(function(err, res) {
if (err) {
$log.error(err);
checkTransaction(count, txp);
return;
}
var accessToken = res.accessToken;
var accountId = res.accountId;
var sellPrice = null;
coinbaseService.sellPrice(accessToken, coinbaseService.getAvailableCurrency(), function(err, sell) {
if (err) {
$log.debug(err);
checkTransaction(count, txp);
return;
}
sellPrice = sell.data;
coinbaseService.getTransactions(accessToken, accountId, function(err, ctxs) {
if (err) {
$log.debug(err);
checkTransaction(count, txp);
return;
}
var coinbaseTransactions = ctxs.data;
var txFound = false;
var ctx;
for(var i = 0; i < coinbaseTransactions.length; i++) {
ctx = coinbaseTransactions[i];
if (ctx.type == 'send' && ctx.from && ctx.amount.amount == amountBTC ) {
$log.warn('Transaction found!', ctx);
txFound = true;
$log.debug('Saving transaction to process later...');
ctx['payment_method'] = $scope.selectedPaymentMethodId.value;
ctx['status'] = 'pending'; // Forcing "pending" status to process later
ctx['price_sensitivity'] = $scope.selectedPriceSensitivity.data;
ctx['sell_price_amount'] = sellPrice ? sellPrice.amount : '';
ctx['sell_price_currency'] = sellPrice ? sellPrice.currency : 'USD';
ctx['description'] = appConfigService.nameCase + ' Wallet: ' + $scope.wallet.name;
coinbaseService.savePendingTransaction(ctx, null, function(err) {
ongoingProcess.set('sellingBitcoin', false, statusChangeHandler);
if (err) $log.debug(err);
});
return;
}
}
if (!txFound) {
// Transaction sent, but could not be verified by Coinbase.com
$log.warn('Transaction not found in Coinbase.');
if (count < 5) {
checkTransaction(count + 1, txp);
} else {
ongoingProcess.set('sellingBitcoin', false, statusChangeHandler);
showError('No transaction found');
return;
}
}
});
});
});
}, 8000, {
'leading': true
});
var statusChangeHandler = function (processName, showName, isOn) {
$log.debug('statusChangeHandler: ', processName, showName, isOn);
if ( processName == 'sellingBitcoin' && !isOn) {
$scope.sendStatus = 'success';
$timeout(function() {
$scope.$digest();
}, 100);
} else if (showName) {
$scope.sendStatus = showName;
}
};
$scope.$on("$ionicView.beforeLeave", function(event, data) {
$ionicConfig.views.swipeBackEnabled(true);
});
$scope.$on("$ionicView.enter", function(event, data) {
$ionicConfig.views.swipeBackEnabled(false);
});
$scope.$on("$ionicView.beforeEnter", function(event, data) {
$scope.isFiat = data.stateParams.currency != 'BCH' && data.stateParams.currency != 'BTC' ? true : false;
amount = data.stateParams.amount;
currency = data.stateParams.currency;
$scope.priceSensitivity = coinbaseService.priceSensitivity;
$scope.selectedPriceSensitivity = { data: coinbaseService.selectedPriceSensitivity };
$scope.network = coinbaseService.getNetwork();
$scope.wallets = profileService.getWallets({
m: 1, // Only 1-signature wallet
onlyComplete: true,
network: $scope.network,
hasFunds: true,
chain: 'BTC'
});
if (lodash.isEmpty($scope.wallets)) {
showErrorAndBack('Insufficient funds');
return;
}
$scope.onWalletSelect($scope.wallets[0]); // Default first wallet
});
$scope.sellRequest = function() {
@ -236,7 +233,7 @@ angular.module('copayApp.controllers').controller('sellCoinbaseController', func
var cancelText = 'Cancel';
popupService.showConfirm(null, message, okText, cancelText, function(ok) {
if (!ok) return;
ongoingProcess.set('sellingBitcoin', true, statusChangeHandler);
coinbaseService.init(function(err, res) {
if (err) {
@ -294,8 +291,8 @@ angular.module('copayApp.controllers').controller('sellCoinbaseController', func
checkTransaction(1, txSent);
});
});
});
});
});
});
});
};
@ -306,6 +303,15 @@ angular.module('copayApp.controllers').controller('sellCoinbaseController', func
$scope.onWalletSelect = function(wallet) {
$scope.wallet = wallet;
var parsedAmount = txFormatService.parseAmount(
wallet,
amount,
currency);
amount = parsedAmount.amount;
currency = parsedAmount.currency;
$scope.amountUnitStr = parsedAmount.amountUnitStr;
processPaymentInfo();
};
$scope.goBackHome = function() {

View file

@ -35,39 +35,7 @@ angular.module('copayApp.controllers').controller('sellGlideraController', funct
}
};
$scope.$on("$ionicView.beforeLeave", function(event, data) {
$ionicConfig.views.swipeBackEnabled(true);
});
$scope.$on("$ionicView.enter", function(event, data) {
$ionicConfig.views.swipeBackEnabled(false);
});
$scope.$on("$ionicView.beforeEnter", function(event, data) {
$scope.isFiat = data.stateParams.currency != 'bits' && data.stateParams.currency != 'BTC' ? true : false;
var parsedAmount = txFormatService.parseAmount(
data.stateParams.amount,
data.stateParams.currency);
amount = parsedAmount.amount;
currency = parsedAmount.currency;
$scope.amountUnitStr = parsedAmount.amountUnitStr;
$scope.network = glideraService.getNetwork();
$scope.wallets = profileService.getWallets({
m: 1, // Only 1-signature wallet
onlyComplete: true,
network: $scope.network,
hasFunds: true,
minAmount: parsedAmount.amountSat
});
if (lodash.isEmpty($scope.wallets)) {
showErrorAndBack('Insufficient funds');
return;
}
$scope.wallet = $scope.wallets[0]; // Default first wallet
var processPaymentInfo = function() {
ongoingProcess.set('connectingGlidera', true);
glideraService.init(function(err, data) {
if (err) {
@ -91,6 +59,35 @@ angular.module('copayApp.controllers').controller('sellGlideraController', funct
$scope.sellInfo = sell;
});
});
};
$scope.$on("$ionicView.beforeLeave", function(event, data) {
$ionicConfig.views.swipeBackEnabled(true);
});
$scope.$on("$ionicView.enter", function(event, data) {
$ionicConfig.views.swipeBackEnabled(false);
});
$scope.$on("$ionicView.beforeEnter", function(event, data) {
$scope.isFiat = data.stateParams.currency != 'BCH' && data.stateParams.currency != 'BTC' ? true : false;
amount = data.stateParams.amount;
currency = data.stateParams.currency;
$scope.network = glideraService.getNetwork();
$scope.wallets = profileService.getWallets({
m: 1, // Only 1-signature wallet
onlyComplete: true,
network: $scope.network,
hasFunds: true,
chain: 'BTC'
});
if (lodash.isEmpty($scope.wallets)) {
showErrorAndBack('Insufficient funds');
return;
}
$scope.onWalletSelect($scope.wallets[0]); // Default first wallet
});
var ask2FaCode = function(mode, cb) {
@ -108,7 +105,7 @@ angular.module('copayApp.controllers').controller('sellGlideraController', funct
popupService.showPrompt(title, message, null, function(twoFaCode) {
if (typeof twoFaCode == 'undefined') return cb();
return cb(twoFaCode);
});
});
} else {
return cb();
}
@ -119,7 +116,7 @@ angular.module('copayApp.controllers').controller('sellGlideraController', funct
var okText = 'Confirm';
var cancelText = 'Cancel';
popupService.showConfirm(null, message, okText, cancelText, function(ok) {
if (!ok) return;
if (!ok) return;
ongoingProcess.set('sellingBitcoin', true, statusChangeHandler);
glideraService.get2faCode($scope.token, function(err, tfa) {
if (err) {
@ -231,6 +228,15 @@ angular.module('copayApp.controllers').controller('sellGlideraController', funct
$scope.onWalletSelect = function(wallet) {
$scope.wallet = wallet;
var parsedAmount = txFormatService.parseAmount(
wallet,
amount,
currency);
amount = parsedAmount.amount;
currency = parsedAmount.currency;
$scope.amountUnitStr = parsedAmount.amountUnitStr;
processPaymentInfo();
};
$scope.goBackHome = function() {

View file

@ -8,7 +8,8 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
$scope.requestSpecificAmount = function() {
$state.go('tabs.paymentRequest.amount', {
id: $scope.wallet.credentials.walletId
id: $scope.wallet.credentials.walletId,
forceChain: $scope.wallet.chain
});
};

View file

@ -218,7 +218,7 @@ angular.module('copayApp.controllers').controller('topUpController', function($s
// Save TX in memory
createdTx = ctxp;
$scope.totalAmountStr = txFormatService.formatAmountStr(ctxp.amount);
$scope.totalAmountStr = txFormatService.formatAmountStr(wallet, ctxp.amount);
setTotalAmount(parsedAmount.amountSat, invoiceFeeSat, ctxp.fee);
@ -256,7 +256,8 @@ angular.module('copayApp.controllers').controller('topUpController', function($s
$scope.wallets = profileService.getWallets({
onlyComplete: true,
network: bitpayService.getEnvironment().network,
hasFunds: true
hasFunds: true,
chain: 'BTC'
});
if (lodash.isEmpty($scope.wallets)) {
@ -319,7 +320,7 @@ angular.module('copayApp.controllers').controller('topUpController', function($s
});
return;
}
var parsedAmount = txFormatService.parseAmount(a, c);
var parsedAmount = txFormatService.parseAmount(wallet, a, c);
initializeTopUp(wallet, parsedAmount);
});
};

View file

@ -112,7 +112,7 @@ angular.module('copayApp.controllers').controller('txDetailsController', functio
return popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Transaction not available at this time'));
}
$scope.btx = txFormatService.processTx(tx);
$scope.btx = txFormatService.processTx($scope.wallet, tx);
txFormatService.formatAlternativeStr(tx.fees, function(v) {
$scope.btx.feeFiatStr = v;
$scope.btx.feeRateStr = ($scope.btx.fees / ($scope.btx.amount + $scope.btx.fees) * 100).toFixed(2) + '%';

View file

@ -27,12 +27,10 @@ angular.module('copayApp.filters', [])
}
})
.filter('formatFiatAmount', ['$filter', '$locale', 'configService',
function(filter, locale, configService) {
function(filter, locale) {
var numberFilter = filter('number');
var formats = locale.NUMBER_FORMATS;
var config = configService.getSync().wallet.settings;
return function(amount) {
if (!config) return amount;
var fractionSize = 2;
var value = numberFilter(amount, fractionSize);

View file

@ -287,7 +287,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
*/
.state('tabs.send.amount', {
url: '/amount/:recipientType/:toAddress/:toName/:toEmail/:toColor',
url: '/amount/:recipientType/:toAddress/:toName/:toEmail/:toColor/:chain',
views: {
'tab-send@tabs': {
controller: 'amountController',
@ -296,7 +296,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
})
.state('tabs.send.confirm', {
url: '/confirm/:recipientType/:toAddress/:toName/:toAmount/:toEmail/:toColor/:description/:useSendMax',
url: '/confirm/:recipientType/:toAddress/:toName/:toAmount/:toEmail/:toColor/:description/:chain/:useSendMax',
views: {
'tab-send@tabs': {
controller: 'confirmController',
@ -681,7 +681,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
})
.state('tabs.paymentRequest.amount', {
url: '/amount',
url: '/amount/:forceChain',
views: {
'tab-receive@tabs': {
controller: 'amountController',
@ -690,7 +690,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
})
.state('tabs.paymentRequest.confirm', {
url: '/confirm/:amount/:currency',
url: '/confirm/:amount/:currency/:chain',
views: {
'tab-receive@tabs': {
controller: 'customAmountController',
@ -923,6 +923,9 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
controllerAs: 'glidera',
templateUrl: 'views/glidera.html'
}
},
params: {
forceChain: 'BTC'
}
})
.state('tabs.buyandsell.glidera.amount', {
@ -976,6 +979,9 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
controllerAs: 'coinbase',
templateUrl: 'views/coinbase.html'
}
},
params: {
forceChain: 'BTC'
}
})
.state('tabs.preferences.coinbase', {
@ -1064,7 +1070,8 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
params: {
nextStep: 'tabs.giftcards.mercadoLibre.buy',
currency: 'BRL',
forceCurrency: true
forceCurrency: true,
forceChain: 'BTC'
}
})
.state('tabs.giftcards.mercadoLibre.buy', {
@ -1115,7 +1122,8 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
params: {
nextStep: 'tabs.giftcards.amazon.buy',
currency: 'USD',
forceCurrency: true
forceCurrency: true,
forceChain: 'BTC'
}
})
.state('tabs.giftcards.amazon.buy', {
@ -1155,6 +1163,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
params: {
id: null,
currency: 'USD',
forceChain: 'BTC',
useSendMax: null
}
})

View file

@ -143,6 +143,14 @@ angular.module('copayApp.services').factory('configService', function(storageSer
configCache.bitpayAccount = defaultConfig.bitpayAccount;
}
if (configCache.wallet.settings.unitCode == 'bit') {
// Convert to BTC. Bits will be disabled
configCache.wallet.settings.unitName = defaultConfig.wallet.settings.unitName;
configCache.wallet.settings.unitToSatoshi = defaultConfig.wallet.settings.unitToSatoshi;
configCache.wallet.settings.unitDecimals = defaultConfig.wallet.settings.unitDecimals;
configCache.wallet.settings.unitCode = defaultConfig.wallet.settings.unitCode;
}
} else {
configCache = lodash.clone(defaultConfig);
};

View file

@ -64,7 +64,6 @@ angular.module('copayApp.services').factory('feeService', function($log, $timeou
}
var walletClient = bwcService.getClient();
var unitName = configService.getSync().wallet.settings.unitName;
walletClient.getFeeLevels('livenet', function(errLivenet, levelsLivenet) {
walletClient.getFeeLevels('testnet', function(errTestnet, levelsTestnet) {

View file

@ -89,6 +89,7 @@ angular.module('copayApp.services')
wallet.copayerId = wallet.credentials.copayerId;
wallet.m = wallet.credentials.m;
wallet.n = wallet.credentials.n;
wallet.chain = wallet.credentials.chain;
root.updateWalletSettings(wallet);
root.wallet[walletId] = wallet;
@ -222,11 +223,13 @@ angular.module('copayApp.services')
return ((config.bwsFor && config.bwsFor[walletId]) || defaults.bws.url);
};
var client = bwcService.getClient(JSON.stringify(credentials), {
bwsurl: getBWSURL(credentials.walletId),
});
// TODO: Should return "chain" = "BTC" or "BCH"
client.credentials.chain = 'BTC';
var skipKeyValidation = shouldSkipValidation(credentials.walletId);
if (!skipKeyValidation)
root.runValidation(client, 500);
@ -749,6 +752,12 @@ angular.module('copayApp.services')
var ret = lodash.values(root.wallet);
if (opts.chain) {
ret = lodash.filter(ret, function(x) {
return (x.credentials.chain == opts.chain);
});
}
if (opts.network) {
ret = lodash.filter(ret, function(x) {
return (x.credentials.network == opts.network);
@ -848,7 +857,7 @@ angular.module('copayApp.services')
});
};
function process(notifications) {
function process(wallet, notifications) {
if (!notifications) return [];
var shown = lodash.sortBy(notifications, 'createdOn').reverse();
@ -861,7 +870,7 @@ angular.module('copayApp.services')
x.types = [x.type];
if (x.data && x.data.amount)
x.amountStr = txFormatService.formatAmountStr(x.data.amount);
x.amountStr = txFormatService.formatAmountStr(wallet, x.data.amount);
x.action = function() {
// TODO?
@ -939,7 +948,7 @@ angular.module('copayApp.services')
notifications = lodash.sortBy(notifications, 'createdOn');
notifications = lodash.compact(lodash.flatten(notifications)).slice(0, MAX);
var total = notifications.length;
return cb(null, process(notifications), total);
return cb(null, process(wallet, notifications), total);
};
});
});

View file

@ -17,10 +17,10 @@ angular.module('copayApp.services').factory('txFormatService', function($filter,
return this.Utils.formatAmount(satoshis, config.unitCode, opts);
};
root.formatAmountStr = function(satoshis) {
root.formatAmountStr = function(wallet, satoshis) {
console.log('[txFormatService.js:20]',wallet); //TODO/
if (isNaN(satoshis)) return;
var config = configService.getSync().wallet.settings;
return root.formatAmount(satoshis) + ' ' + config.unitName;
return root.formatAmount(satoshis) + ' ' + wallet.chain;
};
root.toFiat = function(satoshis, code, cb) {
@ -86,7 +86,7 @@ angular.module('copayApp.services').factory('txFormatService', function($filter,
};
};
root.processTx = function(tx) {
root.processTx = function(wallet, tx) {
if (!tx || tx.action == 'invalid')
return tx;
@ -101,7 +101,7 @@ angular.module('copayApp.services').factory('txFormatService', function($filter,
tx.hasMultiplesOutputs = true;
}
tx.amount = lodash.reduce(tx.outputs, function(total, o) {
o.amountStr = root.formatAmountStr(o.amount);
o.amountStr = root.formatAmountStr(wallet, o.amount);
o.alternativeAmountStr = root.formatAlternativeStr(o.amount);
return total + o.amount;
}, 0);
@ -109,9 +109,9 @@ angular.module('copayApp.services').factory('txFormatService', function($filter,
tx.toAddress = tx.outputs[0].toAddress;
}
tx.amountStr = root.formatAmountStr(tx.amount);
tx.amountStr = root.formatAmountStr(wallet, tx.amount);
tx.alternativeAmountStr = root.formatAlternativeStr(tx.amount);
tx.feeStr = root.formatAmountStr(tx.fee || tx.fees);
tx.feeStr = root.formatAmountStr(wallet, tx.fee || tx.fees);
if (tx.amountStr) {
tx.amountValueStr = tx.amountStr.split(' ')[0];
@ -145,8 +145,6 @@ angular.module('copayApp.services').factory('txFormatService', function($filter,
lodash.each(txps, function(tx) {
tx = txFormatService.processTx(tx);
// no future transactions...
if (tx.createdOn > now)
tx.createdOn = now;
@ -157,6 +155,8 @@ angular.module('copayApp.services').factory('txFormatService', function($filter,
return;
}
tx = txFormatService.processTx(tx.wallet, tx);
var action = lodash.find(tx.actions, {
copayerId: tx.wallet.copayerId
});
@ -180,7 +180,7 @@ angular.module('copayApp.services').factory('txFormatService', function($filter,
return txps;
};
root.parseAmount = function(amount, currency) {
root.parseAmount = function(wallet, amount, currency) {
var config = configService.getSync().wallet.settings;
var satToBtc = 1 / 100000000;
var unitToSatoshi = config.unitToSatoshi;
@ -189,21 +189,21 @@ angular.module('copayApp.services').factory('txFormatService', function($filter,
var alternativeIsoCode = config.alternativeIsoCode;
// If fiat currency
if (currency != 'bits' && currency != 'BTC' && currency != 'sat') {
if (currency != 'BCH' && currency != 'BTC' && currency != 'sat') {
amountUnitStr = $filter('formatFiatAmount')(amount) + ' ' + currency;
amountSat = rateService.fromFiat(amount, currency).toFixed(0);
} else if (currency == 'sat') {
amountSat = amount;
amountUnitStr = root.formatAmountStr(amountSat);
// convert sat to BTC
amountUnitStr = root.formatAmountStr(wallet, amountSat);
// convert sat to BTC or BCH
amount = (amountSat * satToBtc).toFixed(8);
currency = 'BTC';
currency = wallet.chain;
} else {
amountSat = parseInt((amount * unitToSatoshi).toFixed(0));
amountUnitStr = root.formatAmountStr(amountSat);
// convert unit to BTC
amountUnitStr = root.formatAmountStr(wallet, amountSat);
// convert unit to BTC or BCH
amount = (amountSat * satToBtc).toFixed(8);
currency = 'BTC';
currency = wallet.chain;
}
return {

View file

@ -2,8 +2,8 @@
angular.module('copayApp.services').factory('walletService', function($log, $timeout, lodash, trezor, ledger, intelTEE, storageService, configService, rateService, uxLanguage, $filter, gettextCatalog, bwcError, $ionicPopup, fingerprintService, ongoingProcess, gettext, $rootScope, txFormatService, $ionicModal, $state, bwcService, bitcore, popupService) {
// Ratio low amount warning (fee/amount) in incoming TX
var LOW_AMOUNT_RATIO = 0.15;
// Ratio low amount warning (fee/amount) in incoming TX
var LOW_AMOUNT_RATIO = 0.15;
// Ratio of "many utxos" warning in total balance (fee/amount)
var TOTAL_LOW_WARNING_RATIO = .3;
@ -130,7 +130,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
lodash.each(txps, function(tx) {
tx = txFormatService.processTx(tx);
tx = txFormatService.processTx(wallet, tx);
// no future transactions...
if (tx.createdOn > now)
@ -213,14 +213,13 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
// Selected unit
cache.unitToSatoshi = config.settings.unitToSatoshi;
cache.satToUnit = 1 / cache.unitToSatoshi;
cache.unitName = config.settings.unitName;
//STR
cache.totalBalanceStr = txFormatService.formatAmount(cache.totalBalanceSat) + ' ' + cache.unitName;
cache.lockedBalanceStr = txFormatService.formatAmount(cache.lockedBalanceSat) + ' ' + cache.unitName;
cache.availableBalanceStr = txFormatService.formatAmount(cache.availableBalanceSat) + ' ' + cache.unitName;
cache.spendableBalanceStr = txFormatService.formatAmount(cache.spendableAmount) + ' ' + cache.unitName;
cache.pendingBalanceStr = txFormatService.formatAmount(cache.pendingAmount) + ' ' + cache.unitName;
cache.totalBalanceStr = txFormatService.formatAmount(cache.totalBalanceSat) + ' ' + wallet.chain;
cache.lockedBalanceStr = txFormatService.formatAmount(cache.lockedBalanceSat) + ' ' + wallet.chain;
cache.availableBalanceStr = txFormatService.formatAmount(cache.availableBalanceSat) + ' ' + wallet.chain;
cache.spendableBalanceStr = txFormatService.formatAmount(cache.spendableAmount) + ' ' + wallet.chain;
cache.pendingBalanceStr = txFormatService.formatAmount(cache.pendingAmount) + ' ' + wallet.chain;
cache.alternativeName = config.settings.alternativeName;
cache.alternativeIsoCode = config.settings.alternativeIsoCode;
@ -366,7 +365,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
wallet.hasUnsafeConfirmed = false;
lodash.each(txs, function(tx) {
tx = txFormatService.processTx(tx);
tx = txFormatService.processTx(wallet, tx);
// no future transactions...
if (tx.time > now)
@ -400,7 +399,6 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
var LIMIT = 50;
var requestLimit = FIRST_LIMIT;
var walletId = wallet.credentials.walletId;
var config = configService.getSync().wallet.settings;
var opts = opts || {};
var progressFn = opts.progressFn || function() {};
@ -414,17 +412,15 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
var fixTxsUnit = function(txs) {
if (!txs || !txs[0] || !txs[0].amountStr) return;
var cacheUnit = txs[0].amountStr.split(' ')[1];
var cacheChain = txs[0].amountStr.split(' ')[1];
if (cacheUnit == config.unitName)
if (cacheChain == wallet.chain)
return;
var name = ' ' + config.unitName;
$log.debug('Fixing Tx Cache Unit to:' + name)
$log.debug('Fixing Tx Cache Unit to: ' + wallet.chain)
lodash.each(txs, function(tx) {
tx.amountStr = txFormatService.formatAmount(tx.amount) + name;
tx.feeStr = txFormatService.formatAmount(tx.fees) + name;
tx.amountStr = txFormatService.formatAmountStr(wallet, tx.amount);
tx.feeStr = txFormatService.formatAmountStr(wallet, tx.fees);
});
};
@ -788,7 +784,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
//prefs.email (may come from arguments)
prefs.email = config.emailNotifications.email;
prefs.language = uxLanguage.getCurrentLanguage();
prefs.unit = walletSettings.unitCode;
// prefs.unit = walletSettings.unitCode; // TODO: remove, not used
updateRemotePreferencesFor(lodash.clone(clients), prefs, function(err) {
if (err) return cb(err);
@ -922,7 +918,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
};
// Approx utxo amount, from which the uxto is economically redeemable
// Approx utxo amount, from which the uxto is economically redeemable
root.getMinFee = function(wallet, feeLevels, nbOutputs) {
var lowLevelRate = (lodash.find(feeLevels[wallet.network], {
level: 'normal',
@ -933,7 +929,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
};
// Approx utxo amount, from which the uxto is economically redeemable
// Approx utxo amount, from which the uxto is economically redeemable
root.getLowAmount = function(wallet, feeLevels, nbOutputs) {
var minFee = root.getMinFee(wallet,feeLevels, nbOutputs);
return parseInt( minFee / LOW_AMOUNT_RATIO);

View file

@ -139,6 +139,19 @@
}
}
.amount {
.icon-toggle {
font-size: 1.2em;
width: auto;
margin: 0.8em auto;
border: 1px solid $v-subtle-gray;
color: $v-dark-gray;
border-radius: 3px;
padding: 0 10px;
cursor: pointer;
@media(max-height: 280px) {
margin: 0.1em auto;
}
}
&__editable {
&--minimize {
font-size: 22px;
@ -196,7 +209,6 @@
&__result-equiv {
color: $v-mid-gray;
font-size: 1.2em;
margin-top: 2rem;
@media(max-height: 480px) {
margin-top: 0;
font-size: 16px;

View file

@ -48,16 +48,19 @@
<div class="amount">
<div class="amount__editable" ng-class="{'amount__editable--minimize': smallFont, 'amount__editable--standard': !smallFont, 'amount__editable--placeholder': !amount}">
<span class="amount__number">{{amount || "0.00" }}</span>
<a class="amount__currency-toggle" ng-click="toggleAlternative()" ng-show="showAlternativeAmount">{{alternativeIsoCode}}</a>
<a class="amount__currency-toggle" ng-click="toggleAlternative()" ng-show="!showAlternativeAmount">{{unitName}}</a>
<a class="amount__currency-toggle" ng-show="showAlternativeAmount">{{alternativeIsoCode}}</a>
<a class="amount__currency-toggle" ng-click="toggleChain()" ng-show="!showAlternativeAmount">{{chain}}</a>
</div>
<div class="icon-toggle" ng-if="!forceCurrency" ng-click="toggleAlternative()">
<i class="icon ion-arrow-swap"></i>
</div>
<div ng-class="{'amount__results--minimize': smallFont, 'amount__results--standard': !smallFont, 'amount__results--placeholder': !amountResult}" ng-show="!showAlternativeAmount">
<div class="amount__result" ng-show="globalResult">{{globalResult}} {{unitName}}</div>
<div class="amount__result" ng-show="globalResult">{{globalResult}} {{chain}}</div>
<div class="amount__result-equiv">&asymp; {{amountResult || '0.00'}} {{alternativeIsoCode}}</div>
</div>
<div ng-class="{'amount__results--minimize': smallFont, 'amount__results--standard': !smallFont, 'amount__results--placeholder': !amountResult}" ng-show="showAlternativeAmount">
<div class="amount__result" ng-show="globalResult">{{globalResult}} {{alternativeIsoCode}}</div>
<div class="amount__result-equiv">{{alternativeResult || '0.00'}} {{unitName}}</div>
<div class="amount__result-equiv">{{alternativeResult || '0.00'}} {{chain}}</div>
</div>
</div>
</div>

View file

@ -21,7 +21,7 @@
<ion-content scroll="false">
<div class="address" ng-if="address && amountBtc">
<div class="qr-code" copy-to-clipboard="copyToClipboard()">
<qrcode size="220" data="bitcoin:{{address + '?amount=' + amountBtc}}" color="#334"></qrcode>
<qrcode size="220" data="bitcoin:{{address + '?amount=' + amountBtc + '&chain=' + chain}}" color="#334"></qrcode>
</div>
<div class="info">
<div class="item single-line" copy-to-clipboard="address">