aboutsummaryrefslogtreecommitdiffstats
path: root/app/scripts/controllers
diff options
context:
space:
mode:
Diffstat (limited to 'app/scripts/controllers')
-rw-r--r--app/scripts/controllers/computed-balances.js2
-rw-r--r--app/scripts/controllers/detect-tokens.js4
-rw-r--r--app/scripts/controllers/network/contract-addresses.js8
-rw-r--r--app/scripts/controllers/onboarding.js43
-rw-r--r--app/scripts/controllers/preferences.js58
-rw-r--r--app/scripts/controllers/provider-approval.js97
-rw-r--r--app/scripts/controllers/transactions/index.js26
-rw-r--r--app/scripts/controllers/transactions/lib/tx-state-history-helper.js8
-rw-r--r--app/scripts/controllers/transactions/lib/util.js10
-rw-r--r--app/scripts/controllers/transactions/pending-tx-tracker.js4
-rw-r--r--app/scripts/controllers/transactions/tx-state-manager.js10
11 files changed, 182 insertions, 88 deletions
diff --git a/app/scripts/controllers/computed-balances.js b/app/scripts/controllers/computed-balances.js
index e04ce2ef7..caa061df4 100644
--- a/app/scripts/controllers/computed-balances.js
+++ b/app/scripts/controllers/computed-balances.js
@@ -65,7 +65,7 @@ class ComputedbalancesController {
syncAllAccountsFromStore (store) {
const upstream = Object.keys(store.accounts)
const balances = Object.keys(this.balances)
- .map(address => this.balances[address])
+ .map(address => this.balances[address])
// Follow new addresses
for (const address in balances) {
diff --git a/app/scripts/controllers/detect-tokens.js b/app/scripts/controllers/detect-tokens.js
index e6940c613..e6e993073 100644
--- a/app/scripts/controllers/detect-tokens.js
+++ b/app/scripts/controllers/detect-tokens.js
@@ -47,14 +47,14 @@ class DetectTokensController {
}
tokensToDetect.forEach((tokenAddress, index) => {
const balance = result[index]
- if (!balance.isZero()) {
+ if (balance && !balance.isZero()) {
this._preferences.addToken(tokenAddress, contracts[tokenAddress].symbol, contracts[tokenAddress].decimals)
}
})
})
}
- /**
+ /**
* Find if selectedAddress has tokens with contract in contractAddress.
*
* @param {string} contractAddress Hex address of the token contract to explore.
diff --git a/app/scripts/controllers/network/contract-addresses.js b/app/scripts/controllers/network/contract-addresses.js
index 5cd7da1d0..f9385accd 100644
--- a/app/scripts/controllers/network/contract-addresses.js
+++ b/app/scripts/controllers/network/contract-addresses.js
@@ -4,8 +4,8 @@ const SINGLE_CALL_BALANCES_ADDRESS_ROPSTEN = '0xb8e671734ce5c8d7dfbbea5574fa4cf3
const SINGLE_CALL_BALANCES_ADDRESS_KOVAN = '0xb1d3fbb2f83aecd196f474c16ca5d9cffa0d0ffc'
module.exports = {
- SINGLE_CALL_BALANCES_ADDRESS,
- SINGLE_CALL_BALANCES_ADDRESS_RINKEBY,
- SINGLE_CALL_BALANCES_ADDRESS_ROPSTEN,
- SINGLE_CALL_BALANCES_ADDRESS_KOVAN,
+ SINGLE_CALL_BALANCES_ADDRESS,
+ SINGLE_CALL_BALANCES_ADDRESS_RINKEBY,
+ SINGLE_CALL_BALANCES_ADDRESS_ROPSTEN,
+ SINGLE_CALL_BALANCES_ADDRESS_KOVAN,
}
diff --git a/app/scripts/controllers/onboarding.js b/app/scripts/controllers/onboarding.js
new file mode 100644
index 000000000..18fec4993
--- /dev/null
+++ b/app/scripts/controllers/onboarding.js
@@ -0,0 +1,43 @@
+const ObservableStore = require('obs-store')
+const extend = require('xtend')
+
+/**
+ * @typedef {Object} InitState
+ * @property {Boolean} seedPhraseBackedUp Indicates whether the user has completed the seed phrase backup challenge
+ */
+
+/**
+ * @typedef {Object} OnboardingOptions
+ * @property {InitState} initState The initial controller state
+ */
+
+/**
+ * Controller responsible for maintaining
+ * a cache of account balances in local storage
+ */
+class OnboardingController {
+ /**
+ * Creates a new controller instance
+ *
+ * @param {OnboardingOptions} [opts] Controller configuration parameters
+ */
+ constructor (opts = {}) {
+ const initState = extend({
+ seedPhraseBackedUp: null,
+ }, opts.initState)
+ this.store = new ObservableStore(initState)
+ }
+
+ setSeedPhraseBackedUp (newSeedPhraseBackUpState) {
+ this.store.updateState({
+ seedPhraseBackedUp: newSeedPhraseBackUpState,
+ })
+ }
+
+ getSeedPhraseBackedUp () {
+ return this.store.getState().seedPhraseBackedUp
+ }
+
+}
+
+module.exports = OnboardingController
diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js
index acf952bb1..d480834f5 100644
--- a/app/scripts/controllers/preferences.js
+++ b/app/scripts/controllers/preferences.js
@@ -49,13 +49,12 @@ class PreferencesController {
currentLocale: opts.initLangCode,
identities: {},
lostIdentities: {},
- seedWords: null,
forgottenPassword: false,
preferences: {
useNativeCurrencyAsPrimaryCurrency: true,
},
completedOnboarding: false,
- completedUiMigration: true,
+ migratedPrivacyMode: false,
metaMetricsId: null,
metaMetricsSendCount: 0,
}, opts.initState)
@@ -70,7 +69,7 @@ class PreferencesController {
return this.setFeatureFlag(key, value)
}
}
-// PUBLIC METHODS
+ // PUBLIC METHODS
/**
* Sets the {@code forgottenPassword} state property
@@ -81,14 +80,6 @@ class PreferencesController {
}
/**
- * Sets the {@code seedWords} seed words
- * @param {string|null} seedWords the seed words
- */
- setSeedWords (seedWords) {
- this.store.updateState({ seedWords })
- }
-
- /**
* Setter for the `useBlockie` property
*
* @param {boolean} val Whether or not the user prefers blockie indicators
@@ -139,9 +130,9 @@ class PreferencesController {
* @param {String} type Indicates the type of first time flow - create or import - the user wishes to follow
*
*/
- setFirstTimeFlowType (type) {
- this.store.updateState({ firstTimeFlowType: type })
- }
+ setFirstTimeFlowType (type) {
+ this.store.updateState({ firstTimeFlowType: type })
+ }
getSuggestedTokens () {
@@ -503,22 +494,22 @@ class PreferencesController {
* @returns {Promise<array>} Promise resolving to updated frequentRpcList.
*
*/
- addToFrequentRpcList (url, chainId, ticker = 'ETH', nickname = '', rpcPrefs = {}) {
- const rpcList = this.getFrequentRpcListDetail()
- const index = rpcList.findIndex((element) => { return element.rpcUrl === url })
- if (index !== -1) {
- rpcList.splice(index, 1)
- }
- if (url !== 'http://localhost:8545') {
- let checkedChainId
- if (!!chainId && !Number.isNaN(parseInt(chainId))) {
- checkedChainId = chainId
- }
- rpcList.push({ rpcUrl: url, chainId: checkedChainId, ticker, nickname, rpcPrefs })
+ addToFrequentRpcList (url, chainId, ticker = 'ETH', nickname = '', rpcPrefs = {}) {
+ const rpcList = this.getFrequentRpcListDetail()
+ const index = rpcList.findIndex((element) => { return element.rpcUrl === url })
+ if (index !== -1) {
+ rpcList.splice(index, 1)
+ }
+ if (url !== 'http://localhost:8545') {
+ let checkedChainId
+ if (!!chainId && !Number.isNaN(parseInt(chainId))) {
+ checkedChainId = chainId
}
- this.store.updateState({ frequentRpcListDetail: rpcList })
- return Promise.resolve(rpcList)
+ rpcList.push({ rpcUrl: url, chainId: checkedChainId, ticker, nickname, rpcPrefs })
}
+ this.store.updateState({ frequentRpcListDetail: rpcList })
+ return Promise.resolve(rpcList)
+ }
/**
* Removes custom RPC url from state.
@@ -613,12 +604,11 @@ class PreferencesController {
return Promise.resolve(true)
}
- /**
- * Sets the {@code completedUiMigration} state to {@code true}, indicating that the user has completed the UI switch.
- */
- completeUiMigration () {
- this.store.updateState({ completedUiMigration: true })
- return Promise.resolve(true)
+ unsetMigratedPrivacyMode () {
+ this.store.updateState({
+ migratedPrivacyMode: false,
+ })
+ return Promise.resolve()
}
//
diff --git a/app/scripts/controllers/provider-approval.js b/app/scripts/controllers/provider-approval.js
index 06c499780..5d565c385 100644
--- a/app/scripts/controllers/provider-approval.js
+++ b/app/scripts/controllers/provider-approval.js
@@ -18,12 +18,13 @@ class ProviderApprovalController extends SafeEventEmitter {
*/
constructor ({ closePopup, keyringController, openPopup, preferencesController } = {}) {
super()
- this.approvedOrigins = {}
this.closePopup = closePopup
this.keyringController = keyringController
this.openPopup = openPopup
this.preferencesController = preferencesController
this.store = new ObservableStore({
+ approvedOrigins: {},
+ dismissedOrigins: {},
providerRequests: [],
})
}
@@ -45,7 +46,7 @@ class ProviderApprovalController extends SafeEventEmitter {
}
// register the provider request
const metadata = await getSiteMetadata(origin)
- this._handleProviderRequest(origin, metadata.name, metadata.icon, false, null)
+ this._handleProviderRequest(origin, metadata.name, metadata.icon)
// wait for resolution of request
const approved = await new Promise(resolve => this.once(`resolvedRequest:${origin}`, ({ approved }) => resolve(approved)))
if (approved) {
@@ -63,10 +64,12 @@ class ProviderApprovalController extends SafeEventEmitter {
* @param {string} siteTitle - The title of the document requesting full provider access
* @param {string} siteImage - The icon of the window requesting full provider access
*/
- _handleProviderRequest (origin, siteTitle, siteImage, force, tabID) {
- this.store.updateState({ providerRequests: [{ origin, siteTitle, siteImage, tabID }] })
+ _handleProviderRequest (origin, siteTitle, siteImage) {
+ this.store.updateState({ providerRequests: [{ origin, siteTitle, siteImage }] })
const isUnlocked = this.keyringController.memStore.getState().isUnlocked
- if (!force && this.approvedOrigins[origin] && this.caching && isUnlocked) {
+ const { approvedOrigins, dismissedOrigins } = this.store.getState()
+ const originAlreadyHandled = approvedOrigins[origin] || dismissedOrigins[origin]
+ if (originAlreadyHandled && this.caching && isUnlocked) {
return
}
this.openPopup && this.openPopup()
@@ -78,11 +81,27 @@ class ProviderApprovalController extends SafeEventEmitter {
* @param {string} origin - origin of the domain that had provider access approved
*/
approveProviderRequestByOrigin (origin) {
- this.closePopup && this.closePopup()
- const requests = this.store.getState().providerRequests
- const providerRequests = requests.filter(request => request.origin !== origin)
- this.store.updateState({ providerRequests })
- this.approvedOrigins[origin] = true
+ if (this.closePopup) {
+ this.closePopup()
+ }
+
+ const { approvedOrigins, dismissedOrigins, providerRequests } = this.store.getState()
+
+ let _dismissedOrigins = dismissedOrigins
+ if (dismissedOrigins[origin]) {
+ _dismissedOrigins = Object.assign({}, dismissedOrigins)
+ delete _dismissedOrigins[origin]
+ }
+
+ const remainingProviderRequests = providerRequests.filter(request => request.origin !== origin)
+ this.store.updateState({
+ approvedOrigins: {
+ ...approvedOrigins,
+ [origin]: true,
+ },
+ dismissedOrigins: _dismissedOrigins,
+ providerRequests: remainingProviderRequests,
+ })
this.emit(`resolvedRequest:${origin}`, { approved: true })
}
@@ -92,19 +111,62 @@ class ProviderApprovalController extends SafeEventEmitter {
* @param {string} origin - origin of the domain that had provider access approved
*/
rejectProviderRequestByOrigin (origin) {
- this.closePopup && this.closePopup()
- const requests = this.store.getState().providerRequests
- const providerRequests = requests.filter(request => request.origin !== origin)
- this.store.updateState({ providerRequests })
- delete this.approvedOrigins[origin]
+ if (this.closePopup) {
+ this.closePopup()
+ }
+
+ const { approvedOrigins, providerRequests, dismissedOrigins } = this.store.getState()
+ const remainingProviderRequests = providerRequests.filter(request => request.origin !== origin)
+
+ // We're cloning and deleting keys here because we don't want to keep unneeded keys
+ const _approvedOrigins = Object.assign({}, approvedOrigins)
+ delete _approvedOrigins[origin]
+
+ this.store.putState({
+ approvedOrigins: _approvedOrigins,
+ providerRequests: remainingProviderRequests,
+ dismissedOrigins: {
+ ...dismissedOrigins,
+ [origin]: true,
+ },
+ })
this.emit(`resolvedRequest:${origin}`, { approved: false })
}
/**
+ * Silently approves access to a full Ethereum provider API for the origin
+ *
+ * @param {string} origin - origin of the domain that had provider access approved
+ */
+ forceApproveProviderRequestByOrigin (origin) {
+ const { approvedOrigins, dismissedOrigins, providerRequests } = this.store.getState()
+ const remainingProviderRequests = providerRequests.filter(request => request.origin !== origin)
+
+ let _dismissedOrigins = dismissedOrigins
+ if (dismissedOrigins[origin]) {
+ _dismissedOrigins = Object.assign({}, dismissedOrigins)
+ delete _dismissedOrigins[origin]
+ }
+
+ this.store.updateState({
+ approvedOrigins: {
+ ...approvedOrigins,
+ [origin]: true,
+ },
+ dismissedOrigins: _dismissedOrigins,
+ providerRequests: remainingProviderRequests,
+ })
+
+ this.emit(`forceResolvedRequest:${origin}`, { approved: true, forced: true })
+ }
+
+ /**
* Clears any cached approvals for user-approved origins
*/
clearApprovedOrigins () {
- this.approvedOrigins = {}
+ this.store.updateState({
+ approvedOrigins: {},
+ })
}
/**
@@ -115,8 +177,7 @@ class ProviderApprovalController extends SafeEventEmitter {
*/
shouldExposeAccounts (origin) {
const privacyMode = this.preferencesController.getFeatureFlags().privacyMode
- const result = !privacyMode || Boolean(this.approvedOrigins[origin])
- return result
+ return !privacyMode || Boolean(this.store.getState().approvedOrigins[origin])
}
}
diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js
index c4371c25b..a33b46851 100644
--- a/app/scripts/controllers/transactions/index.js
+++ b/app/scripts/controllers/transactions/index.js
@@ -129,7 +129,7 @@ class TransactionController extends EventEmitter {
}
}
-/**
+ /**
Adds a tx to the txlist
@emits ${txMeta.id}:unapproved
*/
@@ -220,7 +220,7 @@ class TransactionController extends EventEmitter {
return txMeta
}
-/**
+ /**
adds the tx gas defaults: gas && gasPrice
@param txMeta {Object} - the txMeta object
@returns {Promise<object>} resolves with txMeta
@@ -495,9 +495,9 @@ class TransactionController extends EventEmitter {
this.txStateManager.updateTx(txMeta, 'transactions#setTxHash')
}
-//
-// PRIVATE METHODS
-//
+ //
+ // PRIVATE METHODS
+ //
/** maps methods for convenience*/
_mapMethods () {
/** @returns the state in transaction controller */
@@ -537,14 +537,14 @@ class TransactionController extends EventEmitter {
loadingDefaults: true,
}).forEach((tx) => {
this.addTxGasDefaults(tx)
- .then((txMeta) => {
- txMeta.loadingDefaults = false
- this.txStateManager.updateTx(txMeta, 'transactions: gas estimation for tx on boot')
- }).catch((error) => {
- tx.loadingDefaults = false
- this.txStateManager.updateTx(tx, 'failed to estimate gas during boot cleanup.')
- this.txStateManager.setTxStatusFailed(tx.id, error)
- })
+ .then((txMeta) => {
+ txMeta.loadingDefaults = false
+ this.txStateManager.updateTx(txMeta, 'transactions: gas estimation for tx on boot')
+ }).catch((error) => {
+ tx.loadingDefaults = false
+ this.txStateManager.updateTx(tx, 'failed to estimate gas during boot cleanup.')
+ this.txStateManager.setTxStatusFailed(tx.id, error)
+ })
})
this.txStateManager.getFilteredTxList({
diff --git a/app/scripts/controllers/transactions/lib/tx-state-history-helper.js b/app/scripts/controllers/transactions/lib/tx-state-history-helper.js
index 4562568e9..76fc5c35b 100644
--- a/app/scripts/controllers/transactions/lib/tx-state-history-helper.js
+++ b/app/scripts/controllers/transactions/lib/tx-state-history-helper.js
@@ -17,10 +17,10 @@ function migrateFromSnapshotsToDiffs (longHistory) {
return (
longHistory
// convert non-initial history entries into diffs
- .map((entry, index) => {
- if (index === 0) return entry
- return generateHistoryEntry(longHistory[index - 1], entry)
- })
+ .map((entry, index) => {
+ if (index === 0) return entry
+ return generateHistoryEntry(longHistory[index - 1], entry)
+ })
)
}
diff --git a/app/scripts/controllers/transactions/lib/util.js b/app/scripts/controllers/transactions/lib/util.js
index 5a8a0cefe..0d2ddddef 100644
--- a/app/scripts/controllers/transactions/lib/util.js
+++ b/app/scripts/controllers/transactions/lib/util.js
@@ -26,7 +26,7 @@ const normalizers = {
gasPrice: gasPrice => addHexPrefix(gasPrice),
}
- /**
+/**
normalizes txParams
@param txParams {object}
@returns {object} normalized txParams
@@ -40,7 +40,7 @@ function normalizeTxParams (txParams, LowerCase) {
return normalizedTxParams
}
- /**
+/**
validates txParams
@param txParams {object}
*/
@@ -59,7 +59,7 @@ function validateTxParams (txParams) {
}
}
- /**
+/**
validates the from field in txParams
@param txParams {object}
*/
@@ -68,7 +68,7 @@ function validateFrom (txParams) {
if (!isValidAddress(txParams.from)) throw new Error('Invalid from address')
}
- /**
+/**
validates the to field in txParams
@param txParams {object}
*/
@@ -85,7 +85,7 @@ function validateRecipient (txParams) {
return txParams
}
- /**
+/**
@returns an {array} of states that can be considered final
*/
function getFinalStates () {
diff --git a/app/scripts/controllers/transactions/pending-tx-tracker.js b/app/scripts/controllers/transactions/pending-tx-tracker.js
index bc11f6633..1ef3be36e 100644
--- a/app/scripts/controllers/transactions/pending-tx-tracker.js
+++ b/app/scripts/controllers/transactions/pending-tx-tracker.js
@@ -186,7 +186,7 @@ class PendingTransactionTracker extends EventEmitter {
this.emit('tx:warning', txMeta, err)
}
}
- /**
+ /**
checks to see if if the tx's nonce has been used by another transaction
@param txMeta {Object} - txMeta object
@emits tx:dropped
@@ -198,7 +198,7 @@ class PendingTransactionTracker extends EventEmitter {
const nextNonce = await this.query.getTransactionCount(from)
const { blockNumber } = await this.query.getTransactionByHash(hash) || {}
if (!blockNumber && parseInt(nextNonce) > parseInt(nonce)) {
- return true
+ return true
}
return false
}
diff --git a/app/scripts/controllers/transactions/tx-state-manager.js b/app/scripts/controllers/transactions/tx-state-manager.js
index 2aa28c270..a91b59918 100644
--- a/app/scripts/controllers/transactions/tx-state-manager.js
+++ b/app/scripts/controllers/transactions/tx-state-manager.js
@@ -34,7 +34,7 @@ class TransactionStateManager extends EventEmitter {
this.store = new ObservableStore(
extend({
transactions: [],
- }, initState))
+ }, initState))
this.txHistoryLimit = txHistoryLimit
this.getNetwork = getNetwork
}
@@ -245,7 +245,7 @@ class TransactionStateManager extends EventEmitter {
})
}
-/**
+ /**
@param opts {object} - an object of fields to search for eg:<br>
let <code>thingsToLookFor = {<br>
to: '0x0..',<br>
@@ -403,9 +403,9 @@ class TransactionStateManager extends EventEmitter {
// Update state
this._saveTxList(otherAccountTxs)
}
-//
-// PRIVATE METHODS
-//
+ //
+ // PRIVATE METHODS
+ //
// STATUS METHODS
// statuses: