Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove keyringMemStore from DetectTokensController #20728

Merged
merged 3 commits into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 20 additions & 23 deletions app/scripts/controllers/detect-tokens.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export default class DetectTokensController {
* @param config.interval
* @param config.preferences
* @param config.network
* @param config.keyringMemStore
* @param config.tokenList
* @param config.tokensController
* @param config.assetsContractController
Expand All @@ -40,7 +39,6 @@ export default class DetectTokensController {
interval = DEFAULT_INTERVAL,
preferences,
network,
keyringMemStore,
tokenList,
tokensController,
assetsContractController = null,
Expand All @@ -52,7 +50,6 @@ export default class DetectTokensController {
this.preferences = preferences;
this.interval = interval;
this.network = network;
this.keyringMemStore = keyringMemStore;
this.tokenList = tokenList;
this.useTokenDetection =
this.preferences?.store.getState().useTokenDetection;
Expand Down Expand Up @@ -91,6 +88,8 @@ export default class DetectTokensController {
this.restartTokenDetection({ chainId: this.chainId });
}
});

this.#registerKeyringHandlers();
}

/**
Expand Down Expand Up @@ -236,26 +235,6 @@ export default class DetectTokensController {
}, interval);
}

/**
* 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) {
this.isUnlocked = isUnlocked;
if (isUnlocked) {
this.restartTokenDetection();
}
}
});
}

/**
* @type {object}
*/
Expand All @@ -275,4 +254,22 @@ export default class DetectTokensController {
return this.isOpen && this.isUnlocked;
}
/* eslint-enable accessor-pairs */

/**
* Constructor helper to register listeners on the keyring
* locked state changes
*/
#registerKeyringHandlers() {
const { isUnlocked } = this.messenger.call('KeyringController:getState');
this.isUnlocked = isUnlocked;

this.messenger.subscribe('KeyringController:unlock', () => {
this.isUnlocked = true;
this.restartTokenDetection();
});

this.messenger.subscribe('KeyringController:lock', () => {
this.isUnlocked = false;
});
}
}
83 changes: 54 additions & 29 deletions app/scripts/controllers/detect-tokens.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { strict as assert } from 'assert';
import sinon from 'sinon';
import nock from 'nock';
import { ObservableStore } from '@metamask/obs-store';
import BigNumber from 'bignumber.js';
import { ControllerMessenger } from '@metamask/base-controller';
import {
Expand All @@ -16,25 +15,30 @@ import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils';
import DetectTokensController from './detect-tokens';
import PreferencesController from './preferences';

function buildMessenger() {
return new ControllerMessenger().getRestricted({
name: 'DetectTokensController',
allowedEvents: ['NetworkController:stateChange'],
});
}
Comment on lines -19 to -24
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been substituted with getRestrictedMessenger which uses the messenger instance available in the higher scope, as it helps registering a mock handler for the KeyringController:getState action.


describe('DetectTokensController', function () {
let sandbox,
assetsContractController,
keyringMemStore,
network,
preferences,
provider,
tokensController,
tokenListController;
tokenListController,
messenger;

const noop = () => undefined;

const getRestrictedMessenger = () => {
return messenger.getRestricted({
name: 'DetectTokensController',
allowedActions: ['KeyringController:getState'],
allowedEvents: [
'NetworkController:stateChange',
'KeyringController:lock',
'KeyringController:unlock',
],
});
};

const networkControllerProviderConfig = {
getAccounts: noop,
};
Expand Down Expand Up @@ -198,7 +202,11 @@ describe('DetectTokensController', function () {
.reply(200, { error: 'ChainId 3 is not supported' })
.persist();

keyringMemStore = new ObservableStore({ isUnlocked: false });
messenger = new ControllerMessenger();
messenger.registerActionHandler('KeyringController:getState', () => ({
isUnlocked: true,
}));

const networkControllerMessenger = new ControllerMessenger();
network = new NetworkController({
messenger: networkControllerMessenger,
Expand Down Expand Up @@ -263,7 +271,11 @@ describe('DetectTokensController', function () {

it('should poll on correct interval', async function () {
const stub = sinon.stub(global, 'setInterval');
new DetectTokensController({ messenger: buildMessenger(), interval: 1337 }); // eslint-disable-line no-new
// eslint-disable-next-line no-new
new DetectTokensController({
messenger: getRestrictedMessenger(),
interval: 1337,
});
assert.strictEqual(stub.getCall(0).args[1], 1337);
stub.restore();
});
Expand All @@ -272,10 +284,9 @@ describe('DetectTokensController', function () {
const clock = sandbox.useFakeTimers();
await network.setProviderType(NETWORK_TYPES.MAINNET);
const controller = new DetectTokensController({
messenger: buildMessenger(),
messenger: getRestrictedMessenger(),
preferences,
network,
keyringMemStore,
tokenList: tokenListController,
tokensController,
assetsContractController,
Expand Down Expand Up @@ -309,10 +320,9 @@ describe('DetectTokensController', function () {
});
await tokenListController.start();
const controller = new DetectTokensController({
messenger: buildMessenger(),
messenger: getRestrictedMessenger(),
preferences,
network,
keyringMemStore,
tokenList: tokenListController,
tokensController,
assetsContractController,
Expand All @@ -333,10 +343,9 @@ describe('DetectTokensController', function () {
sandbox.useFakeTimers();
await network.setProviderType(NETWORK_TYPES.MAINNET);
const controller = new DetectTokensController({
messenger: buildMessenger(),
messenger: getRestrictedMessenger(),
preferences,
network,
keyringMemStore,
tokenList: tokenListController,
tokensController,
assetsContractController,
Expand Down Expand Up @@ -385,10 +394,9 @@ describe('DetectTokensController', function () {
sandbox.useFakeTimers();
await network.setProviderType(NETWORK_TYPES.MAINNET);
const controller = new DetectTokensController({
messenger: buildMessenger(),
messenger: getRestrictedMessenger(),
preferences,
network,
keyringMemStore,
tokenList: tokenListController,
tokensController,
assetsContractController,
Expand Down Expand Up @@ -444,10 +452,9 @@ describe('DetectTokensController', function () {
it('should trigger detect new tokens when change address', async function () {
sandbox.useFakeTimers();
const controller = new DetectTokensController({
messenger: buildMessenger(),
messenger: getRestrictedMessenger(),
preferences,
network,
keyringMemStore,
tokenList: tokenListController,
tokensController,
assetsContractController,
Expand All @@ -464,29 +471,48 @@ describe('DetectTokensController', function () {
it('should trigger detect new tokens when submit password', async function () {
sandbox.useFakeTimers();
const controller = new DetectTokensController({
messenger: buildMessenger(),
messenger: getRestrictedMessenger(),
preferences,
network,
keyringMemStore,
tokenList: tokenListController,
tokensController,
assetsContractController,
});
controller.isOpen = true;
controller.selectedAddress = '0x0';
const stub = sandbox.stub(controller, 'detectNewTokens');
await controller._keyringMemStore.updateState({ isUnlocked: true });

messenger.publish('KeyringController:unlock');

sandbox.assert.called(stub);
assert.equal(controller.isUnlocked, true);
});

it('should not be active after lock event is emitted', async function () {
sandbox.useFakeTimers();
const controller = new DetectTokensController({
messenger: getRestrictedMessenger(),
preferences,
network,
tokenList: tokenListController,
tokensController,
assetsContractController,
});
controller.isOpen = true;

messenger.publish('KeyringController:lock');

assert.equal(controller.isUnlocked, false);
assert.equal(controller.isActive, false);
});

it('should not trigger detect new tokens when not unlocked', async function () {
const clock = sandbox.useFakeTimers();
await network.setProviderType(NETWORK_TYPES.MAINNET);
const controller = new DetectTokensController({
messenger: buildMessenger(),
messenger: getRestrictedMessenger(),
preferences,
network,
keyringMemStore,
tokenList: tokenListController,
tokensController,
assetsContractController,
Expand All @@ -505,10 +531,9 @@ describe('DetectTokensController', function () {
const clock = sandbox.useFakeTimers();
await network.setProviderType(NETWORK_TYPES.MAINNET);
const controller = new DetectTokensController({
messenger: buildMessenger(),
messenger: getRestrictedMessenger(),
preferences,
network,
keyringMemStore,
tokensController,
assetsContractController,
});
Expand Down
8 changes: 6 additions & 2 deletions app/scripts/metamask-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -1142,15 +1142,19 @@ export default class MetamaskController extends EventEmitter {
const detectTokensControllerMessenger =
this.controllerMessenger.getRestricted({
name: 'DetectTokensController',
allowedEvents: ['NetworkController:stateChange'],
allowedActions: ['KeyringController:getState'],
allowedEvents: [
'NetworkController:stateChange',
'KeyringController:lock',
'KeyringController:unlock',
],
});
this.detectTokensController = new DetectTokensController({
messenger: detectTokensControllerMessenger,
preferences: this.preferencesController,
tokensController: this.tokensController,
assetsContractController: this.assetsContractController,
network: this.networkController,
keyringMemStore: this.keyringController.memStore,
tokenList: this.tokenListController,
trackMetaMetricsEvent: this.metaMetricsController.trackEvent.bind(
this.metaMetricsController,
Expand Down