Merge branch 'master' of https://github.com/bitpay/copay into feat/app-identity
This commit is contained in:
commit
9b3a3aab9d
213 changed files with 12663 additions and 7021 deletions
|
|
@ -70,7 +70,7 @@ angular.module('copayApp.services').factory('amazonService', function($http, $lo
|
|||
});
|
||||
|
||||
// Show pending task from the UI
|
||||
storageService.setNextStep('AmazonGiftCards', true, function(err) {});
|
||||
storageService.setNextStep('AmazonGiftCards', 'true', function(err) {});
|
||||
};
|
||||
|
||||
root.getPendingGiftCards = function(cb) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
'use strict';
|
||||
angular.module('copayApp.services')
|
||||
.factory('backupService', function backupServiceFactory($log, $timeout, $stateParams, profileService, sjcl) {
|
||||
.factory('backupService', function backupServiceFactory($log, $timeout, $stateParams, profileService, sjcl, $window) {
|
||||
|
||||
var root = {};
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ angular.module('copayApp.services')
|
|||
|
||||
var walletName = (wallet.alias || '') + (wallet.alias ? '-' : '') + wallet.credentials.walletName;
|
||||
if (opts.noSign) walletName = walletName + '-noSign'
|
||||
var filename = walletName + '-Copaybackup.aes.json';
|
||||
var filename = walletName + '-' + $window.appConfig.nameCase + 'backup.aes.json';
|
||||
_download(ew, filename, cb)
|
||||
};
|
||||
return root;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ angular.module('copayApp.services').factory('bitpayCardService', function($http,
|
|||
|
||||
var _setError = function(msg, e) {
|
||||
$log.error(msg);
|
||||
var error = e.data ? e.data.error : msg;
|
||||
var error = (e && e.data && e.data.error) ? e.data.error : msg;
|
||||
return error;
|
||||
};
|
||||
|
||||
|
|
@ -104,7 +104,7 @@ angular.module('copayApp.services').factory('bitpayCardService', function($http,
|
|||
};
|
||||
|
||||
root.bitAuthPair = function(obj, cb) {
|
||||
var deviceName = 'Unknow device';
|
||||
var deviceName = 'Unknown device';
|
||||
if (platformInfo.isNW) {
|
||||
deviceName = require('os').platform();
|
||||
} else if (platformInfo.isCordova) {
|
||||
|
|
@ -143,7 +143,7 @@ angular.module('copayApp.services').factory('bitpayCardService', function($http,
|
|||
root.getBitpayDebitCards(function(err, data) {
|
||||
if (err) return cb(err);
|
||||
var card = lodash.find(data, {id : cardId});
|
||||
if (!card) return cb(_setError('Not card found'));
|
||||
if (!card) return cb(_setError('Card not found'));
|
||||
// Get invoices
|
||||
$http(_post('/api/v2/' + card.token, json, appIdentity)).then(function(data) {
|
||||
$log.info('BitPay Get Invoices: SUCCESS');
|
||||
|
|
@ -180,7 +180,7 @@ angular.module('copayApp.services').factory('bitpayCardService', function($http,
|
|||
root.getBitpayDebitCards(function(err, data) {
|
||||
if (err) return cb(err);
|
||||
var card = lodash.find(data, {id : cardId});
|
||||
if (!card) return cb(_setError('Not card found'));
|
||||
if (!card) return cb(_setError('Card not found'));
|
||||
$http(_post('/api/v2/' + card.token, json, appIdentity)).then(function(data) {
|
||||
$log.info('BitPay TopUp: SUCCESS');
|
||||
if(data.data.error) {
|
||||
|
|
@ -258,13 +258,30 @@ angular.module('copayApp.services').factory('bitpayCardService', function($http,
|
|||
|
||||
root.remove = function(card, cb) {
|
||||
storageService.removeBitpayDebitCard(BITPAY_CARD_NETWORK, card, function(err) {
|
||||
if (err) {
|
||||
$log.error('Error removing BitPay debit card: ' + err);
|
||||
// Continue, try to remove/cleanup card history
|
||||
}
|
||||
storageService.removeBitpayDebitCardHistory(BITPAY_CARD_NETWORK, card, function(err) {
|
||||
$log.info('BitPay Debit Card(s) Removed: SUCCESS');
|
||||
if (err) {
|
||||
$log.error('Error removing BitPay debit card transaction history: ' + err);
|
||||
return cb(err);
|
||||
}
|
||||
$log.info('Successfully removed BitPay debit card');
|
||||
return cb();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
root.getRates = function(currency, cb) {
|
||||
$http(_get('/rates/' + currency)).then(function(data) {
|
||||
$log.info('BitPay Get Rates: SUCCESS');
|
||||
return cb(data.data.error, data.data.data);
|
||||
}, function(data) {
|
||||
return cb(_setError('BitPay Error: Get Rates', data));
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* CONSTANTS
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -15,6 +15,16 @@ angular.module('copayApp.services').factory('configService', function(storageSer
|
|||
url: 'https://bws.bitpay.com/bws/api',
|
||||
},
|
||||
|
||||
download: {
|
||||
url: 'https://bitpay.com/wallet',
|
||||
},
|
||||
|
||||
rateApp: {
|
||||
ios: 'http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?id=1149581638&pageNumber=0&sortOrdering=2&type=Purple+Software&mt=8',
|
||||
android: 'https://play.google.com/store/apps/details?id=com.bitpay.wallet',
|
||||
wp: ''
|
||||
},
|
||||
|
||||
// wallet default config
|
||||
wallet: {
|
||||
requiredCopayers: 2,
|
||||
|
|
|
|||
|
|
@ -21,14 +21,10 @@ angular.module('copayApp.services').service('externalLinkService', function(plat
|
|||
_restoreHandleOpenURL(old);
|
||||
} else {
|
||||
if (optIn) {
|
||||
var message = gettextCatalog.getString(message),
|
||||
title = gettextCatalog.getString(title),
|
||||
okText = gettextCatalog.getString(okText),
|
||||
cancelText = gettextCatalog.getString(cancelText),
|
||||
openBrowser = function(res) {
|
||||
if (res) window.open(url, '_system');
|
||||
_restoreHandleOpenURL(old);
|
||||
};
|
||||
var openBrowser = function(res) {
|
||||
if (res) window.open(url, '_system');
|
||||
_restoreHandleOpenURL(old);
|
||||
};
|
||||
popupService.showConfirm(title, message, okText, cancelText, openBrowser);
|
||||
} else {
|
||||
window.open(url, '_system');
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.services').factory('feeService', function($log, $stateParams, bwcService, walletService, configService, gettext, lodash, txFormatService) {
|
||||
angular.module('copayApp.services').factory('feeService', function($log, $stateParams, bwcService, walletService, configService, gettext, lodash, txFormatService, gettextCatalog) {
|
||||
var root = {};
|
||||
|
||||
// Constant fee options to translate
|
||||
|
|
@ -15,48 +15,48 @@ angular.module('copayApp.services').factory('feeService', function($log, $stateP
|
|||
return configService.getSync().wallet.settings.feeLevel || 'normal';
|
||||
};
|
||||
|
||||
root.getCurrentFeeValue = function(cb) {
|
||||
console.log('[feeService.js.18:getCurrentFeeValue:] TODO TODO TODO'); //TODO
|
||||
// TODO TODO TODO
|
||||
var wallet = profileService.getWallet($stateParams.walletId);
|
||||
root.getCurrentFeeValue = function(network, cb) {
|
||||
network = network || 'livenet';
|
||||
var feeLevel = root.getCurrentFeeLevel();
|
||||
|
||||
wallet.getFeeLevels(wallet.credentials.network, function(err, levels) {
|
||||
if (err)
|
||||
return cb({
|
||||
message: 'Could not get dynamic fee'
|
||||
});
|
||||
root.getFeeLevels(function(err, levels) {
|
||||
if (err) return cb(err);
|
||||
|
||||
var feeLevelValue = lodash.find(levels, {
|
||||
var feeLevelValue = lodash.find(levels[network], {
|
||||
level: feeLevel
|
||||
});
|
||||
if (!feeLevelValue || !feeLevelValue.feePerKB)
|
||||
|
||||
if (!feeLevelValue || !feeLevelValue.feePerKB) {
|
||||
return cb({
|
||||
message: 'Could not get dynamic fee for level: ' + feeLevel
|
||||
message: gettextCatalog.getString("Could not get dynamic fee for level: {{feeLevel}}", {
|
||||
feeLevel: feeLevel
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
var fee = feeLevelValue.feePerKB;
|
||||
$log.debug('Dynamic fee: ' + feeLevel + ' ' + fee + ' SAT');
|
||||
|
||||
return cb(null, fee);
|
||||
});
|
||||
};
|
||||
|
||||
root.getFeeLevels = function(cb) {
|
||||
var walletClient = bwcService.getClient();
|
||||
|
||||
var unitName = configService.getSync().wallet.settings.unitName;
|
||||
|
||||
walletClient.getFeeLevels('livenet', function(errLivenet, levelsLivenet) {
|
||||
walletClient.getFeeLevels('testnet', function(errTestnet, levelsTestnet) {
|
||||
if (errLivenet || errTestnet) $log.debug('Could not get dynamic fee');
|
||||
else {
|
||||
if (errLivenet || errTestnet) {
|
||||
return cb(gettextCatalog.getString('Could not get dynamic fee'));
|
||||
} else {
|
||||
for (var i = 0; i < 4; i++) {
|
||||
levelsLivenet[i]['feePerKBUnit'] = txFormatService.formatAmount(levelsLivenet[i].feePerKB) + ' ' + unitName;
|
||||
levelsTestnet[i]['feePerKBUnit'] = txFormatService.formatAmount(levelsTestnet[i].feePerKB) + ' ' + unitName;
|
||||
}
|
||||
}
|
||||
|
||||
return cb({
|
||||
return cb(null, {
|
||||
'livenet': levelsLivenet,
|
||||
'testnet': levelsTestnet
|
||||
});
|
||||
|
|
|
|||
58
src/js/services/feedbackService.js
Normal file
58
src/js/services/feedbackService.js
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
'use strict';
|
||||
angular.module('copayApp.services').factory('feedbackService', function($http, $log, $httpParamSerializer, configService) {
|
||||
var root = {};
|
||||
var URL = "https://script.google.com/macros/s/AKfycbybtvNSQKUfgzgXcj3jYLlvCKrcBoktjiJ1V8_cwd2yVkpUBGe3/exec";
|
||||
|
||||
root.send = function(dataSrc, cb) {
|
||||
$http(_post(dataSrc)).then(function() {
|
||||
$log.info("SUCCESS: Feedback sent");
|
||||
return cb();
|
||||
}, function(err) {
|
||||
$log.info("ERROR: Feedback sent anyway.");
|
||||
return cb(err);
|
||||
});
|
||||
};
|
||||
|
||||
var _post = function(dataSrc) {
|
||||
return {
|
||||
method: 'POST',
|
||||
url: URL,
|
||||
headers: {
|
||||
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
|
||||
},
|
||||
data: $httpParamSerializer(dataSrc)
|
||||
};
|
||||
};
|
||||
|
||||
root.isVersionUpdated = function(currentVersion, savedVersion) {
|
||||
|
||||
if (!verifyTagFormat(currentVersion))
|
||||
return 'Cannot verify the format of version tag: ' + currentVersion;
|
||||
if (!verifyTagFormat(savedVersion))
|
||||
return 'Cannot verify the format of the saved version tag: ' + savedVersion;
|
||||
|
||||
var current = formatTagNumber(currentVersion);
|
||||
var saved = formatTagNumber(savedVersion);
|
||||
if (saved.major > current.major || (saved.major == current.major && saved.minor > current.minor))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
function verifyTagFormat(tag) {
|
||||
var regex = /^v?\d+\.\d+\.\d+$/i;
|
||||
return regex.exec(tag);
|
||||
};
|
||||
|
||||
function formatTagNumber(tag) {
|
||||
var formattedNumber = tag.replace(/^v/i, '').split('.');
|
||||
return {
|
||||
major: +formattedNumber[0],
|
||||
minor: +formattedNumber[1],
|
||||
patch: +formattedNumber[2]
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
return root;
|
||||
});
|
||||
|
|
@ -81,7 +81,7 @@ angular.module('copayApp.services').factory('glideraService', function($http, $l
|
|||
$http(req).then(function(data) {
|
||||
$log.info('Glidera Authorization Access Token: SUCCESS');
|
||||
// Show pending task from the UI
|
||||
storageService.setNextStep('BuyAndSell', true, function(err) {});
|
||||
storageService.setNextStep('BuyAndSell', 'true', function(err) {});
|
||||
return cb(null, data.data);
|
||||
}, function(data) {
|
||||
$log.error('Glidera Authorization Access Token: ERROR ' + data.statusText);
|
||||
|
|
@ -192,8 +192,13 @@ angular.module('copayApp.services').factory('glideraService', function($http, $l
|
|||
};
|
||||
|
||||
root.get2faCode = function(token, cb) {
|
||||
if (!token) return cb('Invalid Token');
|
||||
if (!token) {
|
||||
$log.error('Glidera Sent 2FA code by SMS: ERROR Invalid Token');
|
||||
return cb('Invalid Token');
|
||||
}
|
||||
|
||||
$http(_get('/authentication/get2faCode', token)).then(function(data) {
|
||||
|
||||
$log.info('Glidera Sent 2FA code by SMS: SUCCESS');
|
||||
return cb(null, data.status == 200 ? true : false);
|
||||
}, function(data) {
|
||||
|
|
|
|||
|
|
@ -31,17 +31,31 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
|
|||
if (!url) return;
|
||||
name = name.replace(/[\[\]]/g, "\\$&");
|
||||
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
|
||||
results = regex.exec(url);
|
||||
results = regex.exec(url);
|
||||
if (!results) return null;
|
||||
if (!results[2]) return '';
|
||||
return decodeURIComponent(results[2].replace(/\+/g, " "));
|
||||
}
|
||||
|
||||
function checkPrivateKey(privateKey) {
|
||||
try {
|
||||
new bitcore.PrivateKey(privateKey, 'livenet');
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// data extensions for Payment Protocol with non-backwards-compatible request
|
||||
if ((/^bitcoin:\?r=[\w+]/).exec(data)) {
|
||||
data = decodeURIComponent(data.replace('bitcoin:?r=', ''));
|
||||
$state.go('tabs.send', {}, {'reload': true, 'notify': $state.current.name == 'tabs.send' ? false : true}).then(function() {
|
||||
$state.transitionTo('tabs.send.confirm', {paypro: data});
|
||||
$state.go('tabs.send', {}, {
|
||||
'reload': true,
|
||||
'notify': $state.current.name == 'tabs.send' ? false : true
|
||||
}).then(function() {
|
||||
$state.transitionTo('tabs.send.confirm', {
|
||||
paypro: data
|
||||
});
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
|
@ -55,31 +69,43 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
|
|||
var addr = parsed.address ? parsed.address.toString() : '';
|
||||
var message = parsed.message;
|
||||
|
||||
var amount = parsed.amount ? parsed.amount : '';
|
||||
var amount = parsed.amount ? parsed.amount : '';
|
||||
|
||||
if (parsed.r) {
|
||||
payproService.getPayProDetails(parsed.r, function(err, details) {
|
||||
handlePayPro(details);
|
||||
});
|
||||
} else {
|
||||
$state.go('tabs.send', {}, {'reload': true, 'notify': $state.current.name == 'tabs.send' ? false : true});
|
||||
$state.go('tabs.send', {}, {
|
||||
'reload': true,
|
||||
'notify': $state.current.name == 'tabs.send' ? false : true
|
||||
});
|
||||
// Timeout is required to enable the "Back" button
|
||||
$timeout(function() {
|
||||
if (amount) {
|
||||
$state.transitionTo('tabs.send.confirm', {toAmount: amount, toAddress: addr, description:message});
|
||||
$state.transitionTo('tabs.send.confirm', {
|
||||
toAmount: amount,
|
||||
toAddress: addr,
|
||||
description: message
|
||||
});
|
||||
} else {
|
||||
$state.transitionTo('tabs.send.amount', {toAddress: addr});
|
||||
$state.transitionTo('tabs.send.amount', {
|
||||
toAddress: addr
|
||||
});
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
return true;
|
||||
|
||||
// Plain URL
|
||||
// Plain URL
|
||||
} else if (/^https?:\/\//.test(data)) {
|
||||
|
||||
payproService.getPayProDetails(data, function(err, details) {
|
||||
if(err) {
|
||||
root.showMenu({data: data, type: 'url'});
|
||||
if (err) {
|
||||
root.showMenu({
|
||||
data: data,
|
||||
type: 'url'
|
||||
});
|
||||
return;
|
||||
}
|
||||
handlePayPro(details);
|
||||
|
|
@ -87,47 +113,75 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
|
|||
});
|
||||
// Plain Address
|
||||
} else if (bitcore.Address.isValid(data, 'livenet') || bitcore.Address.isValid(data, 'testnet')) {
|
||||
if($state.includes('tabs.scan')) {
|
||||
root.showMenu({data: data, type: 'bitcoinAddress'});
|
||||
if ($state.includes('tabs.scan')) {
|
||||
root.showMenu({
|
||||
data: data,
|
||||
type: 'bitcoinAddress'
|
||||
});
|
||||
} else {
|
||||
goToAmountPage(data);
|
||||
}
|
||||
} else if (data && data.indexOf($window.appConfig.name + '://glidera') === 0) {
|
||||
return $state.go('uriglidera', {url: data});
|
||||
return $state.go('uriglidera', {
|
||||
url: data
|
||||
});
|
||||
} else if (data && data.indexOf($window.appConfig.name + '://coinbase') === 0) {
|
||||
return $state.go('uricoinbase', {url: data});
|
||||
return $state.go('uricoinbase', {
|
||||
url: data
|
||||
});
|
||||
|
||||
// BitPayCard Authentication
|
||||
} else if (data && data.indexOf($window.appConfig.name + '://') === 0) {
|
||||
var secret = getParameterByName('secret', data);
|
||||
var email = getParameterByName('email', data);
|
||||
var otp = getParameterByName('otp', data);
|
||||
$state.go('tabs.home', {}, {'reload': true, 'notify': $state.current.name == 'tabs.home' ? false : true}).then(function() {
|
||||
$state.transitionTo('tabs.bitpayCardIntro', {
|
||||
secret: secret,
|
||||
email: email,
|
||||
otp: otp
|
||||
});
|
||||
var secret = getParameterByName('secret', data);
|
||||
var email = getParameterByName('email', data);
|
||||
var otp = getParameterByName('otp', data);
|
||||
$state.go('tabs.home', {}, {
|
||||
'reload': true,
|
||||
'notify': $state.current.name == 'tabs.home' ? false : true
|
||||
}).then(function() {
|
||||
$state.transitionTo('tabs.bitpayCardIntro', {
|
||||
secret: secret,
|
||||
email: email,
|
||||
otp: otp
|
||||
});
|
||||
return true;
|
||||
});
|
||||
return true;
|
||||
|
||||
// Join
|
||||
// Join
|
||||
} else if (data && data.match(/^copay:[0-9A-HJ-NP-Za-km-z]{70,80}$/)) {
|
||||
$state.go('tabs.home', {}, {'reload': true, 'notify': $state.current.name == 'tabs.home' ? false : true}).then(function() {
|
||||
$state.transitionTo('tabs.add.join', {url: data});
|
||||
$state.go('tabs.home', {}, {
|
||||
'reload': true,
|
||||
'notify': $state.current.name == 'tabs.home' ? false : true
|
||||
}).then(function() {
|
||||
$state.transitionTo('tabs.add.join', {
|
||||
url: data
|
||||
});
|
||||
});
|
||||
return true;
|
||||
|
||||
// Old join
|
||||
// Old join
|
||||
} else if (data && data.match(/^[0-9A-HJ-NP-Za-km-z]{70,80}$/)) {
|
||||
$state.go('tabs.home', {}, {'reload': true, 'notify': $state.current.name == 'tabs.home' ? false : true}).then(function() {
|
||||
$state.transitionTo('tabs.add.join', {url: data});
|
||||
$state.go('tabs.home', {}, {
|
||||
'reload': true,
|
||||
'notify': $state.current.name == 'tabs.home' ? false : true
|
||||
}).then(function() {
|
||||
$state.transitionTo('tabs.add.join', {
|
||||
url: data
|
||||
});
|
||||
});
|
||||
return true;
|
||||
} else if (data && (data.substring(0, 2) == '6P' || checkPrivateKey(data))) {
|
||||
root.showMenu({
|
||||
data: data,
|
||||
type: 'privateKey'
|
||||
});
|
||||
} else {
|
||||
|
||||
if($state.includes('tabs.scan')) {
|
||||
root.showMenu({data: data, type: 'text'});
|
||||
if ($state.includes('tabs.scan')) {
|
||||
root.showMenu({
|
||||
data: data,
|
||||
type: 'text'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -136,13 +190,18 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
|
|||
};
|
||||
|
||||
function goToAmountPage(toAddress) {
|
||||
$state.go('tabs.send', {}, {'reload': true, 'notify': $state.current.name == 'tabs.send' ? false : true});
|
||||
$state.go('tabs.send', {}, {
|
||||
'reload': true,
|
||||
'notify': $state.current.name == 'tabs.send' ? false : true
|
||||
});
|
||||
$timeout(function() {
|
||||
$state.transitionTo('tabs.send.amount', {toAddress: toAddress});
|
||||
$state.transitionTo('tabs.send.amount', {
|
||||
toAddress: toAddress
|
||||
});
|
||||
}, 100);
|
||||
}
|
||||
|
||||
function handlePayPro(payProDetails){
|
||||
function handlePayPro(payProDetails) {
|
||||
var stateParams = {
|
||||
toAmount: payProDetails.amount,
|
||||
toAddress: payProDetails.toAddress,
|
||||
|
|
@ -150,7 +209,10 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
|
|||
paypro: payProDetails
|
||||
};
|
||||
scannerService.pausePreview();
|
||||
$state.go('tabs.send', {}, {'reload': true, 'notify': $state.current.name == 'tabs.send' ? false : true}).then(function() {
|
||||
$state.go('tabs.send', {}, {
|
||||
'reload': true,
|
||||
'notify': $state.current.name == 'tabs.send' ? false : true
|
||||
}).then(function() {
|
||||
$timeout(function() {
|
||||
$state.transitionTo('tabs.send.confirm', stateParams);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.services')
|
||||
.factory('localStorageService', function(platformInfo, $timeout, $log) {
|
||||
.factory('localStorageService', function(platformInfo, $timeout, $log, lodash) {
|
||||
var isNW = platformInfo.isNW;
|
||||
var isChromeApp = platformInfo.isChromeApp;
|
||||
var root = {};
|
||||
|
|
@ -45,6 +45,14 @@ angular.module('copayApp.services')
|
|||
root.set = function(k, v, cb) {
|
||||
if (isChromeApp || isNW) {
|
||||
var obj = {};
|
||||
|
||||
if (lodash.isObject(v)) {
|
||||
v = JSON.stringify(v);
|
||||
}
|
||||
if (!lodash.isString(v)) {
|
||||
v = v.toString();
|
||||
}
|
||||
|
||||
obj[k] = v;
|
||||
|
||||
chrome.storage.local.set(obj, cb);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ angular.module('copayApp.services').factory('ongoingProcess', function($log, $ti
|
|||
'recreating': gettext('Recreating Wallet...'),
|
||||
'rejectTx': gettext('Rejecting payment proposal'),
|
||||
'removeTx': gettext('Deleting payment proposal'),
|
||||
'retrivingInputs': gettext('Retrieving inputs information'),
|
||||
'retrievingInputs': gettext('Retrieving inputs information'),
|
||||
'scanning': gettext('Scanning Wallet funds...'),
|
||||
'sendingTx': gettext('Sending transaction'),
|
||||
'signingTx': gettext('Signing transaction'),
|
||||
|
|
@ -33,6 +33,13 @@ angular.module('copayApp.services').factory('ongoingProcess', function($log, $ti
|
|||
'validatingWallet': gettext('Validating wallet integrity...'),
|
||||
'validatingWords': gettext('Validating recovery phrase...'),
|
||||
'loadingTxInfo': gettext('Loading transaction info...'),
|
||||
'sendingFeedback': gettext('Sending feedback...'),
|
||||
'generatingNewAddress': gettext('Generating new address...'),
|
||||
'gettingAddresses': gettext('Getting addresses...'),
|
||||
'sendingByEmail': gettext('Preparing addresses...'),
|
||||
'sending2faCode': gettext('Sending 2FA code...'),
|
||||
'buyingBitcoin': gettext('Buying Bitcoin...'),
|
||||
'sellingBitcoin': gettext('Selling Bitcoin...')
|
||||
};
|
||||
|
||||
root.clear = function() {
|
||||
|
|
@ -64,7 +71,7 @@ angular.module('copayApp.services').factory('ongoingProcess', function($log, $ti
|
|||
|
||||
var showName = $filter('translate')(processNames[name] || name);
|
||||
|
||||
if(customHandler) {
|
||||
if (customHandler) {
|
||||
customHandler(processName, showName, isOn);
|
||||
} else if (root.onGoingProcessName) {
|
||||
if (isCordova) {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ angular.module('copayApp.services').service('popupService', function($log, $ioni
|
|||
$ionicPopup.prompt({
|
||||
title: title,
|
||||
subTitle: message,
|
||||
inputType: opts.inputType,
|
||||
cssClass: opts.class,
|
||||
template: '<input ng-model="data.response" type="' + opts.inputType + '" autofocus>',
|
||||
inputPlaceholder: opts.inputPlaceholder,
|
||||
defaultText: opts.defaultText
|
||||
}).then(function(res) {
|
||||
|
|
@ -51,12 +52,12 @@ angular.module('copayApp.services').service('popupService', function($log, $ioni
|
|||
|
||||
var _cordovaConfirm = function(title, message, okText, cancelText, cb) {
|
||||
var onConfirm = function(buttonIndex) {
|
||||
if (buttonIndex == 1) return cb(true);
|
||||
if (buttonIndex == 2) return cb(true);
|
||||
else return cb(false);
|
||||
}
|
||||
okText = okText || gettextCatalog.getString('OK');
|
||||
cancelText = cancelText || gettextCatalog.getString('Cancel');
|
||||
navigator.notification.confirm(message, onConfirm, title, [okText, cancelText]);
|
||||
navigator.notification.confirm(message, onConfirm, title, [cancelText, okText]);
|
||||
};
|
||||
|
||||
var _cordovaPrompt = function(title, message, opts, cb) {
|
||||
|
|
@ -118,7 +119,7 @@ angular.module('copayApp.services').service('popupService', function($log, $ioni
|
|||
this.showPrompt = function(title, message, opts, cb) {
|
||||
$log.warn(title ? (title + ': ' + message) : message);
|
||||
|
||||
opts = opts || {};
|
||||
opts = opts || {};
|
||||
|
||||
if (isCordova && !opts.forceHTMLPrompt)
|
||||
_cordovaPrompt(title, message, opts, cb);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
'use strict';
|
||||
angular.module('copayApp.services')
|
||||
.factory('profileService', function profileServiceFactory($rootScope, $timeout, $filter, $log, sjcl, lodash, storageService, bwcService, configService, pushNotificationsService, gettext, gettextCatalog, bwcError, uxLanguage, platformInfo, txFormatService, $state) {
|
||||
.factory('profileService', function profileServiceFactory($rootScope, $timeout, $filter, $log, sjcl, lodash, storageService, bwcService, configService, pushNotificationsService, gettextCatalog, bwcError, uxLanguage, platformInfo, txFormatService, $state) {
|
||||
|
||||
|
||||
var isChromeApp = platformInfo.isChromeApp;
|
||||
|
|
@ -361,14 +361,14 @@ angular.module('copayApp.services')
|
|||
|
||||
} catch (ex) {
|
||||
$log.info(ex);
|
||||
return cb(gettext('Could not create: Invalid wallet recovery phrase'));
|
||||
return cb(gettextCatalog.getString('Could not create: Invalid wallet recovery phrase'));
|
||||
}
|
||||
} else if (opts.extendedPrivateKey) {
|
||||
try {
|
||||
walletClient.seedFromExtendedPrivateKey(opts.extendedPrivateKey);
|
||||
} catch (ex) {
|
||||
$log.warn(ex);
|
||||
return cb(gettext('Could not create using the specified extended private key'));
|
||||
return cb(gettextCatalog.getString('Could not create using the specified extended private key'));
|
||||
}
|
||||
} else if (opts.extendedPublicKey) {
|
||||
try {
|
||||
|
|
@ -378,7 +378,7 @@ angular.module('copayApp.services')
|
|||
});
|
||||
} catch (ex) {
|
||||
$log.warn("Creating wallet from Extended Public Key Arg:", ex, opts);
|
||||
return cb(gettext('Could not create using the specified extended public key'));
|
||||
return cb(gettextCatalog.getString('Could not create using the specified extended public key'));
|
||||
}
|
||||
} else {
|
||||
var lang = uxLanguage.getCurrentLanguage();
|
||||
|
|
@ -421,7 +421,7 @@ angular.module('copayApp.services')
|
|||
singleAddress: opts.singleAddress,
|
||||
walletPrivKey: opts.walletPrivKey,
|
||||
}, function(err, secret) {
|
||||
if (err) return bwcError.cb(err, gettext('Error creating wallet'), cb);
|
||||
if (err) return bwcError.cb(err, gettextCatalog.getString('Error creating wallet'), cb);
|
||||
return cb(null, walletClient, secret);
|
||||
});
|
||||
});
|
||||
|
|
@ -451,11 +451,11 @@ angular.module('copayApp.services')
|
|||
if (lodash.find(root.profile.credentials, {
|
||||
'walletId': walletData.walletId
|
||||
})) {
|
||||
return cb(gettext('Cannot join the same wallet more that once'));
|
||||
return cb(gettextCatalog.getString('Cannot join the same wallet more that once'));
|
||||
}
|
||||
} catch (ex) {
|
||||
$log.debug(ex);
|
||||
return cb(gettext('Bad wallet invitation'));
|
||||
return cb(gettextCatalog.getString('Bad wallet invitation'));
|
||||
}
|
||||
opts.networkName = walletData.network;
|
||||
$log.debug('Joining Wallet:', opts);
|
||||
|
|
@ -464,7 +464,7 @@ angular.module('copayApp.services')
|
|||
if (err) return cb(err);
|
||||
|
||||
walletClient.joinWallet(opts.secret, opts.myName || 'me', {}, function(err) {
|
||||
if (err) return bwcError.cb(err, gettext('Could not join wallet'), cb);
|
||||
if (err) return bwcError.cb(err, gettextCatalog.getString('Could not join wallet'), cb);
|
||||
addAndBindWalletClient(walletClient, {
|
||||
bwsurl: opts.bwsurl
|
||||
}, cb);
|
||||
|
|
@ -521,12 +521,12 @@ angular.module('copayApp.services')
|
|||
// Adds and bind a new client to the profile
|
||||
var addAndBindWalletClient = function(client, opts, cb) {
|
||||
if (!client || !client.credentials)
|
||||
return cb(gettext('Could not access wallet'));
|
||||
return cb(gettextCatalog.getString('Could not access wallet'));
|
||||
|
||||
var walletId = client.credentials.walletId
|
||||
|
||||
if (!root.profile.addWallet(JSON.parse(client.export())))
|
||||
return cb(gettext('Wallet already in Copay'));
|
||||
return cb(gettextCatalog.getString('Wallet already in Copay'));
|
||||
|
||||
|
||||
var skipKeyValidation = root.profile.isChecked(platformInfo.ua, walletId);
|
||||
|
|
@ -595,15 +595,7 @@ angular.module('copayApp.services')
|
|||
password: opts.password
|
||||
});
|
||||
} catch (err) {
|
||||
return cb(gettext('Could not import. Check input file and spending password'));
|
||||
}
|
||||
|
||||
if (walletClient.hasPrivKeyEncrypted()) {
|
||||
try {
|
||||
walletClient.disablePrivateKeyEncryption();
|
||||
} catch (e) {
|
||||
$log.warn(e);
|
||||
}
|
||||
return cb(gettextCatalog.getString('Could not import. Check input file and spending password'));
|
||||
}
|
||||
|
||||
str = JSON.parse(str);
|
||||
|
|
@ -634,7 +626,7 @@ angular.module('copayApp.services')
|
|||
if (err instanceof errors.NOT_AUTHORIZED)
|
||||
return cb(err);
|
||||
|
||||
return bwcError.cb(err, gettext('Could not import'), cb);
|
||||
return bwcError.cb(err, gettextCatalog.getString('Could not import'), cb);
|
||||
}
|
||||
|
||||
addAndBindWalletClient(walletClient, {
|
||||
|
|
@ -665,7 +657,7 @@ angular.module('copayApp.services')
|
|||
if (err instanceof errors.NOT_AUTHORIZED)
|
||||
return cb(err);
|
||||
|
||||
return bwcError.cb(err, gettext('Could not import'), cb);
|
||||
return bwcError.cb(err, gettextCatalog.getString('Could not import'), cb);
|
||||
}
|
||||
|
||||
addAndBindWalletClient(walletClient, {
|
||||
|
|
@ -688,7 +680,7 @@ angular.module('copayApp.services')
|
|||
if (err instanceof errors.NOT_AUTHORIZED)
|
||||
err.name = 'WALLET_DOES_NOT_EXIST';
|
||||
|
||||
return bwcError.cb(err, gettext('Could not import'), cb);
|
||||
return bwcError.cb(err, gettextCatalog.getString('Could not import'), cb);
|
||||
}
|
||||
|
||||
addAndBindWalletClient(walletClient, {
|
||||
|
|
@ -773,6 +765,12 @@ angular.module('copayApp.services')
|
|||
});
|
||||
}
|
||||
|
||||
if (opts.m) {
|
||||
ret = lodash.filter(ret, function(w) {
|
||||
return (w.credentials.m == opts.m);
|
||||
});
|
||||
}
|
||||
|
||||
if (opts.onlyComplete) {
|
||||
ret = lodash.filter(ret, function(w) {
|
||||
return w.isComplete();
|
||||
|
|
@ -795,7 +793,7 @@ angular.module('copayApp.services')
|
|||
root.getNotifications = function(opts, cb) {
|
||||
opts = opts || {};
|
||||
|
||||
var TIME_STAMP = 60 * 60 * 24 * 7;
|
||||
var TIME_STAMP = 60 * 60 * 6;
|
||||
var MAX = 100;
|
||||
|
||||
var typeFilter = {
|
||||
|
|
@ -861,26 +859,25 @@ angular.module('copayApp.services')
|
|||
|
||||
var finale = shown; // GROUPING DISABLED!
|
||||
|
||||
// var finale = [],
|
||||
// prev;
|
||||
//
|
||||
//
|
||||
// // Item grouping... DISABLED.
|
||||
//
|
||||
// // REMOVE (if we want 1-to-1 notification) ????
|
||||
// lodash.each(shown, function(x) {
|
||||
// if (prev && prev.walletId === x.walletId && prev.txpId && prev.txpId === x.txpId && prev.creatorId && prev.creatorId === x.creatorId) {
|
||||
// prev.types.push(x.type);
|
||||
// prev.data = lodash.assign(prev.data, x.data);
|
||||
// prev.txid = prev.txid || x.txid;
|
||||
// prev.amountStr = prev.amountStr || x.amountStr;
|
||||
// prev.creatorName = prev.creatorName || x.creatorName;
|
||||
// } else {
|
||||
// finale.push(x);
|
||||
// prev = x;
|
||||
// }
|
||||
// });
|
||||
//
|
||||
var finale = [],
|
||||
prev;
|
||||
|
||||
|
||||
// Item grouping... DISABLED.
|
||||
|
||||
// REMOVE (if we want 1-to-1 notification) ????
|
||||
lodash.each(shown, function(x) {
|
||||
if (prev && prev.walletId === x.walletId && prev.txpId && prev.txpId === x.txpId && prev.creatorId && prev.creatorId === x.creatorId) {
|
||||
prev.types.push(x.type);
|
||||
prev.data = lodash.assign(prev.data, x.data);
|
||||
prev.txid = prev.txid || x.txid;
|
||||
prev.amountStr = prev.amountStr || x.amountStr;
|
||||
prev.creatorName = prev.creatorName || x.creatorName;
|
||||
} else {
|
||||
finale.push(x);
|
||||
prev = x;
|
||||
}
|
||||
});
|
||||
|
||||
var u = bwcService.getUtils();
|
||||
lodash.each(finale, function(x) {
|
||||
|
|
|
|||
|
|
@ -111,18 +111,24 @@ RateService.prototype.fromFiat = function(amount, code) {
|
|||
return amount / this.getRate(code) * this.BTC_TO_SAT;
|
||||
};
|
||||
|
||||
RateService.prototype.listAlternatives = function() {
|
||||
RateService.prototype.listAlternatives = function(sort) {
|
||||
var self = this;
|
||||
if (!this.isAvailable()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return self.lodash.map(this.getAlternatives(), function(item) {
|
||||
var alternatives = self.lodash.map(this.getAlternatives(), function(item) {
|
||||
return {
|
||||
name: item.name,
|
||||
isoCode: item.isoCode
|
||||
}
|
||||
});
|
||||
if (sort) {
|
||||
alternatives.sort(function(a, b) {
|
||||
return a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1;
|
||||
});
|
||||
}
|
||||
return self.lodash.uniq(alternatives, 'isoCode');
|
||||
};
|
||||
|
||||
angular.module('copayApp.services').factory('rateService', function($http, lodash) {
|
||||
|
|
|
|||
|
|
@ -77,23 +77,23 @@ angular.module('copayApp.services')
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// UPGRADING STORAGE
|
||||
//
|
||||
//
|
||||
// 1. Write a function to upgrade the desired storage key(s). The function should have the protocol:
|
||||
//
|
||||
//
|
||||
// _upgrade_x(key, network, cb), where:
|
||||
//
|
||||
//
|
||||
// `x` is the name of the storage key
|
||||
// `key` is the name of the storage key being upgraded
|
||||
// `key` is the name of the storage key being upgraded
|
||||
// `network` is one of 'livenet', 'testnet'
|
||||
//
|
||||
// 2. Add the storage key to `_upgraders` object using the name of the key as the `_upgrader` object key
|
||||
// with the value being the name of the upgrade function (e.g., _upgrade_x). In order to avoid conflicts
|
||||
// when a storage key is involved in multiple upgraders as well as predicte the order in which upgrades
|
||||
// occur the `_upgrader` object key should be prefixed with '##_' (e.g., '01_') to create a unique and
|
||||
// occur the `_upgrader` object key should be prefixed with '##_' (e.g., '01_') to create a unique and
|
||||
// sortable name. This format is interpreted by the _upgrade() function.
|
||||
//
|
||||
//
|
||||
// Upgraders are executed in numerical order per the '##_' object key prefix.
|
||||
//
|
||||
//
|
||||
var _upgraders = {
|
||||
'00_bitpayDebitCards' : _upgrade_bitpayDebitCards, // 2016-11: Upgrade bitpayDebitCards-x to bitpayAccounts-x
|
||||
'01_bitpayCardCredentials' : _upgrade_bitpayCardCredentials // 2016-11: Upgrade bitpayCardCredentials-x to appIdentity-x
|
||||
|
|
@ -244,6 +244,14 @@ angular.module('copayApp.services')
|
|||
storage.remove('profile', cb);
|
||||
};
|
||||
|
||||
root.setFeedbackInfo = function(feedbackValues, cb) {
|
||||
storage.set('feedback', feedbackValues, cb);
|
||||
};
|
||||
|
||||
root.getFeedbackInfo = function(cb) {
|
||||
storage.get('feedback', cb);
|
||||
};
|
||||
|
||||
root.storeFocusedWalletId = function(id, cb) {
|
||||
storage.set('focusedWalletId', id || '', cb);
|
||||
};
|
||||
|
|
@ -390,6 +398,14 @@ angular.module('copayApp.services')
|
|||
storage.remove('nextStep-' + service, cb);
|
||||
};
|
||||
|
||||
root.setLastCurrencyUsed = function(lastCurrencyUsed, cb) {
|
||||
storage.set('lastCurrencyUsed', lastCurrencyUsed, cb)
|
||||
};
|
||||
|
||||
root.getLastCurrencyUsed = function(cb) {
|
||||
storage.get('lastCurrencyUsed', cb)
|
||||
};
|
||||
|
||||
root.checkQuota = function() {
|
||||
var block = '';
|
||||
// 50MB
|
||||
|
|
@ -459,7 +475,10 @@ angular.module('copayApp.services')
|
|||
if (lodash.isEmpty(data) || !data.email) return cb('No card(s) to set');
|
||||
storage.get('bitpayAccounts-' + network, function(err, bitpayAccounts) {
|
||||
if (err) return cb(err);
|
||||
bitpayAccounts = JSON.parse(bitpayAccounts) || {};
|
||||
if (lodash.isString(bitpayAccounts)) {
|
||||
bitpayAccounts = JSON.parse(bitpayAccounts);
|
||||
}
|
||||
bitpayAccounts = bitpayAccounts || {};
|
||||
bitpayAccounts[data.email] = bitpayAccounts[data.email] || {};
|
||||
bitpayAccounts[data.email]['bitpayDebitCards-' + network] = data;
|
||||
storage.set('bitpayAccounts-' + network, JSON.stringify(bitpayAccounts), cb);
|
||||
|
|
@ -468,7 +487,10 @@ angular.module('copayApp.services')
|
|||
|
||||
root.getBitpayDebitCards = function(network, cb) {
|
||||
storage.get('bitpayAccounts-' + network, function(err, bitpayAccounts) {
|
||||
bitpayAccounts = JSON.parse(bitpayAccounts) || {};
|
||||
if (lodash.isString(bitpayAccounts)) {
|
||||
bitpayAccounts = JSON.parse(bitpayAccounts);
|
||||
}
|
||||
bitpayAccounts = bitpayAccounts || {};
|
||||
var cards = [];
|
||||
Object.keys(bitpayAccounts).forEach(function(email) {
|
||||
// For the UI, add the account email to the card object.
|
||||
|
|
@ -490,15 +512,20 @@ angular.module('copayApp.services')
|
|||
if (lodash.isEmpty(card) || !card.eid) return cb('No card to remove');
|
||||
storage.get('bitpayAccounts-' + network, function(err, bitpayAccounts) {
|
||||
if (err) cb(err);
|
||||
bitpayAccounts = JSON.parse(bitpayAccounts) || {};
|
||||
if (lodash.isString(bitpayAccounts)) {
|
||||
bitpayAccounts = JSON.parse(bitpayAccounts);
|
||||
}
|
||||
bitpayAccounts = bitpayAccounts || {};
|
||||
Object.keys(bitpayAccounts).forEach(function(userId) {
|
||||
var data = bitpayAccounts[userId]['bitpayDebitCards-' + network];
|
||||
var newCards = lodash.reject(data.cards, {'eid': card.eid});
|
||||
var newCards = lodash.reject(data.cards, {
|
||||
'eid': card.eid
|
||||
});
|
||||
data.cards = newCards;
|
||||
root.setBitpayDebitCards(network, data, function(err) {
|
||||
if (err) cb(err);
|
||||
// If there are no more cards in storage then re-enable the next step entry.
|
||||
root.getBitpayDebitCards(network, function(err, cards){
|
||||
root.getBitpayDebitCards(network, function(err, cards) {
|
||||
if (err) cb(err);
|
||||
if (cards.length == 0) {
|
||||
root.removeNextStep('BitpayCard', cb);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.services')
|
||||
.factory('trezor', function($log, $timeout, gettext, lodash, bitcore, hwWallet) {
|
||||
.factory('trezor', function($log, $timeout, lodash, bitcore, hwWallet) {
|
||||
var root = {};
|
||||
|
||||
var SETTLE_TIME = 3000;
|
||||
|
|
@ -82,7 +82,7 @@ angular.module('copayApp.services')
|
|||
if (txp.outputs.length > 1)
|
||||
return callback('Only single output TXPs are supported in TREZOR');
|
||||
} else {
|
||||
return callback('Unknown TXP at TREZOR');
|
||||
return callback('Unknown TXP at TREZOR');
|
||||
}
|
||||
|
||||
if (txp.outputs) {
|
||||
|
|
|
|||
|
|
@ -8,42 +8,39 @@ angular.module('copayApp.services')
|
|||
root.availableLanguages = [{
|
||||
name: 'English',
|
||||
isoCode: 'en',
|
||||
}, {
|
||||
name: 'Český',
|
||||
isoCode: 'cs',
|
||||
}, {
|
||||
name: 'Français',
|
||||
isoCode: 'fr',
|
||||
}, {
|
||||
name: 'Italiano',
|
||||
isoCode: 'it',
|
||||
}, {
|
||||
name: 'Deutsch',
|
||||
isoCode: 'de',
|
||||
}, {
|
||||
name: 'Español',
|
||||
isoCode: 'es',
|
||||
}, {
|
||||
name: '日本語',
|
||||
isoCode: 'ja',
|
||||
useIdeograms: true,
|
||||
}, {
|
||||
name: '中文(简体)',
|
||||
isoCode: 'zh',
|
||||
useIdeograms: true,
|
||||
}, {
|
||||
name: 'Polski',
|
||||
isoCode: 'pl',
|
||||
}, {
|
||||
name: 'Pусский',
|
||||
isoCode: 'ru',
|
||||
name: 'Français',
|
||||
isoCode: 'fr',
|
||||
// }, {
|
||||
// name: 'Český',
|
||||
// isoCode: 'cs',
|
||||
// }, {
|
||||
// name: 'Italiano',
|
||||
// isoCode: 'it',
|
||||
// }, {
|
||||
// name: 'Deutsch',
|
||||
// isoCode: 'de',
|
||||
// }, {
|
||||
// name: '日本語',
|
||||
// isoCode: 'ja',
|
||||
// useIdeograms: true,
|
||||
// }, {
|
||||
// name: '中文(简体)',
|
||||
// isoCode: 'zh',
|
||||
// useIdeograms: true,
|
||||
// }, {
|
||||
// name: 'Polski',
|
||||
// isoCode: 'pl',
|
||||
// }, {
|
||||
// name: 'Pусский',
|
||||
// isoCode: 'ru',
|
||||
}];
|
||||
|
||||
|
||||
root._detect = function(cb) {
|
||||
|
||||
return cb('en'); //disable auto detection for release;
|
||||
|
||||
var userLang, androidLang;
|
||||
if (navigator && navigator.globalization) {
|
||||
|
||||
|
|
|
|||
|
|
@ -29,16 +29,6 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
});
|
||||
};
|
||||
|
||||
// // RECEIVE
|
||||
// // Check address
|
||||
// root.isUsed(wallet.walletId, balance.byAddress, function(err, used) {
|
||||
// if (used) {
|
||||
// $log.debug('Address used. Creating new');
|
||||
// $rootScope.$emit('Local/AddressIsUsed');
|
||||
// }
|
||||
// });
|
||||
//
|
||||
|
||||
var _signWithLedger = function(wallet, txp, cb) {
|
||||
$log.info('Requesting Ledger Chrome app to sign the transaction');
|
||||
|
||||
|
|
@ -67,32 +57,6 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
});
|
||||
};
|
||||
|
||||
// TODO
|
||||
// This handles errors from BWS/index which normally
|
||||
// trigger from async events (like updates).
|
||||
// Debounce function avoids multiple popups
|
||||
var _handleError = function(err) {
|
||||
$log.warn('wallet ERROR: ', err);
|
||||
|
||||
$log.warn('TODO');
|
||||
return; // TODO!!!
|
||||
if (err instanceof errors.NOT_AUTHORIZED) {
|
||||
|
||||
console.log('[walletService.js.93] TODO NOT AUTH'); //TODO
|
||||
// TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
|
||||
wallet.notAuthorized = true;
|
||||
$state.go('tabs.home');
|
||||
} else if (err instanceof errors.NOT_FOUND) {
|
||||
popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Could not access Wallet Service: Not found'));
|
||||
} else {
|
||||
var msg = ""
|
||||
$rootScope.$emit('Local/ClientError', (err.error ? err.error : err));
|
||||
popupService.showAlert(gettextCatalog.getString('Error'), bwcError.msg(err, gettextCatalog.getString('Error at Wallet Service')));
|
||||
}
|
||||
};
|
||||
root.handleError = lodash.debounce(_handleError, 1000);
|
||||
|
||||
|
||||
root.invalidateCache = function(wallet) {
|
||||
if (wallet.cachedStatus)
|
||||
wallet.cachedStatus.isValid = false;
|
||||
|
|
@ -180,8 +144,9 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
if (err instanceof errors.NOT_AUTHORIZED) {
|
||||
return cb('WALLET_NOT_REGISTERED');
|
||||
}
|
||||
return cb(bwcError.msg(err, gettext('Could not update Wallet')));
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
return cb(null, ret);
|
||||
});
|
||||
};
|
||||
|
|
@ -196,19 +161,22 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
// Address with Balance
|
||||
cache.balanceByAddress = balance.byAddress;
|
||||
|
||||
// Total wallet balance is same regardless of 'spend unconfirmed funds' setting.
|
||||
cache.totalBalanceSat = balance.totalAmount;
|
||||
|
||||
// Spend unconfirmed funds
|
||||
if (config.spendUnconfirmed) {
|
||||
cache.totalBalanceSat = balance.totalAmount;
|
||||
cache.lockedBalanceSat = balance.lockedAmount;
|
||||
cache.availableBalanceSat = balance.availableAmount;
|
||||
cache.totalBytesToSendMax = balance.totalBytesToSendMax;
|
||||
cache.pendingAmount = null;
|
||||
cache.pendingAmount = 0;
|
||||
cache.spendableAmount = balance.totalAmount - balance.lockedAmount;
|
||||
} else {
|
||||
cache.totalBalanceSat = balance.totalConfirmedAmount;
|
||||
cache.lockedBalanceSat = balance.lockedConfirmedAmount;
|
||||
cache.availableBalanceSat = balance.availableConfirmedAmount;
|
||||
cache.totalBytesToSendMax = balance.totalBytesToSendConfirmedMax;
|
||||
cache.pendingAmount = balance.totalAmount - balance.totalConfirmedAmount;
|
||||
cache.spendableAmount = balance.totalConfirmedAmount - balance.lockedAmount;
|
||||
}
|
||||
|
||||
// Selected unit
|
||||
|
|
@ -220,25 +188,35 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
cache.totalBalanceStr = txFormatService.formatAmount(cache.totalBalanceSat) + ' ' + cache.unitName;
|
||||
cache.lockedBalanceStr = txFormatService.formatAmount(cache.lockedBalanceSat) + ' ' + cache.unitName;
|
||||
cache.availableBalanceStr = txFormatService.formatAmount(cache.availableBalanceSat) + ' ' + cache.unitName;
|
||||
cache.pendingBalanceStr = txFormatService.formatAmount(cache.totalBalanceSat + (cache.pendingAmount === null? 0 : cache.pendingAmount)) + ' ' + cache.unitName;
|
||||
|
||||
if (cache.pendingAmount !== null && cache.pendingAmount !== 0) {
|
||||
cache.pendingAmountStr = txFormatService.formatAmount(cache.pendingAmount) + ' ' + cache.unitName;
|
||||
} else {
|
||||
cache.pendingAmountStr = null;
|
||||
}
|
||||
cache.spendableBalanceStr = txFormatService.formatAmount(cache.spendableAmount) + ' ' + cache.unitName;
|
||||
cache.pendingBalanceStr = txFormatService.formatAmount(cache.pendingAmount) + ' ' + cache.unitName;
|
||||
|
||||
cache.alternativeName = config.settings.alternativeName;
|
||||
cache.alternativeIsoCode = config.settings.alternativeIsoCode;
|
||||
|
||||
// Check address
|
||||
root.isAddressUsed(wallet, balance.byAddress, function(err, used) {
|
||||
if (used) {
|
||||
$log.debug('Address used. Creating new');
|
||||
// Force new address
|
||||
root.getAddress(wallet, true, function(err, addr) {
|
||||
$log.debug('New address: ', addr);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
rateService.whenAvailable(function() {
|
||||
|
||||
var totalBalanceAlternative = rateService.toFiat(cache.totalBalanceSat, cache.alternativeIsoCode);
|
||||
var pendingBalanceAlternative = rateService.toFiat(cache.pendingAmount, cache.alternativeIsoCode);
|
||||
var lockedBalanceAlternative = rateService.toFiat(cache.lockedBalanceSat, cache.alternativeIsoCode);
|
||||
var spendableBalanceAlternative = rateService.toFiat(cache.spendableAmount, cache.alternativeIsoCode);
|
||||
var alternativeConversionRate = rateService.toFiat(100000000, cache.alternativeIsoCode);
|
||||
|
||||
cache.totalBalanceAlternative = $filter('formatFiatAmount')(totalBalanceAlternative);
|
||||
cache.pendingBalanceAlternative = $filter('formatFiatAmount')(pendingBalanceAlternative);
|
||||
cache.lockedBalanceAlternative = $filter('formatFiatAmount')(lockedBalanceAlternative);
|
||||
cache.spendableBalanceAlternative = $filter('formatFiatAmount')(spendableBalanceAlternative);
|
||||
cache.alternativeConversionRate = $filter('formatFiatAmount')(alternativeConversionRate);
|
||||
|
||||
cache.alternativeBalanceAvailable = true;
|
||||
|
|
@ -337,7 +315,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
return tx.txid != endingTxid;
|
||||
});
|
||||
|
||||
return cb(null, res, res.length == limit);
|
||||
return cb(null, res, res.length >= limit);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -428,7 +406,16 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
|
||||
function getNewTxs(newTxs, skip, cb) {
|
||||
getTxsFromServer(wallet, skip, endingTxid, requestLimit, function(err, res, shouldContinue) {
|
||||
if (err) return cb(err);
|
||||
if (err) {
|
||||
$log.warn(bwcError.msg(err, 'BWS Error')); //TODO
|
||||
if (err instanceof errors.CONNECTION_ERROR || (err.message && err.message.match(/5../))) {
|
||||
log.info('Retrying history download in 5 secs...');
|
||||
return $timeout(function() {
|
||||
return getNewTxs(newTxs, skip, cb);
|
||||
}, 5000);
|
||||
};
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
newTxs = newTxs.concat(processNewTxs(wallet, lodash.compact(res)));
|
||||
|
||||
|
|
@ -587,20 +574,13 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
if (lodash.isEmpty(txp) || lodash.isEmpty(wallet))
|
||||
return cb('MISSING_PARAMETER');
|
||||
|
||||
if (txp.sendMax) {
|
||||
wallet.createTxProposal(txp, function(err, createdTxp) {
|
||||
if (err) return cb(err);
|
||||
else return cb(null, createdTxp);
|
||||
});
|
||||
} else {
|
||||
wallet.createTxProposal(txp, function(err, createdTxp) {
|
||||
if (err) return cb(err);
|
||||
else {
|
||||
$log.debug('Transaction created');
|
||||
return cb(null, createdTxp);
|
||||
}
|
||||
});
|
||||
}
|
||||
wallet.createTxProposal(txp, function(err, createdTxp) {
|
||||
if (err) return cb(err);
|
||||
else {
|
||||
$log.debug('Transaction created');
|
||||
return cb(null, createdTxp);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
root.publishTx = function(wallet, txp, cb) {
|
||||
|
|
@ -760,12 +740,13 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
});
|
||||
};
|
||||
|
||||
root.isUsed = function(wallet, byAddress, cb) {
|
||||
// Check address
|
||||
root.isAddressUsed = function(wallet, byAddress, cb) {
|
||||
storageService.getLastAddress(wallet.id, function(err, addr) {
|
||||
var used = lodash.find(byAddress, {
|
||||
address: addr
|
||||
});
|
||||
return cb(null, used);
|
||||
return cb(err, used);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -797,13 +778,30 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
});
|
||||
};
|
||||
|
||||
root.getAddress = function(wallet, forceNew, cb) {
|
||||
root.getMainAddresses = function(wallet, opts, cb) {
|
||||
opts = opts || {};
|
||||
opts.reverse = true;
|
||||
wallet.getMainAddresses(opts, function(err, addresses) {
|
||||
return cb(err, addresses);
|
||||
});
|
||||
};
|
||||
|
||||
root.getBalance = function(wallet, opts, cb) {
|
||||
opts = opts || {};
|
||||
wallet.getBalance(opts, function(err, resp) {
|
||||
return cb(err, resp);
|
||||
});
|
||||
};
|
||||
|
||||
root.getAddress = function(wallet, forceNew, cb) {
|
||||
storageService.getLastAddress(wallet.id, function(err, addr) {
|
||||
if (err) return cb(err);
|
||||
|
||||
if (!forceNew && addr) return cb(null, addr);
|
||||
|
||||
if (!wallet.isComplete())
|
||||
return cb('WALLET_NOT_COMPLETE');
|
||||
|
||||
createAddress(wallet, function(err, _addr) {
|
||||
if (err) return cb(err, addr);
|
||||
storageService.storeLastAddress(wallet.id, _addr, function() {
|
||||
|
|
@ -829,7 +827,8 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
var askPassword = function(name, title, cb) {
|
||||
var opts = {
|
||||
inputType: 'password',
|
||||
forceHTMLPrompt: true
|
||||
forceHTMLPrompt: true,
|
||||
class: 'text-warn'
|
||||
};
|
||||
popupService.showPrompt(title, name, opts, function(res) {
|
||||
if (!res) return cb();
|
||||
|
|
@ -839,9 +838,12 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
|
||||
|
||||
root.encrypt = function(wallet, cb) {
|
||||
askPassword(wallet.name, gettext('Enter new spending password'), function(password) {
|
||||
var title = gettextCatalog.getString('Enter new spending password');
|
||||
var warnMsg = gettextCatalog.getString('Your wallet key will be encrypted. The Spending Password cannot be recovered. Be sure to write it down.');
|
||||
askPassword(warnMsg, title, function(password) {
|
||||
if (!password) return cb('no password');
|
||||
askPassword(wallet.name, gettext('Confirm you new spending password'), function(password2) {
|
||||
title = gettextCatalog.getString('Confirm you new spending password');
|
||||
askPassword(warnMsg, gettextCatalog.getString('Confirm you new spending password'), function(password2) {
|
||||
if (!password2 || password != password2)
|
||||
return cb('password mismatch');
|
||||
|
||||
|
|
@ -854,7 +856,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
|
||||
root.decrypt = function(wallet, cb) {
|
||||
$log.debug('Disabling private key encryption for' + wallet.name);
|
||||
askPassword(wallet.name, gettext('Enter Spending Password'), function(password) {
|
||||
askPassword(null, gettextCatalog.getString('Enter Spending Password'), function(password) {
|
||||
if (!password) return cb('no password');
|
||||
|
||||
try {
|
||||
|
|
@ -869,7 +871,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
root.handleEncryptedWallet = function(wallet, cb) {
|
||||
if (!root.isEncrypted(wallet)) return cb();
|
||||
|
||||
askPassword(wallet.name, gettext('Enter Spending Password'), function(password) {
|
||||
askPassword(wallet.name, gettextCatalog.getString('Enter Spending Password'), function(password) {
|
||||
if (!password) return cb('No password');
|
||||
if (!wallet.checkPassword(password)) return cb('Wrong password');
|
||||
|
||||
|
|
@ -892,20 +894,14 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
};
|
||||
|
||||
|
||||
root.onlyPublish = function(wallet, txp, cb) {
|
||||
ongoingProcess.set('sendingTx', true);
|
||||
root.onlyPublish = function(wallet, txp, cb, customStatusHandler) {
|
||||
ongoingProcess.set('sendingTx', true, customStatusHandler);
|
||||
root.publishTx(wallet, txp, function(err, publishedTxp) {
|
||||
root.invalidateCache(wallet);
|
||||
|
||||
ongoingProcess.set('sendingTx', false);
|
||||
if (err) return cb(err);
|
||||
|
||||
var type = root.getViewStatus(wallet, createdTxp);
|
||||
root.openStatusModal(type, createdTxp, function() {
|
||||
$rootScope.$emit('Local/TxAction', wallet.id);
|
||||
return;
|
||||
});
|
||||
return cb(null, publishedTxp);
|
||||
ongoingProcess.set('sendingTx', false, customStatusHandler);
|
||||
if (err) return cb(bwcError.msg(err));
|
||||
$rootScope.$emit('Local/TxAction', wallet.id);
|
||||
return cb();
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -934,13 +930,13 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
}
|
||||
|
||||
root.prepare(wallet, function(err, password) {
|
||||
if (err) return cb('Prepare error: ' + err);
|
||||
if (err) return cb(bwcError.msg(err));
|
||||
|
||||
ongoingProcess.set('sendingTx', true, customStatusHandler);
|
||||
|
||||
publishFn(wallet, txp, function(err, publishedTxp) {
|
||||
ongoingProcess.set('sendingTx', false, customStatusHandler);
|
||||
if (err) return cb('Send Error: ' + err);
|
||||
if (err) return cb(bwcError.msg(err));
|
||||
|
||||
ongoingProcess.set('signingTx', true, customStatusHandler);
|
||||
root.signTx(wallet, publishedTxp, password, function(err, signedTxp) {
|
||||
|
|
@ -950,10 +946,9 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
|
||||
if (err) {
|
||||
$log.warn('sign error:' + err);
|
||||
// TODO?
|
||||
var msg = err.message ?
|
||||
var msg = err && err.message ?
|
||||
err.message :
|
||||
gettext('The payment was created but could not be completed. Please try again from home screen');
|
||||
gettextCatalog.getString('The payment was created but could not be completed. Please try again from home screen');
|
||||
|
||||
$rootScope.$emit('Local/TxAction', wallet.id);
|
||||
return cb(msg);
|
||||
|
|
@ -963,7 +958,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
ongoingProcess.set('broadcastingTx', true, customStatusHandler);
|
||||
root.broadcastTx(wallet, signedTxp, function(err, broadcastedTxp) {
|
||||
ongoingProcess.set('broadcastingTx', false, customStatusHandler);
|
||||
if (err) return cb('sign error' + err);
|
||||
if (err) return cb(bwcError.msg(err));
|
||||
|
||||
$rootScope.$emit('Local/TxAction', wallet.id);
|
||||
var type = root.getViewStatus(wallet, broadcastedTxp);
|
||||
|
|
@ -1090,6 +1085,12 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
|
|||
return type;
|
||||
};
|
||||
|
||||
root.getSendMaxInfo = function(wallet, opts, cb) {
|
||||
opts = opts || {};
|
||||
wallet.getSendMaxInfo(opts, function(err, res) {
|
||||
return cb(err, res);
|
||||
});
|
||||
};
|
||||
|
||||
return root;
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue