2014-04-16 17:50:10 -03:00
'use strict' ;
2014-09-03 01:25:08 -03:00
var preconditions = require ( 'preconditions' ) . singleton ( ) ;
2014-04-16 17:50:10 -03:00
2014-08-01 01:09:46 -03:00
var TxProposals = require ( './TxProposals' ) ;
2014-04-16 17:50:10 -03:00
var PublicKeyRing = require ( './PublicKeyRing' ) ;
var PrivateKey = require ( './PrivateKey' ) ;
var Wallet = require ( './Wallet' ) ;
2014-09-04 01:33:12 -03:00
var _ = require ( 'underscore' ) ;
2014-09-23 15:24:57 -03:00
var log = require ( '../log' ) ;
2014-09-03 01:25:08 -03:00
var PluginManager = require ( './PluginManager' ) ;
2014-09-23 15:24:57 -03:00
var Async = module . exports . Async = require ( './Async' ) ;
var Insight = module . exports . Insight = require ( './Insight' ) ;
2014-09-10 13:56:49 -07:00
var preconditions = require ( 'preconditions' ) . singleton ( ) ;
2014-09-23 15:24:57 -03:00
var Storage = module . exports . Storage = require ( './Storage' ) ;
2014-06-15 20:55:23 -07:00
2014-09-04 01:33:12 -03:00
/ * *
* @ desc
2014-09-26 05:00:43 -03:00
* Identity - stores the state for a wallet in creation
2014-09-04 01:33:12 -03:00
*
* @ param { Object } config - configuration for this wallet
*
* @ TODO : Don ' t pass a class for these three components
* -- send a factory or instance , the 'new' call considered harmful for refactoring
* -- arguable , since all of them is called with an object as argument .
* -- Still , could it be hard to refactor ? ( for example , what if we want to fail hard if a network call gets interrupted ? )
* @ param { Storage } config . Storage - the class to instantiate to store the wallet ( StorageLocalEncrypted by default )
* @ param { Object } config . storage - the configuration to be sent to the Storage constructor
* @ param { Network } config . Network - the class to instantiate to make network requests to copayers ( the Async module by default )
2014-09-10 11:12:28 -07:00
* @ param { Object } config . network - the configurations to be sent to the Network and Blockchain constructors
2014-09-04 01:33:12 -03:00
* @ param { Blockchain } config . Blockchain - the class to instantiate to get information about the blockchain ( Insight by default )
* @ TODO : Investigate what parameters go inside this object
* @ param { Object } config . wallet - default configuration for the wallet
* @ TODO : put ` version ` inside of the config object
* @ param { string } version - the version of copay for which this wallet was generated ( for example , 0.4 . 7 )
2014-09-08 15:42:55 -03:00
* @ constructor
2014-04-16 17:50:10 -03:00
* /
2014-09-03 01:25:08 -03:00
2014-09-26 05:00:43 -03:00
function Identity ( config , version , pluginManager ) {
2014-04-16 17:50:10 -03:00
var self = this ;
2014-09-15 16:11:26 -03:00
preconditions . checkArgument ( config ) ;
preconditions . checkArgument ( config . network ) ;
2014-05-21 11:10:19 -03:00
2014-09-03 01:25:08 -03:00
this . Storage = config . Storage || Storage ;
2014-08-07 15:23:17 -03:00
this . Network = config . Network || Async ;
2014-06-15 20:55:23 -07:00
this . Blockchain = config . Blockchain || Insight ;
2014-09-03 01:25:08 -03:00
var storageOpts = { } ;
if ( pluginManager ) {
storageOpts = {
storage : pluginManager . get ( 'STORAGE' )
} ;
}
this . storage = new this . Storage ( storageOpts ) ;
2014-06-15 20:55:23 -07:00
2014-09-10 11:12:28 -07:00
this . networks = {
'livenet' : new this . Network ( config . network . livenet ) ,
'testnet' : new this . Network ( config . network . testnet ) ,
} ;
this . blockchains = {
'livenet' : new this . Blockchain ( config . network . livenet ) ,
'testnet' : new this . Blockchain ( config . network . testnet ) ,
} ;
2014-04-16 17:50:10 -03:00
2014-09-15 16:11:26 -03:00
this . walletDefaults = config . wallet || { } ;
2014-06-16 15:51:19 -03:00
this . version = version ;
2014-09-04 01:33:12 -03:00
} ;
2014-04-16 17:50:10 -03:00
2014-09-10 11:12:28 -07:00
/ * *
* @ desc obtain network name from serialized wallet
* @ param { Object } wallet object
* @ return { string } network name
* /
2014-09-26 05:00:43 -03:00
Identity . prototype . obtainNetworkName = function ( obj ) {
2014-09-10 11:12:28 -07:00
return obj . networkName ||
obj . opts . networkName ||
obj . publicKeyRing . networkName ||
obj . privateKey . networkName ;
} ;
2014-09-04 01:33:12 -03:00
/ * *
* @ desc Deserialize an object to a Wallet
2014-09-10 11:12:28 -07:00
* @ param { Object } wallet object
2014-09-04 01:33:12 -03:00
* @ param { string [ ] } skipFields - fields to skip when importing
* @ return { Wallet }
* /
2014-09-26 05:00:43 -03:00
Identity . prototype . fromObj = function ( inObj , skipFields ) {
2014-09-15 17:45:06 -03:00
var networkName = this . obtainNetworkName ( inObj ) ;
2014-09-10 11:12:28 -07:00
preconditions . checkState ( networkName ) ;
2014-09-15 17:45:06 -03:00
preconditions . checkArgument ( inObj ) ;
var obj = JSON . parse ( JSON . stringify ( inObj ) ) ;
2014-06-09 20:08:12 -03:00
2014-09-08 14:24:57 -03:00
// not stored options
obj . opts = obj . opts || { } ;
2014-06-16 15:51:19 -03:00
obj . opts . reconnectDelay = this . walletDefaults . reconnectDelay ;
2014-06-09 20:08:12 -03:00
2014-08-20 14:45:59 -04:00
skipFields = skipFields || [ ] ;
2014-09-04 16:13:30 -03:00
skipFields . forEach ( function ( k ) {
2014-08-20 17:23:34 -04:00
if ( obj [ k ] ) {
2014-08-20 14:45:59 -04:00
delete obj [ k ] ;
2014-09-04 16:13:30 -03:00
} else
2014-08-20 14:45:59 -04:00
throw new Error ( 'unknown field:' + k ) ;
} ) ;
2014-09-10 11:12:28 -07:00
var w = Wallet . fromObj ( obj , this . storage , this . networks [ networkName ] , this . blockchains [ networkName ] ) ;
2014-06-13 11:47:22 -03:00
if ( ! w ) return false ;
this . _checkVersion ( w . version ) ;
2014-04-25 19:12:13 -03:00
return w ;
} ;
2014-09-04 01:33:12 -03:00
/ * *
* @ desc Imports a wallet from an encrypted base64 object
* @ param { string } base64 - the base64 encoded object
2014-09-18 18:29:00 -03:00
* @ param { string } passphrase - passphrase to decrypt it
2014-09-04 01:33:12 -03:00
* @ param { string [ ] } skipFields - fields to ignore when importing
* @ return { Wallet }
* /
2014-09-26 05:00:43 -03:00
Identity . prototype . fromEncryptedObj = function ( base64 , passphrase , skipFields ) {
2014-09-18 18:29:00 -03:00
this . storage . setPassphrase ( passphrase ) ;
2014-05-01 18:32:22 -03:00
var walletObj = this . storage . import ( base64 ) ;
2014-06-02 18:59:38 -03:00
if ( ! walletObj ) return false ;
2014-09-14 13:52:43 -03:00
return this . fromObj ( walletObj , skipFields ) ;
2014-05-01 18:32:22 -03:00
} ;
2014-09-04 01:33:12 -03:00
/ * *
* @ TODO : import is a reserved keyword ! DONT USE IT
2014-09-26 05:00:43 -03:00
* @ TODO : this is essentialy the same method as { @ link Identity # fromEncryptedObj } !
2014-09-04 01:33:12 -03:00
* @ desc Imports a wallet from an encrypted base64 object
* @ param { string } base64 - the base64 encoded object
2014-09-18 18:29:00 -03:00
* @ param { string } passphrase - passphrase to decrypt it
2014-09-04 01:33:12 -03:00
* @ param { string [ ] } skipFields - fields to ignore when importing
* @ return { Wallet }
* /
2014-09-26 05:00:43 -03:00
Identity . prototype . import = function ( base64 , passphrase , skipFields ) {
2014-06-18 10:58:34 -03:00
var self = this ;
2014-09-22 15:02:41 -03:00
return self . fromEncryptedObj ( base64 , passphrase , skipFields ) ;
2014-09-04 01:33:12 -03:00
} ;
2014-05-01 18:32:22 -03:00
2014-09-26 05:00:43 -03:00
Identity . prototype . migrateWallet = function ( walletId , passphrase , cb ) {
2014-09-23 14:54:09 -03:00
var self = this ;
self . storage . setPassphrase ( passphrase ) ;
2014-09-23 16:01:02 -03:00
self . read _Old ( walletId , null , function ( err , wallet ) {
2014-09-23 14:54:09 -03:00
if ( err ) return cb ( err ) ;
2014-09-23 16:01:02 -03:00
wallet . store ( function ( err ) {
if ( err ) return cb ( err ) ;
self . storage . deleteWallet _Old ( walletId , function ( err ) {
if ( err ) return cb ( err ) ;
self . storage . removeGlobal ( 'nameFor::' + walletId , function ( ) {
return cb ( ) ;
} ) ;
2014-09-23 14:54:09 -03:00
} ) ;
} ) ;
} ) ;
} ;
2014-09-04 01:33:12 -03:00
/ * *
* @ desc Retrieve a wallet from storage
* @ param { string } walletId - the wallet id
* @ param { string [ ] } skipFields - parameters to ignore when importing
2014-09-13 10:25:13 -03:00
* @ param { function } callback - { err , Wallet }
2014-09-04 01:33:12 -03:00
* /
2014-09-26 05:00:43 -03:00
Identity . prototype . read = function ( walletId , skipFields , cb ) {
2014-09-13 10:25:13 -03:00
var self = this ,
err ;
2014-04-28 11:22:41 -03:00
var obj = { } ;
2014-04-25 19:12:13 -03:00
2014-09-23 16:01:02 -03:00
this . storage . readWallet ( walletId , function ( err , ret ) {
if ( err ) return cb ( err ) ;
2014-09-23 10:16:26 -03:00
_ . each ( Wallet . PERSISTED _PROPERTIES , function ( p ) {
obj [ p ] = ret [ p ] ;
} ) ;
2014-09-13 10:25:13 -03:00
if ( ! _ . any ( _ . values ( obj ) ) )
return cb ( new Error ( 'Wallet not found' ) ) ;
var w , err ;
obj . id = walletId ;
try {
w = self . fromObj ( obj , skipFields ) ;
} catch ( e ) {
if ( e && e . message && e . message . indexOf ( 'MISSOPTS' ) ) {
err = new Error ( 'Could not read: ' + walletId ) ;
} else {
err = e ;
}
w = null ;
}
return cb ( err , w ) ;
2014-09-04 16:13:30 -03:00
} ) ;
2014-04-16 17:50:10 -03:00
} ;
2014-04-28 11:22:41 -03:00
2014-09-26 05:00:43 -03:00
Identity . prototype . read _Old = function ( walletId , skipFields , cb ) {
2014-09-23 16:01:02 -03:00
var self = this ,
err ;
var obj = { } ;
this . storage . readWallet _Old ( walletId , function ( err , ret ) {
if ( err ) return cb ( err ) ;
_ . each ( Wallet . PERSISTED _PROPERTIES , function ( p ) {
obj [ p ] = ret [ p ] ;
} ) ;
if ( ! _ . any ( _ . values ( obj ) ) )
return cb ( new Error ( 'Wallet not found' ) ) ;
var w , err ;
obj . id = walletId ;
try {
w = self . fromObj ( obj , skipFields ) ;
} catch ( e ) {
if ( e && e . message && e . message . indexOf ( 'MISSOPTS' ) ) {
err = new Error ( 'Could not read: ' + walletId ) ;
} else {
err = e ;
}
w = null ;
}
return cb ( err , w ) ;
} ) ;
} ;
2014-09-14 13:52:43 -03:00
2014-09-04 01:33:12 -03:00
/ * *
2014-09-14 13:52:43 -03:00
* @ desc This method instantiates a wallet . Usefull for stubbing .
*
* @ param { opts } opts , ready for new Wallet ( opts )
*
* /
2014-09-26 05:00:43 -03:00
Identity . prototype . _getWallet = function ( opts ) {
2014-09-14 13:52:43 -03:00
return new Wallet ( opts ) ;
2014-04-16 17:50:10 -03:00
} ;
2014-09-04 01:33:12 -03:00
/ * *
2014-09-14 13:52:43 -03:00
* @ desc This method prepares options for a new Wallet
2014-09-04 01:33:12 -03:00
*
* @ param { Object } opts
* @ param { string } opts . id
* @ param { PrivateKey = } opts . privateKey
* @ param { string = } opts . privateKeyHex
* @ param { number } opts . requiredCopayers
* @ param { number } opts . totalCopayers
* @ param { PublicKeyRing = } opts . publicKeyRing
* @ param { string } opts . nickname
* @ param { string } opts . passphrase
* @ TODO : Figure out what is this parameter
* @ param { ? } opts . spendUnconfirmed this . walletDefaults . spendUnconfirmed ? ?
* @ TODO : Figure out in what unit is this reconnect delay .
* @ param { number } opts . reconnectDelay milliseconds ?
* @ param { number = } opts . version
2014-09-03 15:43:27 -03:00
* @ param { callback } opts . version
2014-09-04 01:33:12 -03:00
* @ return { Wallet }
* /
2014-09-26 05:00:43 -03:00
Identity . prototype . create = function ( opts , cb ) {
2014-09-08 10:46:57 -03:00
preconditions . checkArgument ( cb ) ;
2014-09-10 13:56:49 -07:00
opts = opts || { } ;
opts . networkName = opts . networkName || 'testnet' ;
2014-09-10 11:12:28 -07:00
2014-09-01 12:35:40 -03:00
log . debug ( '### CREATING NEW WALLET.' + ( opts . id ? ' USING ID: ' + opts . id : ' NEW ID' ) + ( opts . privateKey ? ' USING PrivateKey: ' + opts . privateKey . getId ( ) : ' NEW PrivateKey' ) ) ;
2014-04-16 17:50:10 -03:00
2014-08-21 14:54:36 -04:00
var privOpts = {
2014-09-09 15:30:49 -07:00
networkName : opts . networkName ,
2014-08-21 14:54:36 -04:00
} ;
2014-09-04 16:13:30 -03:00
if ( opts . privateKeyHex && opts . privateKeyHex . length > 1 ) {
2014-08-21 14:54:36 -04:00
privOpts . extendedPrivateKeyString = opts . privateKeyHex ;
}
opts . privateKey = opts . privateKey || new PrivateKey ( privOpts ) ;
2014-04-20 12:41:28 -03:00
2014-04-16 17:50:10 -03:00
var requiredCopayers = opts . requiredCopayers || this . walletDefaults . requiredCopayers ;
2014-06-16 15:51:19 -03:00
var totalCopayers = opts . totalCopayers || this . walletDefaults . totalCopayers ;
2014-08-14 18:46:42 -04:00
opts . lockTimeoutMin = this . walletDefaults . idleDurationMin ;
2014-04-16 17:50:10 -03:00
opts . publicKeyRing = opts . publicKeyRing || new PublicKeyRing ( {
2014-09-09 15:30:49 -07:00
networkName : opts . networkName ,
2014-04-16 17:50:10 -03:00
requiredCopayers : requiredCopayers ,
totalCopayers : totalCopayers ,
} ) ;
2014-05-28 16:10:05 -03:00
opts . publicKeyRing . addCopayer (
opts . privateKey . deriveBIP45Branch ( ) . extendedPublicKeyString ( ) ,
2014-08-01 11:24:16 -03:00
opts . nickname
) ;
2014-09-01 12:35:40 -03:00
log . debug ( '\t### PublicKeyRing Initialized' ) ;
2014-04-16 17:50:10 -03:00
2014-08-05 16:42:51 -03:00
opts . txProposals = opts . txProposals || new TxProposals ( {
2014-09-09 15:30:49 -07:00
networkName : opts . networkName ,
2014-04-16 17:50:10 -03:00
} ) ;
2014-09-01 12:35:40 -03:00
log . debug ( '\t### TxProposals Initialized' ) ;
2014-04-16 17:50:10 -03:00
2014-05-01 10:03:58 -03:00
2014-04-16 17:50:10 -03:00
opts . storage = this . storage ;
2014-09-10 11:12:28 -07:00
opts . network = this . networks [ opts . networkName ] ;
opts . blockchain = this . blockchains [ opts . networkName ] ;
2014-04-16 20:58:57 -03:00
2014-04-16 17:50:10 -03:00
opts . spendUnconfirmed = opts . spendUnconfirmed || this . walletDefaults . spendUnconfirmed ;
2014-06-16 15:51:19 -03:00
opts . reconnectDelay = opts . reconnectDelay || this . walletDefaults . reconnectDelay ;
2014-04-16 17:50:10 -03:00
opts . requiredCopayers = requiredCopayers ;
2014-06-16 15:51:19 -03:00
opts . totalCopayers = totalCopayers ;
opts . version = opts . version || this . version ;
2014-08-14 18:46:42 -04:00
2014-09-18 18:29:00 -03:00
this . storage . setPassphrase ( opts . passphrase ) ;
2014-09-14 13:52:43 -03:00
var w = this . _getWallet ( opts ) ;
2014-09-03 15:43:27 -03:00
var self = this ;
2014-09-14 13:52:43 -03:00
w . store ( function ( err ) {
if ( err ) return cb ( err ) ;
self . storage . setLastOpened ( w . id , function ( err ) {
return cb ( err , w ) ;
2014-09-03 15:43:27 -03:00
} ) ;
} ) ;
2014-04-16 17:50:10 -03:00
} ;
2014-09-04 01:33:12 -03:00
/ * *
* @ desc Checks if a version is compatible with the current version
* @ param { string } inVersion - a version , with major , minor , and revision , period - separated ( x . y . z )
* @ throws { Error } if there ' s a major version difference
* /
2014-09-26 05:00:43 -03:00
Identity . prototype . _checkVersion = function ( inVersion ) {
2014-05-14 21:02:01 -03:00
var thisV = this . version . split ( '.' ) ;
var thisV0 = parseInt ( thisV [ 0 ] ) ;
2014-06-16 15:51:19 -03:00
var inV = inVersion . split ( '.' ) ;
var inV0 = parseInt ( inV [ 0 ] ) ;
2014-05-14 21:02:01 -03:00
//We only check for major version differences
2014-06-16 15:51:19 -03:00
if ( thisV0 < inV0 ) {
2014-05-14 21:02:01 -03:00
throw new Error ( 'Major difference in software versions' +
2014-09-04 16:13:30 -03:00
'. Received:' + inVersion +
'. Current version:' + this . version +
'. Aborting.' ) ;
2014-05-14 21:02:01 -03:00
}
} ;
2014-09-04 01:33:12 -03:00
/ * *
* @ desc Retrieve a wallet from the storage
* @ param { string } walletId - the id of the wallet
* @ param { string } passphrase - the passphrase to decode it
2014-09-03 01:25:08 -03:00
* @ param { function } callback ( err , { Wallet } )
* @ return
2014-09-04 01:33:12 -03:00
* /
2014-09-26 05:00:43 -03:00
Identity . prototype . open = function ( walletId , passphrase , cb ) {
2014-09-08 10:46:57 -03:00
preconditions . checkArgument ( cb ) ;
2014-09-08 14:58:23 -03:00
var self = this ;
2014-09-18 16:38:18 -03:00
self . storage . setPassphrase ( passphrase ) ;
2014-09-08 14:58:23 -03:00
2014-09-23 14:54:09 -03:00
self . migrateWallet ( walletId , passphrase , function ( ) {
self . read ( walletId , null , function ( err , w ) {
if ( err ) return cb ( err ) ;
w . store ( function ( err ) {
self . storage . setLastOpened ( walletId , function ( ) {
return cb ( err , w ) ;
} ) ;
2014-09-03 01:25:08 -03:00
} ) ;
} ) ;
} ) ;
2014-04-16 20:58:57 -03:00
} ;
2014-09-26 05:00:43 -03:00
Identity . prototype . getWallets = function ( cb ) {
2014-09-24 10:47:19 -03:00
var self = this ;
this . storage . getWallets ( function ( wallets ) {
wallets . forEach ( function ( i ) {
2014-09-03 01:25:08 -03:00
i . show = i . name ? ( ( i . name + ' <' + i . id + '>' ) ) : i . id ;
} ) ;
2014-09-24 10:47:19 -03:00
self . storage . getLastOpened ( function ( lastId ) {
var last = _ . findWhere ( wallets , {
id : lastId
} ) ;
if ( last )
last . lastOpened = true ;
return cb ( null , wallets ) ;
} )
2014-04-24 16:35:52 -03:00
} ) ;
} ;
2014-04-16 17:50:10 -03:00
2014-09-04 01:33:12 -03:00
/ * *
* @ desc Deletes this wallet . This involves removing it from the storage instance
* @ TODO : delete is a reserved javascript keyword . NEVER USE IT .
* @ param { string } walletId
* @ TODO : Why is there a callback ?
* @ callback cb
* @ return { ? } the result of the callback
* /
2014-09-26 05:00:43 -03:00
Identity . prototype . delete = function ( walletId , cb ) {
2014-09-23 16:01:02 -03:00
var self = this ;
self . storage . deleteWallet ( walletId , function ( err ) {
2014-09-13 10:25:13 -03:00
if ( err ) return cb ( err ) ;
2014-09-23 16:01:02 -03:00
self . storage . setLastOpened ( null , function ( err ) {
2014-09-13 10:25:13 -03:00
return cb ( err ) ;
} ) ;
} ) ;
2014-04-16 17:50:10 -03:00
} ;
2014-09-04 01:33:12 -03:00
/ * *
* @ desc Pass through to { @ link Wallet # secret }
* /
2014-09-26 05:00:43 -03:00
Identity . prototype . decodeSecret = function ( secret ) {
2014-05-14 14:24:24 -07:00
try {
return Wallet . decodeSecret ( secret ) ;
} catch ( e ) {
return false ;
}
2014-06-09 18:01:15 -03:00
} ;
2014-04-16 20:58:57 -03:00
2014-09-04 01:33:12 -03:00
/ * *
* @ callback walletCreationCallback
2014-09-08 15:42:55 -03:00
* @ param { ? } err - an error , if any , that happened during the wallet creation
2014-09-04 01:33:12 -03:00
* @ param { Wallet = } wallet - the wallet created
* /
2014-04-20 12:41:28 -03:00
2014-09-04 01:33:12 -03:00
/ * *
* @ desc Start the network functionality .
*
* Start up the Network instance and try to join a wallet defined by the
* parameter < tt > secret < / t t > u s i n g t h e p a r a m e t e r < t t > n i c k n a m e < / t t > . E n c o d e
* information locally using < tt > passphrase < / t t > . < t t > p r i v a t e H e x < / t t > i s t h e
* private extended master key . < tt > cb < / t t > h a s t w o p a r a m s : e r r o r a n d w a l l e t .
*
2014-09-14 13:52:43 -03:00
* @ param { object } opts
* @ param { string } opts . secret - the wallet secret
* @ param { string } opts . passphrase - a passphrase to use to encrypt the wallet for persistance
* @ param { string } opts . nickname - a nickname for the current user
* @ param { string } opts . privateHex - the private extended master key
2014-09-04 01:33:12 -03:00
* @ param { walletCreationCallback } cb - a callback
* /
2014-09-26 05:00:43 -03:00
Identity . prototype . joinCreateSession = function ( opts , cb ) {
2014-09-14 13:52:43 -03:00
preconditions . checkArgument ( opts ) ;
preconditions . checkArgument ( opts . secret ) ;
preconditions . checkArgument ( opts . passphrase ) ;
preconditions . checkArgument ( opts . nickname ) ;
2014-09-08 10:46:57 -03:00
preconditions . checkArgument ( cb ) ;
2014-08-20 18:00:33 -04:00
var self = this ;
2014-09-14 13:52:43 -03:00
var decodedSecret = this . decodeSecret ( opts . secret ) ;
2014-09-10 14:01:10 -07:00
if ( ! decodedSecret || ! decodedSecret . networkName || ! decodedSecret . pubKey ) {
2014-09-10 11:12:28 -07:00
return cb ( 'badSecret' ) ;
}
2014-06-16 15:51:19 -03:00
2014-08-20 18:00:33 -04:00
var privOpts = {
2014-09-09 15:30:49 -07:00
networkName : decodedSecret . networkName ,
2014-08-20 18:00:33 -04:00
} ;
2014-09-14 13:52:43 -03:00
if ( opts . privateHex && opts . privateHex . length > 1 ) {
2014-10-04 11:30:08 -03:00
privOpts . extendedPrivateKeyString = opts . privateHex ;
2014-08-20 18:00:33 -04:00
}
2014-04-20 12:41:28 -03:00
//Create our PrivateK
2014-08-20 18:00:33 -04:00
var privateKey = new PrivateKey ( privOpts ) ;
2014-09-01 12:35:40 -03:00
log . debug ( '\t### PrivateKey Initialized' ) ;
2014-09-18 18:29:00 -03:00
var joinOpts = {
2014-04-24 23:13:55 -03:00
copayerId : privateKey . getId ( ) ,
2014-06-26 08:49:22 -07:00
privkey : privateKey . getIdPriv ( ) ,
2014-09-03 16:51:02 -03:00
key : privateKey . getIdKey ( ) ,
2014-09-09 15:30:49 -07:00
secretNumber : decodedSecret . secretNumber ,
2014-04-24 23:13:55 -03:00
} ;
2014-09-10 11:12:28 -07:00
var joinNetwork = this . networks [ decodedSecret . networkName ] ;
joinNetwork . cleanUp ( ) ;
2014-07-08 15:25:12 -03:00
// This is a hack to reconize if the connection was rejected or the peer wasn't there.
var connectedOnce = false ;
2014-09-10 11:12:28 -07:00
joinNetwork . on ( 'connected' , function ( sender , data ) {
2014-07-08 15:25:12 -03:00
connectedOnce = true ;
} ) ;
2014-09-19 11:15:45 -03:00
joinNetwork . on ( 'connect_error' , function ( ) {
return cb ( 'connectionError' ) ;
} ) ;
2014-09-10 11:12:28 -07:00
joinNetwork . on ( 'serverError' , function ( ) {
2014-07-08 15:25:12 -03:00
return cb ( 'joinError' ) ;
} ) ;
2014-09-18 18:29:00 -03:00
joinNetwork . start ( joinOpts , function ( ) {
joinNetwork . greet ( decodedSecret . pubKey , joinOpts . secretNumber ) ;
2014-09-10 11:12:28 -07:00
joinNetwork . on ( 'data' , function ( sender , data ) {
2014-09-15 14:25:09 -03:00
if ( data . type === 'walletId' && data . opts ) {
2014-10-04 19:52:43 -03:00
if ( ! data . networkName || data . networkName !== decodedSecret . networkName ) {
2014-06-09 21:00:28 -03:00
return cb ( 'badNetwork' ) ;
}
2014-10-04 19:52:43 -03:00
data . opts . networkName = data . networkName ;
2014-06-09 21:00:28 -03:00
2014-09-23 15:24:57 -03:00
var walletOpts = _ . clone ( data . opts ) ;
2014-09-18 18:29:00 -03:00
walletOpts . id = data . walletId ;
walletOpts . privateKey = privateKey ;
walletOpts . nickname = opts . nickname ;
walletOpts . passphrase = opts . passphrase ;
self . create ( walletOpts , function ( err , w ) {
if ( w ) {
w . sendWalletReady ( decodedSecret . pubKey ) ;
2014-09-15 14:25:09 -03:00
} else {
if ( ! err ) err = 'walletFull' ;
2014-09-18 18:29:00 -03:00
log . info ( err ) ;
2014-09-15 14:25:09 -03:00
}
return cb ( err , w ) ;
} ) ;
2014-04-20 16:16:09 -03:00
}
2014-04-16 20:58:57 -03:00
} ) ;
} ) ;
} ;
2014-09-26 05:00:43 -03:00
module . exports = Identity ;