@ -1,6 +1,9 @@
const ObservableStore = require ( 'obs-store' )
const normalizeAddress = require ( 'eth-sig-util' ) . normalize
const extend = require ( 'xtend' )
const notifier = require ( '../lib/bug-notifier' )
const log = require ( 'loglevel' )
const { version } = require ( '../../manifest.json' )
class PreferencesController {
@ -28,7 +31,12 @@ class PreferencesController {
featureFlags : { } ,
currentLocale : opts . initLangCode ,
identities : { } ,
lostIdentities : { } ,
} , opts . initState )
this . getFirstTimeInfo = opts . getFirstTimeInfo || null
this . notifier = opts . notifier || notifier
this . store = new ObservableStore ( initState )
}
// PUBLIC METHODS
@ -63,6 +71,13 @@ class PreferencesController {
this . store . updateState ( { currentLocale : key } )
}
/ * *
* Updates identities to only include specified addresses . Removes identities
* not included in addresses array
*
* @ param { string [ ] } addresses An array of hex addresses
*
* /
setAddresses ( addresses ) {
const oldIdentities = this . store . getState ( ) . identities
const identities = addresses . reduce ( ( ids , address , index ) => {
@ -73,6 +88,76 @@ class PreferencesController {
this . store . updateState ( { identities } )
}
/ * *
* Adds addresses to the identities object without removing identities
*
* @ param { string [ ] } addresses An array of hex addresses
*
* /
addAddresses ( addresses ) {
const identities = this . store . getState ( ) . identities
addresses . forEach ( ( address ) => {
// skip if already exists
if ( identities [ address ] ) return
// add missing identity
const identityCount = Object . keys ( identities ) . length
identities [ address ] = { name : ` Account ${ identityCount + 1 } ` , address }
} )
this . store . updateState ( { identities } )
}
/ *
* Synchronizes identity entries with known accounts .
* Removes any unknown identities , and returns the resulting selected address .
*
* @ param { Array < string > } addresses known to the vault .
* @ returns { Promise < string > } selectedAddress the selected address .
* /
syncAddresses ( addresses ) {
let { identities , lostIdentities } = this . store . getState ( )
let newlyLost = { }
Object . keys ( identities ) . forEach ( ( identity ) => {
if ( ! addresses . includes ( identity ) ) {
newlyLost [ identity ] = identities [ identity ]
delete identities [ identity ]
}
} )
// Identities are no longer present.
if ( Object . keys ( newlyLost ) . length > 0 ) {
// Notify our servers:
const uri = 'https://diagnostics.metamask.io/v1/orphanedAccounts'
const firstTimeInfo = this . getFirstTimeInfo ? this . getFirstTimeInfo ( ) : { }
this . notifier . notify ( uri , {
accounts : Object . keys ( newlyLost ) ,
metadata : {
version ,
firstTimeInfo ,
} ,
} )
. catch ( log . error )
for ( let key in newlyLost ) {
lostIdentities [ key ] = newlyLost [ key ]
}
}
this . store . updateState ( { identities , lostIdentities } )
this . addAddresses ( addresses )
// If the selected account is no longer valid,
// select an arbitrary other account:
let selected = this . getSelectedAddress ( )
if ( ! addresses . includes ( selected ) ) {
selected = addresses [ 0 ]
this . setSelectedAddress ( selected )
}
return selected
}
/ * *
* Setter for the ` selectedAddress ` property
*
@ -111,7 +196,7 @@ class PreferencesController {
/ * *
* Adds a new token to the token array , or updates the token if passed an address that already exists .
* Modifies the existing tokens array from the store . All objects in the tokens array array AddedToken objects .
* @ see AddedToken { @ link AddedToken }
* @ see AddedToken { @ link AddedToken }
*
* @ param { string } rawAddress Hex address of the token contract . May or may not be a checksum address .
* @ param { string } symbol The symbol of the token
@ -197,7 +282,7 @@ class PreferencesController {
}
/ * *
* Setter for the ` currentAccountTab ` property
* Setter for the ` currentAccountTab ` property
*
* @ param { string } currentAccountTab Specifies the new tab to be marked as current
* @ returns { Promise < void > } Promise resolves with undefined
@ -215,7 +300,7 @@ class PreferencesController {
* The returned list will have a max length of 2. If the _url currently exists it the list , it will be moved to the
* end of the list . The current list is modified and returned as a promise .
*
* @ param { string } _url The rpc url to add to the frequentRpcList .
* @ param { string } _url The rpc url to add to the frequentRpcList .
* @ returns { Promise < array > } The updated frequentRpcList .
*
* /