2014-04-17 11:46:49 -03:00
'use strict' ;
2014-06-12 17:42:26 -03:00
var bitcore = require ( 'bitcore' ) ;
2014-04-17 11:46:49 -03:00
2014-06-03 17:42:36 -03:00
angular . module ( 'copayApp.services' )
2014-09-02 10:48:22 -03:00
. factory ( 'controllerUtils' , function ( $rootScope , $sce , $location , notification , $timeout , uriHandler , rateService ) {
2014-08-22 13:13:04 -04:00
var root = { } ;
2014-05-07 19:04:36 -03:00
2014-08-22 13:13:04 -04:00
root . redirIfLogged = function ( ) {
if ( $rootScope . wallet ) {
2014-08-29 12:33:56 -03:00
$location . path ( 'receive' ) ;
2014-08-22 13:13:04 -04:00
}
} ;
2014-08-06 18:41:37 -03:00
2014-08-22 13:13:04 -04:00
root . logout = function ( ) {
if ( $rootScope . wallet )
2014-08-28 18:58:43 -03:00
$rootScope . wallet . close ( ) ;
2014-06-24 12:57:15 -03:00
2014-08-22 13:13:04 -04:00
$rootScope . wallet = null ;
delete $rootScope [ 'wallet' ] ;
2014-04-23 18:07:20 -03:00
2014-08-22 13:13:04 -04:00
// Clear rootScope
for ( var i in $rootScope ) {
if ( i . charAt ( 0 ) != '$' ) {
delete $rootScope [ i ] ;
}
}
2014-06-12 11:03:24 -03:00
2014-08-22 13:13:04 -04:00
$location . path ( '/' ) ;
} ;
2014-06-12 11:03:24 -03:00
2014-08-22 13:13:04 -04:00
root . onError = function ( scope ) {
if ( scope ) scope . loading = false ;
root . logout ( ) ;
2014-08-12 15:26:15 -04:00
}
2014-08-22 13:13:04 -04:00
root . onErrorDigest = function ( scope , msg ) {
root . onError ( scope ) ;
if ( msg ) {
notification . error ( 'Error' , msg ) ;
2014-08-12 15:26:15 -04:00
}
2014-08-22 13:13:04 -04:00
} ;
2014-07-08 08:58:24 -03:00
2014-09-09 15:30:21 -03:00
root . installWalletHandlers = function ( w , $scope ) {
w . on ( 'connectionError' , function ( ) {
var message = "Could not connect to the Insight server. Check your settings and network configuration" ;
notification . error ( 'Networking Error' , message ) ;
2014-08-22 13:13:04 -04:00
root . onErrorDigest ( $scope ) ;
} ) ;
2014-09-09 15:30:21 -03:00
w . on ( 'ready' , function ( ) {
2014-08-22 13:13:04 -04:00
$scope . loading = false ;
} ) ;
2014-04-24 23:13:55 -03:00
2014-08-22 13:13:04 -04:00
w . on ( 'corrupt' , function ( peerId ) {
notification . error ( 'Error' , 'Received corrupt message from ' + peerId ) ;
} ) ;
w . on ( 'ready' , function ( myPeerID ) {
$rootScope . wallet = w ;
if ( $rootScope . pendingPayment ) {
$location . path ( 'send' ) ;
} else {
$location . path ( 'receive' ) ;
}
} ) ;
2014-05-16 18:48:17 -03:00
2014-08-22 13:13:04 -04:00
w . on ( 'publicKeyRingUpdated' , function ( dontDigest ) {
2014-09-09 19:05:23 -03:00
root . updateAddressList ( ) ;
2014-08-22 13:13:04 -04:00
if ( ! dontDigest ) {
$rootScope . $digest ( ) ;
}
} ) ;
2014-09-09 15:30:21 -03:00
2014-09-09 15:40:12 -03:00
w . on ( 'tx' , function ( address ) {
notification . funds ( 'Funds received!' , address ) ;
2014-09-09 15:30:21 -03:00
root . updateBalance ( function ( ) {
$rootScope . $digest ( ) ;
} ) ;
} ) ;
w . on ( 'balanceUpdated' , function ( ) {
root . updateBalance ( function ( ) {
$rootScope . $digest ( ) ;
} ) ;
} ) ;
2014-09-09 20:55:51 -03:00
w . on ( 'insightReconnected' , function ( ) {
2014-09-09 15:30:21 -03:00
$rootScope . reconnecting = false ;
2014-09-09 20:55:51 -03:00
root . updateAddressList ( ) ;
2014-09-09 15:30:21 -03:00
root . updateBalance ( function ( ) {
$rootScope . $digest ( ) ;
} ) ;
} ) ;
2014-09-09 20:55:51 -03:00
w . on ( 'insightError' , function ( ) {
2014-09-09 15:30:21 -03:00
$rootScope . reconnecting = true ;
$rootScope . $digest ( ) ;
} ) ;
2014-08-22 13:13:04 -04:00
w . on ( 'txProposalsUpdated' , function ( dontDigest ) {
root . updateTxs ( ) ;
// give sometime to the tx to propagate.
$timeout ( function ( ) {
root . updateBalance ( function ( ) {
if ( ! dontDigest ) {
$rootScope . $digest ( ) ;
}
} ) ;
} , 3000 ) ;
} ) ;
w . on ( 'txProposalEvent' , function ( e ) {
2014-09-09 21:31:25 -03:00
2014-08-22 13:13:04 -04:00
var user = w . publicKeyRing . nicknameForCopayer ( e . cId ) ;
switch ( e . type ) {
case 'signed' :
notification . info ( 'Transaction Update' , 'A transaction was signed by ' + user ) ;
break ;
case 'rejected' :
notification . info ( 'Transaction Update' , 'A transaction was rejected by ' + user ) ;
break ;
case 'corrupt' :
notification . error ( 'Transaction Error' , 'Received corrupt transaction from ' + user ) ;
break ;
}
} ) ;
w . on ( 'addressBookUpdated' , function ( dontDigest ) {
if ( ! dontDigest ) {
$rootScope . $digest ( ) ;
}
} ) ;
w . on ( 'connect' , function ( peerID ) {
2014-05-09 11:59:38 -03:00
$rootScope . $digest ( ) ;
2014-08-22 13:13:04 -04:00
} ) ;
w . on ( 'close' , root . onErrorDigest ) ;
w . on ( 'locked' , root . onErrorDigest . bind ( this ) ) ;
2014-09-09 15:30:21 -03:00
} ;
root . setupRootVariables = function ( ) {
uriHandler . register ( ) ;
$rootScope . unitName = config . unitName ;
$rootScope . txAlertCount = 0 ;
$rootScope . reconnecting = false ;
$rootScope . isCollapsed = true ;
$rootScope . $watch ( 'txAlertCount' , function ( txAlertCount ) {
if ( txAlertCount && txAlertCount > 0 ) {
notification . info ( 'New Transaction' , ( $rootScope . txAlertCount == 1 ) ? 'You have a pending transaction proposal' : 'You have ' + $rootScope . txAlertCount + ' pending transaction proposals' , txAlertCount ) ;
}
} ) ;
} ;
root . startNetwork = function ( w , $scope ) {
root . setupRootVariables ( ) ;
root . installWalletHandlers ( w , $scope ) ;
2014-09-09 19:05:23 -03:00
root . updateAddressList ( ) ;
2014-09-09 15:30:21 -03:00
notification . enableHtml5Mode ( ) ; // for chrome: if support, enable it
2014-08-22 13:13:04 -04:00
w . netStart ( ) ;
} ;
2014-06-16 12:44:18 -03:00
2014-09-09 15:53:47 -03:00
// TODO movie this to wallet
2014-08-22 13:13:04 -04:00
root . updateAddressList = function ( ) {
var w = $rootScope . wallet ;
if ( w && w . isReady ( ) )
$rootScope . addrInfos = w . getAddressesInfo ( ) ;
} ;
2014-05-13 04:03:09 -03:00
2014-08-22 13:13:04 -04:00
root . updateBalance = function ( cb ) {
var w = $rootScope . wallet ;
if ( ! w ) return root . onErrorDigest ( ) ;
if ( ! w . isReady ( ) ) return ;
2014-09-03 11:27:58 -03:00
w . removeTxWithSpentInputs ( ) ;
2014-08-22 13:13:04 -04:00
$rootScope . balanceByAddr = { } ;
$rootScope . updatingBalance = true ;
w . getBalance ( function ( err , balanceSat , balanceByAddrSat , safeBalanceSat ) {
2014-08-29 10:50:52 -03:00
if ( err ) throw err ;
2014-05-20 14:34:55 -07:00
2014-09-04 11:12:08 -03:00
var satToUnit = 1 / w . settings . unitToSatoshi ;
2014-08-22 13:13:04 -04:00
var COIN = bitcore . util . COIN ;
2014-08-06 13:59:33 -03:00
2014-08-22 13:13:04 -04:00
$rootScope . totalBalance = balanceSat * satToUnit ;
$rootScope . totalBalanceBTC = ( balanceSat / COIN ) ;
$rootScope . availableBalance = safeBalanceSat * satToUnit ;
$rootScope . availableBalanceBTC = ( safeBalanceSat / COIN ) ;
2014-06-16 12:44:18 -03:00
2014-08-22 13:13:04 -04:00
$rootScope . lockedBalance = ( balanceSat - safeBalanceSat ) * satToUnit ;
$rootScope . lockedBalanceBTC = ( balanceSat - safeBalanceSat ) / COIN ;
2014-05-13 04:03:09 -03:00
2014-08-22 13:13:04 -04:00
var balanceByAddr = { } ;
for ( var ii in balanceByAddrSat ) {
balanceByAddr [ ii ] = balanceByAddrSat [ ii ] * satToUnit ;
}
$rootScope . balanceByAddr = balanceByAddr ;
root . updateAddressList ( ) ;
$rootScope . updatingBalance = false ;
2014-09-01 10:42:30 -03:00
rateService . whenAvailable ( function ( ) {
2014-09-04 11:59:26 -03:00
$rootScope . totalBalanceAlternative = rateService . toFiat ( balanceSat , w . settings . alternativeIsoCode ) ;
$rootScope . alternativeIsoCode = w . settings . alternativeIsoCode ;
$rootScope . lockedBalanceAlternative = rateService . toFiat ( balanceSat - safeBalanceSat , w . settings . alternativeIsoCode ) ;
2014-09-01 10:42:30 -03:00
return cb ? cb ( ) : null ;
} ) ;
2014-08-22 13:13:04 -04:00
} ) ;
} ;
2014-08-04 13:54:08 -03:00
2014-08-22 13:13:04 -04:00
root . updateTxs = function ( opts ) {
var w = $rootScope . wallet ;
if ( ! w ) return ;
opts = opts || $rootScope . txsOpts || { } ;
2014-09-04 11:12:08 -03:00
var satToUnit = 1 / w . settings . unitToSatoshi ;
2014-08-22 13:13:04 -04:00
var myCopayerId = w . getMyCopayerId ( ) ;
var pendingForUs = 0 ;
var inT = w . getTxProposals ( ) . sort ( function ( t1 , t2 ) {
return t2 . createdTs - t1 . createdTs
} ) ;
var txs = [ ] ;
inT . forEach ( function ( i , index ) {
if ( opts . skip && ( index < opts . skip [ 0 ] || index >= opts . skip [ 1 ] ) ) {
return txs . push ( null ) ;
}
if ( myCopayerId != i . creator && ! i . finallyRejected && ! i . sentTs && ! i . rejectedByUs && ! i . signedByUs ) {
pendingForUs ++ ;
}
if ( ! i . finallyRejected && ! i . sentTs ) {
i . isPending = 1 ;
}
if ( ! ! opts . pending == ! ! i . isPending ) {
var tx = i . builder . build ( ) ;
var outs = [ ] ;
tx . outs . forEach ( function ( o ) {
2014-09-11 11:29:45 -07:00
var addr = bitcore . Address . fromScriptPubKey ( o . getScript ( ) , w . getNetworkName ( ) ) [ 0 ] . toString ( ) ;
2014-08-22 13:13:04 -04:00
if ( ! w . addressIsOwn ( addr , {
excludeMain : true
} ) ) {
outs . push ( {
address : addr ,
value : bitcore . util . valueToBigInt ( o . getValue ( ) ) * satToUnit ,
} ) ;
}
} ) ;
// extra fields
i . outs = outs ;
i . fee = i . builder . feeSat * satToUnit ;
i . missingSignatures = tx . countInputMissingSignatures ( 0 ) ;
i . actionList = getActionList ( i . peerActions ) ;
txs . push ( i ) ;
}
} ) ;
$rootScope . txs = txs ;
$rootScope . txsOpts = opts ;
if ( $rootScope . pendingTxCount < pendingForUs ) {
$rootScope . txAlertCount = pendingForUs ;
2014-08-12 15:26:15 -04:00
}
2014-08-22 13:13:04 -04:00
$rootScope . pendingTxCount = pendingForUs ;
} ;
2014-08-12 15:26:15 -04:00
2014-08-22 13:13:04 -04:00
function getActionList ( actions ) {
var peers = Object . keys ( actions ) . map ( function ( i ) {
return {
cId : i ,
actions : actions [ i ]
}
} ) ;
return peers . sort ( function ( a , b ) {
return ! ! b . actions . create - ! ! a . actions . create ;
} ) ;
2014-08-04 13:54:08 -03:00
}
2014-08-22 13:13:04 -04:00
return root ;
} ) ;