Compare commits
No commits in common. "master" and "wallet/release/5.1-rc1" have entirely different histories.
master
...
wallet/rel
21 changed files with 1122 additions and 1324 deletions
14
.vscode/launch.json
vendored
14
.vscode/launch.json
vendored
|
|
@ -1,14 +0,0 @@
|
||||||
{
|
|
||||||
// Use IntelliSense to learn about possible attributes.
|
|
||||||
// Hover to view descriptions of existing attributes.
|
|
||||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
||||||
"version": "0.2.0",
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"type": "node",
|
|
||||||
"request": "launch",
|
|
||||||
"name": "Launch Program",
|
|
||||||
"program": "${workspaceFolder}/www/index.html"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -366,13 +366,13 @@ module.exports = function(grunt) {
|
||||||
grunt.registerTask('build-mobile-release', ['build-ios-release', 'build-android-release']);
|
grunt.registerTask('build-mobile-release', ['build-ios-release', 'build-android-release']);
|
||||||
|
|
||||||
// Build ios
|
// Build ios
|
||||||
grunt.registerTask('start-ios', ['default', 'exec:build_ios_debug', 'exec:xcode']);
|
grunt.registerTask('start-ios', ['exec:build_ios_debug', 'exec:xcode']);
|
||||||
grunt.registerTask('build-ios-debug', ['default', 'exec:build_ios_debug']);
|
grunt.registerTask('build-ios-debug', ['exec:build_ios_debug']);
|
||||||
grunt.registerTask('build-ios-release', ['prod', 'exec:build_ios_release']);
|
grunt.registerTask('build-ios-release', ['prod', 'exec:build_ios_release']);
|
||||||
|
|
||||||
// Build android
|
// Build android
|
||||||
grunt.registerTask('start-android', ['build-android-debug', 'exec:run_android']);
|
grunt.registerTask('start-android', ['build-android-debug', 'exec:run_android']);
|
||||||
grunt.registerTask('build-android-debug', ['default', 'exec:build_android_debug']);
|
grunt.registerTask('build-android-debug', ['exec:build_android_debug']);
|
||||||
grunt.registerTask('start-android-emulator', ['build-android-debug', 'exec:run_android_emulator']);
|
grunt.registerTask('start-android-emulator', ['build-android-debug', 'exec:run_android_emulator']);
|
||||||
grunt.registerTask('build-android-release', ['prod', 'exec:build_android_release', 'sign-android']);
|
grunt.registerTask('build-android-release', ['prod', 'exec:build_android_release', 'sign-android']);
|
||||||
grunt.registerTask('sign-android', ['exec:sign_android']);
|
grunt.registerTask('sign-android', ['exec:sign_android']);
|
||||||
|
|
|
||||||
21
README.md
21
README.md
|
|
@ -1,24 +1,3 @@
|
||||||
This is a fork of the Bitcoin.com wallet to add additional features.
|
|
||||||
Features included:
|
|
||||||
|
|
||||||
- Zero fee transactions (only works for Bitcoin Cash). You will be asked for, if you want to send a transaction as zero fee on the confirmation page.
|
|
||||||
|
|
||||||
## Zero fee transactions:
|
|
||||||
Because most network nodes on the Bitcoin Cash network don't relay zero fee txs, you will experience some strange issues, but don't worry: for me personally the Bitcoin.com pool has included all my zero fee transactions, but please beware that the receiver probably won't see your tx before it has been confirmed and please do also keep in mind, that the transactions coming after it won't confirm or be seen before the zero fee one has been confirmed.
|
|
||||||
|
|
||||||
If you do already have a Bitcoin.com wallet, you need to create a new one to use this feature or change the wallet URL to: https://bws.freepages.dk/bws/api
|
|
||||||
|
|
||||||
## Disclaimer
|
|
||||||
|
|
||||||
Please beware this is my personal experimental project. You are more than welcome to play with it, but I don't take any responsibility of loss of funds due to errors in the code, so please make sure you made a backup before running this software.
|
|
||||||
|
|
||||||
## Builds
|
|
||||||
|
|
||||||
You can build the software yourself using the instructions below or use prebuilt binaries which can be found here (currently Windows and Linux only): https://ipfs.io/ipfs/QmR1DaS3QsDS48SzAWKUWFfmtMfJc4tgMtkSk3JFmuzewe
|
|
||||||
|
|
||||||
##
|
|
||||||
|
|
||||||
|
|
||||||
The Bitcoin.com wallet is a fork of the Copay Wallet (https://github.com/bitpay/copay).
|
The Bitcoin.com wallet is a fork of the Copay Wallet (https://github.com/bitpay/copay).
|
||||||
|
|
||||||
The Bitcoin.com wallet is a secure bitcoin wallet platform for both desktop and mobile devices. It uses [Bitcore Wallet Service](https://github.com/Bitcoin-com/bitcore-wallet-service) (our fork of the [Bitpay Bitcore Wallet Service](https://github.com/bitpay/bitcore-wallet-service)) (BWS) for peer synchronization and network interfacing.
|
The Bitcoin.com wallet is a secure bitcoin wallet platform for both desktop and mobile devices. It uses [Bitcore Wallet Service](https://github.com/Bitcoin-com/bitcore-wallet-service) (our fork of the [Bitpay Bitcore Wallet Service](https://github.com/bitpay/bitcore-wallet-service)) (BWS) for peer synchronization and network interfacing.
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,9 @@
|
||||||
"windowsAppId": "804636ee-b017-4cad-8719-e58ac97ffa5c",
|
"windowsAppId": "804636ee-b017-4cad-8719-e58ac97ffa5c",
|
||||||
"pushSenderId": "1036948132229",
|
"pushSenderId": "1036948132229",
|
||||||
"description": "A Secure Bitcoin Wallet",
|
"description": "A Secure Bitcoin Wallet",
|
||||||
"version": "5.1.3",
|
"version": "5.1.2",
|
||||||
"fullVersion": "5.1-rc2",
|
"fullVersion": "5.1-rc1",
|
||||||
"androidVersion": "501003",
|
"androidVersion": "501002",
|
||||||
"_extraCSS": "",
|
"_extraCSS": "",
|
||||||
"_enabledExtensions": {
|
"_enabledExtensions": {
|
||||||
"coinbase": false,
|
"coinbase": false,
|
||||||
|
|
|
||||||
|
|
@ -517,8 +517,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
|
||||||
if (!lodash.isEmpty(warningMsg))
|
if (!lodash.isEmpty(warningMsg))
|
||||||
msg += '\n' + warningMsg;
|
msg += '\n' + warningMsg;
|
||||||
|
|
||||||
popupService.showAlert(null, msg, function() {});
|
popupService.showAlert(null, msg, function() {});
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.onWalletSelect = function(wallet) {
|
$scope.onWalletSelect = function(wallet) {
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('copayApp.controllers').controller('servicesController', function(externalLinkService, $scope, $ionicScrollDelegate, $timeout, servicesService, configService) {
|
angular.module('copayApp.controllers').controller('servicesController', function($scope, $ionicScrollDelegate, $timeout, servicesService, configService) {
|
||||||
$scope.hide = false;
|
$scope.hide = false;
|
||||||
|
|
||||||
configService.whenAvailable(function(config) {
|
configService.whenAvailable(function(config) {
|
||||||
|
|
@ -20,8 +20,4 @@ angular.module('copayApp.controllers').controller('servicesController', function
|
||||||
}, 10);
|
}, 10);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.open = function(url) {
|
|
||||||
externalLinkService.open(url, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ angular.module('copayApp.controllers').controller('shapeshiftController', functi
|
||||||
walletsBtc = profileService.getWallets({coin: 'btc'});
|
walletsBtc = profileService.getWallets({coin: 'btc'});
|
||||||
walletsBch = profileService.getWallets({coin: 'bch'});
|
walletsBch = profileService.getWallets({coin: 'bch'});
|
||||||
$scope.fromWallets = lodash.filter(walletsBtc.concat(walletsBch), function(w) {
|
$scope.fromWallets = lodash.filter(walletsBtc.concat(walletsBch), function(w) {
|
||||||
return (w.status && w.status.balance && w.status.balance.availableAmount > 0);
|
return w.status.balance.availableAmount > 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.singleFromWallet = $scope.fromWallets.length === 1;
|
$scope.singleFromWallet = $scope.fromWallets.length === 1;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
angular.module('copayApp.controllers').controller('tabReceiveController', function($rootScope, $scope, $timeout, $log, $ionicModal, $state, $ionicHistory, $ionicPopover, storageService, platformInfo, walletService, profileService, configService, lodash, gettextCatalog, popupService, bwcError, bitcoinCashJsService, $ionicNavBarDelegate, sendFlowService, txFormatService, soundService, clipboardService) {
|
angular.module('copayApp.controllers').controller('tabReceiveController', function($rootScope, $scope, $timeout, $log, $ionicModal, $state, $ionicHistory, $ionicPopover, storageService, platformInfo, walletService, profileService, configService, lodash, gettextCatalog, popupService, bwcError, bitcoinCashJsService, $ionicNavBarDelegate, sendFlowService, txFormatService, soundService, clipboardService) {
|
||||||
|
|
||||||
var CLOSE_NORMAL = 1000;
|
|
||||||
var listeners = [];
|
var listeners = [];
|
||||||
$scope.bchAddressType = { type: 'cashaddr' };
|
$scope.bchAddressType = { type: 'cashaddr' };
|
||||||
var bchAddresses = {};
|
var bchAddresses = {};
|
||||||
|
|
@ -11,11 +10,12 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
|
||||||
$scope.isCordova = platformInfo.isCordova;
|
$scope.isCordova = platformInfo.isCordova;
|
||||||
$scope.isNW = platformInfo.isNW;
|
$scope.isNW = platformInfo.isNW;
|
||||||
|
|
||||||
var currentAddressSocket = null;
|
var currentAddressSocket = {};
|
||||||
var paymentSubscriptionObj = { op:'addr_sub' };
|
var paymentSubscriptionObj = { op:"addr_sub" }
|
||||||
|
|
||||||
|
var config;
|
||||||
|
|
||||||
$scope.displayBalanceAsFiat = true;
|
$scope.displayBalanceAsFiat = true;
|
||||||
$scope.$on('$ionicView.beforeLeave', onBeforeLeave);
|
|
||||||
|
|
||||||
$scope.requestSpecificAmount = function() {
|
$scope.requestSpecificAmount = function() {
|
||||||
sendFlowService.start({
|
sendFlowService.start({
|
||||||
|
|
@ -24,50 +24,6 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function connectSocket() {
|
|
||||||
// Close existing socket if not connected with current address
|
|
||||||
if (currentAddressSocket) {
|
|
||||||
currentAddressSocket.close([CLOSE_NORMAL]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($scope.wallet.coin === 'bch') {
|
|
||||||
// listen to bch address
|
|
||||||
currentAddressSocket = new WebSocket('wss://ws.blockchain.info/bch/inv');
|
|
||||||
paymentSubscriptionObj.addr = $scope.addrBchLegacy;
|
|
||||||
} else {
|
|
||||||
// listen to btc address
|
|
||||||
currentAddressSocket = new WebSocket('wss://ws.blockchain.info/inv');
|
|
||||||
paymentSubscriptionObj.addr = $scope.addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create subscription to address
|
|
||||||
var msg = JSON.stringify(paymentSubscriptionObj);
|
|
||||||
currentAddressSocket.onopen = function (event) {
|
|
||||||
currentAddressSocket.send(msg);
|
|
||||||
};
|
|
||||||
|
|
||||||
// listen for response
|
|
||||||
currentAddressSocket.onmessage = function (event) {
|
|
||||||
//console.log("message received:" + event.data);
|
|
||||||
receivedPayment(event.data);
|
|
||||||
};
|
|
||||||
|
|
||||||
currentAddressSocket.onclose = function(event) {
|
|
||||||
if (event.code !== CLOSE_NORMAL) {
|
|
||||||
$log.debug('Socket was closed abnormally. Reconnect will be attempted in 1 second.');
|
|
||||||
$timeout(function() {
|
|
||||||
connectSocket();
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
currentAddressSocket.onerror = function(err) {
|
|
||||||
console.error('Socket encountered error: ', err, 'Closing socket');
|
|
||||||
currentAddressSocket.close();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.setAddress = function(newAddr, copyAddress) {
|
$scope.setAddress = function(newAddr, copyAddress) {
|
||||||
$scope.addr = null;
|
$scope.addr = null;
|
||||||
if (!$scope.wallet || $scope.generatingAddress || !$scope.wallet.isComplete()) return;
|
if (!$scope.wallet || $scope.generatingAddress || !$scope.wallet.isComplete()) return;
|
||||||
|
|
@ -80,24 +36,49 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
|
||||||
popupService.showAlert(err);
|
popupService.showAlert(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($scope.wallet.coin === 'bch') {
|
//close existing socket
|
||||||
bchAddresses = bitcoinCashJsService.translateAddresses(addr);
|
if (currentAddressSocket.close === 'function') {
|
||||||
$scope.addr = bchAddresses[$scope.bchAddressType.type];
|
currentAddressSocket.close();
|
||||||
$scope.addrBchLegacy = bchAddresses['legacy'];
|
|
||||||
} else {
|
|
||||||
$scope.addr = addr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
connectSocket();
|
if ($scope.wallet.coin == 'bch') {
|
||||||
|
bchAddresses = bitcoinCashJsService.translateAddresses(addr);
|
||||||
|
$scope.addr = bchAddresses[$scope.bchAddressType.type];
|
||||||
|
$scope.addrBchLegacy = bchAddresses['legacy'];
|
||||||
|
|
||||||
|
// listen to bch address
|
||||||
|
currentAddressSocket = new WebSocket("wss://ws.blockchain.info/bch/inv");
|
||||||
|
paymentSubscriptionObj.addr = bchAddresses['legacy'];
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$scope.addr = addr;
|
||||||
|
|
||||||
|
// listen to btc address
|
||||||
|
currentAddressSocket = new WebSocket("wss://ws.blockchain.info/inv");
|
||||||
|
paymentSubscriptionObj.addr = $scope.addr
|
||||||
|
}
|
||||||
|
|
||||||
if (copyAddress === true) {
|
if (copyAddress === true) {
|
||||||
try {
|
try {
|
||||||
clipboardService.copyToClipboard($scope.wallet.coin == 'bch' && $scope.bchAddressType.type == 'cashaddr' ? 'bitcoincash:' + $scope.addr : $scope.addr);
|
clipboardService.copyToClipboard($scope.wallet.coin == 'bch' && $scope.bchAddressType.type == 'cashaddr' ? 'bitcoincash:' + $scope.addr : $scope.addr);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
$log.debug('Error copying to clipboard:');
|
$log.debug("Error copying to clipboard:");
|
||||||
$log.debug(error);
|
$log.debug(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// create subscription
|
||||||
|
var msg = JSON.stringify(paymentSubscriptionObj);
|
||||||
|
currentAddressSocket.onopen = function (event) {
|
||||||
|
//console.log("message sent: " + msg);
|
||||||
|
currentAddressSocket.send(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// listen for response
|
||||||
|
currentAddressSocket.onmessage = function (event) {
|
||||||
|
//console.log("message received:" + event.data);
|
||||||
|
receivedPayment(event.data);
|
||||||
|
}
|
||||||
|
|
||||||
$timeout(function() {
|
$timeout(function() {
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
|
|
@ -183,6 +164,7 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
|
||||||
// Notify new tx
|
// Notify new tx
|
||||||
$scope.$emit('bwsEvent', $scope.wallet.id);
|
$scope.$emit('bwsEvent', $scope.wallet.id);
|
||||||
|
|
||||||
|
|
||||||
$scope.$apply(function () {
|
$scope.$apply(function () {
|
||||||
$scope.showingPaymentReceived = true;
|
$scope.showingPaymentReceived = true;
|
||||||
});
|
});
|
||||||
|
|
@ -251,10 +233,6 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function onBeforeLeave() {
|
|
||||||
currentAddressSocket.close([CLOSE_NORMAL]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.$on("$ionicView.beforeEnter", function(event, data) {
|
$scope.$on("$ionicView.beforeEnter", function(event, data) {
|
||||||
$scope.wallets = profileService.getWallets();
|
$scope.wallets = profileService.getWallets();
|
||||||
$scope.singleWallet = $scope.wallets.length == 1;
|
$scope.singleWallet = $scope.wallets.length == 1;
|
||||||
|
|
@ -280,6 +258,7 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
|
||||||
|
|
||||||
configService.whenAvailable(function(_config) {
|
configService.whenAvailable(function(_config) {
|
||||||
$scope.displayBalanceAsFiat = _config.wallet.settings.priceDisplay === 'fiat';
|
$scope.displayBalanceAsFiat = _config.wallet.settings.priceDisplay === 'fiat';
|
||||||
|
config = _config;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -203,7 +203,6 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
|
||||||
|
|
||||||
|
|
||||||
function updateTxHistoryFromCachedData() {
|
function updateTxHistoryFromCachedData() {
|
||||||
$scope.vm.gettingCachedHistory = true;
|
|
||||||
walletHistoryService.getCachedTxHistory($scope.wallet.id, function onGetCachedTxHistory(err, txHistory){
|
walletHistoryService.getCachedTxHistory($scope.wallet.id, function onGetCachedTxHistory(err, txHistory){
|
||||||
$scope.vm.gettingCachedHistory = false;
|
$scope.vm.gettingCachedHistory = false;
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|
@ -401,9 +400,8 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
|
||||||
|
|
||||||
var refreshInterval;
|
var refreshInterval;
|
||||||
|
|
||||||
$scope.$on("$ionicView.afterEnter", function onAfterEnter(event, data) {
|
$scope.$on("$ionicView.afterEnter", function(event, data) {
|
||||||
updateTxHistoryFromCachedData();
|
$scope.updateAll();
|
||||||
$scope.updateAll(true, true);
|
|
||||||
// refreshAmountSection();
|
// refreshAmountSection();
|
||||||
refreshInterval = $interval($scope.onRefresh, 10 * 1000);
|
refreshInterval = $interval($scope.onRefresh, 10 * 1000);
|
||||||
$timeout(function() {
|
$timeout(function() {
|
||||||
|
|
|
||||||
|
|
@ -1,204 +1,189 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
(function () {
|
angular.module('copayApp.controllers').controller('walletSelectorController', function($scope, $state, sendFlowService, configService, gettextCatalog, profileService, txFormatService) {
|
||||||
|
|
||||||
angular
|
var fromWalletId = '';
|
||||||
.module('copayApp.controllers')
|
var priceDisplayAsFiat = false;
|
||||||
.controller('walletSelectorController', walletSelectorController);
|
var unitDecimals = 0;
|
||||||
|
var unitsFromSatoshis = 0;
|
||||||
|
|
||||||
function walletSelectorController ($scope, $state, sendFlowService, configService, gettextCatalog, ongoingProcess, profileService, walletService, txFormatService) {
|
$scope.$on("$ionicView.beforeEnter", onBeforeEnter);
|
||||||
var fromWalletId = '';
|
$scope.$on("$ionicView.enter", onEnter);
|
||||||
var priceDisplayAsFiat = false;
|
|
||||||
var unitDecimals = 0;
|
function onBeforeEnter(event, data) {
|
||||||
var unitsFromSatoshis = 0;
|
if (data.direction == "back") {
|
||||||
|
sendFlowService.state.pop();
|
||||||
$scope.$on("$ionicView.beforeEnter", onBeforeEnter);
|
|
||||||
$scope.$on("$ionicView.enter", onEnter);
|
|
||||||
|
|
||||||
function onBeforeEnter(event, data) {
|
|
||||||
if (data.direction == "back") {
|
|
||||||
sendFlowService.state.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.params = sendFlowService.state.getClone();
|
|
||||||
|
|
||||||
console.log('walletSelector onBeforeEnter after back sendflow', $scope.params);
|
|
||||||
|
|
||||||
var config = configService.getSync().wallet.settings;
|
|
||||||
priceDisplayAsFiat = config.priceDisplay === 'fiat';
|
|
||||||
unitDecimals = config.unitDecimals;
|
|
||||||
unitsFromSatoshis = 1 / config.unitToSatoshi;
|
|
||||||
|
|
||||||
if ($scope.params.isWalletTransfer) {
|
|
||||||
$scope.sendFlowTitle = gettextCatalog.getString('Transfer between wallets');
|
|
||||||
} else if (!$scope.params.thirdParty) {
|
|
||||||
$scope.sendFlowTitle = gettextCatalog.getString('Send');
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.coin = false; // Wallets to show (for destination screen or contacts)
|
|
||||||
$scope.type = $scope.params['fromWalletId'] ? 'destination' : 'origin'; // origin || destination
|
|
||||||
fromWalletId = $scope.params['fromWalletId'];
|
|
||||||
|
|
||||||
if ($scope.type === 'destination' && $scope.params.toAddress) {
|
|
||||||
$state.transitionTo(getNextStep($scope.params));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($scope.params.coin) {
|
|
||||||
$scope.coin = $scope.params.coin; // Contacts have a coin embedded
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($scope.params.amount) { // There is an amount, so presume that it is a payment request
|
|
||||||
$scope.sendFlowTitle = gettextCatalog.getString('Payment Request');
|
|
||||||
$scope.specificAmount = $scope.specificAlternativeAmount = '';
|
|
||||||
$scope.isPaymentRequest = true;
|
|
||||||
}
|
|
||||||
if ($scope.params.thirdParty) {
|
|
||||||
$scope.thirdParty = $scope.params.thirdParty;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function onEnter (event, data) {
|
|
||||||
configService.whenAvailable(function(config) {
|
|
||||||
$scope.selectedPriceDisplay = config.wallet.settings.priceDisplay;
|
|
||||||
});
|
|
||||||
|
|
||||||
if ($scope.thirdParty) {
|
|
||||||
// Third party services specific logic
|
|
||||||
handleThirdPartyIfShapeshift();
|
|
||||||
}
|
|
||||||
|
|
||||||
prepareWalletLists();
|
|
||||||
formatRequestedAmount();
|
|
||||||
};
|
|
||||||
|
|
||||||
function formatRequestedAmount() {
|
|
||||||
if ($scope.params.amount) {
|
|
||||||
var cryptoAmount = (unitsFromSatoshis * $scope.params.amount).toFixed(unitDecimals);
|
|
||||||
var cryptoCoin = $scope.coin.toUpperCase();
|
|
||||||
|
|
||||||
txFormatService.formatAlternativeStr($scope.coin, $scope.params.amount, function onFormatAlternativeStr(formatted){
|
|
||||||
if (formatted) {
|
|
||||||
var fiatParts = formatted.split(' ');
|
|
||||||
var fiatAmount = fiatParts[0];
|
|
||||||
var fiatCurrrency = fiatParts.length > 1 ? fiatParts[1] : '';
|
|
||||||
|
|
||||||
if (priceDisplayAsFiat) {
|
|
||||||
$scope.requestAmount = fiatAmount;
|
|
||||||
$scope.requestCurrency = fiatCurrrency;
|
|
||||||
|
|
||||||
$scope.requestAmountSecondary = cryptoAmount;
|
|
||||||
$scope.requestCurrencySecondary = cryptoCoin;
|
|
||||||
} else {
|
|
||||||
$scope.requestAmount = cryptoAmount;
|
|
||||||
$scope.requestCurrency = cryptoCoin;
|
|
||||||
|
|
||||||
$scope.requestAmountSecondary = fiatAmount;
|
|
||||||
$scope.requestCurrencySecondary = fiatCurrrency;
|
|
||||||
}
|
|
||||||
$scope.$apply();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleThirdPartyIfShapeshift() {
|
$scope.params = sendFlowService.state.getClone();
|
||||||
console.log($scope.thirdParty, $scope.coin);
|
|
||||||
if ($scope.thirdParty.id === 'shapeshift' && $scope.type === 'destination') { // Shapeshift wants to know the
|
console.log('walletSelector onBeforeEnter after back sendflow', $scope.params);
|
||||||
$scope.coin = profileService.getWallet(fromWalletId).coin;
|
|
||||||
if ($scope.coin === 'bch') {
|
var config = configService.getSync().wallet.settings;
|
||||||
$scope.coin = 'btc';
|
priceDisplayAsFiat = config.priceDisplay === 'fiat';
|
||||||
} else {
|
unitDecimals = config.unitDecimals;
|
||||||
$scope.coin = 'bch';
|
unitsFromSatoshis = 1 / config.unitToSatoshi;
|
||||||
}
|
|
||||||
}
|
if ($scope.params.isWalletTransfer) {
|
||||||
|
$scope.sendFlowTitle = gettextCatalog.getString('Transfer between wallets');
|
||||||
|
} else if (!$scope.params.thirdParty) {
|
||||||
|
$scope.sendFlowTitle = gettextCatalog.getString('Send');
|
||||||
}
|
}
|
||||||
|
|
||||||
function prepareWalletLists() {
|
$scope.coin = false; // Wallets to show (for destination screen or contacts)
|
||||||
var walletsAll = [];
|
$scope.type = $scope.params['fromWalletId'] ? 'destination' : 'origin'; // origin || destination
|
||||||
var walletsSufficientFunds = [];
|
fromWalletId = $scope.params['fromWalletId'];
|
||||||
$scope.walletsInsufficientFunds = []; // For origin screen
|
|
||||||
|
|
||||||
if ($scope.type === 'origin') {
|
if ($scope.type === 'destination' && $scope.params.toAddress) {
|
||||||
$scope.headerTitle = gettextCatalog.getString('Choose a wallet to send from');
|
$state.transitionTo(getNextStep($scope.params));
|
||||||
|
}
|
||||||
|
|
||||||
if ($scope.params.amount || $scope.coin) {
|
if ($scope.params.coin) {
|
||||||
|
$scope.coin = $scope.params.coin; // Contacts have a coin embedded
|
||||||
|
}
|
||||||
|
|
||||||
walletsAll = profileService.getWallets({coin: $scope.coin});
|
if ($scope.params.amount) { // There is an amount, so presume that it is a payment request
|
||||||
ongoingProcess.set('scanning', true);
|
$scope.sendFlowTitle = gettextCatalog.getString('Payment Request');
|
||||||
walletsAll.forEach(function forWallet(wallet) {
|
$scope.specificAmount = $scope.specificAlternativeAmount = '';
|
||||||
if (!wallet.status && !wallet.cachedStatus) {
|
$scope.isPaymentRequest = true;
|
||||||
walletService.getStatus(wallet, {}, function(err, status) {
|
}
|
||||||
wallet.status = status;
|
if ($scope.params.thirdParty) {
|
||||||
if (status.availableBalanceSat > ($scope.params.amount ? $scope.params.amount : 0)) {
|
$scope.thirdParty = $scope.params.thirdParty;
|
||||||
walletsSufficientFunds.push(wallet);
|
}
|
||||||
} else {
|
};
|
||||||
$scope.walletsInsufficientFunds.push(wallet);
|
|
||||||
}
|
|
||||||
if ($scope.coin === 'btc') { // As this is a promise
|
|
||||||
$scope.walletsBtc = walletsSufficientFunds;
|
|
||||||
} else {
|
|
||||||
$scope.walletsBch = walletsSufficientFunds;
|
|
||||||
}
|
|
||||||
ongoingProcess.set('scanning', false);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
var walletStatus = null;
|
|
||||||
if (wallet.status && wallet.status.isValid) {
|
|
||||||
walletStatus = wallet.status;
|
|
||||||
} else if (wallet.cachedStatus && wallet.status.isValid) {
|
|
||||||
walletStatus = wallet.cachedStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (walletStatus && walletStatus.availableBalanceSat > ($scope.params.amount ? $scope.params.amount : 0)) {
|
function onEnter (event, data) {
|
||||||
walletsSufficientFunds.push(wallet);
|
configService.whenAvailable(function(config) {
|
||||||
} else {
|
$scope.selectedPriceDisplay = config.wallet.settings.priceDisplay;
|
||||||
$scope.walletsInsufficientFunds.push(wallet);
|
});
|
||||||
}
|
|
||||||
ongoingProcess.set('scanning', false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if ($scope.coin === 'btc') {
|
if ($scope.thirdParty) {
|
||||||
$scope.walletsBtc = walletsSufficientFunds;
|
// Third party services specific logic
|
||||||
|
handleThirdPartyIfShapeshift();
|
||||||
|
}
|
||||||
|
|
||||||
|
prepareWalletLists();
|
||||||
|
formatRequestedAmount();
|
||||||
|
};
|
||||||
|
|
||||||
|
function formatRequestedAmount() {
|
||||||
|
if ($scope.params.amount) {
|
||||||
|
var cryptoAmount = (unitsFromSatoshis * $scope.params.amount).toFixed(unitDecimals);
|
||||||
|
var cryptoCoin = $scope.coin.toUpperCase();
|
||||||
|
|
||||||
|
txFormatService.formatAlternativeStr($scope.coin, $scope.params.amount, function onFormatAlternativeStr(formatted){
|
||||||
|
if (formatted) {
|
||||||
|
var fiatParts = formatted.split(' ');
|
||||||
|
var fiatAmount = fiatParts[0];
|
||||||
|
var fiatCurrrency = fiatParts.length > 1 ? fiatParts[1] : '';
|
||||||
|
|
||||||
|
if (priceDisplayAsFiat) {
|
||||||
|
$scope.requestAmount = fiatAmount;
|
||||||
|
$scope.requestCurrency = fiatCurrrency;
|
||||||
|
|
||||||
|
$scope.requestAmountSecondary = cryptoAmount;
|
||||||
|
$scope.requestCurrencySecondary = cryptoCoin;
|
||||||
} else {
|
} else {
|
||||||
$scope.walletsBch = walletsSufficientFunds;
|
$scope.requestAmount = cryptoAmount;
|
||||||
|
$scope.requestCurrency = cryptoCoin;
|
||||||
|
|
||||||
|
$scope.requestAmountSecondary = fiatAmount;
|
||||||
|
$scope.requestCurrencySecondary = fiatCurrrency;
|
||||||
}
|
}
|
||||||
} else {
|
$scope.$apply();
|
||||||
$scope.walletsBch = profileService.getWallets({coin: 'bch', hasFunds: true});
|
|
||||||
$scope.walletsBtc = profileService.getWallets({coin: 'btc', hasFunds: true});
|
|
||||||
$scope.walletsInsufficientFunds = profileService.getWallets({coin: $scope.coin, hasNoFunds: true});
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
} else if ($scope.type === 'destination') {
|
|
||||||
if (!$scope.coin) { // Allow for the coin to be set by a third party
|
|
||||||
$scope.fromWallet = profileService.getWallet(fromWalletId);
|
|
||||||
$scope.coin = $scope.fromWallet.coin; // Only show wallets with the select origin wallet coin
|
|
||||||
}
|
|
||||||
$scope.headerTitle = gettextCatalog.getString('Choose a wallet to send to');
|
|
||||||
|
|
||||||
if ($scope.coin === 'btc') { // if no specific coin is set or coin is set btc
|
|
||||||
$scope.walletsBtc = profileService.getWallets({coin: $scope.coin});
|
|
||||||
} else {
|
|
||||||
$scope.walletsBch = profileService.getWallets({coin: $scope.coin});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$scope.useWallet = function(wallet) {
|
|
||||||
var params = sendFlowService.state.getClone();
|
|
||||||
if ($scope.type === 'origin') { // we're on the origin screen, set wallet to send from
|
|
||||||
params.fromWalletId = wallet.id;
|
|
||||||
} else { // we're on the destination screen, set wallet to send to
|
|
||||||
params.toWalletId = wallet.id;
|
|
||||||
}
|
|
||||||
sendFlowService.goNext(params);
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.goBack = function() {
|
|
||||||
sendFlowService.router.goBack();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
})();
|
|
||||||
|
function handleThirdPartyIfShapeshift() {
|
||||||
|
console.log($scope.thirdParty, $scope.coin);
|
||||||
|
if ($scope.thirdParty.id === 'shapeshift' && $scope.type === 'destination') { // Shapeshift wants to know the
|
||||||
|
$scope.coin = profileService.getWallet(fromWalletId).coin;
|
||||||
|
if ($scope.coin === 'bch') {
|
||||||
|
$scope.coin = 'btc';
|
||||||
|
} else {
|
||||||
|
$scope.coin = 'bch';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function prepareWalletLists() {
|
||||||
|
var walletsAll = [];
|
||||||
|
var walletsSufficientFunds = [];
|
||||||
|
$scope.walletsInsufficientFunds = []; // For origin screen
|
||||||
|
|
||||||
|
if ($scope.type === 'origin') {
|
||||||
|
$scope.headerTitle = gettextCatalog.getString('Choose a wallet to send from');
|
||||||
|
|
||||||
|
if ($scope.params.amount) {
|
||||||
|
|
||||||
|
walletsAll = profileService.getWallets({coin: $scope.coin});
|
||||||
|
|
||||||
|
walletsAll.forEach(function forWallet(wallet){
|
||||||
|
if (wallet.status.availableBalanceSat > $scope.params.amount) {
|
||||||
|
walletsSufficientFunds.push(wallet);
|
||||||
|
} else {
|
||||||
|
$scope.walletsInsufficientFunds.push(wallet);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($scope.coin === 'btc') {
|
||||||
|
$scope.walletsBtc = walletsSufficientFunds;
|
||||||
|
} else {
|
||||||
|
$scope.walletsBch = walletsSufficientFunds;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if ($scope.coin) {
|
||||||
|
walletsAll = profileService.getWallets({coin: $scope.coin});
|
||||||
|
walletsAll.forEach(function forWallet(wallet){
|
||||||
|
if (wallet.status.availableBalanceSat > 0) {
|
||||||
|
walletsSufficientFunds.push(wallet);
|
||||||
|
} else {
|
||||||
|
$scope.walletsInsufficientFunds.push(wallet);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($scope.coin === 'btc') {
|
||||||
|
$scope.walletsBtc = walletsSufficientFunds;
|
||||||
|
} else {
|
||||||
|
$scope.walletsBch = walletsSufficientFunds;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$scope.walletsBch = profileService.getWallets({coin: 'bch', hasFunds: true});
|
||||||
|
$scope.walletsBtc = profileService.getWallets({coin: 'btc', hasFunds: true});
|
||||||
|
$scope.walletsInsufficientFunds = profileService.getWallets({coin: $scope.coin, hasNoFunds: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if ($scope.type === 'destination') {
|
||||||
|
if (!$scope.coin) { // Allow for the coin to be set by a third party
|
||||||
|
$scope.fromWallet = profileService.getWallet(fromWalletId);
|
||||||
|
$scope.coin = $scope.fromWallet.coin; // Only show wallets with the select origin wallet coin
|
||||||
|
}
|
||||||
|
$scope.headerTitle = gettextCatalog.getString('Choose a wallet to send to');
|
||||||
|
|
||||||
|
if ($scope.coin === 'btc') { // if no specific coin is set or coin is set btc
|
||||||
|
$scope.walletsBtc = profileService.getWallets({coin: $scope.coin});
|
||||||
|
} else {
|
||||||
|
$scope.walletsBch = profileService.getWallets({coin: $scope.coin});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$scope.useWallet = function(wallet) {
|
||||||
|
var params = sendFlowService.state.getClone();
|
||||||
|
if ($scope.type === 'origin') { // we're on the origin screen, set wallet to send from
|
||||||
|
params.fromWalletId = wallet.id;
|
||||||
|
} else { // we're on the destination screen, set wallet to send to
|
||||||
|
params.toWalletId = wallet.id;
|
||||||
|
}
|
||||||
|
sendFlowService.goNext(params);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.goBack = function() {
|
||||||
|
sendFlowService.router.goBack();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
@ -12,7 +12,6 @@
|
||||||
totalBalanceSat: '@',
|
totalBalanceSat: '@',
|
||||||
// The Wallet object is sometimes not stringify()-able, so not interpolatable,
|
// The Wallet object is sometimes not stringify()-able, so not interpolatable,
|
||||||
// so can't be passed to a directive.
|
// so can't be passed to a directive.
|
||||||
walletCoin: '@',
|
|
||||||
walletStatus: '@',
|
walletStatus: '@',
|
||||||
walletCachedBalance: '@',
|
walletCachedBalance: '@',
|
||||||
walletCachedBalanceUpdatedOn: '@',
|
walletCachedBalanceUpdatedOn: '@',
|
||||||
|
|
@ -32,6 +31,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
function displayCryptoBalance(walletStatus, walletCachedBalance, walletCachedBalanceUpdatedOn, walletCachedStatus) {
|
function displayCryptoBalance(walletStatus, walletCachedBalance, walletCachedBalanceUpdatedOn, walletCachedStatus) {
|
||||||
|
console.log('displayCryptoBalance()');
|
||||||
|
|
||||||
if (walletStatus && walletStatus.isValid && walletStatus.totalBalanceStr) {
|
if (walletStatus && walletStatus.isValid && walletStatus.totalBalanceStr) {
|
||||||
setDisplay(walletStatus.totalBalanceStr, '');
|
setDisplay(walletStatus.totalBalanceStr, '');
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
setDisplay('', '');
|
setDisplay('', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayFiatBalance(walletStatus, walletCachedStatus, walletCoin) {
|
function displayFiatBalance(walletStatus, walletCachedStatus) {
|
||||||
var displayAmount = '';
|
var displayAmount = '';
|
||||||
if (walletStatus && walletStatus.isValid && walletStatus.alternativeBalanceAvailable) {
|
if (walletStatus && walletStatus.isValid && walletStatus.alternativeBalanceAvailable) {
|
||||||
displayAmount = walletStatus.totalBalanceAlternative + ' ' + walletStatus.alternativeIsoCode;
|
displayAmount = walletStatus.totalBalanceAlternative + ' ' + walletStatus.alternativeIsoCode;
|
||||||
|
|
@ -66,7 +66,7 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
getFiatBalance(walletStatus, walletCachedStatus, walletCoin);
|
getFiatBalance(wallet);
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatBalance() {
|
function formatBalance() {
|
||||||
|
|
@ -94,30 +94,19 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (displayAsFiat) {
|
if (displayAsFiat) {
|
||||||
displayFiatBalance(walletStatusObj, walletCachedStatusObj, $scope.walletCoin);
|
displayFiatBalance(walletStatusObj, walletCachedStatusObj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFiatBalance(walletStatus, walletCachedStatus, walletCoin) {
|
function getFiatBalance(wallet) {
|
||||||
var totalBalanceSat = null;
|
if (!(wallet.status && wallet.status.isValid)) {
|
||||||
|
$log.warn('Abandoning call to get fiat balance, because no valid wallet status.');
|
||||||
if (walletStatus && walletStatus.isValid) {
|
|
||||||
totalBalanceSat = walletStatus.totalBalanceSat
|
|
||||||
} else if (walletCachedStatus && walletCachedStatus.isValid) {
|
|
||||||
totalBalanceSat = walletCachedStatus.totalBalanceSat
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0 is valid
|
|
||||||
if (totalBalanceSat === null) {
|
|
||||||
$log.warn('Abandoning call to get fiat balance, because no valid wallet status (cached or otherwise).');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
txFormatService.formatAlternativeStr(walletCoin, totalBalanceSat, function onFormatAlernativeStr(formatted) {
|
txFormatService.formatAlternativeStr(wallet.coin, wallet.status.totalBalanceSat, function onFormatAlernativeStr(formatted) {
|
||||||
if (formatted) {
|
if (formatted) {
|
||||||
setDisplay(formatted, '');
|
setDisplay(formatted, '');
|
||||||
} else {
|
|
||||||
$log.error('Failed to format fiat balance of wallet.');
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -18,7 +18,7 @@ angular.module('copayApp.services').factory('configService', function(storageSer
|
||||||
},
|
},
|
||||||
|
|
||||||
bwscash: {
|
bwscash: {
|
||||||
url: 'https://bws.freepages.dk/bws/api'
|
url: 'https://bwscash.bitcoin.com/bws/api'
|
||||||
},
|
},
|
||||||
|
|
||||||
download: {
|
download: {
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ angular.module('copayApp.services').factory('feeService', function($log, $timeou
|
||||||
normal: gettext('Normal'),
|
normal: gettext('Normal'),
|
||||||
economy: gettext('Economy'),
|
economy: gettext('Economy'),
|
||||||
superEconomy: gettext('Super Economy'),
|
superEconomy: gettext('Super Economy'),
|
||||||
// free: gettext('No fee (works only for BCH)'),
|
|
||||||
custom: gettext('Custom')
|
custom: gettext('Custom')
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -32,7 +31,6 @@ angular.module('copayApp.services').factory('feeService', function($log, $timeou
|
||||||
root.getFeeRate = function(coin, network, feeLevel, cb) {
|
root.getFeeRate = function(coin, network, feeLevel, cb) {
|
||||||
|
|
||||||
if (feeLevel == 'custom') return cb();
|
if (feeLevel == 'custom') return cb();
|
||||||
// if (feeLevel == 'free') return cb(null, 0);
|
|
||||||
|
|
||||||
network = network || 'livenet';
|
network = network || 'livenet';
|
||||||
|
|
||||||
|
|
@ -50,8 +48,8 @@ angular.module('copayApp.services').factory('feeService', function($log, $timeou
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
var feeRate = feeLevelRate.feePerKb;
|
|
||||||
|
|
||||||
|
var feeRate = feeLevelRate.feePerKb;
|
||||||
|
|
||||||
if (!fromCache) $log.debug('Dynamic fee: ' + feeLevel + '/' + network + ' ' + (feeLevelRate.feePerKb / 1000).toFixed() + ' SAT/B');
|
if (!fromCache) $log.debug('Dynamic fee: ' + feeLevel + '/' + network + ' ' + (feeLevelRate.feePerKb / 1000).toFixed() + ' SAT/B');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,8 +74,10 @@ angular.module('copayApp.services').factory('ongoingProcess', function($log, $ti
|
||||||
root.onGoingProcessName = name;
|
root.onGoingProcessName = name;
|
||||||
|
|
||||||
var showName = $filter('translate')(processNames[name] || name);
|
var showName = $filter('translate')(processNames[name] || name);
|
||||||
|
|
||||||
if (root.onGoingProcessName) {
|
if (customHandler) {
|
||||||
|
customHandler(processName, showName, isOn);
|
||||||
|
} else if (root.onGoingProcessName) {
|
||||||
var tmpl;
|
var tmpl;
|
||||||
if (isWindowsPhoneApp) tmpl = '<div>' + showName + '</div>';
|
if (isWindowsPhoneApp) tmpl = '<div>' + showName + '</div>';
|
||||||
else tmpl = '<div class="item-icon-left">' + showName + '<ion-spinner class="spinner-stable" icon="lines"></ion-spinner></div>';
|
else tmpl = '<div class="item-icon-left">' + showName + '<ion-spinner class="spinner-stable" icon="lines"></ion-spinner></div>';
|
||||||
|
|
@ -85,10 +87,6 @@ angular.module('copayApp.services').factory('ongoingProcess', function($log, $ti
|
||||||
} else {
|
} else {
|
||||||
$ionicLoading.hide();
|
$ionicLoading.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (customHandler) {
|
|
||||||
customHandler(processName, showName, isOn);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ angular.module('copayApp.services').factory('servicesService', function(configSe
|
||||||
name: 'shapeshift',
|
name: 'shapeshift',
|
||||||
title: 'Shapeshift',
|
title: 'Shapeshift',
|
||||||
icon: 'icon-shapeshift',
|
icon: 'icon-shapeshift',
|
||||||
href: 'https://shapeshift.io/'
|
sref: 'tabs.shapeshift',
|
||||||
}];
|
}];
|
||||||
|
|
||||||
root.register = function(serviceInfo) {
|
root.register = function(serviceInfo) {
|
||||||
|
|
|
||||||
|
|
@ -27,23 +27,20 @@
|
||||||
|
|
||||||
function addEarlyTransactions(walletId, cachedTxs, newTxs) {
|
function addEarlyTransactions(walletId, cachedTxs, newTxs) {
|
||||||
|
|
||||||
var cachedTxIndexFromId = {};
|
var cachedTxIds = {};
|
||||||
cachedTxs.forEach(function forCachedTx(tx){
|
cachedTxs.forEach(function forCachedTx(tx){
|
||||||
cachedTxIndexFromId[tx.txid] = true;
|
cachedTxIds[tx.txid] = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
var confirmationsUpdated = false;
|
|
||||||
var someTransactionsWereNew = false;
|
var someTransactionsWereNew = false;
|
||||||
var overlappingTxsCount = 0;
|
var overlappingTxsCount = 0;
|
||||||
|
|
||||||
newTxs.forEach(function forNewTx(tx){
|
newTxs.forEach(function forNewTx(tx){
|
||||||
if (typeof cachedTxIndexFromId[tx.txid] === "undefined") {
|
if (cachedTxIds[tx.txid]) {
|
||||||
|
overlappingTxsCount++;
|
||||||
|
} else {
|
||||||
someTransactionsWereNew = true;
|
someTransactionsWereNew = true;
|
||||||
cachedTxs.push(tx);
|
cachedTxs.push(tx);
|
||||||
} else {
|
|
||||||
var txUpdated = updateCachedTx(cachedTxs, cachedTxIndexFromId, tx);
|
|
||||||
confirmationsUpdated = confirmationsUpdated || txUpdated;
|
|
||||||
overlappingTxsCount++;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -53,8 +50,6 @@
|
||||||
if (overlappingTxFraction >= MIN_KNOWN_TX_OVERLAP_FRACTION) { // We are good
|
if (overlappingTxFraction >= MIN_KNOWN_TX_OVERLAP_FRACTION) { // We are good
|
||||||
if (someTransactionsWereNew) {
|
if (someTransactionsWereNew) {
|
||||||
saveTxHistory(walletId, cachedTxs);
|
saveTxHistory(walletId, cachedTxs);
|
||||||
} else if (confirmationsUpdated) {
|
|
||||||
saveTxHistory(walletId, cachedTxs);
|
|
||||||
} else if (overlappingTxsCount === newTxs.length) {
|
} else if (overlappingTxsCount === newTxs.length) {
|
||||||
allTransactionsFetched = true;
|
allTransactionsFetched = true;
|
||||||
}
|
}
|
||||||
|
|
@ -70,24 +65,21 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function addLatestTransactions(walletId, cachedTxs, newTxs) {
|
function addLatestTransactions(walletId, cachedTxs, newTxs) {
|
||||||
var cachedTxIndexFromId = {};
|
var cachedTxIds = {};
|
||||||
cachedTxs.forEach(function forCachedTx(tx, txIndex){
|
cachedTxs.forEach(function forCachedTx(tx){
|
||||||
cachedTxIndexFromId[tx.txid] = txIndex;
|
cachedTxIds[tx.txid] = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
var someTransactionsWereNew = false;
|
var someTransactionsWereNew = false;
|
||||||
var confirmationsUpdated = false;
|
|
||||||
var overlappingTxsCount = 0;
|
var overlappingTxsCount = 0;
|
||||||
var uniqueNewTxs = [];
|
var uniqueNewTxs = [];
|
||||||
|
|
||||||
newTxs.forEach(function forNewTx(tx){
|
newTxs.forEach(function forNewTx(tx){
|
||||||
if (typeof cachedTxIndexFromId[tx.txid] === "undefined") {
|
if (cachedTxIds[tx.txid]) {
|
||||||
|
overlappingTxsCount++;
|
||||||
|
} else {
|
||||||
someTransactionsWereNew = true;
|
someTransactionsWereNew = true;
|
||||||
uniqueNewTxs.push(tx);
|
uniqueNewTxs.push(tx);
|
||||||
} else {
|
|
||||||
var txUpdated = updateCachedTx(cachedTxs, cachedTxIndexFromId, tx);
|
|
||||||
confirmationsUpdated = confirmationsUpdated || txUpdated;
|
|
||||||
overlappingTxsCount++;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -99,9 +91,6 @@
|
||||||
saveTxHistory(walletId, allTxs);
|
saveTxHistory(walletId, allTxs);
|
||||||
return allTxs;
|
return allTxs;
|
||||||
} else {
|
} else {
|
||||||
if (confirmationsUpdated) {
|
|
||||||
saveTxHistory(walletId, cachedTxs);
|
|
||||||
}
|
|
||||||
return cachedTxs;
|
return cachedTxs;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -115,8 +104,6 @@
|
||||||
|
|
||||||
// Only clear the cache once we have received new transactions from the server.
|
// Only clear the cache once we have received new transactions from the server.
|
||||||
/**
|
/**
|
||||||
* @param wallet
|
|
||||||
* @param start
|
|
||||||
* @param {function(err, txs)} cb - transactions is always an array, may be empty
|
* @param {function(err, txs)} cb - transactions is always an array, may be empty
|
||||||
*/
|
*/
|
||||||
function fetchTxHistoryByPage(wallet, start, cb) {
|
function fetchTxHistoryByPage(wallet, start, cb) {
|
||||||
|
|
@ -147,7 +134,6 @@
|
||||||
* @param {function(error, txs)} cb - txs is always an array, may be empty
|
* @param {function(error, txs)} cb - txs is always an array, may be empty
|
||||||
*/
|
*/
|
||||||
function getCachedTxHistory(walletId, cb) {
|
function getCachedTxHistory(walletId, cb) {
|
||||||
console.log('txhistory updateLocalTxHistoryByPage()');
|
|
||||||
storageService.getTxHistory(walletId, function onGetTxHistory(err, txHistoryString){
|
storageService.getTxHistory(walletId, function onGetTxHistory(err, txHistoryString){
|
||||||
if (err) {
|
if (err) {
|
||||||
return cb(err, []);
|
return cb(err, []);
|
||||||
|
|
@ -201,7 +187,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
return processedTxs;
|
return processedTxs;
|
||||||
}
|
};
|
||||||
|
|
||||||
function saveTxHistory(walletId, processedTxs) {
|
function saveTxHistory(walletId, processedTxs) {
|
||||||
storageService.setTxHistory(processedTxs, walletId, function onSetTxHistory(error){
|
storageService.setTxHistory(processedTxs, walletId, function onSetTxHistory(error){
|
||||||
|
|
@ -211,26 +197,9 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the cached tx was updated
|
|
||||||
* @param {*} cachedTxs
|
|
||||||
* @param {*} cachedTxIndexFromId - Indices for cachedTxs, based on txid
|
|
||||||
* @param {*} tx - The most recent tx info
|
|
||||||
*/
|
|
||||||
function updateCachedTx(cachedTxs, cachedTxIndexFromId, tx) {
|
|
||||||
var updated = false;
|
|
||||||
var txIndex = cachedTxIndexFromId[tx.txid];
|
|
||||||
var cachedTx = cachedTxs[txIndex];
|
|
||||||
|
|
||||||
if (cachedTx.confirmations < SAFE_CONFIRMATIONS && tx.confirmations > cachedTx.confirmations) {
|
|
||||||
cachedTxs[txIndex].confirmations = tx.confirmations;
|
|
||||||
updated = true;
|
|
||||||
}
|
|
||||||
return updated;
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateLocalTxHistoryByPage(wallet, getLatest, flushCacheOnNew, cb) {
|
function updateLocalTxHistoryByPage(wallet, getLatest, flushCacheOnNew, cb) {
|
||||||
console.log('txhistory updaetLocalTxHistoryByPage()');
|
|
||||||
if (flushCacheOnNew) {
|
if (flushCacheOnNew) {
|
||||||
fetchTxHistoryByPage(wallet, 0, function onFetchTxHistory(err, txs){
|
fetchTxHistoryByPage(wallet, 0, function onFetchTxHistory(err, txs){
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|
@ -271,5 +240,10 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
})();
|
})();
|
||||||
209
www/css/main.css
209
www/css/main.css
|
|
@ -10083,7 +10083,7 @@ ion-view.deflash-blue:before, ion-view#view-amount:before, ion-view#view-confirm
|
||||||
.onboarding .button.button-white.button-standard,
|
.onboarding .button.button-white.button-standard,
|
||||||
.onboarding .button.button-green.button-standard,
|
.onboarding .button.button-green.button-standard,
|
||||||
.onboarding .button.button-assertive.button-standard, #shapeshift .button-shapeshift {
|
.onboarding .button.button-assertive.button-standard, #shapeshift .button-shapeshift {
|
||||||
width: 90%;
|
width: 85%;
|
||||||
max-width: 300px;
|
max-width: 300px;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
|
|
@ -10195,7 +10195,6 @@ ion-view.deflash-blue:before, ion-view#view-amount:before, ion-view#view-confirm
|
||||||
.button {
|
.button {
|
||||||
border-radius: 6px; }
|
border-radius: 6px; }
|
||||||
.button.button-full {
|
.button.button-full {
|
||||||
border-radius: 0;
|
|
||||||
display: block; }
|
display: block; }
|
||||||
.button-green {
|
.button-green {
|
||||||
border-color: #FFF;
|
border-color: #FFF;
|
||||||
|
|
@ -10264,8 +10263,8 @@ ion-view.deflash-blue:before, ion-view#view-amount:before, ion-view#view-confirm
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
text-decoration: none; }
|
text-decoration: none; }
|
||||||
.button-white-outline.active, .button-white-outline.activated {
|
.button-white-outline.active, .button-white-outline.activated {
|
||||||
border-color: #FFFFFF;
|
border-color: #FFF;
|
||||||
background-color: #FFFFFF; }
|
background-color: #FAFAFA; }
|
||||||
.button-white-outline.button-outline {
|
.button-white-outline.button-outline {
|
||||||
border-color: #FFFFFF;
|
border-color: #FFFFFF;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
|
@ -10633,7 +10632,7 @@ qrcode {
|
||||||
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long .primary-amount-display {
|
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.long .primary-amount-display {
|
||||||
font-size: 2em; } }
|
font-size: 2em; } }
|
||||||
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long .primary-amount-display {
|
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long .primary-amount-display {
|
||||||
font-size: 1.2em; }
|
font-size: 0.9em; }
|
||||||
@media (min-width: 375px) {
|
@media (min-width: 375px) {
|
||||||
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long .primary-amount-display {
|
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long input, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long .unit, #view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount.very-long .primary-amount-display {
|
||||||
font-size: 1.3em; } }
|
font-size: 1.3em; } }
|
||||||
|
|
@ -10660,8 +10659,7 @@ qrcode {
|
||||||
line-height: 1em; }
|
line-height: 1em; }
|
||||||
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount .primary-amount-display {
|
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .primary-amount .primary-amount-display {
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
word-break: break-all;
|
word-break: break-all; }
|
||||||
width: 100%; }
|
|
||||||
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .alternative-amount {
|
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .alternative-amount {
|
||||||
color: #6F6F70; }
|
color: #6F6F70; }
|
||||||
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .switch-currencies {
|
#view-amount .scroll-content .send-amount .send-amount-tool .send-amount-tool-input .switch-currencies {
|
||||||
|
|
@ -10682,33 +10680,30 @@ qrcode {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
margin: 0 14px; }
|
margin: 0 14px; }
|
||||||
#view-amount .scroll-content .send-amount-extras .available-funds {
|
#view-amount .scroll-content .send-amount-extras .available-funds {
|
||||||
color: #6F6F70;
|
color: #6F6F70; }
|
||||||
text-align: left; }
|
|
||||||
#view-amount .scroll-content .send-amount-extras .change-currency {
|
|
||||||
text-align: right; }
|
|
||||||
#view-amount .scroll-content .send-amount-extras .warning {
|
#view-amount .scroll-content .send-amount-extras .warning {
|
||||||
color: #b7664d; }
|
color: #b7664d; }
|
||||||
#view-amount .scroll-content .send-amount-extras .extra {
|
#view-amount .scroll-content .send-amount-extras .extra,
|
||||||
flex: 1;
|
#view-amount .scroll-content .send-amount-extras button.extra {
|
||||||
|
/*display: flex;*/
|
||||||
|
flex: 0 1 auto; }
|
||||||
|
#view-amount .scroll-content .send-amount-extras button.extra {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: #000;
|
||||||
|
font-family: 'ProximaNova';
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: normal;
|
||||||
|
min-height: auto;
|
||||||
|
min-width: auto;
|
||||||
|
padding: 0; }
|
||||||
|
#view-amount .scroll-content .send-amount-extras .button .icon:before {
|
||||||
|
font-size: 14px;
|
||||||
line-height: normal; }
|
line-height: normal; }
|
||||||
#view-amount .scroll-content .send-amount-extras .extra .button {
|
#view-amount .scroll-content .send-amount-extras .button span {
|
||||||
background: none;
|
display: flex;
|
||||||
border: none;
|
align-items: center;
|
||||||
border-radius: 0;
|
justify-content: center; }
|
||||||
color: #000;
|
|
||||||
font-family: 'ProximaNova';
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: normal;
|
|
||||||
min-height: auto;
|
|
||||||
min-width: auto;
|
|
||||||
padding: 0; }
|
|
||||||
#view-amount .scroll-content .send-amount-extras .extra .button .icon:before {
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: normal; }
|
|
||||||
#view-amount .scroll-content .send-amount-extras .extra .button span {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center; }
|
|
||||||
#view-amount .scroll-content .button.no-margin {
|
#view-amount .scroll-content .button.no-margin {
|
||||||
margin: 0; }
|
margin: 0; }
|
||||||
#view-amount .scroll-content .notification-warning {
|
#view-amount .scroll-content .notification-warning {
|
||||||
|
|
@ -10944,14 +10939,14 @@ qrcode {
|
||||||
#tab-home .buttons .button {
|
#tab-home .buttons .button {
|
||||||
border: 2px solid;
|
border: 2px solid;
|
||||||
border-radius: 47px;
|
border-radius: 47px;
|
||||||
padding: 8px 2px 8px 2px;
|
padding: 0 15px 0 15px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 300px;
|
max-width: 300px;
|
||||||
font-size: 19px;
|
font-size: 19px;
|
||||||
font-weight: bolder;
|
font-weight: bolder;
|
||||||
min-height: 0;
|
min-height: auto;
|
||||||
line-height: 19px; }
|
line-height: 36px; }
|
||||||
|
|
||||||
#tab-home .wallet-coin-logo {
|
#tab-home .wallet-coin-logo {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
|
@ -11018,10 +11013,6 @@ qrcode {
|
||||||
#tab-home .release .title {
|
#tab-home .release .title {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #444; }
|
color: #444; }
|
||||||
#tab-home .release .release-notes {
|
|
||||||
white-space: pre;
|
|
||||||
white-space: pre-line;
|
|
||||||
text-align: left; }
|
|
||||||
#tab-home .release .button {
|
#tab-home .release .button {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border: none; }
|
border: none; }
|
||||||
|
|
@ -11034,14 +11025,6 @@ qrcode {
|
||||||
#tab-home .badge {
|
#tab-home .badge {
|
||||||
top: 11px; }
|
top: 11px; }
|
||||||
|
|
||||||
.popup-update .popup-buttons {
|
|
||||||
display: block; }
|
|
||||||
|
|
||||||
.popup-update .popup-buttons .button {
|
|
||||||
display: block;
|
|
||||||
min-width: 100% !important;
|
|
||||||
margin-top: 4px; }
|
|
||||||
|
|
||||||
#tab-receive .button-share {
|
#tab-receive .button-share {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
|
|
@ -11118,8 +11101,6 @@ qrcode {
|
||||||
|
|
||||||
#tab-receive .payment-received-container {
|
#tab-receive .payment-received-container {
|
||||||
margin: 0 20px; }
|
margin: 0 20px; }
|
||||||
#tab-receive .payment-received-container svg {
|
|
||||||
max-height: 400px; }
|
|
||||||
#tab-receive .payment-received-container .payment-received-amount {
|
#tab-receive .payment-received-container .payment-received-amount {
|
||||||
font-size: 1.8em;
|
font-size: 1.8em;
|
||||||
display: block;
|
display: block;
|
||||||
|
|
@ -11226,7 +11207,7 @@ qrcode {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
margin-top: 18px; }
|
margin-top: 18px; }
|
||||||
#tab-send .send-wrapper .buttons .button {
|
#tab-send .send-wrapper .buttons .button {
|
||||||
min-height: 65px;
|
height: 60px;
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
margin-right: 0px;
|
margin-right: 0px;
|
||||||
width: 95%;
|
width: 95%;
|
||||||
|
|
@ -11303,9 +11284,7 @@ qrcode {
|
||||||
margin-top: 18px; }
|
margin-top: 18px; }
|
||||||
#tab-send .sendTip .buttons .button {
|
#tab-send .sendTip .buttons .button {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 19px;
|
font-size: 19px; }
|
||||||
line-height: 26px;
|
|
||||||
padding: 8px 6px; }
|
|
||||||
#tab-send .sendTip .button-first-contact img {
|
#tab-send .sendTip .button-first-contact img {
|
||||||
height: 19px;
|
height: 19px;
|
||||||
width: 19px;
|
width: 19px;
|
||||||
|
|
@ -11941,13 +11920,6 @@ qrcode {
|
||||||
#walletDetails .bp-content.status-bar {
|
#walletDetails .bp-content.status-bar {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
margin-top: env(safe-area-inset-top); }
|
margin-top: env(safe-area-inset-top); }
|
||||||
#walletDetails .bp-content.collapse ion-content {
|
|
||||||
margin-top: 40px; }
|
|
||||||
#walletDetails .bp-content.collapse .amount__scale, #walletDetails .bp-content.collapse .amount__error {
|
|
||||||
-webkit-transform: scale3d(0.5, 0.5, 0.5) translateY(0px);
|
|
||||||
transform: scale3d(0.5, 0.5, 0.5) translateY(0px); }
|
|
||||||
#walletDetails .bp-content.collapse .amount-alternative, #walletDetails .bp-content.collapse .send-receive-buttons, #walletDetails .bp-content.collapse .wallet-details-wallet-info {
|
|
||||||
opacity: 0; }
|
|
||||||
#walletDetails .bar-header {
|
#walletDetails .bar-header {
|
||||||
border: 0;
|
border: 0;
|
||||||
background: #eeb640; }
|
background: #eeb640; }
|
||||||
|
|
@ -11960,12 +11932,9 @@ qrcode {
|
||||||
#walletDetails ion-content {
|
#walletDetails ion-content {
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
transition: all 0.25s ease-in-out;
|
|
||||||
margin-top: 185px;
|
|
||||||
margin-bottom: 16px; }
|
margin-bottom: 16px; }
|
||||||
@media only screen and (max-height: 500px) {
|
#walletDetails ion-content.collapsible {
|
||||||
#walletDetails ion-content {
|
margin-top: 230px; }
|
||||||
margin-top: 165px; } }
|
|
||||||
#walletDetails ion-content .scroll {
|
#walletDetails ion-content .scroll {
|
||||||
background: #f8f8f9;
|
background: #f8f8f9;
|
||||||
min-height: 300px; }
|
min-height: 300px; }
|
||||||
|
|
@ -11996,45 +11965,38 @@ qrcode {
|
||||||
justify-content: space-evenly;
|
justify-content: space-evenly;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 20px;
|
bottom: 20px; }
|
||||||
transition: all 0.25s ease-in-out; }
|
|
||||||
#walletDetails .amount-wrapper .send-receive-buttons > .col {
|
#walletDetails .amount-wrapper .send-receive-buttons > .col {
|
||||||
padding: 5px 10px;
|
padding: 5px 10px;
|
||||||
margin-bottom: 0; }
|
margin-bottom: 0; }
|
||||||
#walletDetails .amount-wrapper .send-receive-buttons .button {
|
#walletDetails .amount-wrapper .send-receive-buttons .button {
|
||||||
border: 2px solid;
|
border: 2px solid;
|
||||||
border-radius: 47px;
|
border-radius: 47px;
|
||||||
padding: 6px 2px 6px 2px;
|
padding: 0 15px 0 15px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 300px;
|
max-width: 300px;
|
||||||
font-size: 19px;
|
font-size: 19px;
|
||||||
font-weight: bolder;
|
font-weight: bolder;
|
||||||
min-height: 0;
|
min-height: auto;
|
||||||
line-height: 19px; }
|
line-height: 36px; }
|
||||||
#walletDetails .amount {
|
#walletDetails .amount {
|
||||||
align-items: center;
|
width: 100%;
|
||||||
color: #fff;
|
|
||||||
display: block;
|
|
||||||
height: 230px;
|
|
||||||
justify-content: center;
|
|
||||||
padding-top: 40px;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
transition: all 0.25s ease-in-out;
|
color: #fff;
|
||||||
width: 100%; }
|
height: 230px;
|
||||||
@media only screen and (max-height: 500px) {
|
padding-top: 40px;
|
||||||
#walletDetails .amount {
|
display: block;
|
||||||
height: 210px; } }
|
align-items: center;
|
||||||
|
justify-content: center; }
|
||||||
#walletDetails .amount__balance {
|
#walletDetails .amount__balance {
|
||||||
-webkit-transform: scale3d(1, 1, 1) translateY(45px);
|
-webkit-transform: scale3d(1, 1, 1) translateY(45px);
|
||||||
transform: scale3d(1, 1, 1) translateY(45px);
|
transform: scale3d(1, 1, 1) translateY(45px); }
|
||||||
transition: all 0.25s ease-in-out; }
|
|
||||||
#walletDetails .amount__updating {
|
#walletDetails .amount__updating {
|
||||||
z-index: 999;
|
z-index: 999;
|
||||||
margin-top: -2.1rem; }
|
margin-top: -2.1rem; }
|
||||||
#walletDetails .amount-alternative {
|
#walletDetails .amount-alternative {
|
||||||
line-height: 36px;
|
line-height: 36px; }
|
||||||
transition: all 0.25s ease-in-out; }
|
|
||||||
#walletDetails .amount__button-balance {
|
#walletDetails .amount__button-balance {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
border: 1px solid rgba(255, 255, 255, 0.25);
|
border: 1px solid rgba(255, 255, 255, 0.25);
|
||||||
|
|
@ -12044,8 +12006,7 @@ qrcode {
|
||||||
vertical-align: middle; }
|
vertical-align: middle; }
|
||||||
#walletDetails .amount__error {
|
#walletDetails .amount__error {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
padding: 35px 20px;
|
padding: 35px 20px; }
|
||||||
opacity: 1; }
|
|
||||||
#walletDetails .no-alternative {
|
#walletDetails .no-alternative {
|
||||||
padding-top: 45px; }
|
padding-top: 45px; }
|
||||||
#walletDetails .item.item-footer {
|
#walletDetails .item.item-footer {
|
||||||
|
|
@ -12110,9 +12071,7 @@ a.item {
|
||||||
font-size: 0.9em; }
|
font-size: 0.9em; }
|
||||||
|
|
||||||
.loading-wallet svg {
|
.loading-wallet svg {
|
||||||
margin-top: 0;
|
margin-top: 0; }
|
||||||
width: 16px;
|
|
||||||
height: 16px; }
|
|
||||||
|
|
||||||
#advanced-settings .list .item:before {
|
#advanced-settings .list .item:before {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
@ -12166,9 +12125,7 @@ a.item {
|
||||||
margin-top: 18px; }
|
margin-top: 18px; }
|
||||||
#shapeshift .empty-case .buttons .button {
|
#shapeshift .empty-case .buttons .button {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 19px;
|
font-size: 19px; }
|
||||||
line-height: 26px;
|
|
||||||
padding: 8px 6px; }
|
|
||||||
#shapeshift .empty-case .button-first-contact img {
|
#shapeshift .empty-case .button-first-contact img {
|
||||||
height: 19px;
|
height: 19px;
|
||||||
width: 19px;
|
width: 19px;
|
||||||
|
|
@ -13855,7 +13812,6 @@ click-to-accept {
|
||||||
height: 92px;
|
height: 92px;
|
||||||
width: 100%; }
|
width: 100%; }
|
||||||
click-to-accept .click-to-accept__button.button.button-primary.button-standard {
|
click-to-accept .click-to-accept__button.button.button-primary.button-standard {
|
||||||
border-radius: 0;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
max-width: 9999px;
|
max-width: 9999px;
|
||||||
width: 100%; }
|
width: 100%; }
|
||||||
|
|
@ -13962,8 +13918,6 @@ slide-to-accept {
|
||||||
height: 92px;
|
height: 92px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: #494949; }
|
background: #494949; }
|
||||||
slide-to-accept .slide .button {
|
|
||||||
border-radius: 0; }
|
|
||||||
slide-to-accept .slide__listener {
|
slide-to-accept .slide__listener {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
@ -15395,25 +15349,20 @@ log-options #check-bar .checkbox-icon {
|
||||||
#cash-scan a {
|
#cash-scan a {
|
||||||
cursor: pointer; }
|
cursor: pointer; }
|
||||||
|
|
||||||
#view-review slide-to-accept, #view-review slide-to-accept-success {
|
#view-review {
|
||||||
margin-bottom: constant(safe-area-inset-bottom);
|
background-color: #494949; }
|
||||||
/* iOS 11.0 */
|
#view-review slide-to-accept, #view-review slide-to-accept-success {
|
||||||
margin-bottom: env(safe-area-inset-bottom);
|
margin-bottom: constant(safe-area-inset-bottom);
|
||||||
/* iOS 11.2 */ }
|
/* iOS 11.0 */
|
||||||
|
margin-bottom: env(safe-area-inset-bottom);
|
||||||
#view-review .fee-summary {
|
/* iOS 11.2 */ }
|
||||||
bottom: 92px;
|
#view-review .fee-summary {
|
||||||
bottom: calc(92px + constant(safe-area-inset-bottom));
|
position: absolute;
|
||||||
/* iOS 11.0 */
|
bottom: 92px; }
|
||||||
bottom: calc(92px + env(safe-area-inset-bottom));
|
#view-review .shapeshift-banner, #view-review .bitpay-banner, #view-review .egifter-banner {
|
||||||
/* iOS 11.2 */
|
box-shadow: none; }
|
||||||
position: absolute; }
|
#view-review .warning {
|
||||||
|
color: #b7664d; }
|
||||||
#view-review .shapeshift-banner, #view-review .bitpay-banner, #view-review .egifter-banner {
|
|
||||||
box-shadow: none; }
|
|
||||||
|
|
||||||
#view-review .warning {
|
|
||||||
color: #b7664d; }
|
|
||||||
|
|
||||||
.gravatar {
|
.gravatar {
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
|
@ -15446,7 +15395,6 @@ log-options #check-bar .checkbox-icon {
|
||||||
left: 13px;
|
left: 13px;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
-webkit-transform: translate(0, -50%);
|
|
||||||
transform: translate(0, -50%); }
|
transform: translate(0, -50%); }
|
||||||
|
|
||||||
.item .item-content.item-content-compact {
|
.item .item-content.item-content-compact {
|
||||||
|
|
@ -15515,8 +15463,8 @@ ion-content.padded-bottom-cta-with-summary {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis; }
|
text-overflow: ellipsis; }
|
||||||
.address-frame.expanded {
|
.address-frame.expanded {
|
||||||
white-space: normal;
|
white-space: pre-wrap;
|
||||||
text-overflow: clip; }
|
word-break: break-all; }
|
||||||
.address-frame .prefix {
|
.address-frame .prefix {
|
||||||
color: #000000; }
|
color: #000000; }
|
||||||
.address-frame .mid {
|
.address-frame .mid {
|
||||||
|
|
@ -15559,13 +15507,13 @@ ion-content.padded-bottom-cta-with-summary {
|
||||||
transform: scale(1, 1); }
|
transform: scale(1, 1); }
|
||||||
|
|
||||||
.fee-summary {
|
.fee-summary {
|
||||||
background-color: #F2F2F2;
|
position: relative;
|
||||||
box-sizing: border-box;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
padding: 5px 12px 15px;
|
padding: 5px 12px 15px;
|
||||||
position: relative;
|
box-sizing: border-box;
|
||||||
width: 100%; }
|
background-color: #F2F2F2; }
|
||||||
.fee-summary:before {
|
.fee-summary:before {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
@ -15575,16 +15523,16 @@ ion-content.padded-bottom-cta-with-summary {
|
||||||
height: 15px;
|
height: 15px;
|
||||||
background: linear-gradient(to bottom, rgba(242, 242, 242, 0) 0%, #f2f2f2 100%); }
|
background: linear-gradient(to bottom, rgba(242, 242, 242, 0) 0%, #f2f2f2 100%); }
|
||||||
.fee-summary .amount {
|
.fee-summary .amount {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
width: 100%; }
|
width: 100%; }
|
||||||
.fee-summary .amount .fee-fiat {
|
.fee-summary .amount .fee-fiat.positive {
|
||||||
display: inline; }
|
color: #70955F; }
|
||||||
.fee-summary .amount .fee-fiat.positive {
|
.fee-summary .amount .fee-fiat.negative {
|
||||||
color: #70955F; }
|
color: #C24633; }
|
||||||
.fee-summary .amount .fee-fiat.negative {
|
|
||||||
color: #C24633; }
|
|
||||||
.fee-summary .amount .fee-crypto {
|
.fee-summary .amount .fee-crypto {
|
||||||
color: #A7A7A7;
|
color: #A7A7A7; }
|
||||||
float: right; }
|
|
||||||
|
|
||||||
.formatted-amount {
|
.formatted-amount {
|
||||||
display: inline-block; }
|
display: inline-block; }
|
||||||
|
|
@ -15609,9 +15557,6 @@ ion-content.padded-bottom-cta-with-summary {
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
text-transform: uppercase; }
|
text-transform: uppercase; }
|
||||||
|
|
||||||
.wallet-balance-directive {
|
|
||||||
display: inline-block; }
|
|
||||||
|
|
||||||
/* This is for rules that don't yet have a home.
|
/* This is for rules that don't yet have a home.
|
||||||
* Our goal is to delete this file. Search the regex: /class=".*CLASS.*?"/
|
* Our goal is to delete this file. Search the regex: /class=".*CLASS.*?"/
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div ng-show="!hide">
|
<div ng-show="!hide">
|
||||||
<div ng-repeat="service in services track by $index">
|
<div ng-repeat="service in services track by $index">
|
||||||
<a ng-if="service.sref" ui-sref="{{service.sref}}" id="home_{{service.name}}" title="{{service.title || service.name}}" class="track_link_click_out item item-sub item-icon-left item-big-icon-left item-icon-right next-step">
|
<a ui-sref="{{service.sref}}" id="home_{{service.name}}" title="{{service.title || service.name}}" class="track_link_click_out item item-sub item-icon-left item-big-icon-left item-icon-right next-step">
|
||||||
<i class="icon big-icon-svg theme-circle theme-circle-services">
|
|
||||||
<div class="bg {{service.icon}}"></div>
|
|
||||||
</i>
|
|
||||||
<span>{{service.title || service.name}}</span>
|
|
||||||
<i class="icon bp-arrow-right"></i>
|
|
||||||
</a>
|
|
||||||
<a ng-if="!service.sref" ng-click="open('{{service.href}}')" id="home_{{service.name}}" title="{{service.title || service.name}}" class="track_link_click_out item item-sub item-icon-left item-big-icon-left item-icon-right next-step">
|
|
||||||
<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 {{service.icon}}"></div>
|
<div class="bg {{service.icon}}"></div>
|
||||||
</i>
|
</i>
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,14 @@
|
||||||
</i>
|
</i>
|
||||||
<h2>{{fromWallet.name}}</h2>
|
<h2>{{fromWallet.name}}</h2>
|
||||||
<wallet-balance
|
<wallet-balance
|
||||||
display-as-fiat="{{displayBalanceAsFiat}}"
|
display-as-fiat="{{displayBalanceAsFiat}}"
|
||||||
wallet-coin="{{fromWallet.coin}}"
|
|
||||||
wallet-status="{{fromWallet.status}}"
|
wallet-status="{{fromWallet.status}}"
|
||||||
wallet-cached-balance="{{fromWallet.cachedBalance}}"
|
wallet-cached-balance="{{fromWallet.cachedBalance}}"
|
||||||
wallet-cached-balance-updated-on="{{fromWallet.cachedBalanceUpdatedOn}}"
|
wallet-cached-balance-updated-on="{{fromWallet.cachedBalanceUpdatedOn}}"
|
||||||
wallet-cached-status="{{fromWallet.cachedStatus}}"
|
wallet-cached-status="{{fromWallet.cachedStatus}}"
|
||||||
total-balance-sat="{{fromWallet.status.totalBalanceSat}}"></wallet-balance>
|
total-balance-sat="{{fromWallet.status.totalBalanceSat}}"></wallet-balance>
|
||||||
|
<!--<p ng-show="vm.origin.balanceAmount">{{vm.origin.balanceAmount}} {{vm.origin.balanceCurrency}}</p>-->
|
||||||
|
<!--<formatted-amount value="{{fromWallet.status.totalBalanceStr ? fromWallet.status.totalBalanceStr : ( fromWallet.cachedBalance ? fromWallet.cachedBalance + (fromWallet.cachedBalanceUpdatedOn ? ' · ' + ( fromWallet.cachedBalanceUpdatedOn * 1000 | amTimeAgo) : '') : '' ) }}"></formatted-amount>-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
<div class="header--request__amount-alt" ng-show="requestAmountSecondary" translate>{{requestAmountSecondary}} {{requestCurrencySecondary}}</div>
|
<div class="header--request__amount-alt" ng-show="requestAmountSecondary" translate>{{requestAmountSecondary}} {{requestCurrencySecondary}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="wallets-header">
|
<div class="wallets-header">
|
||||||
<div class="title" ng-if="walletsBch.length > 0 || walletsBtc.length > 0 || walletsInsufficientFunds.length > 0">
|
<div class="title">
|
||||||
{{headerTitle}}
|
{{headerTitle}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue