mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-28 23:06:37 +01:00
Trigger unlock popup in appStateController using ApprovalController (#18386)
This commit is contained in:
parent
5d2c4c143a
commit
a3af0b53e3
@ -1,5 +1,7 @@
|
|||||||
import EventEmitter from 'events';
|
import EventEmitter from 'events';
|
||||||
import { ObservableStore } from '@metamask/obs-store';
|
import { ObservableStore } from '@metamask/obs-store';
|
||||||
|
import { v4 as uuid } from 'uuid';
|
||||||
|
import log from 'loglevel';
|
||||||
import { METAMASK_CONTROLLER_EVENTS } from '../metamask-controller';
|
import { METAMASK_CONTROLLER_EVENTS } from '../metamask-controller';
|
||||||
import { MINUTE } from '../../../shared/constants/time';
|
import { MINUTE } from '../../../shared/constants/time';
|
||||||
import { AUTO_LOCK_TIMEOUT_ALARM } from '../../../shared/constants/alarms';
|
import { AUTO_LOCK_TIMEOUT_ALARM } from '../../../shared/constants/alarms';
|
||||||
@ -8,8 +10,11 @@ import { isBeta } from '../../../ui/helpers/utils/build-types';
|
|||||||
import {
|
import {
|
||||||
ENVIRONMENT_TYPE_BACKGROUND,
|
ENVIRONMENT_TYPE_BACKGROUND,
|
||||||
POLLING_TOKEN_ENVIRONMENT_TYPES,
|
POLLING_TOKEN_ENVIRONMENT_TYPES,
|
||||||
|
ORIGIN_METAMASK,
|
||||||
} from '../../../shared/constants/app';
|
} from '../../../shared/constants/app';
|
||||||
|
|
||||||
|
const APPROVAL_REQUEST_TYPE = 'unlock';
|
||||||
|
|
||||||
export default class AppStateController extends EventEmitter {
|
export default class AppStateController extends EventEmitter {
|
||||||
/**
|
/**
|
||||||
* @param {object} opts
|
* @param {object} opts
|
||||||
@ -20,9 +25,9 @@ export default class AppStateController extends EventEmitter {
|
|||||||
isUnlocked,
|
isUnlocked,
|
||||||
initState,
|
initState,
|
||||||
onInactiveTimeout,
|
onInactiveTimeout,
|
||||||
showUnlockRequest,
|
|
||||||
preferencesStore,
|
preferencesStore,
|
||||||
qrHardwareStore,
|
qrHardwareStore,
|
||||||
|
messenger,
|
||||||
} = opts;
|
} = opts;
|
||||||
super();
|
super();
|
||||||
|
|
||||||
@ -59,8 +64,6 @@ export default class AppStateController extends EventEmitter {
|
|||||||
this.waitingForUnlock = [];
|
this.waitingForUnlock = [];
|
||||||
addUnlockListener(this.handleUnlock.bind(this));
|
addUnlockListener(this.handleUnlock.bind(this));
|
||||||
|
|
||||||
this._showUnlockRequest = showUnlockRequest;
|
|
||||||
|
|
||||||
preferencesStore.subscribe(({ preferences }) => {
|
preferencesStore.subscribe(({ preferences }) => {
|
||||||
const currentState = this.store.getState();
|
const currentState = this.store.getState();
|
||||||
if (currentState.timeoutMinutes !== preferences.autoLockTimeLimit) {
|
if (currentState.timeoutMinutes !== preferences.autoLockTimeLimit) {
|
||||||
@ -74,6 +77,9 @@ export default class AppStateController extends EventEmitter {
|
|||||||
|
|
||||||
const { preferences } = preferencesStore.getState();
|
const { preferences } = preferencesStore.getState();
|
||||||
this._setInactiveTimeout(preferences.autoLockTimeLimit);
|
this._setInactiveTimeout(preferences.autoLockTimeLimit);
|
||||||
|
|
||||||
|
this.messagingSystem = messenger;
|
||||||
|
this._approvalRequestId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,7 +114,7 @@ export default class AppStateController extends EventEmitter {
|
|||||||
this.waitingForUnlock.push({ resolve });
|
this.waitingForUnlock.push({ resolve });
|
||||||
this.emit(METAMASK_CONTROLLER_EVENTS.UPDATE_BADGE);
|
this.emit(METAMASK_CONTROLLER_EVENTS.UPDATE_BADGE);
|
||||||
if (shouldShowUnlockRequest) {
|
if (shouldShowUnlockRequest) {
|
||||||
this._showUnlockRequest();
|
this._requestApproval();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,6 +128,8 @@ export default class AppStateController extends EventEmitter {
|
|||||||
}
|
}
|
||||||
this.emit(METAMASK_CONTROLLER_EVENTS.UPDATE_BADGE);
|
this.emit(METAMASK_CONTROLLER_EVENTS.UPDATE_BADGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._acceptApproval();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -369,4 +377,39 @@ export default class AppStateController extends EventEmitter {
|
|||||||
serviceWorkerLastActiveTime,
|
serviceWorkerLastActiveTime,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_requestApproval() {
|
||||||
|
this._approvalRequestId = uuid();
|
||||||
|
|
||||||
|
this.messagingSystem
|
||||||
|
.call(
|
||||||
|
'ApprovalController:addRequest',
|
||||||
|
{
|
||||||
|
id: this._approvalRequestId,
|
||||||
|
origin: ORIGIN_METAMASK,
|
||||||
|
type: APPROVAL_REQUEST_TYPE,
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
.catch(() => {
|
||||||
|
// Intentionally ignored as promise not currently used
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_acceptApproval() {
|
||||||
|
if (!this._approvalRequestId) {
|
||||||
|
log.error('Attempted to accept missing unlock approval request');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.messagingSystem.call(
|
||||||
|
'ApprovalController:acceptRequest',
|
||||||
|
this._approvalRequestId,
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
log.error('Failed to accept transaction approval request', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._approvalRequestId = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,158 @@
|
|||||||
|
import { ObservableStore } from '@metamask/obs-store';
|
||||||
|
import log from 'loglevel';
|
||||||
|
import { ORIGIN_METAMASK } from '../../../shared/constants/app';
|
||||||
import AppStateController from './app-state';
|
import AppStateController from './app-state';
|
||||||
|
|
||||||
|
jest.mock('loglevel');
|
||||||
|
|
||||||
|
let appStateController, mockStore;
|
||||||
|
|
||||||
describe('AppStateController', () => {
|
describe('AppStateController', () => {
|
||||||
|
mockStore = new ObservableStore();
|
||||||
|
const createAppStateController = (initState = {}) => {
|
||||||
|
return new AppStateController({
|
||||||
|
addUnlockListener: jest.fn(),
|
||||||
|
isUnlocked: jest.fn(() => true),
|
||||||
|
initState,
|
||||||
|
onInactiveTimeout: jest.fn(),
|
||||||
|
showUnlockRequest: jest.fn(),
|
||||||
|
preferencesStore: {
|
||||||
|
subscribe: jest.fn(),
|
||||||
|
getState: jest.fn(() => ({
|
||||||
|
preferences: {
|
||||||
|
autoLockTimeLimit: 0,
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
qrHardwareStore: {
|
||||||
|
subscribe: jest.fn(),
|
||||||
|
},
|
||||||
|
messenger: {
|
||||||
|
call: jest.fn(() => ({
|
||||||
|
catch: jest.fn(),
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
appStateController = createAppStateController({ store: mockStore });
|
||||||
|
});
|
||||||
|
|
||||||
describe('setOutdatedBrowserWarningLastShown', () => {
|
describe('setOutdatedBrowserWarningLastShown', () => {
|
||||||
it('should set the last shown time', () => {
|
it('sets the last shown time', () => {
|
||||||
const appStateController = new AppStateController({
|
appStateController = createAppStateController();
|
||||||
|
const date = new Date();
|
||||||
|
|
||||||
|
appStateController.setOutdatedBrowserWarningLastShown(date);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
appStateController.store.getState().outdatedBrowserWarningLastShown,
|
||||||
|
).toStrictEqual(date);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sets outdated browser warning last shown timestamp', () => {
|
||||||
|
const lastShownTimestamp = Date.now();
|
||||||
|
appStateController = createAppStateController();
|
||||||
|
const updateStateSpy = jest.spyOn(
|
||||||
|
appStateController.store,
|
||||||
|
'updateState',
|
||||||
|
);
|
||||||
|
|
||||||
|
appStateController.setOutdatedBrowserWarningLastShown(lastShownTimestamp);
|
||||||
|
|
||||||
|
expect(updateStateSpy).toHaveBeenCalledTimes(1);
|
||||||
|
expect(updateStateSpy).toHaveBeenCalledWith({
|
||||||
|
outdatedBrowserWarningLastShown: lastShownTimestamp,
|
||||||
|
});
|
||||||
|
|
||||||
|
updateStateSpy.mockRestore();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getUnlockPromise', () => {
|
||||||
|
it('waits for unlock if the extension is locked', async () => {
|
||||||
|
appStateController = createAppStateController();
|
||||||
|
const isUnlockedMock = jest
|
||||||
|
.spyOn(appStateController, 'isUnlocked')
|
||||||
|
.mockReturnValue(false);
|
||||||
|
const waitForUnlockSpy = jest.spyOn(appStateController, 'waitForUnlock');
|
||||||
|
|
||||||
|
appStateController.getUnlockPromise(true);
|
||||||
|
expect(isUnlockedMock).toHaveBeenCalled();
|
||||||
|
expect(waitForUnlockSpy).toHaveBeenCalledWith(expect.any(Function), true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('resolves immediately if the extension is already unlocked', async () => {
|
||||||
|
appStateController = createAppStateController();
|
||||||
|
const isUnlockedMock = jest
|
||||||
|
.spyOn(appStateController, 'isUnlocked')
|
||||||
|
.mockReturnValue(true);
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
appStateController.getUnlockPromise(false),
|
||||||
|
).resolves.toBeUndefined();
|
||||||
|
|
||||||
|
expect(isUnlockedMock).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('waitForUnlock', () => {
|
||||||
|
it('resolves immediately if already unlocked', async () => {
|
||||||
|
const emitSpy = jest.spyOn(appStateController, 'emit');
|
||||||
|
const resolveFn = jest.fn();
|
||||||
|
appStateController.waitForUnlock(resolveFn, false);
|
||||||
|
expect(emitSpy).toHaveBeenCalledWith('updateBadge');
|
||||||
|
expect(appStateController.messagingSystem.call).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('creates approval request when waitForUnlock is called with shouldShowUnlockRequest as true', async () => {
|
||||||
|
jest.spyOn(appStateController, 'isUnlocked').mockReturnValue(false);
|
||||||
|
|
||||||
|
const resolveFn = jest.fn();
|
||||||
|
appStateController.waitForUnlock(resolveFn, true);
|
||||||
|
|
||||||
|
expect(appStateController.messagingSystem.call).toHaveBeenCalledTimes(1);
|
||||||
|
expect(appStateController.messagingSystem.call).toHaveBeenCalledWith(
|
||||||
|
'ApprovalController:addRequest',
|
||||||
|
expect.objectContaining({
|
||||||
|
id: expect.any(String),
|
||||||
|
origin: ORIGIN_METAMASK,
|
||||||
|
type: 'unlock',
|
||||||
|
}),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('handleUnlock', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.spyOn(appStateController, 'isUnlocked').mockReturnValue(false);
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
it('accepts approval request revolving all the related promises', async () => {
|
||||||
|
const emitSpy = jest.spyOn(appStateController, 'emit');
|
||||||
|
const resolveFn = jest.fn();
|
||||||
|
appStateController.waitForUnlock(resolveFn, true);
|
||||||
|
|
||||||
|
appStateController.handleUnlock();
|
||||||
|
|
||||||
|
expect(emitSpy).toHaveBeenCalled();
|
||||||
|
expect(emitSpy).toHaveBeenCalledWith('updateBadge');
|
||||||
|
expect(appStateController.messagingSystem.call).toHaveBeenCalled();
|
||||||
|
expect(appStateController.messagingSystem.call).toHaveBeenCalledWith(
|
||||||
|
'ApprovalController:acceptRequest',
|
||||||
|
expect.any(String),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('logs if rejecting approval request throws', async () => {
|
||||||
|
appStateController._approvalRequestId = 'mock-approval-request-id';
|
||||||
|
appStateController = new AppStateController({
|
||||||
addUnlockListener: jest.fn(),
|
addUnlockListener: jest.fn(),
|
||||||
isUnlocked: jest.fn(() => true),
|
isUnlocked: jest.fn(() => true),
|
||||||
initState: {},
|
|
||||||
onInactiveTimeout: jest.fn(),
|
onInactiveTimeout: jest.fn(),
|
||||||
showUnlockRequest: jest.fn(),
|
showUnlockRequest: jest.fn(),
|
||||||
preferencesStore: {
|
preferencesStore: {
|
||||||
@ -20,14 +166,184 @@ describe('AppStateController', () => {
|
|||||||
qrHardwareStore: {
|
qrHardwareStore: {
|
||||||
subscribe: jest.fn(),
|
subscribe: jest.fn(),
|
||||||
},
|
},
|
||||||
|
messenger: {
|
||||||
|
call: jest.fn(() => {
|
||||||
|
throw new Error('mock error');
|
||||||
|
}),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
const date = new Date();
|
|
||||||
|
|
||||||
appStateController.setOutdatedBrowserWarningLastShown(date);
|
appStateController.handleUnlock();
|
||||||
|
|
||||||
|
expect(log.error).toHaveBeenCalledTimes(1);
|
||||||
|
expect(log.error).toHaveBeenCalledWith(
|
||||||
|
'Attempted to accept missing unlock approval request',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns without call messenger if no approval request in pending', async () => {
|
||||||
|
const emitSpy = jest.spyOn(appStateController, 'emit');
|
||||||
|
|
||||||
|
appStateController.handleUnlock();
|
||||||
|
|
||||||
|
expect(emitSpy).toHaveBeenCalledTimes(0);
|
||||||
|
expect(appStateController.messagingSystem.call).toHaveBeenCalledTimes(0);
|
||||||
|
expect(log.error).toHaveBeenCalledTimes(1);
|
||||||
|
expect(log.error).toHaveBeenCalledWith(
|
||||||
|
'Attempted to accept missing unlock approval request',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setDefaultHomeActiveTabName', () => {
|
||||||
|
it('sets the default home tab name', () => {
|
||||||
|
appStateController.setDefaultHomeActiveTabName('testTabName');
|
||||||
|
expect(appStateController.store.getState().defaultHomeActiveTabName).toBe(
|
||||||
|
'testTabName',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setConnectedStatusPopoverHasBeenShown', () => {
|
||||||
|
it('sets connected status popover as shown', () => {
|
||||||
|
appStateController.setConnectedStatusPopoverHasBeenShown();
|
||||||
|
expect(
|
||||||
|
appStateController.store.getState().connectedStatusPopoverHasBeenShown,
|
||||||
|
).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setRecoveryPhraseReminderHasBeenShown', () => {
|
||||||
|
it('sets recovery phrase reminder as shown', () => {
|
||||||
|
appStateController.setRecoveryPhraseReminderHasBeenShown();
|
||||||
|
expect(
|
||||||
|
appStateController.store.getState().recoveryPhraseReminderHasBeenShown,
|
||||||
|
).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setRecoveryPhraseReminderLastShown', () => {
|
||||||
|
it('sets the last shown time of recovery phrase reminder', () => {
|
||||||
|
const timestamp = Date.now();
|
||||||
|
appStateController.setRecoveryPhraseReminderLastShown(timestamp);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
appStateController.store.getState().outdatedBrowserWarningLastShown,
|
appStateController.store.getState().recoveryPhraseReminderLastShown,
|
||||||
).toStrictEqual(date);
|
).toBe(timestamp);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setLastActiveTime', () => {
|
||||||
|
it('sets the last active time to the current time', () => {
|
||||||
|
const spy = jest.spyOn(appStateController, '_resetTimer');
|
||||||
|
appStateController.setLastActiveTime();
|
||||||
|
|
||||||
|
expect(spy).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setBrowserEnvironment', () => {
|
||||||
|
it('sets the current browser and OS environment', () => {
|
||||||
|
appStateController.setBrowserEnvironment('Windows', 'Chrome');
|
||||||
|
expect(
|
||||||
|
appStateController.store.getState().browserEnvironment,
|
||||||
|
).toStrictEqual({
|
||||||
|
os: 'Windows',
|
||||||
|
browser: 'Chrome',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('addPollingToken', () => {
|
||||||
|
it('adds a pollingToken for a given environmentType', () => {
|
||||||
|
const pollingTokenType = 'popupGasPollTokens';
|
||||||
|
appStateController.addPollingToken('token1', pollingTokenType);
|
||||||
|
expect(appStateController.store.getState()[pollingTokenType]).toContain(
|
||||||
|
'token1',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('removePollingToken', () => {
|
||||||
|
it('removes a pollingToken for a given environmentType', () => {
|
||||||
|
const pollingTokenType = 'popupGasPollTokens';
|
||||||
|
appStateController.addPollingToken('token1', pollingTokenType);
|
||||||
|
appStateController.removePollingToken('token1', pollingTokenType);
|
||||||
|
expect(
|
||||||
|
appStateController.store.getState()[pollingTokenType],
|
||||||
|
).not.toContain('token1');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('clearPollingTokens', () => {
|
||||||
|
it('clears all pollingTokens', () => {
|
||||||
|
appStateController.addPollingToken('token1', 'popupGasPollTokens');
|
||||||
|
appStateController.addPollingToken('token2', 'notificationGasPollTokens');
|
||||||
|
appStateController.addPollingToken('token3', 'fullScreenGasPollTokens');
|
||||||
|
appStateController.clearPollingTokens();
|
||||||
|
|
||||||
|
expect(
|
||||||
|
appStateController.store.getState().popupGasPollTokens,
|
||||||
|
).toStrictEqual([]);
|
||||||
|
expect(
|
||||||
|
appStateController.store.getState().notificationGasPollTokens,
|
||||||
|
).toStrictEqual([]);
|
||||||
|
expect(
|
||||||
|
appStateController.store.getState().fullScreenGasPollTokens,
|
||||||
|
).toStrictEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setShowTestnetMessageInDropdown', () => {
|
||||||
|
it('sets whether the testnet dismissal link should be shown in the network dropdown', () => {
|
||||||
|
appStateController.setShowTestnetMessageInDropdown(true);
|
||||||
|
expect(
|
||||||
|
appStateController.store.getState().showTestnetMessageInDropdown,
|
||||||
|
).toBe(true);
|
||||||
|
|
||||||
|
appStateController.setShowTestnetMessageInDropdown(false);
|
||||||
|
expect(
|
||||||
|
appStateController.store.getState().showTestnetMessageInDropdown,
|
||||||
|
).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setShowBetaHeader', () => {
|
||||||
|
it('sets whether the beta notification heading on the home page', () => {
|
||||||
|
appStateController.setShowBetaHeader(true);
|
||||||
|
expect(appStateController.store.getState().showBetaHeader).toBe(true);
|
||||||
|
|
||||||
|
appStateController.setShowBetaHeader(false);
|
||||||
|
expect(appStateController.store.getState().showBetaHeader).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setCurrentPopupId', () => {
|
||||||
|
it('sets the currentPopupId in the appState', () => {
|
||||||
|
const popupId = 'popup1';
|
||||||
|
|
||||||
|
appStateController.setCurrentPopupId(popupId);
|
||||||
|
expect(appStateController.store.getState().currentPopupId).toBe(popupId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getCurrentPopupId', () => {
|
||||||
|
it('retrieves the currentPopupId saved in the appState', () => {
|
||||||
|
const popupId = 'popup1';
|
||||||
|
|
||||||
|
appStateController.setCurrentPopupId(popupId);
|
||||||
|
expect(appStateController.getCurrentPopupId()).toBe(popupId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setFirstTimeUsedNetwork', () => {
|
||||||
|
it('updates the array of the first time used networks', () => {
|
||||||
|
const chainId = '0x1';
|
||||||
|
|
||||||
|
appStateController.setFirstTimeUsedNetwork(chainId);
|
||||||
|
expect(appStateController.store.getState().usedNetworks[chainId]).toBe(
|
||||||
|
true,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -520,9 +520,15 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
isUnlocked: this.isUnlocked.bind(this),
|
isUnlocked: this.isUnlocked.bind(this),
|
||||||
initState: initState.AppStateController,
|
initState: initState.AppStateController,
|
||||||
onInactiveTimeout: () => this.setLocked(),
|
onInactiveTimeout: () => this.setLocked(),
|
||||||
showUnlockRequest: opts.showUserConfirmation,
|
|
||||||
preferencesStore: this.preferencesController.store,
|
preferencesStore: this.preferencesController.store,
|
||||||
qrHardwareStore: this.qrHardwareKeyring.getMemStore(),
|
qrHardwareStore: this.qrHardwareKeyring.getMemStore(),
|
||||||
|
messenger: this.controllerMessenger.getRestricted({
|
||||||
|
name: 'AppStateController',
|
||||||
|
allowedActions: [
|
||||||
|
`${this.approvalController.name}:addRequest`,
|
||||||
|
`${this.approvalController.name}:acceptRequest`,
|
||||||
|
],
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const currencyRateMessenger = this.controllerMessenger.getRestricted({
|
const currencyRateMessenger = this.controllerMessenger.getRestricted({
|
||||||
|
Loading…
Reference in New Issue
Block a user