2015-03-06 12:00:10 -03:00
'use strict' ;
angular . module ( 'copayApp.controllers' ) . controller ( 'importController' ,
2016-12-27 15:19:53 -03:00
function ( $scope , $timeout , $log , $state , $stateParams , $ionicHistory , $ionicScrollDelegate , profileService , configService , sjcl , ledger , trezor , derivationPathHelper , platformInfo , bwcService , ongoingProcess , walletService , popupService , gettextCatalog , appConfigService ) {
2016-05-31 14:55:08 -03:00
var isChromeApp = platformInfo . isChromeApp ;
var isDevel = platformInfo . isDevel ;
2015-03-06 12:00:10 -03:00
var reader = new FileReader ( ) ;
2015-10-16 12:35:18 -03:00
var defaults = configService . getDefaults ( ) ;
2016-06-07 17:11:57 -03:00
var errors = bwcService . getErrors ( ) ;
2016-09-06 16:40:57 -03:00
$scope . init = function ( ) {
$scope . isSafari = platformInfo . isSafari ;
$scope . isCordova = platformInfo . isCordova ;
$scope . formData = { } ;
$scope . formData . bwsurl = defaults . bws . url ;
$scope . formData . derivationPath = derivationPathHelper . default ;
$scope . formData . account = 1 ;
$scope . importErr = false ;
2016-12-27 15:19:53 -03:00
$scope . showHardwareWallet = appConfigService . name == 'copay' ;
2016-09-06 16:40:57 -03:00
if ( $stateParams . code )
$scope . processWalletInfo ( $stateParams . code ) ;
2016-06-29 10:19:49 -03:00
$scope . seedOptions = [ ] ;
2015-11-04 15:45:33 -03:00
2016-12-28 16:49:42 -03:00
if ( isChromeApp || isDevel ) {
2016-06-29 10:19:49 -03:00
$scope . seedOptions . push ( {
2015-11-05 16:00:38 -03:00
id : 'ledger' ,
2015-11-11 14:11:35 -03:00
label : 'Ledger Hardware Wallet' ,
2015-11-05 16:00:38 -03:00
} ) ;
2016-06-29 10:19:49 -03:00
$scope . seedOptions . push ( {
2015-11-05 16:00:38 -03:00
id : 'trezor' ,
2015-11-11 14:11:35 -03:00
label : 'Trezor Hardware Wallet' ,
2015-11-05 16:00:38 -03:00
} ) ;
2016-06-29 10:19:49 -03:00
$scope . seedSource = $scope . seedOptions [ 0 ] ;
2015-11-05 16:00:38 -03:00
}
2015-11-04 15:45:33 -03:00
} ;
2016-06-29 17:04:40 -03:00
$scope . processWalletInfo = function ( code ) {
2016-07-15 13:25:25 -03:00
if ( ! code ) return ;
2016-09-06 16:40:57 -03:00
2016-06-29 10:19:49 -03:00
$scope . importErr = false ;
2016-06-28 15:34:10 -03:00
var parsedCode = code . split ( '|' ) ;
2016-06-28 17:29:47 -03:00
2016-06-29 17:04:40 -03:00
if ( parsedCode . length != 5 ) {
2016-06-30 17:28:09 -03:00
/// Trying to import a malformed wallet export QR code
2016-09-01 10:56:13 -03:00
popupService . showAlert ( gettextCatalog . getString ( 'Error' ) , gettextCatalog . getString ( 'Incorrect code format' ) ) ;
2016-06-28 17:29:47 -03:00
return ;
}
2016-06-28 15:34:10 -03:00
var info = {
type : parsedCode [ 0 ] ,
2016-06-28 17:29:47 -03:00
data : parsedCode [ 1 ] ,
2016-06-29 17:04:40 -03:00
network : parsedCode [ 2 ] ,
derivationPath : parsedCode [ 3 ] ,
hasPassphrase : parsedCode [ 4 ] == 'true' ? true : false
2016-06-28 15:34:10 -03:00
} ;
2016-06-29 12:24:31 -03:00
if ( info . type == 1 && info . hasPassphrase )
2016-10-26 17:10:21 -03:00
popupService . showAlert ( gettextCatalog . getString ( 'Error' ) , gettextCatalog . getString ( 'Password required. Make sure to enter your password in advanced options' ) ) ;
2016-06-29 12:24:31 -03:00
2016-09-06 16:40:57 -03:00
$scope . formData . derivationPath = info . derivationPath ;
$scope . formData . testnetEnabled = info . network == 'testnet' ? true : false ;
2016-06-28 15:34:10 -03:00
$timeout ( function ( ) {
2016-09-06 16:40:57 -03:00
$scope . formData . words = info . data ;
$scope . $apply ( ) ;
2016-06-28 15:34:10 -03:00
} , 1 ) ;
2015-08-24 17:09:59 -03:00
} ;
var _importBlob = function ( str , opts ) {
2015-04-30 13:03:30 -03:00
var str2 , err ;
2015-03-06 12:00:10 -03:00
try {
2016-09-06 15:11:02 -03:00
str2 = sjcl . decrypt ( $scope . formData . password , str ) ;
2015-03-06 12:00:10 -03:00
} catch ( e ) {
2016-09-01 10:56:13 -03:00
err = gettextCatalog . getString ( 'Could not decrypt file, check your password' ) ;
2015-03-06 12:00:10 -03:00
$log . warn ( e ) ;
} ;
2015-04-30 13:03:30 -03:00
if ( err ) {
2016-09-01 10:56:13 -03:00
popupService . showAlert ( gettextCatalog . getString ( 'Error' ) , err ) ;
2015-04-30 13:03:30 -03:00
return ;
}
2016-06-13 15:25:40 -03:00
ongoingProcess . set ( 'importingWallet' , true ) ;
2015-10-20 12:03:08 -03:00
opts . compressed = null ;
opts . password = null ;
2015-03-06 12:00:10 -03:00
$timeout ( function ( ) {
2016-08-18 00:27:23 -03:00
profileService . importWallet ( str2 , opts , function ( err , client ) {
2016-06-13 15:25:40 -03:00
ongoingProcess . set ( 'importingWallet' , false ) ;
2015-03-06 12:00:10 -03:00
if ( err ) {
2016-09-01 10:56:13 -03:00
popupService . showAlert ( gettextCatalog . getString ( 'Error' ) , err ) ;
2016-08-15 16:07:30 -03:00
return ;
2015-03-06 12:00:10 -03:00
}
2016-09-01 16:03:43 -03:00
finish ( client ) ;
2015-03-06 12:00:10 -03:00
} ) ;
} , 100 ) ;
} ;
2015-10-20 12:03:08 -03:00
var _importExtendedPrivateKey = function ( xPrivKey , opts ) {
2016-06-13 15:25:40 -03:00
ongoingProcess . set ( 'importingWallet' , true ) ;
2015-09-05 00:11:14 -03:00
$timeout ( function ( ) {
2016-08-18 00:27:23 -03:00
profileService . importExtendedPrivateKey ( xPrivKey , opts , function ( err , client ) {
2016-06-13 15:25:40 -03:00
ongoingProcess . set ( 'importingWallet' , false ) ;
2015-09-05 00:11:14 -03:00
if ( err ) {
2016-06-07 17:11:57 -03:00
if ( err instanceof errors . NOT _AUTHORIZED ) {
2016-06-29 10:19:49 -03:00
$scope . importErr = true ;
2016-06-07 17:11:57 -03:00
} else {
2016-09-01 10:56:13 -03:00
popupService . showAlert ( gettextCatalog . getString ( 'Error' ) , err ) ;
2016-06-07 17:11:57 -03:00
}
2015-09-05 00:11:14 -03:00
return $timeout ( function ( ) {
$scope . $apply ( ) ;
} ) ;
}
2016-09-01 16:03:43 -03:00
finish ( client ) ;
2015-09-05 00:11:14 -03:00
} ) ;
} , 100 ) ;
} ;
2016-06-29 17:04:40 -03:00
/ *
IMPORT FROM PUBLIC KEY - PENDING
var _importExtendedPublicKey = function ( xPubKey , opts ) {
ongoingProcess . set ( 'importingWallet' , true ) ;
$timeout ( function ( ) {
profileService . importExtendedPublicKey ( opts , function ( err , walletId ) {
ongoingProcess . set ( 'importingWallet' , false ) ;
if ( err ) {
$scope . error = err ;
return $timeout ( function ( ) {
$scope . $apply ( ) ;
} ) ;
}
2016-09-01 16:08:41 -03:00
profileService . setBackupFlag ( walletId ) ;
if ( $stateParams . fromOnboarding ) {
profileService . setDisclaimerAccepted ( function ( err ) {
if ( err ) $log . error ( err ) ;
} ) ;
}
2016-09-06 15:11:02 -03:00
2016-08-19 13:07:18 -03:00
$state . go ( 'tabs.home' ) ;
2016-06-29 17:04:40 -03:00
} ) ;
} , 100 ) ;
} ;
* /
2015-09-03 01:49:48 -03:00
var _importMnemonic = function ( words , opts ) {
2016-06-13 15:25:40 -03:00
ongoingProcess . set ( 'importingWallet' , true ) ;
2015-08-24 17:09:59 -03:00
$timeout ( function ( ) {
2016-08-18 00:27:23 -03:00
profileService . importMnemonic ( words , opts , function ( err , client ) {
2016-06-13 15:25:40 -03:00
ongoingProcess . set ( 'importingWallet' , false ) ;
2016-06-07 16:16:38 -03:00
2016-06-07 17:11:57 -03:00
if ( err ) {
if ( err instanceof errors . NOT _AUTHORIZED ) {
2016-06-29 10:19:49 -03:00
$scope . importErr = true ;
2016-06-07 17:11:57 -03:00
} else {
2016-09-01 10:56:13 -03:00
popupService . showAlert ( gettextCatalog . getString ( 'Error' ) , err ) ;
2016-06-07 17:11:57 -03:00
}
2015-08-24 17:09:59 -03:00
return $timeout ( function ( ) {
$scope . $apply ( ) ;
} ) ;
}
2016-09-01 16:03:43 -03:00
finish ( client ) ;
2015-08-24 17:09:59 -03:00
} ) ;
} , 100 ) ;
} ;
2016-09-06 15:11:02 -03:00
$scope . setDerivationPath = function ( ) {
2016-09-06 16:40:57 -03:00
$scope . formData . derivationPath = $scope . formData . testnetEnabled ? derivationPathHelper . defaultTestnet : derivationPathHelper . default ;
2016-06-28 15:34:10 -03:00
} ;
2016-06-15 10:24:46 -03:00
2015-03-06 12:00:10 -03:00
$scope . getFile = function ( ) {
// If we use onloadend, we need to check the readyState.
reader . onloadend = function ( evt ) {
if ( evt . target . readyState == FileReader . DONE ) { // DONE == 2
2015-10-20 12:03:08 -03:00
var opts = { } ;
2016-09-06 15:11:02 -03:00
opts . bwsurl = $scope . formData . bwsurl ;
2015-10-20 12:03:08 -03:00
_importBlob ( evt . target . result , opts ) ;
2015-03-06 12:00:10 -03:00
}
}
} ;
2016-06-29 10:19:49 -03:00
$scope . importBlob = function ( form ) {
2015-03-06 12:00:10 -03:00
if ( form . $invalid ) {
2016-09-01 10:56:13 -03:00
popupService . showAlert ( gettextCatalog . getString ( 'Error' ) , gettextCatalog . getString ( 'There is an error in the form' ) ) ;
2015-03-06 12:00:10 -03:00
return ;
}
2016-09-06 15:11:02 -03:00
var backupFile = $scope . formData . file ;
var backupText = $scope . formData . backupText ;
var password = $scope . formData . password ;
2015-03-06 12:00:10 -03:00
if ( ! backupFile && ! backupText ) {
2016-09-01 10:56:13 -03:00
popupService . showAlert ( gettextCatalog . getString ( 'Error' ) , gettextCatalog . getString ( 'Please, select your backup file' ) ) ;
2015-03-06 12:00:10 -03:00
return ;
}
if ( backupFile ) {
reader . readAsBinaryString ( backupFile ) ;
} else {
2015-10-20 12:03:08 -03:00
var opts = { } ;
2016-09-06 15:11:02 -03:00
opts . bwsurl = $scope . formData . bwsurl ;
2015-10-20 12:03:08 -03:00
_importBlob ( backupText , opts ) ;
2015-08-24 17:09:59 -03:00
}
} ;
2016-06-29 10:19:49 -03:00
$scope . importMnemonic = function ( form ) {
2015-08-24 17:09:59 -03:00
if ( form . $invalid ) {
2016-09-01 10:56:13 -03:00
popupService . showAlert ( gettextCatalog . getString ( 'Error' ) , gettextCatalog . getString ( 'There is an error in the form' ) ) ;
2015-08-24 17:09:59 -03:00
return ;
}
var opts = { } ;
2016-09-06 15:11:02 -03:00
if ( $scope . formData . bwsurl )
opts . bwsurl = $scope . formData . bwsurl ;
2016-09-06 16:40:57 -03:00
var pathData = derivationPathHelper . parse ( $scope . formData . derivationPath ) ;
2016-05-09 12:03:25 -03:00
if ( ! pathData ) {
2016-09-01 10:56:13 -03:00
popupService . showAlert ( gettextCatalog . getString ( 'Error' ) , gettextCatalog . getString ( 'Invalid derivation path' ) ) ;
2016-05-09 12:03:25 -03:00
return ;
}
2016-09-06 15:11:02 -03:00
2016-05-09 12:03:25 -03:00
opts . account = pathData . account ;
opts . networkName = pathData . networkName ;
opts . derivationStrategy = pathData . derivationStrategy ;
2016-09-06 15:11:02 -03:00
var words = $scope . formData . words || null ;
2015-08-24 17:09:59 -03:00
2015-09-02 15:56:00 -03:00
if ( ! words ) {
2016-10-26 17:10:21 -03:00
popupService . showAlert ( gettextCatalog . getString ( 'Error' ) , gettextCatalog . getString ( 'Please enter the recovery phrase' ) ) ;
2016-12-29 13:37:00 -03:00
return ;
2015-10-16 12:35:18 -03:00
} else if ( words . indexOf ( 'xprv' ) == 0 || words . indexOf ( 'tprv' ) == 0 ) {
2015-10-20 12:03:08 -03:00
return _importExtendedPrivateKey ( words , opts ) ;
2016-06-29 17:04:40 -03:00
} else if ( words . indexOf ( 'xpub' ) == 0 || words . indexOf ( 'tpuv' ) == 0 ) {
return _importExtendedPublicKey ( words , opts ) ;
2015-09-02 15:56:00 -03:00
} else {
2015-09-15 12:07:34 -03:00
var wordList = words . split ( /[\u3000\s]+/ ) ;
2015-09-05 01:02:01 -03:00
2016-05-30 16:32:28 -03:00
if ( ( wordList . length % 3 ) != 0 ) {
2016-10-26 17:10:21 -03:00
popupService . showAlert ( gettextCatalog . getString ( 'Error' ) , gettextCatalog . getString ( 'Wrong number of recovery words: ' ) + wordList . length ) ;
2016-09-01 10:56:13 -03:00
return ;
2016-05-30 16:32:28 -03:00
}
2015-09-02 15:56:00 -03:00
}
2016-09-06 15:11:02 -03:00
opts . passphrase = $scope . formData . passphrase || null ;
2015-09-03 01:49:48 -03:00
_importMnemonic ( words , opts ) ;
2015-03-06 12:00:10 -03:00
} ;
2015-09-04 21:18:20 -03:00
2016-06-29 10:19:49 -03:00
$scope . importTrezor = function ( account , isMultisig ) {
2015-11-04 00:53:26 -03:00
trezor . getInfoForNewWallet ( isMultisig , account , function ( err , lopts ) {
2016-06-13 15:25:40 -03:00
ongoingProcess . clear ( ) ;
2015-09-29 12:45:06 -03:00
if ( err ) {
2016-09-01 10:56:13 -03:00
popupService . showAlert ( gettextCatalog . getString ( 'Error' ) , err ) ;
2015-09-29 12:45:06 -03:00
return ;
}
2015-10-20 12:46:46 -03:00
2015-09-29 12:45:06 -03:00
lopts . externalSource = 'trezor' ;
2016-09-06 16:40:57 -03:00
lopts . bwsurl = $scope . formData . bwsurl ;
2016-06-13 15:25:40 -03:00
ongoingProcess . set ( 'importingWallet' , true ) ;
2015-09-29 12:45:06 -03:00
$log . debug ( 'Import opts' , lopts ) ;
2015-10-20 12:46:46 -03:00
2016-08-15 16:07:30 -03:00
profileService . importExtendedPublicKey ( lopts , function ( err , wallet ) {
2016-06-13 15:25:40 -03:00
ongoingProcess . set ( 'importingWallet' , false ) ;
2015-09-29 12:45:06 -03:00
if ( err ) {
2016-09-01 10:56:13 -03:00
popupService . showAlert ( gettextCatalog . getString ( 'Error' ) , err ) ;
return ;
2015-09-29 12:45:06 -03:00
}
2016-09-01 16:03:43 -03:00
finish ( wallet ) ;
2015-09-29 12:45:06 -03:00
} ) ;
} , 100 ) ;
} ;
2016-06-29 10:19:49 -03:00
$scope . importHW = function ( form ) {
2016-12-28 16:49:42 -03:00
if ( form . $invalid || $scope . formData . account < 0 ) {
2016-10-26 17:10:21 -03:00
popupService . showAlert ( gettextCatalog . getString ( 'Error' ) , gettextCatalog . getString ( 'There is an error in the form' ) ) ;
2015-09-04 21:18:20 -03:00
return ;
}
2016-09-06 16:40:57 -03:00
2016-06-29 10:19:49 -03:00
$scope . importErr = false ;
2015-11-04 15:45:33 -03:00
2016-12-28 16:49:42 -03:00
var account = $scope . formData . account ;
2016-05-30 16:32:28 -03:00
2016-09-06 16:40:57 -03:00
if ( $scope . seedSource . id == 'trezor' ) {
2016-05-30 16:32:28 -03:00
if ( account < 1 ) {
2016-10-26 17:10:21 -03:00
popupService . showAlert ( gettextCatalog . getString ( 'Error' ) , gettextCatalog . getString ( 'Invalid account number' ) ) ;
2015-11-05 19:46:32 -03:00
return ;
}
account = account - 1 ;
}
2015-11-04 15:45:33 -03:00
2016-09-06 16:40:57 -03:00
switch ( $scope . seedSource . id ) {
2015-11-04 15:45:33 -03:00
case ( 'ledger' ) :
2016-06-13 15:25:40 -03:00
ongoingProcess . set ( 'connectingledger' , true ) ;
2016-06-29 10:19:49 -03:00
$scope . importLedger ( account ) ;
2015-11-04 15:45:33 -03:00
break ;
case ( 'trezor' ) :
2016-06-13 15:25:40 -03:00
ongoingProcess . set ( 'connectingtrezor' , true ) ;
2016-09-06 16:40:57 -03:00
$scope . importTrezor ( account , $scope . formData . isMultisig ) ;
2015-11-04 15:45:33 -03:00
break ;
default :
throw ( 'Error: bad source id' ) ;
} ;
} ;
2016-06-29 10:19:49 -03:00
$scope . importLedger = function ( account ) {
2015-11-04 00:53:26 -03:00
ledger . getInfoForNewWallet ( true , account , function ( err , lopts ) {
2016-06-13 15:25:40 -03:00
ongoingProcess . clear ( ) ;
2015-09-04 21:18:20 -03:00
if ( err ) {
2016-09-01 10:56:13 -03:00
popupService . showAlert ( gettextCatalog . getString ( 'Error' ) , err ) ;
2015-09-04 21:18:20 -03:00
return ;
}
2015-10-20 12:46:46 -03:00
2015-09-04 21:18:20 -03:00
lopts . externalSource = 'ledger' ;
2016-09-06 16:40:57 -03:00
lopts . bwsurl = $scope . formData . bwsurl ;
2016-06-13 15:25:40 -03:00
ongoingProcess . set ( 'importingWallet' , true ) ;
2015-09-04 21:18:20 -03:00
$log . debug ( 'Import opts' , lopts ) ;
2015-10-20 12:46:46 -03:00
2016-08-15 16:07:30 -03:00
profileService . importExtendedPublicKey ( lopts , function ( err , wallet ) {
2016-06-13 15:25:40 -03:00
ongoingProcess . set ( 'importingWallet' , false ) ;
2015-09-04 21:18:20 -03:00
if ( err ) {
2016-09-01 10:56:13 -03:00
popupService . showAlert ( gettextCatalog . getString ( 'Error' ) , err ) ;
return ;
2015-09-04 21:18:20 -03:00
}
2016-09-01 16:03:43 -03:00
finish ( wallet ) ;
} ) ;
} , 100 ) ;
} ;
2016-08-15 16:07:30 -03:00
2016-09-01 16:03:43 -03:00
var finish = function ( wallet ) {
walletService . updateRemotePreferences ( wallet , { } , function ( ) {
$log . debug ( 'Remote preferences saved for:' + wallet . credentials . walletId )
} ) ;
2016-08-30 17:31:29 -03:00
2016-09-01 16:03:43 -03:00
profileService . setBackupFlag ( wallet . credentials . walletId ) ;
if ( $stateParams . fromOnboarding ) {
profileService . setDisclaimerAccepted ( function ( err ) {
if ( err ) $log . error ( err ) ;
2015-09-04 21:18:20 -03:00
} ) ;
2016-09-01 16:03:43 -03:00
}
2016-09-23 12:42:33 -03:00
$ionicHistory . removeBackView ( ) ;
2016-09-19 12:06:46 -03:00
$state . go ( 'tabs.home' , {
fromOnboarding : $stateParams . fromOnboarding
} ) ;
2015-09-04 21:18:20 -03:00
} ;
2016-10-12 17:43:23 -03:00
$scope . showAdvChange = function ( ) {
$scope . showAdv = ! $scope . showAdv ;
$scope . resizeView ( ) ;
} ;
$scope . resizeView = function ( ) {
$timeout ( function ( ) {
$ionicScrollDelegate . resize ( ) ;
2016-12-14 15:37:15 -03:00
} , 10 ) ;
2016-10-12 17:43:23 -03:00
} ;
2016-12-19 17:56:43 -03:00
$scope . $on ( "$ionicView.beforeEnter" , function ( event , data ) {
$scope . init ( ) ;
} ) ;
2015-03-06 12:00:10 -03:00
} ) ;