Sends wallet to wallet transaction with sound.
This commit is contained in:
parent
3ca95d6d40
commit
5973b30551
2 changed files with 99 additions and 52 deletions
|
|
@ -4,7 +4,7 @@ angular
|
||||||
.module('copayApp.controllers')
|
.module('copayApp.controllers')
|
||||||
.controller('reviewController', reviewController);
|
.controller('reviewController', reviewController);
|
||||||
|
|
||||||
function reviewController(addressbookService, bitcoinCashJsService, bitcore, bitcoreCash, bwcError, configService, feeService, gettextCatalog, $ionicLoading, $ionicModal, lodash, $log, ongoingProcess, platformInfo, popupService, profileService, $scope, $timeout, txFormatService, walletService) {
|
function reviewController(addressbookService, bitcoinCashJsService, bitcore, bitcoreCash, bwcError, configService, feeService, gettextCatalog, $ionicLoading, $ionicModal, lodash, $log, ongoingProcess, platformInfo, popupService, profileService, $scope, soundService, $state, $timeout, txConfirmNotification, txFormatService, walletService) {
|
||||||
var vm = this;
|
var vm = this;
|
||||||
|
|
||||||
vm.buttonText = '';
|
vm.buttonText = '';
|
||||||
|
|
@ -24,16 +24,15 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
|
||||||
vm.fiatCurrency = '';
|
vm.fiatCurrency = '';
|
||||||
vm.feeIsHigh = false;
|
vm.feeIsHigh = false;
|
||||||
vm.feeLessThanACent = false;
|
vm.feeLessThanACent = false;
|
||||||
|
vm.isCordova = platformInfo.isCordova;
|
||||||
|
vm.notReadyMessage = '';
|
||||||
vm.origin = {
|
vm.origin = {
|
||||||
balanceAmount: '',
|
balanceAmount: '',
|
||||||
balanceCurrency: '',
|
balanceCurrency: '',
|
||||||
color: '',
|
|
||||||
currency: '',
|
currency: '',
|
||||||
currencyColor: '',
|
currencyColor: '',
|
||||||
name: '',
|
|
||||||
};
|
};
|
||||||
vm.isCordova = platformInfo.isCordova;
|
vm.originWallet = null;
|
||||||
vm.notReadyMessage = '';
|
|
||||||
vm.primaryAmount = '';
|
vm.primaryAmount = '';
|
||||||
vm.primaryCurrency = '';
|
vm.primaryCurrency = '';
|
||||||
vm.usingMerchantFee = false;
|
vm.usingMerchantFee = false;
|
||||||
|
|
@ -41,7 +40,9 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
|
||||||
vm.secondaryAmount = '';
|
vm.secondaryAmount = '';
|
||||||
vm.secondaryCurrency = '';
|
vm.secondaryCurrency = '';
|
||||||
vm.sendingTitle = gettextCatalog.getString('You are sending');
|
vm.sendingTitle = gettextCatalog.getString('You are sending');
|
||||||
|
vm.sendStatus = '';
|
||||||
vm.thirdParty = false;
|
vm.thirdParty = false;
|
||||||
|
vm.wallet = null;
|
||||||
|
|
||||||
var config = null;
|
var config = null;
|
||||||
var coin = '';
|
var coin = '';
|
||||||
|
|
@ -50,7 +51,6 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
|
||||||
var usingMerchantFee = false;
|
var usingMerchantFee = false;
|
||||||
var destinationWalletId = '';
|
var destinationWalletId = '';
|
||||||
var originWalletId = '';
|
var originWalletId = '';
|
||||||
var originWallet;
|
|
||||||
var priceDisplayIsFiat = true;
|
var priceDisplayIsFiat = true;
|
||||||
var satoshis = null;
|
var satoshis = null;
|
||||||
var toAddress = '';
|
var toAddress = '';
|
||||||
|
|
@ -68,11 +68,9 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
|
||||||
satoshis = parseInt(data.stateParams.amount, 10);
|
satoshis = parseInt(data.stateParams.amount, 10);
|
||||||
toAddress = data.stateParams.toAddr;
|
toAddress = data.stateParams.toAddr;
|
||||||
|
|
||||||
originWallet = profileService.getWallet(originWalletId);
|
vm.originWallet = profileService.getWallet(originWalletId);
|
||||||
vm.origin.currency = originWallet.coin.toUpperCase();
|
vm.origin.currency = vm.originWallet.coin.toUpperCase();
|
||||||
vm.origin.color = originWallet.color;
|
coin = vm.originWallet.coin;
|
||||||
vm.origin.name = originWallet.name;
|
|
||||||
coin = originWallet.coin;
|
|
||||||
|
|
||||||
if (data.stateParams.thirdParty) {
|
if (data.stateParams.thirdParty) {
|
||||||
vm.thirdParty = JSON.parse(data.stateParams.thirdParty); // Parse stringified JSON-object
|
vm.thirdParty = JSON.parse(data.stateParams.thirdParty); // Parse stringified JSON-object
|
||||||
|
|
@ -93,20 +91,20 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
|
||||||
} else {
|
} else {
|
||||||
config = configCache;
|
config = configCache;
|
||||||
priceDisplayIsFiat = config.wallet.settings.priceDisplay === 'fiat';
|
priceDisplayIsFiat = config.wallet.settings.priceDisplay === 'fiat';
|
||||||
vm.origin.currencyColor = originWallet.coin === 'btc' ? config.bitcoinWalletColor : config.bitcoinCashWalletColor;
|
vm.origin.currencyColor = vm.originWallet.coin === 'btc' ? config.bitcoinWalletColor : config.bitcoinCashWalletColor;
|
||||||
unitFromSat = 1 / config.wallet.settings.unitToSatoshi;
|
unitFromSat = 1 / config.wallet.settings.unitToSatoshi;
|
||||||
}
|
}
|
||||||
updateSendAmounts();
|
updateSendAmounts();
|
||||||
getOriginWalletBalance(originWallet);
|
getOriginWalletBalance(vm.originWallet);
|
||||||
handleDestinationAsAddress(toAddress, coin);
|
handleDestinationAsAddress(toAddress, coin);
|
||||||
handleDestinationAsWallet(data.stateParams.toWalletId);
|
handleDestinationAsWallet(data.stateParams.toWalletId);
|
||||||
createVanityTransaction(data);
|
createVanityTransaction(data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
vm.approve = function(onSendStatusChange) {
|
vm.approve = function() {
|
||||||
|
|
||||||
if (!tx || !originWallet) return;
|
if (!tx || !vm.originWallet) return;
|
||||||
|
|
||||||
if ($scope.paymentExpired) {
|
if ($scope.paymentExpired) {
|
||||||
popupService.showAlert(null, gettextCatalog.getString('This bitcoin payment request has expired.'));
|
popupService.showAlert(null, gettextCatalog.getString('This bitcoin payment request has expired.'));
|
||||||
|
|
@ -117,42 +115,42 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ongoingProcess.set('creatingTx', true, onSendStatusChange);
|
ongoingProcess.set('creatingTx', true, statusChangeHandler);
|
||||||
getTxp(lodash.clone(tx), originWallet, false, function(err, txp) {
|
getTxp(lodash.clone(tx), vm.originWallet, false, function(err, txp) {
|
||||||
ongoingProcess.set('creatingTx', false, onSendStatusChange);
|
ongoingProcess.set('creatingTx', false, statusChangeHandler);
|
||||||
if (err) return;
|
if (err) return;
|
||||||
|
|
||||||
// confirm txs for more that 20usd, if not spending/touchid is enabled
|
// confirm txs for more that 20usd, if not spending/touchid is enabled
|
||||||
function confirmTx(cb) {
|
function confirmTx(cb) {
|
||||||
if (walletService.isEncrypted(originWallet))
|
if (walletService.isEncrypted(vm.originWallet))
|
||||||
return cb();
|
return cb();
|
||||||
|
|
||||||
var amountUsd = parseFloat(txFormatService.formatToUSD(originWallet.coin, txp.amount));
|
var amountUsd = parseFloat(txFormatService.formatToUSD(vm.originWallet.coin, txp.amount));
|
||||||
return cb();
|
return cb();
|
||||||
};
|
};
|
||||||
|
|
||||||
function publishAndSign() {
|
function publishAndSign() {
|
||||||
if (!originWallet.canSign() && !originWallet.isPrivKeyExternal()) {
|
if (!vm.originWallet.canSign() && !vm.originWallet.isPrivKeyExternal()) {
|
||||||
$log.info('No signing proposal: No private key');
|
$log.info('No signing proposal: No private key');
|
||||||
|
|
||||||
return walletService.onlyPublish(originWallet, txp, function(err) {
|
return walletService.onlyPublish(vm.originWallet, txp, function(err) {
|
||||||
if (err) setSendError(err);
|
if (err) setSendError(err);
|
||||||
}, onSendStatusChange);
|
}, statusChangeHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
walletService.publishAndSign(originWallet, txp, function(err, txp) {
|
walletService.publishAndSign(vm.originWallet, txp, function(err, txp) {
|
||||||
if (err) return setSendError(err);
|
if (err) return setSendError(err);
|
||||||
if (config.confirmedTxsNotifications && config.confirmedTxsNotifications.enabled) {
|
if (config.confirmedTxsNotifications && config.confirmedTxsNotifications.enabled) {
|
||||||
txConfirmNotification.subscribe(originWallet, {
|
txConfirmNotification.subscribe(vm.originWallet, {
|
||||||
txid: txp.txid
|
txid: txp.txid
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, onSendStatusChange);
|
}, statusChangeHandler);
|
||||||
};
|
};
|
||||||
|
|
||||||
confirmTx(function(nok) {
|
confirmTx(function(nok) {
|
||||||
if (nok) {
|
if (nok) {
|
||||||
$scope.sendStatus = '';
|
vm.sendStatus = '';
|
||||||
$timeout(function() {
|
$timeout(function() {
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
});
|
});
|
||||||
|
|
@ -172,7 +170,7 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
|
||||||
scope.network = tx.network;
|
scope.network = tx.network;
|
||||||
scope.feeLevel = tx.feeLevel;
|
scope.feeLevel = tx.feeLevel;
|
||||||
scope.noSave = true;
|
scope.noSave = true;
|
||||||
scope.coin = originWallet.coin;
|
scope.coin = vm.originWallet.coin;
|
||||||
|
|
||||||
if (usingCustomFee) {
|
if (usingCustomFee) {
|
||||||
scope.customFeePerKB = tx.feeRate;
|
scope.customFeePerKB = tx.feeRate;
|
||||||
|
|
@ -202,7 +200,7 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
|
||||||
tx.feeLevel = newFeeLevel;
|
tx.feeLevel = newFeeLevel;
|
||||||
if (usingCustomFee) tx.feeRate = parseInt(customFeePerKB);
|
if (usingCustomFee) tx.feeRate = parseInt(customFeePerKB);
|
||||||
|
|
||||||
updateTx(tx, originWallet, {
|
updateTx(tx, vm.originWallet, {
|
||||||
clearCache: true,
|
clearCache: true,
|
||||||
dryRun: true
|
dryRun: true
|
||||||
}, function() {});
|
}, function() {});
|
||||||
|
|
@ -228,7 +226,7 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
|
||||||
toEmail: vm.destination.email || null,
|
toEmail: vm.destination.email || null,
|
||||||
toColor: vm.destination.color || null,
|
toColor: vm.destination.color || null,
|
||||||
network: false,
|
network: false,
|
||||||
coin: originWallet.coin,
|
coin: vm.originWallet.coin,
|
||||||
txp: {},
|
txp: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -281,7 +279,7 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function getOriginWalletBalance(originWallet) {
|
function getOriginWalletBalance(originWallet) {
|
||||||
var balanceText = getWalletBalanceDisplayText(originWallet);
|
var balanceText = getWalletBalanceDisplayText(vm.originWallet);
|
||||||
vm.origin.balanceAmount = balanceText.amount;
|
vm.origin.balanceAmount = balanceText.amount;
|
||||||
vm.origin.balanceCurrency = balanceText.currency;
|
vm.origin.balanceCurrency = balanceText.currency;
|
||||||
}
|
}
|
||||||
|
|
@ -476,6 +474,18 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vm.onSuccessConfirm = function() {
|
||||||
|
vm.sendStatus = '';
|
||||||
|
$ionicHistory.nextViewOptions({
|
||||||
|
disableAnimate: true,
|
||||||
|
historyRoot: true
|
||||||
|
});
|
||||||
|
$state.go('tabs.send').then(function() {
|
||||||
|
$ionicHistory.clearHistory();
|
||||||
|
$state.transitionTo('tabs.home');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
function setButtonText(isMultisig, isPayPro) {
|
function setButtonText(isMultisig, isPayPro) {
|
||||||
if (isPayPro) {
|
if (isPayPro) {
|
||||||
if (vm.isCordova) {
|
if (vm.isCordova) {
|
||||||
|
|
@ -536,12 +546,12 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
|
||||||
vm.showAddress = false;
|
vm.showAddress = false;
|
||||||
|
|
||||||
|
|
||||||
setButtonText(originWallet.credentials.m > 1, !!tx.paypro);
|
setButtonText(vm.originWallet.credentials.m > 1, !!tx.paypro);
|
||||||
|
|
||||||
if (tx.paypro)
|
if (tx.paypro)
|
||||||
_paymentTimeControl(tx.paypro.expires);
|
_paymentTimeControl(tx.paypro.expires);
|
||||||
|
|
||||||
updateTx(tx, originWallet, {
|
updateTx(tx, vm.originWallet, {
|
||||||
dryRun: true
|
dryRun: true
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
$timeout(function() {
|
$timeout(function() {
|
||||||
|
|
@ -562,6 +572,43 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
|
||||||
// }
|
// }
|
||||||
// });
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function statusChangeHandler(processName, showName, isOn) {
|
||||||
|
$log.debug('statusChangeHandler: ', processName, showName, isOn);
|
||||||
|
if (
|
||||||
|
(
|
||||||
|
processName === 'broadcastingTx' ||
|
||||||
|
((processName === 'signingTx') && vm.originWallet.m > 1) ||
|
||||||
|
(processName == 'sendingTx' && !vm.originWallet.canSign() && !vm.originWallet.isPrivKeyExternal())
|
||||||
|
) && !isOn) {
|
||||||
|
$scope.sendStatus = 'success';
|
||||||
|
|
||||||
|
if ($state.current.name === "tabs.send.review") { // XX SP: Otherwise all open wallets on other devices play this sound if you have been in a send flow before on that device.
|
||||||
|
soundService.play('misc/payment_sent.mp3');
|
||||||
|
}
|
||||||
|
|
||||||
|
var channel = "firebase";
|
||||||
|
if (platformInfo.isNW) {
|
||||||
|
channel = "ga";
|
||||||
|
}
|
||||||
|
// When displaying Fiat, if the formatting fails, the crypto will be the primary amount.
|
||||||
|
var amount = priceDisplayIsFiat ? vm.secondaryAmount || vm.primaryAmount : vm.primaryAmount;
|
||||||
|
var log = new window.BitAnalytics.LogEvent("transfer_success", [{
|
||||||
|
"coin": vm.originWallet.coin,
|
||||||
|
"type": "outgoing",
|
||||||
|
"amount": amount,
|
||||||
|
"fees": vm.feeCrypto
|
||||||
|
}], [channel, "adjust"]);
|
||||||
|
window.BitAnalytics.LogEventHandlers.postEvent(log);
|
||||||
|
|
||||||
|
$timeout(function() {
|
||||||
|
$scope.$digest();
|
||||||
|
}, 100);
|
||||||
|
} else if (showName) {
|
||||||
|
$scope.sendStatus = showName;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function updateTx(tx, wallet, opts, cb) {
|
function updateTx(tx, wallet, opts, cb) {
|
||||||
ongoingProcess.set('calculatingFee', true);
|
ongoingProcess.set('calculatingFee', true);
|
||||||
|
|
||||||
|
|
@ -589,8 +636,8 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
|
||||||
// updateAmount();
|
// updateAmount();
|
||||||
// refresh();
|
// refresh();
|
||||||
|
|
||||||
var feeServiceLevel = usingMerchantFee && originWallet.coin == 'btc' ? 'urgent' : tx.feeLevel;
|
var feeServiceLevel = usingMerchantFee && vm.originWallet.coin == 'btc' ? 'urgent' : tx.feeLevel;
|
||||||
feeService.getFeeRate(originWallet.coin, tx.network, feeServiceLevel, function(err, feeRate) {
|
feeService.getFeeRate(vm.originWallet.coin, tx.network, feeServiceLevel, function(err, feeRate) {
|
||||||
if (err) {
|
if (err) {
|
||||||
ongoingProcess.set('calculatingFee', false);
|
ongoingProcess.set('calculatingFee', false);
|
||||||
return cb(err);
|
return cb(err);
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,10 @@
|
||||||
<div class="item-content item-content-avatar">
|
<div class="item-content item-content-avatar">
|
||||||
<i class="icon big-icon-svg theme-circle theme-circle-services">
|
<i class="icon big-icon-svg theme-circle theme-circle-services">
|
||||||
<div class="bg icon-wallet"
|
<div class="bg icon-wallet"
|
||||||
style="background-color: {{vm.origin.color}}"
|
style="background-color: {{vm.originWallet.color}}"
|
||||||
></div>
|
></div>
|
||||||
</i>
|
</i>
|
||||||
<h2>{{vm.origin.name}} <span class="highlight" style="color: {{vm.origin.currencyColor}}">({{vm.origin.currency}})</span></h2>
|
<h2>{{vm.originWallet.name}} <span class="highlight" style="color: {{vm.origin.currencyColor}}">({{vm.origin.currency}})</span></h2>
|
||||||
<p ng-show="vm.origin.balanceAmount">{{vm.origin.balanceAmount}} {{vm.origin.balanceCurrency}}</p>
|
<p ng-show="vm.origin.balanceAmount">{{vm.origin.balanceAmount}} {{vm.origin.balanceCurrency}}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -73,7 +73,7 @@
|
||||||
</ion-content>
|
</ion-content>
|
||||||
|
|
||||||
<div class="fee-summary">
|
<div class="fee-summary">
|
||||||
<div class="fee-fiat" ng-if="vm.feeLessThanACent">Fee: Less than 1 cent</div>
|
<div class="fee-fiat positive" ng-if="vm.feeLessThanACent">Fee: Less than 1 cent</div>
|
||||||
<div class="fee-fiat" ng-class="vm.feeIsHigh ? 'negative' : 'positive'" ng-if="!vm.feeLessThanACent">Fee: {{vm.feeFiat}} {{vm.feeCurrency}}</div>
|
<div class="fee-fiat" ng-class="vm.feeIsHigh ? 'negative' : 'positive'" ng-if="!vm.feeLessThanACent">Fee: {{vm.feeFiat}} {{vm.feeCurrency}}</div>
|
||||||
<div class="fee-crypto" ng-if="vm.feeCrypto">
|
<div class="fee-crypto" ng-if="vm.feeCrypto">
|
||||||
{{vm.feeCrypto}} {{vm.origin.currency}}
|
{{vm.feeCrypto}} {{vm.origin.currency}}
|
||||||
|
|
@ -81,25 +81,25 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<click-to-accept
|
<click-to-accept
|
||||||
ng-click="approve(tx, wallet, statusChangeHandler)"
|
ng-click="vm.approve()"
|
||||||
ng-if="(!vm.isCordova)"
|
ng-if="!vm.isCordova"
|
||||||
click-send-status="sendStatus"
|
click-send-status="vm.sendStatus"
|
||||||
is-disabled="!wallet">
|
is-disabled="!vm.readyToSend">
|
||||||
{{buttonText}}
|
{{vm.buttonText}}
|
||||||
</click-to-accept>
|
</click-to-accept>
|
||||||
<slide-to-accept
|
<slide-to-accept
|
||||||
ng-if="vm.isCordova"
|
ng-if="vm.isCordova"
|
||||||
slide-on-confirm="approve(tx, wallet, statusChangeHandler)"
|
slide-on-confirm="vm.approve()"
|
||||||
slide-send-status="sendStatus"
|
slide-send-status="vm.sendStatus"
|
||||||
is-disabled="!wallet">
|
is-disabled="!vm.readyToSend">
|
||||||
{{buttonText}}
|
{{vm.buttonText}}
|
||||||
</slide-to-accept>
|
</slide-to-accept>
|
||||||
<slide-to-accept-success
|
<slide-to-accept-success
|
||||||
slide-success-show="sendStatus === 'success'"
|
slide-success-show="vm.sendStatus === 'success'"
|
||||||
slide-success-on-confirm="onSuccessConfirm()"
|
slide-success-on-confirm="vm.onSuccessConfirm()"
|
||||||
slide-success-hide-on-confirm="true">
|
slide-success-hide-on-confirm="true">
|
||||||
<span ng-show="wallet.m == 1 && (wallet.canSign() || wallet.isPrivKeyExternal())" translate>Payment Sent</span>
|
<span ng-show="vm.originWallet.m == 1 && (vm.originWallet.canSign() || vm.originWallet.isPrivKeyExternal())" translate>Payment Sent</span>
|
||||||
<span ng-show="wallet.m > 1 && (wallet.canSign() || wallet.isPrivKeyExternal())" translate>Proposal Created</span>
|
<span ng-show="vm.originWallet.m > 1 && (vm.originWallet.canSign() || vm.originWallet.isPrivKeyExternal())" translate>Proposal Created</span>
|
||||||
<span ng-show="!wallet.canSign() && !wallet.isPrivKeyExternal()" translate>Transaction Created</span>
|
<span ng-show="!vm.originWallet.canSign() && !vm.originWallet.isPrivKeyExternal()" translate>Transaction Created</span>
|
||||||
</slide-to-accept-success>
|
</slide-to-accept-success>
|
||||||
</ion-view>
|
</ion-view>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue