diff --git a/app/scripts/controllers/detect-tokens.js b/app/scripts/controllers/detect-tokens.js index db21f7489..f1810cfa1 100644 --- a/app/scripts/controllers/detect-tokens.js +++ b/app/scripts/controllers/detect-tokens.js @@ -16,11 +16,11 @@ class DetectTokensController { * * @param {Object} [config] - Options to configure controller */ - constructor ({ interval = DEFAULT_INTERVAL, preferences, network } = {}) { + constructor ({ interval = DEFAULT_INTERVAL, preferences, network, keyringMemStore } = {}) { this.preferences = preferences this.interval = interval this.network = network - this._isActive = false + this.keyringMemStore = keyringMemStore } /** @@ -28,7 +28,7 @@ class DetectTokensController { * */ async detectNewTokens () { - if (!this._isActive) { return } + if (!this.isActive) { return } if (this._network.store.getState().provider.type !== MAINNET) { return } this.web3.setProvider(this._network._provider) for (const contractAddress in contracts) { @@ -64,7 +64,7 @@ class DetectTokensController { * */ restartTokenDetection () { - if (this._isActive && this.selectedAddress) { + if (this.isActive && this.selectedAddress) { this.detectNewTokens() this.interval = DEFAULT_INTERVAL } @@ -105,15 +105,19 @@ class DetectTokensController { } /** - * In setter, when _isActive is changed, detectNewTokens and restart polling - * @type {Object} - */ - set isActive (active) { - if (this._isActive !== active) { - this._isActive = active - this.restartTokenDetection() + * In setter when isUnlocked is updated to true, detectNewTokens and restart polling + * @type {Object} + */ + set keyringMemStore (keyringMemStore) { + if (!keyringMemStore) { return } + this._keyringMemStore = keyringMemStore + this._keyringMemStore.subscribe(({ isUnlocked }) => { + if (this.isUnlocked !== isUnlocked) { + if (isUnlocked) { this.restartTokenDetection() } + this.isUnlocked = isUnlocked } - } + }) + } } module.exports = DetectTokensController diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 39527ae3b..4e97ce583 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -113,12 +113,6 @@ module.exports = class MetamaskController extends EventEmitter { preferences: this.preferencesController.store, }) - // detect tokens controller - this.detectTokensController = new DetectTokensController({ - preferences: this.preferencesController, - network: this.networkController, - }) - this.recentBlocksController = new RecentBlocksController({ blockTracker: this.blockTracker, provider: this.provider, @@ -151,6 +145,13 @@ module.exports = class MetamaskController extends EventEmitter { this.accountTracker.syncWithAddresses(addresses) }) + // detect tokens controller + this.detectTokensController = new DetectTokensController({ + preferences: this.preferencesController, + network: this.networkController, + keyringMemStore: this.keyringController.memStore, + }) + // address book controller this.addressBookController = new AddressBookController({ initState: initState.AddressBookController, @@ -1276,7 +1277,8 @@ module.exports = class MetamaskController extends EventEmitter { } /** - * A method for activating the retrieval of price data, which should only be fetched when the UI is visible. + * A method for activating the retrieval of price data and auto detect tokens, + * which should only be fetched when the UI is visible. * @private * @param {boolean} active - True if price data should be getting fetched. */ diff --git a/test/unit/app/controllers/detect-tokens-test.js b/test/unit/app/controllers/detect-tokens-test.js index 49492c543..dcb3c431f 100644 --- a/test/unit/app/controllers/detect-tokens-test.js +++ b/test/unit/app/controllers/detect-tokens-test.js @@ -1,14 +1,17 @@ const assert = require('assert') const sinon = require('sinon') +const ObservableStore = require('obs-store') const DetectTokensController = require('../../../../app/scripts/controllers/detect-tokens') const NetworkController = require('../../../../app/scripts/controllers/network/network') const PreferencesController = require('../../../../app/scripts/controllers/preferences') describe('DetectTokensController', () => { - const sandbox = sinon.createSandbox() + const sandbox = sinon.createSandbox() let clock + let keyringMemStore before(async () => { - }) + keyringMemStore = new ObservableStore({ isUnlocked: false}) + }) after(() => { sandbox.restore() }) @@ -25,7 +28,7 @@ describe('DetectTokensController', () => { const network = new NetworkController() network.setProviderType('mainnet') const preferences = new PreferencesController() - const controller = new DetectTokensController({preferences: preferences, network: network}) + const controller = new DetectTokensController({ preferences: preferences, network: network, keyringMemStore: keyringMemStore }) controller.isActive = true var stub = sandbox.stub(controller, 'detectNewTokens') @@ -44,7 +47,7 @@ describe('DetectTokensController', () => { const network = new NetworkController() network.setProviderType('rinkeby') const preferences = new PreferencesController() - const controller = new DetectTokensController({preferences: preferences, network: network}) + const controller = new DetectTokensController({ preferences: preferences, network: network, keyringMemStore: keyringMemStore }) controller.isActive = true var stub = sandbox.stub(controller, 'detectTokenBalance') @@ -59,7 +62,7 @@ describe('DetectTokensController', () => { const network = new NetworkController() network.setProviderType('mainnet') const preferences = new PreferencesController() - const controller = new DetectTokensController({preferences: preferences, network: network}) + const controller = new DetectTokensController({ preferences: preferences, network: network, keyringMemStore: keyringMemStore }) controller.isActive = true sandbox.stub(controller, 'detectTokenBalance') @@ -78,7 +81,7 @@ describe('DetectTokensController', () => { network.setProviderType('mainnet') const preferences = new PreferencesController() preferences.addToken('0x0d262e5dc4a06a0f1c90ce79c7a60c09dfc884e4', 'J8T', 8) - const controller = new DetectTokensController({preferences: preferences, network: network}) + const controller = new DetectTokensController({ preferences: preferences, network: network, keyringMemStore: keyringMemStore }) controller.isActive = true sandbox.stub(controller, 'detectTokenBalance') @@ -91,4 +94,27 @@ describe('DetectTokensController', () => { assert.deepEqual(preferences.store.getState().tokens, [{address: '0x0d262e5dc4a06a0f1c90ce79c7a60c09dfc884e4', decimals: 8, symbol: 'J8T'}, {address: '0xbc86727e770de68b1060c91f6bb6945c73e10388', decimals: 18, symbol: 'XNK'}]) }) + + 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.isActive = true + var stub = sandbox.stub(controller, 'detectNewTokens') + await preferences.setSelectedAddress('0xbc86727e770de68b1060c91f6bb6945c73e10388') + sandbox.assert.called(stub) + }) + + 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.isActive = true + controller.selectedAddress = '0x0' + var stub = sandbox.stub(controller, 'detectNewTokens') + await controller._keyringMemStore.updateState({ isUnlocked: true }) + sandbox.assert.called(stub) + }) })