From 7349e8237a7316670d123f55757814a7502d3fdf Mon Sep 17 00:00:00 2001 From: matiu Date: Sat, 9 Sep 2017 21:14:27 -0300 Subject: [PATCH] refactor duplicate --- app-template/package-template.json | 2 +- src/js/controllers/cashScan.js | 131 ++++++++++++++++++++--------- src/js/controllers/tab-home.js | 2 + src/js/services/onGoingProcess.js | 3 +- src/js/services/profileService.js | 1 - src/js/services/walletService.js | 40 ++++++++- www/views/cashScan.html | 23 +++-- www/views/tab-home.html | 5 +- 8 files changed, 152 insertions(+), 55 deletions(-) diff --git a/app-template/package-template.json b/app-template/package-template.json index 7f7dc5d84..22e23c632 100644 --- a/app-template/package-template.json +++ b/app-template/package-template.json @@ -56,7 +56,7 @@ "bezier-easing": "^2.0.3", "bhttp": "1.2.1", "bitauth": "^0.2.1", - "bitcore-wallet-client": "6.0.1", + "bitcore-wallet-client": "6.1.0", "bower": "^1.7.9", "cordova-android": "5.1.1", "cordova-custom-config": "^3.0.5", diff --git a/src/js/controllers/cashScan.js b/src/js/controllers/cashScan.js index 311502aab..4bc429e07 100644 --- a/src/js/controllers/cashScan.js +++ b/src/js/controllers/cashScan.js @@ -1,48 +1,62 @@ - 'use strict'; angular.module('copayApp.controllers').controller('cashScanController', - function($rootScope, $timeout, $scope, $state, $stateParams, $ionicModal, $ionicScrollDelegate, $window, gettextCatalog, lodash, popupService, ongoingProcess, profileService, walletService, configService, $log, txFormatService, bwcError, pushNotificationsService, bwcService) { + function($rootScope, $timeout, $scope, $state, $stateParams, $ionicModal, $ionicScrollDelegate, $window, gettextCatalog, lodash, popupService, ongoingProcess, profileService, walletService, configService, $log, txFormatService, bwcError, pushNotificationsService, bwcService) { var wallet; var errors = bwcService.getErrors(); - $scope.error = null; + $scope.error = null; $scope.$on("$ionicView.enter", function(event, data) { updateAllWallets(); }); var updateAllWallets = function() { - var wallets = profileService.getWallets({coin:'btc', onlyComplete:true, network: 'livenet' }); + var wallets1 = profileService.getWallets({ + coin: 'btc', + onlyComplete: true, + network: 'livenet' + }); + + if (lodash.isEmpty(wallets1)) { + $state.go('tabs.home'); + return; + } + + // Filter out already duplicated wallets + var walletsBCH = profileService.getWallets({ + coin: 'bch', + network: 'livenet' + }); + var xPubKeyIndex = lodash.indexBy(walletsBCH, "credentials.xPubKey"); + + wallets1 = lodash.filter(wallets1, function(w) { + return !xPubKeyIndex[w.credentials.xPubKey]; + }); - var kk = lodash.indexBy(wallets,"credentials.xPubKey"); - - - // TODO ? - if (lodash.isEmpty(wallets)) return; - - - var walletsBCH = profileService.getWallets({coin:'bch', network: 'livenet' }); - var xPubKeyIndex = lodash.indexBy(walletsBCH,"credentials.xPubKey"); - -// wallets= lodash.filter(wallets,function(w) { return !xPubKeyIndex[w.credentials.xPubKey]; }); + // Filter out non BIP44 wallets + var wallets = lodash.filter(wallets1, function(w) { + return w.credentials.derivationStrategy == 'BIP44' + }); $scope.wallets = wallets; + $scope.nonBIP44 = wallets1.length != wallets.length; var i = wallets.length; var j = 0; lodash.each(wallets, function(wallet) { - walletService.getBalance(wallet, {coin:'bch'}, function(err, balance) { + walletService.getBalance(wallet, { + coin: 'bch' + }, function(err, balance) { if (err) { wallet.error = (err === 'WALLET_NOT_REGISTERED') ? gettextCatalog.getString('Wallet not registered') : bwcError.msg(err); $log.error(err); return; - } -// + } + // -console.log('[otherBalance.js.28:balance:]',balance); //TODO wallet.error = null; wallet.bchBalance = txFormatService.formatAmountStr('bch', balance.availableAmount); if (++j == i) { @@ -58,24 +72,26 @@ console.log('[otherBalance.js.28:balance:]',balance); //TODO }; $scope.duplicate = function(wallet) { - $scope.error = null; - $log.debug('Duplicating wallet for BCH:' + wallet.id + ':' + wallet.name); + $scope.error = null; + $log.debug('Duplicating wallet for BCH:' + wallet.id + ':' + wallet.name); var opts = {}; opts.name = wallet.name + '[BCH]'; opts.m = wallet.m; opts.n = wallet.n; - opts.myName = wallet.credentials.copayerName; + opts.myName = wallet.credentials.copayerName; opts.networkName = wallet.network; opts.coin = 'bch'; + opts.walletPrivKey = wallet.credentials.walletPrivKey; + opts.compliantDerivation = wallet.credentials.compliantDerivation; - // TODO: finger print / decrypt - $log.warn('TODO finger print / decrypt'); - opts.extendedPrivateKey = wallet.credentials.xPrivKey; function setErr(err, cb) { - $scope.error = bwcError.cb(err, gettextCatalog.getString('Could not duplicate'), function() { - return cb(err); + + if (!cb) cb = function() {}; + + $scope.error = bwcError.cb(err, gettextCatalog.getString('Could not duplicate'), function() { + return cb(err); }); $timeout(function() { $rootScope.$apply(); @@ -83,35 +99,70 @@ console.log('[otherBalance.js.28:balance:]',balance); //TODO } function importOrCreate(cb) { - walletService.getStatus(wallet, {}, function(err, status){ + walletService.getStatus(wallet, {}, function(err, status) { if (err) return cb(err); - opts.singleAddress = status.wallet.singleAddress; + opts.singleAddress = status.wallet.singleAddress; // first try to import - profileService.importExtendedPrivateKey(opts.extendedPrivateKey, opts, function(err, client) { - if (err && !(err instanceof errors.NOT_AUTHORIZED) ) { + profileService.importExtendedPrivateKey(opts.extendedPrivateKey, opts, function(err, newWallet) { + if (err && !(err instanceof errors.NOT_AUTHORIZED)) { return setErr(err, cb); } if (err) { // create and store a wallet - return profileService.createWallet(opts, function(err, client) { + return profileService.createWallet(opts, function(err, newWallet) { if (err) return setErr(err, cb); - return cb(null, client, true); + return cb(null, newWallet, true); }); } - return cb(null, client); + return cb(null, newWallet); }); }); }; + // Multisig wallets? add Copayers + function addCopayers(newWallet, isNew, cb) { + if (!isNew) return cb(); + if (wallet.n == 1) return cb(); - importOrCreate(function(err, client, isNew) { - if (err) return; - walletService.updateRemotePreferences(client); - pushNotificationsService.updateSubscription(client); - walletService.startScan(wallet, function() { }); - $state.go('tabs.home'); + $log.info('Adding copayers for BCH wallet config:' + wallet.m + '-' + wallet.n); + + walletService.copyCopayers(wallet, newWallet, function(err) { + if (err) return setErr(err, cb); + + return cb(); + }); + }; + + walletService.getKeys(wallet,function(err,keys) { + if (err) { + $scope.error = err; + return $timeout(function() { + $rootScope.$apply(); + }, 10); + } + opts.extendedPrivateKey = keys.xPrivKey; + ongoingProcess.set('duplicatingWallet', true); + importOrCreate(function(err, newWallet, isNew) { + if (err) { + ongoingProcess.set('duplicatingWallet', false); + return; + } + walletService.updateRemotePreferences(newWallet); + pushNotificationsService.updateSubscription(newWallet); + + addCopayers(newWallet, isNew, function(err) { + ongoingProcess.set('duplicatingWallet', false); + if (err) + return setErr(err); + + if (isNew) + walletService.startScan(newWallet, function() {}); + + $state.go('tabs.home'); + }); + }); }); } }); diff --git a/src/js/controllers/tab-home.js b/src/js/controllers/tab-home.js index 79be14391..a3a614e21 100644 --- a/src/js/controllers/tab-home.js +++ b/src/js/controllers/tab-home.js @@ -224,6 +224,7 @@ angular.module('copayApp.controllers').controller('tabHomeController', wallet.error = null; wallet.status = status; + wallet.updating = status && status.wallet && status.wallet.scanStatus == 'running'; // TODO service refactor? not in profile service profileService.setLastKnownBalance(wallet.id, wallet.status.totalBalanceStr, function() {}); } @@ -242,6 +243,7 @@ angular.module('copayApp.controllers').controller('tabHomeController', return; } wallet.status = status; + wallet.updating = status && status.wallet && status.wallet.scanStatus == 'running'; updateTxps(); }); }; diff --git a/src/js/services/onGoingProcess.js b/src/js/services/onGoingProcess.js index e0f82fc40..94d746202 100644 --- a/src/js/services/onGoingProcess.js +++ b/src/js/services/onGoingProcess.js @@ -45,7 +45,8 @@ angular.module('copayApp.services').factory('ongoingProcess', function($log, $ti 'cancelingGiftCard': 'Canceling Gift Card...', 'creatingGiftCard': 'Creating Gift Card...', 'buyingGiftCard': 'Buying Gift Card...', - 'topup': gettext('Top up in progress...') + 'topup': gettext('Top up in progress...'), + 'duplicatingWallet': gettext('Duplicating wallet...'), }; root.clear = function() { diff --git a/src/js/services/profileService.js b/src/js/services/profileService.js index d944eca43..f93fc03a8 100644 --- a/src/js/services/profileService.js +++ b/src/js/services/profileService.js @@ -386,7 +386,6 @@ angular.module('copayApp.services') } } } - return cb(null, walletClient); }; // Creates a wallet on BWC/BWS diff --git a/src/js/services/walletService.js b/src/js/services/walletService.js index 3768cecaa..b456fae61 100644 --- a/src/js/services/walletService.js +++ b/src/js/services/walletService.js @@ -259,6 +259,8 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim }; function cacheStatus(status) { + if (status.wallet && status.wallet.scanStatus == 'running') return; + wallet.cachedStatus = status ||  {}; var cache = wallet.cachedStatus; cache.statusUpdatedOn = Date.now(); @@ -931,15 +933,17 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim // Approx utxo amount, from which the uxto is economically redeemable root.getLowAmount = function(wallet, feeLevels, nbOutputs) { - var minFee = root.getMinFee(wallet,feeLevels, nbOutputs); - return parseInt( minFee / LOW_AMOUNT_RATIO); + var minFee = root.getMinFee(wallet, feeLevels, nbOutputs); + return parseInt(minFee / LOW_AMOUNT_RATIO); }; root.getLowUtxos = function(wallet, levels, cb) { - wallet.getUtxos({coin: wallet.coin}, function(err, resp) { + wallet.getUtxos({ + coin: wallet.coin + }, function(err, resp) { if (err || !resp || !resp.length) return cb(); var minFee = root.getMinFee(wallet, levels, resp.length); @@ -955,7 +959,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim var totalLow = lodash.sum(lowUtxos, 'satoshis'); return cb(err, { - allUtxos: resp || [], + allUtxos: resp || [], lowUtxos: lowUtxos || [], warning: minFee / balance > TOTAL_LOW_WARNING_RATIO, minFee: minFee, @@ -1237,5 +1241,33 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim else return 'bitcoin'; } + + root.copyCopayers = function(wallet, newWallet, cb) { + var c = wallet.credentials; + + var walletPrivKey = bitcore.PrivateKey.fromString(c.walletPrivKey); + + var copayer = 1, + i = 0, + l = c.publicKeyRing.length; + var mainErr = null; + + lodash.each(c.publicKeyRing, function(item) { + var name = item.copayerName || ('copayer ' + copayer++); + newWallet._doJoinWallet(newWallet.credentials.walletId, walletPrivKey, item.xPubKey, item.requestPubKey, name, { + coin: newWallet.credentials.coin, + }, function(err) { + //Ignore error is copayer already in wallet + if (err && !(err instanceof errors.COPAYER_IN_WALLET)) { + mainErr = err; + } + + if (++i == l) { + return cb(mainErr); + } + }); + }); + }; + return root; }); diff --git a/www/views/cashScan.html b/www/views/cashScan.html index 1d8c0a9af..602154605 100644 --- a/www/views/cashScan.html +++ b/www/views/cashScan.html @@ -14,10 +14,17 @@ BTC Wallets - {{wallet.error}} +
+ {{error}} +
+ +
+ Some of you wallets are not elegible for Bitcon Cash support because there where created before Copay v1.2. Please use our recovery tool to access your Bitcoin Cash balance for those wallets +
+
@@ -26,16 +33,20 @@ {{wallet.name || wallet.id}}

- {{wallet.bchBalance || 'Checking...'}} + {{wallet.bchBalance || 'Checking...'}} {{wallet.m}}-of-{{wallet.n}}  

- + + +
+ +
diff --git a/www/views/tab-home.html b/www/views/tab-home.html index 6ac7c2bca..da3764c50 100644 --- a/www/views/tab-home.html +++ b/www/views/tab-home.html @@ -95,9 +95,10 @@ TODO Remove: Incomplete - {{wallet.status.totalBalanceStr ? wallet.status.totalBalanceStr : ( wallet.cachedBalance ? wallet.cachedBalance + (wallet.cachedBalanceUpdatedOn ? ' · ' + ( wallet.cachedBalanceUpdatedOn * 1000 | amTimeAgo) : '') : '' ) }} + {{wallet.status.totalBalanceStr ? wallet.status.totalBalanceStr : ( wallet.cachedBalance ? wallet.cachedBalance + (wallet.cachedBalanceUpdatedOn ? ' · ' + ( wallet.cachedBalanceUpdatedOn * 1000 | amTimeAgo) : '') : '' ) }} + Scanning for funds... - [Balance Hidden] + [Balance Hidden] {{wallet.m}}-of-{{wallet.n}}