aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/scripts/controllers/detect-tokens.js2
-rw-r--r--app/scripts/controllers/preferences.js82
-rw-r--r--app/scripts/metamask-controller.js1
-rw-r--r--app/scripts/migrations/028.js37
-rw-r--r--app/scripts/migrations/index.js1
-rw-r--r--test/unit/app/controllers/detect-tokens-test.js21
-rw-r--r--test/unit/app/controllers/preferences-controller-test.js5
-rw-r--r--ui/app/actions.js3
8 files changed, 118 insertions, 34 deletions
diff --git a/app/scripts/controllers/detect-tokens.js b/app/scripts/controllers/detect-tokens.js
index 195ec918a..62e639795 100644
--- a/app/scripts/controllers/detect-tokens.js
+++ b/app/scripts/controllers/detect-tokens.js
@@ -85,7 +85,7 @@ class DetectTokensController {
set preferences (preferences) {
if (!preferences) { return }
this._preferences = preferences
- preferences.store.subscribe(({ tokens }) => { this.tokenAddresses = tokens.map((obj) => { return obj.address }) })
+ preferences.store.subscribe(({ tokens = [] }) => { this.tokenAddresses = tokens.map((obj) => { return obj.address }) })
preferences.store.subscribe(({ selectedAddress }) => {
if (this.selectedAddress !== selectedAddress) {
this.selectedAddress = selectedAddress
diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js
index f6250dc16..88b6fa998 100644
--- a/app/scripts/controllers/preferences.js
+++ b/app/scripts/controllers/preferences.js
@@ -13,6 +13,7 @@ class PreferencesController {
* @property {array} store.frequentRpcList A list of custom rpcs to provide the user
* @property {string} store.currentAccountTab Indicates the selected tab in the ui
* @property {array} store.tokens The tokens the user wants display in their token lists
+ * @property {object} store.accountTokens The tokens stored per account and then per network type
* @property {boolean} store.useBlockie The users preference for blockie identicons within the UI
* @property {object} store.featureFlags A key-boolean map, where keys refer to features and booleans to whether the
* user wishes to see that feature
@@ -24,6 +25,7 @@ class PreferencesController {
const initState = extend({
frequentRpcList: [],
currentAccountTab: 'history',
+ accountTokens: {},
tokens: [],
useBlockie: false,
featureFlags: {},
@@ -33,8 +35,10 @@ class PreferencesController {
}, opts.initState)
this.diagnostics = opts.diagnostics
-
+ this.network = opts.network
this.store = new ObservableStore(initState)
+ this._defineTokens()
+ this._subscribeProviderType()
}
// PUBLIC METHODS
@@ -77,12 +81,17 @@ class PreferencesController {
*/
setAddresses (addresses) {
const oldIdentities = this.store.getState().identities
+ const accountTokens = this.store.getState().accountTokens
+
const identities = addresses.reduce((ids, address, index) => {
const oldId = oldIdentities[address] || {}
ids[address] = {name: `Account ${index + 1}`, address, ...oldId}
return ids
}, {})
- this.store.updateState({ identities })
+ for (const address in identities) {
+ if (!(address in accountTokens)) accountTokens[address] = {}
+ }
+ this.store.updateState({ identities, accountTokens })
}
/**
@@ -93,11 +102,13 @@ class PreferencesController {
*/
removeAddress (address) {
const identities = this.store.getState().identities
+ const accountTokens = this.store.getState().accountTokens
if (!identities[address]) {
throw new Error(`${address} can't be deleted cause it was not found`)
}
delete identities[address]
- this.store.updateState({ identities })
+ delete accountTokens[address]
+ this.store.updateState({ identities, accountTokens })
// If the selected account is no longer valid,
// select an arbitrary other account:
@@ -117,14 +128,17 @@ class PreferencesController {
*/
addAddresses (addresses) {
const identities = this.store.getState().identities
+ const accountTokens = this.store.getState().accountTokens
addresses.forEach((address) => {
// skip if already exists
if (identities[address]) return
// add missing identity
const identityCount = Object.keys(identities).length
+
+ if (!(address in accountTokens)) accountTokens[address] = {}
identities[address] = { name: `Account ${identityCount + 1}`, address }
})
- this.store.updateState({ identities })
+ this.store.updateState({ identities, accountTokens })
}
/*
@@ -179,11 +193,16 @@ class PreferencesController {
*
*/
setSelectedAddress (_address) {
- return new Promise((resolve, reject) => {
- const address = normalizeAddress(_address)
- this.store.updateState({ selectedAddress: address })
- resolve()
- })
+ const address = normalizeAddress(_address)
+ const accountTokens = this.store.getState().accountTokens
+ const providerType = this.network.providerStore.getState().type
+
+ if (!(address in accountTokens)) accountTokens[address] = {}
+ if (!(providerType in accountTokens[address])) accountTokens[address][providerType] = []
+ const tokens = accountTokens[address][providerType]
+ this.store.updateState({ selectedAddress: address, tokens })
+
+ return Promise.resolve(tokens)
}
/**
@@ -233,7 +252,11 @@ class PreferencesController {
tokens.push(newEntry)
}
- this.store.updateState({ tokens })
+ const selectedAddress = this.store.getState().selectedAddress
+ const accountTokens = this.store.getState().accountTokens
+ const providerType = this.network.providerStore.getState().type
+ accountTokens[selectedAddress][providerType] = tokens
+ this.store.updateState({ accountTokens, tokens })
return Promise.resolve(tokens)
}
@@ -246,11 +269,13 @@ class PreferencesController {
*
*/
removeToken (rawAddress) {
- const tokens = this.store.getState().tokens
+ const accountTokens = this.store.getState().accountTokens
+ const selectedAddress = this.store.getState().selectedAddress
+ const providerType = this.network.providerStore.getState().type
+ const updatedTokens = accountTokens[selectedAddress][providerType].filter(token => token.address !== rawAddress)
+ accountTokens[selectedAddress][providerType] = updatedTokens
+ this.store.updateState({ accountTokens, tokens: updatedTokens })
- const updatedTokens = tokens.filter(token => token.address !== rawAddress)
-
- this.store.updateState({ tokens: updatedTokens })
return Promise.resolve(updatedTokens)
}
@@ -376,6 +401,35 @@ class PreferencesController {
//
// PRIVATE METHODS
//
+
+ /**
+ * Getter definition for the `tokens` property of store when controller is initialized
+ *
+ *
+ */
+ _defineTokens () {
+ const selectedAddress = this.store.getState().selectedAddress
+ const accountTokens = this.store.getState().accountTokens
+ const providerType = this.network.providerStore.getState().type
+ if (!(selectedAddress in accountTokens)) accountTokens[selectedAddress] = {}
+ if (!(providerType in accountTokens[selectedAddress])) return []
+ this.tokens = accountTokens[selectedAddress][providerType]
+ }
+
+ /**
+ * Subscription to network provider type
+ *
+ *
+ */
+ _subscribeProviderType () {
+ this.network.providerStore.subscribe(({ type }) => {
+ const selectedAddress = this.store.getState().selectedAddress
+ const accountTokens = this.store.getState().accountTokens
+ if (!(type in accountTokens[selectedAddress])) accountTokens[selectedAddress][type] = []
+ const tokens = accountTokens[selectedAddress][type]
+ this.store.updateState({ tokens })
+ })
+ }
}
module.exports = PreferencesController
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index bcc7075c2..df84bcba4 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -87,6 +87,7 @@ module.exports = class MetamaskController extends EventEmitter {
this.preferencesController = new PreferencesController({
initState: initState.PreferencesController,
initLangCode: opts.initLangCode,
+ network: this.networkController,
})
// currency controller
diff --git a/app/scripts/migrations/028.js b/app/scripts/migrations/028.js
new file mode 100644
index 000000000..e36884a9c
--- /dev/null
+++ b/app/scripts/migrations/028.js
@@ -0,0 +1,37 @@
+// next version number
+const version = 28
+
+/*
+
+normalizes txParams on unconfirmed txs
+
+*/
+const clone = require('clone')
+
+module.exports = {
+ version,
+
+ migrate: async function (originalVersionedData) {
+ const versionedData = clone(originalVersionedData)
+ versionedData.meta.version = version
+ const state = versionedData.data
+ const newState = transformState(state)
+ versionedData.data = newState
+ return versionedData
+ },
+}
+
+function transformState (state) {
+ const newState = state
+
+ if (newState.PreferencesController) {
+ if (newState.PreferencesController.tokens) {
+ const tokens = newState.TransactionController.tokens
+ const selectedAddress = newState.PreferencesController.selectedAddress
+ newState.PreferencesController.tokens = []
+ newState.PreferencesController.accountTokens = {selectedAddress: {'mainnet': tokens}}
+ }
+ }
+
+ return newState
+}
diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js
index bd0005221..3b512715e 100644
--- a/app/scripts/migrations/index.js
+++ b/app/scripts/migrations/index.js
@@ -38,4 +38,5 @@ module.exports = [
require('./025'),
require('./026'),
require('./027'),
+ require('./028'),
]
diff --git a/test/unit/app/controllers/detect-tokens-test.js b/test/unit/app/controllers/detect-tokens-test.js
index 426ffe23a..d6c3fad8a 100644
--- a/test/unit/app/controllers/detect-tokens-test.js
+++ b/test/unit/app/controllers/detect-tokens-test.js
@@ -7,10 +7,11 @@ const PreferencesController = require('../../../../app/scripts/controllers/prefe
describe('DetectTokensController', () => {
const sandbox = sinon.createSandbox()
- let clock
- let keyringMemStore
- before(async () => {
+ let clock, keyringMemStore, network, preferences
+ beforeEach(async () => {
keyringMemStore = new ObservableStore({ isUnlocked: false})
+ network = new NetworkController({ provider: { type: 'mainnet' }})
+ preferences = new PreferencesController({ network })
})
after(() => {
sandbox.restore()
@@ -25,9 +26,7 @@ describe('DetectTokensController', () => {
it('should be called on every polling period', async () => {
clock = sandbox.useFakeTimers()
- const network = new NetworkController()
network.setProviderType('mainnet')
- const preferences = new PreferencesController()
const controller = new DetectTokensController({ preferences: preferences, network: network, keyringMemStore: keyringMemStore })
controller.isOpen = true
controller.isUnlocked = true
@@ -45,9 +44,7 @@ describe('DetectTokensController', () => {
})
it('should not check tokens while in test network', async () => {
- const network = new NetworkController()
network.setProviderType('rinkeby')
- const preferences = new PreferencesController()
const controller = new DetectTokensController({ preferences: preferences, network: network, keyringMemStore: keyringMemStore })
controller.isOpen = true
controller.isUnlocked = true
@@ -61,9 +58,7 @@ describe('DetectTokensController', () => {
})
it('should only check and add tokens while in main network', async () => {
- const network = new NetworkController()
network.setProviderType('mainnet')
- const preferences = new PreferencesController()
const controller = new DetectTokensController({ preferences: preferences, network: network, keyringMemStore: keyringMemStore })
controller.isOpen = true
controller.isUnlocked = true
@@ -80,9 +75,7 @@ describe('DetectTokensController', () => {
})
it('should not detect same token while in main network', async () => {
- const network = new NetworkController()
network.setProviderType('mainnet')
- const preferences = new PreferencesController()
preferences.addToken('0x0d262e5dc4a06a0f1c90ce79c7a60c09dfc884e4', 'J8T', 8)
const controller = new DetectTokensController({ preferences: preferences, network: network, keyringMemStore: keyringMemStore })
controller.isOpen = true
@@ -100,9 +93,7 @@ describe('DetectTokensController', () => {
})
it('should trigger detect new tokens when change address', async () => {
- const network = new NetworkController()
network.setProviderType('mainnet')
- const preferences = new PreferencesController()
const controller = new DetectTokensController({ preferences: preferences, network: network, keyringMemStore: keyringMemStore })
controller.isOpen = true
controller.isUnlocked = true
@@ -112,9 +103,7 @@ describe('DetectTokensController', () => {
})
it('should trigger detect new tokens when submit password', async () => {
- const network = new NetworkController()
network.setProviderType('mainnet')
- const preferences = new PreferencesController()
const controller = new DetectTokensController({ preferences: preferences, network: network, keyringMemStore: keyringMemStore })
controller.isOpen = true
controller.selectedAddress = '0x0'
@@ -124,9 +113,7 @@ describe('DetectTokensController', () => {
})
it('should not trigger detect new tokens when not open or not unlocked', async () => {
- const network = new NetworkController()
network.setProviderType('mainnet')
- const preferences = new PreferencesController()
const controller = new DetectTokensController({ preferences: preferences, network: network, keyringMemStore: keyringMemStore })
controller.isOpen = true
controller.isUnlocked = false
diff --git a/test/unit/app/controllers/preferences-controller-test.js b/test/unit/app/controllers/preferences-controller-test.js
index e055500b1..0b96fdfa5 100644
--- a/test/unit/app/controllers/preferences-controller-test.js
+++ b/test/unit/app/controllers/preferences-controller-test.js
@@ -1,11 +1,14 @@
const assert = require('assert')
+const ObservableStore = require('obs-store')
const PreferencesController = require('../../../../app/scripts/controllers/preferences')
describe('preferences controller', function () {
let preferencesController
+ let network
beforeEach(() => {
- preferencesController = new PreferencesController()
+ network = {providerStore: new ObservableStore({ type: 'mainnet' })}
+ preferencesController = new PreferencesController({ network })
})
describe('setAddresses', function () {
diff --git a/ui/app/actions.js b/ui/app/actions.js
index 7a8d9667d..4f71d911b 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -1483,11 +1483,12 @@ function showAccountDetail (address) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
log.debug(`background.setSelectedAddress`)
- background.setSelectedAddress(address, (err) => {
+ background.setSelectedAddress(address, (err, tokens) => {
dispatch(actions.hideLoadingIndication())
if (err) {
return dispatch(actions.displayWarning(err.message))
}
+ dispatch(updateTokens(tokens))
dispatch({
type: actions.SHOW_ACCOUNT_DETAIL,
value: address,