mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
[MMI] Move mmi actions to extension (#18057)
* MMI adds actions and background files to the institution/ folder * MMI lint fix * MMI lint fix * MMI import path fixed to be relative * MMI import path fixed * MMI adds the relative path to isErrorWithMessage * MMI adds the tests for mmi actions * MMI lint fix * adds tests to mmi actions * prettier fix * MMI prettier and adds test * MMI prettier * MMI lint fix * MMI prettier fix * MMI rename folder
This commit is contained in:
parent
ada47802b3
commit
c022d2eb9a
@ -308,6 +308,10 @@ interface DappSuggestedGasFees {
|
||||
* An object representing a transaction, in whatever state it is in.
|
||||
*/
|
||||
export interface TransactionMeta {
|
||||
///: BEGIN:ONLY_INCLUDE_IN(mmi)
|
||||
custodyStatus: string;
|
||||
custodyId?: string;
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
/**
|
||||
* The block number this transaction was included in. Currently only present
|
||||
* on incoming transactions!
|
||||
|
@ -86,6 +86,12 @@ import { TxParams } from '../../app/scripts/controllers/transactions/tx-state-ma
|
||||
import { CustomGasSettings } from '../../app/scripts/controllers/transactions';
|
||||
import { ThemeType } from '../../shared/constants/preferences';
|
||||
import * as actionConstants from './actionConstants';
|
||||
///: BEGIN:ONLY_INCLUDE_IN(mmi)
|
||||
import {
|
||||
checkForUnapprovedTypedMessages,
|
||||
updateCustodyState,
|
||||
} from './institutional/institution-actions';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
import {
|
||||
generateActionId,
|
||||
callBackgroundMethod,
|
||||
@ -713,6 +719,11 @@ export function signPersonalMsg(
|
||||
}
|
||||
|
||||
dispatch(updateMetamaskState(newState));
|
||||
///: BEGIN:ONLY_INCLUDE_IN(mmi)
|
||||
if (newState.unapprovedTypedMessages) {
|
||||
return checkForUnapprovedTypedMessages(msgData, newState);
|
||||
}
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
dispatch(completedTx(msgData.metamaskId));
|
||||
dispatch(closeCurrentNotificationWindow());
|
||||
return msgData;
|
||||
@ -840,6 +851,11 @@ export function signTypedMsg(
|
||||
}
|
||||
|
||||
dispatch(updateMetamaskState(newState));
|
||||
///: BEGIN:ONLY_INCLUDE_IN(mmi)
|
||||
if (newState.unapprovedTypedMessages) {
|
||||
return checkForUnapprovedTypedMessages(msgData, newState);
|
||||
}
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
dispatch(completedTx(msgData.metamaskId));
|
||||
dispatch(closeCurrentNotificationWindow());
|
||||
return msgData;
|
||||
@ -1848,6 +1864,10 @@ export function updateMetamaskState(
|
||||
|
||||
dispatch(initializeSendState({ chainHasChanged: true }));
|
||||
}
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(mmi)
|
||||
updateCustodyState(dispatch, newState, getState());
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
};
|
||||
}
|
||||
|
||||
|
338
ui/store/institutional/institution-actions.test.js
Normal file
338
ui/store/institutional/institution-actions.test.js
Normal file
@ -0,0 +1,338 @@
|
||||
import sinon from 'sinon';
|
||||
import configureStore from 'redux-mock-store';
|
||||
import thunk from 'redux-thunk';
|
||||
import MetaMaskController from '../../../app/scripts/metamask-controller';
|
||||
import { _setBackgroundConnection } from '../action-queue';
|
||||
import {
|
||||
showInteractiveReplacementTokenModal,
|
||||
showCustodyConfirmLink,
|
||||
checkForUnapprovedTypedMessages,
|
||||
updateCustodyState,
|
||||
} from './institution-actions';
|
||||
|
||||
const middleware = [thunk];
|
||||
const defaultState = {
|
||||
metamask: {
|
||||
currentLocale: 'test',
|
||||
selectedAddress: '0xFirstAddress',
|
||||
provider: { chainId: '0x1' },
|
||||
accounts: {
|
||||
'0xFirstAddress': {
|
||||
balance: '0x0',
|
||||
},
|
||||
},
|
||||
identities: {
|
||||
'0xFirstAddress': {},
|
||||
},
|
||||
cachedBalances: {
|
||||
'0x1': {
|
||||
'0xFirstAddress': '0x0',
|
||||
},
|
||||
},
|
||||
custodyStatusMaps: {
|
||||
saturn: {
|
||||
signed: {
|
||||
mmStatus: 'signed',
|
||||
shortText: 'signed',
|
||||
longText: 'signed',
|
||||
finished: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
currentNetworkTxList: [
|
||||
{
|
||||
id: 0,
|
||||
time: 0,
|
||||
txParams: {
|
||||
from: '0xAddress',
|
||||
to: '0xRecipient',
|
||||
},
|
||||
custodyId: '0',
|
||||
custodyStatus: 'signed',
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
time: 1,
|
||||
txParams: {
|
||||
from: '0xAddress',
|
||||
to: '0xRecipient',
|
||||
},
|
||||
custodyId: '1',
|
||||
custodyStatus: 'signed',
|
||||
},
|
||||
],
|
||||
custodyAccountDetails: {
|
||||
'0xAddress': {
|
||||
address: '0xc96348083d806DFfc546b36e05AF1f9452CDAe91',
|
||||
details: 'details',
|
||||
custodyType: 'testCustody - Saturn',
|
||||
},
|
||||
},
|
||||
},
|
||||
appState: {
|
||||
modal: {
|
||||
open: true,
|
||||
modalState: {
|
||||
name: 'CUSTODY_CONFIRM_LINK',
|
||||
props: {
|
||||
custodyId: '1',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const mockStore = (state = defaultState) => configureStore(middleware)(state);
|
||||
const baseMockState = defaultState.metamask;
|
||||
|
||||
describe('#InstitutionActions', () => {
|
||||
let background;
|
||||
|
||||
beforeEach(async () => {
|
||||
background = sinon.createStubInstance(MetaMaskController, {
|
||||
getState: sinon.stub().callsFake((cb) => cb(null, baseMockState)),
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sinon.restore();
|
||||
});
|
||||
|
||||
it('calls showModal with the property name of showInteractiveReplacementTokenModal', async () => {
|
||||
const store = mockStore();
|
||||
|
||||
background.getApi.returns({
|
||||
setFeatureFlag: sinon
|
||||
.stub()
|
||||
.callsFake((_, __, cb) => cb(new Error('error'))),
|
||||
});
|
||||
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
const expectedActions = [
|
||||
{
|
||||
type: 'UI_MODAL_OPEN',
|
||||
payload: { name: 'INTERACTIVE_REPLACEMENT_TOKEN_MODAL' },
|
||||
},
|
||||
];
|
||||
|
||||
await store.dispatch(showInteractiveReplacementTokenModal());
|
||||
|
||||
expect(store.getActions()).toStrictEqual(expectedActions);
|
||||
});
|
||||
|
||||
it('calls showModal with the property name of showCustodyConfirmLink', async () => {
|
||||
const store = mockStore();
|
||||
|
||||
background.getApi.returns({
|
||||
setFeatureFlag: sinon
|
||||
.stub()
|
||||
.callsFake((_, __, cb) => cb(new Error('error'))),
|
||||
});
|
||||
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
const expectedActions = [
|
||||
{
|
||||
type: 'UI_MODAL_OPEN',
|
||||
payload: {
|
||||
name: 'CUSTODY_CONFIRM_LINK',
|
||||
link: 'link',
|
||||
address: '0x1',
|
||||
closeNotification: false,
|
||||
custodyId: 'custodyId',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
await store.dispatch(
|
||||
showCustodyConfirmLink('link', '0x1', false, 'custodyId'),
|
||||
);
|
||||
|
||||
expect(store.getActions()).toStrictEqual(expectedActions);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#checkForUnapprovedTypedMessages', () => {
|
||||
it('calls checkForUnapprovedTypedMessages and returns the messageData', async () => {
|
||||
const messageData = {
|
||||
id: 1,
|
||||
type: 'tx',
|
||||
msgParams: {
|
||||
metamaskId: 2,
|
||||
data: '0x1',
|
||||
},
|
||||
custodyId: '123',
|
||||
status: 'unapproved',
|
||||
};
|
||||
|
||||
expect(
|
||||
checkForUnapprovedTypedMessages(messageData, {
|
||||
unapprovedTypedMessages: { msg: 'msg' },
|
||||
}),
|
||||
).toBe(messageData);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#updateCustodyState', () => {
|
||||
let background;
|
||||
|
||||
beforeEach(async () => {
|
||||
background = sinon.createStubInstance(MetaMaskController, {
|
||||
getState: sinon.stub().callsFake((cb) => cb(null, baseMockState)),
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sinon.restore();
|
||||
});
|
||||
|
||||
it('calls updateCustodyState but returns early undefined', async () => {
|
||||
const store = mockStore();
|
||||
|
||||
background.getApi.returns({
|
||||
setFeatureFlag: sinon
|
||||
.stub()
|
||||
.callsFake((_, __, cb) => cb(new Error('error'))),
|
||||
});
|
||||
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
const newState = {
|
||||
provider: {
|
||||
nickname: 'mainnet',
|
||||
chainId: '0x1',
|
||||
},
|
||||
featureFlags: {
|
||||
showIncomingTransactions: false,
|
||||
},
|
||||
selectedAddress: '0xAddress',
|
||||
};
|
||||
|
||||
const custodyState = updateCustodyState(store.dispatch, newState, newState);
|
||||
expect(custodyState).toBe(undefined);
|
||||
});
|
||||
|
||||
it('calls updateCustodyState and returns the hideModal', async () => {
|
||||
const store = mockStore();
|
||||
|
||||
background.getApi.returns({
|
||||
setFeatureFlag: sinon
|
||||
.stub()
|
||||
.callsFake((_, __, cb) => cb(new Error('error'))),
|
||||
});
|
||||
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
const newState = {
|
||||
provider: {
|
||||
nickname: 'mainnet',
|
||||
chainId: '0x1',
|
||||
},
|
||||
featureFlags: {
|
||||
showIncomingTransactions: false,
|
||||
},
|
||||
selectedAddress: '0xAddress',
|
||||
currentNetworkTxList: [
|
||||
{
|
||||
id: 0,
|
||||
time: 0,
|
||||
txParams: {
|
||||
from: '0xAddress',
|
||||
to: '0xRecipient',
|
||||
},
|
||||
custodyId: '0',
|
||||
custodyStatus: 'approved',
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
time: 1,
|
||||
txParams: {
|
||||
from: '0xAddress',
|
||||
to: '0xRecipient',
|
||||
},
|
||||
custodyId: '1',
|
||||
custodyStatus: 'approved',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const expectedActions = [
|
||||
{
|
||||
type: 'UI_MODAL_CLOSE',
|
||||
},
|
||||
];
|
||||
|
||||
updateCustodyState(store.dispatch, newState, defaultState);
|
||||
|
||||
expect(store.getActions()).toStrictEqual(expectedActions);
|
||||
});
|
||||
|
||||
it('calls updateCustodyState and closes INTERACTIVE_REPLACEMENT_TOKEN_MODAL', async () => {
|
||||
const store = mockStore();
|
||||
|
||||
background.getApi.returns({
|
||||
setFeatureFlag: sinon
|
||||
.stub()
|
||||
.callsFake((_, __, cb) => cb(new Error('error'))),
|
||||
});
|
||||
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
const newState = {
|
||||
provider: {
|
||||
nickname: 'mainnet',
|
||||
chainId: '0x1',
|
||||
},
|
||||
featureFlags: {
|
||||
showIncomingTransactions: false,
|
||||
},
|
||||
selectedAddress: '0xAddress',
|
||||
currentNetworkTxList: [
|
||||
{
|
||||
id: 0,
|
||||
time: 0,
|
||||
txParams: {
|
||||
from: '0xAddress',
|
||||
to: '0xRecipient',
|
||||
},
|
||||
custodyId: '0',
|
||||
custodyStatus: 'approved',
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
time: 1,
|
||||
txParams: {
|
||||
from: '0xAddress',
|
||||
to: '0xRecipient',
|
||||
},
|
||||
custodyId: '1',
|
||||
custodyStatus: 'approved',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const customState = {
|
||||
...defaultState,
|
||||
appState: {
|
||||
modal: {
|
||||
open: true,
|
||||
modalState: {
|
||||
name: 'INTERACTIVE_REPLACEMENT_TOKEN_MODAL',
|
||||
props: {
|
||||
custodyId: '1',
|
||||
closeNotification: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const closedNotification = updateCustodyState(
|
||||
store.dispatch,
|
||||
newState,
|
||||
customState,
|
||||
);
|
||||
expect(closedNotification).toBe(undefined);
|
||||
});
|
||||
});
|
130
ui/store/institutional/institution-actions.ts
Normal file
130
ui/store/institutional/institution-actions.ts
Normal file
@ -0,0 +1,130 @@
|
||||
import { ThunkAction, ThunkDispatch } from 'redux-thunk';
|
||||
import { AnyAction } from 'redux';
|
||||
import {
|
||||
closeCurrentNotificationWindow,
|
||||
hideModal,
|
||||
showModal,
|
||||
} from '../actions';
|
||||
import {
|
||||
CombinedBackgroundAndReduxState,
|
||||
MetaMaskReduxState,
|
||||
TemporaryMessageDataType,
|
||||
} from '../store';
|
||||
import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils';
|
||||
|
||||
export function showInteractiveReplacementTokenModal(): ThunkAction<
|
||||
void,
|
||||
MetaMaskReduxState,
|
||||
unknown,
|
||||
AnyAction
|
||||
> {
|
||||
return (dispatch) => {
|
||||
dispatch(
|
||||
showModal({
|
||||
name: 'INTERACTIVE_REPLACEMENT_TOKEN_MODAL',
|
||||
}),
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export function showCustodyConfirmLink(
|
||||
link: string,
|
||||
address: string,
|
||||
closeNotification: boolean,
|
||||
custodyId: string,
|
||||
): ThunkAction<void, MetaMaskReduxState, unknown, AnyAction> {
|
||||
return (dispatch) => {
|
||||
dispatch(
|
||||
showModal({
|
||||
name: 'CUSTODY_CONFIRM_LINK',
|
||||
link,
|
||||
address,
|
||||
closeNotification,
|
||||
custodyId,
|
||||
}),
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export function updateCustodyState(
|
||||
dispatch: ThunkDispatch<CombinedBackgroundAndReduxState, unknown, AnyAction>,
|
||||
newState: MetaMaskReduxState['metamask'],
|
||||
state: CombinedBackgroundAndReduxState & any,
|
||||
) {
|
||||
if (!newState.currentNetworkTxList || !state.metamask.currentNetworkTxList) {
|
||||
return;
|
||||
}
|
||||
|
||||
const differentTxs = newState.currentNetworkTxList.filter(
|
||||
(item) =>
|
||||
state.metamask.currentNetworkTxList.filter(
|
||||
(tx: { [key: string]: any }) =>
|
||||
tx.custodyId === item.custodyId &&
|
||||
tx.custodyStatus !== item.custodyStatus,
|
||||
).length > 0,
|
||||
);
|
||||
|
||||
const txStateSaysDeepLinkShouldClose = Boolean(
|
||||
differentTxs.find((tx) => {
|
||||
const custodyAccountDetails =
|
||||
state.metamask.custodyAccountDetails[
|
||||
toChecksumHexAddress(tx.txParams.from)
|
||||
];
|
||||
const custody = custodyAccountDetails?.custodyType
|
||||
.split(' - ')[1]
|
||||
.toLowerCase();
|
||||
if (!custody) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
tx.custodyId === state.appState.modal.modalState.props?.custodyId &&
|
||||
(state.metamask.custodyStatusMaps[custody][tx.custodyStatus]
|
||||
?.mmStatus !== 'approved' ||
|
||||
tx.custodyStatus === 'created')
|
||||
);
|
||||
}),
|
||||
);
|
||||
|
||||
if (
|
||||
state.appState.modal.open &&
|
||||
state.appState.modal.modalState.name === 'CUSTODY_CONFIRM_LINK' &&
|
||||
txStateSaysDeepLinkShouldClose
|
||||
) {
|
||||
if (state.appState.modal.modalState.props?.closeNotification) {
|
||||
dispatch(closeCurrentNotificationWindow());
|
||||
}
|
||||
dispatch(hideModal());
|
||||
}
|
||||
|
||||
if (
|
||||
state.appState.modal.open &&
|
||||
state.appState.modal.modalState.name ===
|
||||
'INTERACTIVE_REPLACEMENT_TOKEN_MODAL'
|
||||
) {
|
||||
if (state.appState.modal.modalState.props?.closeNotification) {
|
||||
dispatch(closeCurrentNotificationWindow());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function checkForUnapprovedTypedMessages(
|
||||
msgData: TemporaryMessageDataType['msgParams'],
|
||||
newState: MetaMaskReduxState['metamask'],
|
||||
) {
|
||||
const custodianUnapprovedMessages = Object.keys(
|
||||
newState.unapprovedTypedMessages,
|
||||
)
|
||||
.map((key) => newState.unapprovedTypedMessages[key])
|
||||
.filter((message) => message.custodyId && message.status === 'unapproved');
|
||||
|
||||
if (custodianUnapprovedMessages && custodianUnapprovedMessages.length > 0) {
|
||||
return {
|
||||
...msgData,
|
||||
custodyId:
|
||||
newState.unapprovedTypedMessages[msgData.metamaskId]?.custodyId,
|
||||
};
|
||||
}
|
||||
|
||||
return msgData;
|
||||
}
|
125
ui/store/institutional/institution-background.test.js
Normal file
125
ui/store/institutional/institution-background.test.js
Normal file
@ -0,0 +1,125 @@
|
||||
import { mmiActionsFactory } from './institution-background';
|
||||
|
||||
describe('Institution Actions', () => {
|
||||
describe('#mmiActionsFactory', () => {
|
||||
it('returns mmiActions object', async () => {
|
||||
const actionsMock = {
|
||||
connectCustodyAddresses: jest.fn(),
|
||||
getCustodianAccounts: jest.fn(),
|
||||
getCustodianAccountsByAddress: jest.fn(),
|
||||
getCustodianTransactionDeepLink: jest.fn(),
|
||||
getCustodianConfirmDeepLink: jest.fn(),
|
||||
getCustodianSignMessageDeepLink: jest.fn(),
|
||||
getCustodianToken: jest.fn(),
|
||||
getCustodianJWTList: jest.fn(),
|
||||
setComplianceAuthData: jest.fn(),
|
||||
deleteComplianceAuthData: jest.fn(),
|
||||
generateComplianceReport: jest.fn(),
|
||||
getComplianceHistoricalReportsByAddress: jest.fn(),
|
||||
syncReportsInProgress: jest.fn(),
|
||||
removeConnectInstitutionalFeature: jest.fn(),
|
||||
removeAddTokenConnectRequest: jest.fn(),
|
||||
setCustodianConnectRequest: jest.fn(),
|
||||
getCustodianConnectRequest: jest.fn(),
|
||||
getMmiConfiguration: jest.fn(),
|
||||
getAllCustodianAccountsWithToken: jest.fn(),
|
||||
setWaitForConfirmDeepLinkDialog: jest.fn(),
|
||||
setCustodianNewRefreshToken: jest.fn(),
|
||||
};
|
||||
const mmiActions = mmiActionsFactory({
|
||||
log: { debug: jest.fn(), error: jest.fn() },
|
||||
showLoadingIndication: jest.fn(),
|
||||
submitRequestToBackground: jest.fn(() => actionsMock),
|
||||
displayWarning: jest.fn(),
|
||||
hideLoadingIndication: jest.fn(),
|
||||
forceUpdateMetamaskState: jest.fn(),
|
||||
showModal: jest.fn(),
|
||||
callBackgroundMethod: jest.fn(() => actionsMock),
|
||||
});
|
||||
|
||||
const connectCustodyAddresses = mmiActions.connectCustodyAddresses(
|
||||
{},
|
||||
'0xAddress',
|
||||
);
|
||||
mmiActions.getCustodianAccounts(
|
||||
'token',
|
||||
'apiUrl',
|
||||
'custody',
|
||||
'getNonImportedAccounts',
|
||||
{},
|
||||
);
|
||||
mmiActions.getCustodianAccountsByAddress(
|
||||
'jwt',
|
||||
'apiUrl',
|
||||
'address',
|
||||
'custody',
|
||||
{},
|
||||
4,
|
||||
);
|
||||
mmiActions.getMmiConfiguration({
|
||||
portfolio: {
|
||||
enabled: true,
|
||||
url: 'https://portfolio.io',
|
||||
},
|
||||
custodians: [],
|
||||
});
|
||||
mmiActions.getCustodianToken({});
|
||||
mmiActions.getCustodianConnectRequest({
|
||||
token: 'token',
|
||||
custodianType: 'custodianType',
|
||||
custodianName: 'custodianname',
|
||||
apiUrl: undefined,
|
||||
});
|
||||
mmiActions.getCustodianTransactionDeepLink('0xAddress', 'txId');
|
||||
mmiActions.getCustodianConfirmDeepLink('txId');
|
||||
mmiActions.getCustodianSignMessageDeepLink('0xAddress', 'custodyTxId');
|
||||
mmiActions.getCustodianJWTList({});
|
||||
mmiActions.getAllCustodianAccountsWithToken({
|
||||
custodianType: 'custodianType',
|
||||
token: 'token',
|
||||
});
|
||||
mmiActions.setComplianceAuthData({
|
||||
clientId: 'id',
|
||||
projectId: 'projectId',
|
||||
});
|
||||
mmiActions.deleteComplianceAuthData();
|
||||
mmiActions.generateComplianceReport('0xAddress');
|
||||
mmiActions.getComplianceHistoricalReportsByAddress(
|
||||
'0xAddress',
|
||||
'projectId',
|
||||
);
|
||||
mmiActions.syncReportsInProgress({
|
||||
address: '0xAddress',
|
||||
historicalReports: [],
|
||||
});
|
||||
mmiActions.removeConnectInstitutionalFeature({
|
||||
origin: 'origin',
|
||||
projectId: 'projectId',
|
||||
});
|
||||
mmiActions.removeAddTokenConnectRequest({
|
||||
origin: 'origin',
|
||||
apiUrl: 'https://jupiter-custody.codefi.network',
|
||||
token: 'token',
|
||||
});
|
||||
mmiActions.setCustodianConnectRequest({
|
||||
token: 'token',
|
||||
apiUrl: 'https://jupiter-custody.codefi.network',
|
||||
custodianType: 'custodianType',
|
||||
custodianName: 'custodianname',
|
||||
});
|
||||
const setWaitForConfirmDeepLinkDialog =
|
||||
mmiActions.setWaitForConfirmDeepLinkDialog(true);
|
||||
mmiActions.setCustodianNewRefreshToken(
|
||||
'address',
|
||||
'oldAuthDetails',
|
||||
'oldApiUrl',
|
||||
'newAuthDetails',
|
||||
'newApiUrl',
|
||||
);
|
||||
connectCustodyAddresses(jest.fn());
|
||||
setWaitForConfirmDeepLinkDialog(jest.fn());
|
||||
expect(connectCustodyAddresses).toBeDefined();
|
||||
expect(setWaitForConfirmDeepLinkDialog).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
211
ui/store/institutional/institution-background.ts
Normal file
211
ui/store/institutional/institution-background.ts
Normal file
@ -0,0 +1,211 @@
|
||||
import log from 'loglevel';
|
||||
import { ThunkAction } from 'redux-thunk';
|
||||
import { AnyAction } from 'redux';
|
||||
import {
|
||||
forceUpdateMetamaskState,
|
||||
displayWarning,
|
||||
hideLoadingIndication,
|
||||
showLoadingIndication,
|
||||
} from '../actions';
|
||||
import {
|
||||
callBackgroundMethod,
|
||||
submitRequestToBackground,
|
||||
} from '../action-queue';
|
||||
import { MetaMaskReduxState } from '../store';
|
||||
import { isErrorWithMessage } from '../../../shared/modules/error';
|
||||
|
||||
export function showInteractiveReplacementTokenBanner(
|
||||
url: string,
|
||||
oldRefreshToken: string,
|
||||
) {
|
||||
return () => {
|
||||
callBackgroundMethod(
|
||||
'showInteractiveReplacementTokenBanner',
|
||||
[url, oldRefreshToken],
|
||||
(err) => {
|
||||
if (isErrorWithMessage(err)) {
|
||||
throw new Error(err.message);
|
||||
}
|
||||
},
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* A factory that contains all MMI actions ready to use
|
||||
* Example usage:
|
||||
* const mmiActions = mmiActionsFactory();
|
||||
* mmiActions.connectCustodyAddresses(...)
|
||||
*/
|
||||
export function mmiActionsFactory() {
|
||||
function createAsyncAction(
|
||||
name: string,
|
||||
params: any,
|
||||
useForceUpdateMetamaskState?: any,
|
||||
loadingText?: string,
|
||||
): ThunkAction<void, MetaMaskReduxState, unknown, AnyAction> {
|
||||
log.debug(`background.${name}`);
|
||||
return async (dispatch) => {
|
||||
if (loadingText) {
|
||||
dispatch(showLoadingIndication(loadingText));
|
||||
}
|
||||
let result;
|
||||
try {
|
||||
result = await submitRequestToBackground(name, [...params]);
|
||||
} catch (error) {
|
||||
dispatch(displayWarning(error));
|
||||
if (isErrorWithMessage(error)) {
|
||||
throw new Error(error.message);
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
if (loadingText) {
|
||||
dispatch(hideLoadingIndication());
|
||||
}
|
||||
if (useForceUpdateMetamaskState) {
|
||||
await forceUpdateMetamaskState(dispatch);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
function createAction(name: string, payload: any) {
|
||||
return () => {
|
||||
callBackgroundMethod(name, [payload], (err) => {
|
||||
if (isErrorWithMessage(err)) {
|
||||
throw new Error(err.message);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
connectCustodyAddresses: (
|
||||
custodianType: string,
|
||||
custodianName: string,
|
||||
newAccounts: string[],
|
||||
) =>
|
||||
createAsyncAction(
|
||||
'connectCustodyAddresses',
|
||||
[custodianType, custodianName, newAccounts],
|
||||
forceUpdateMetamaskState,
|
||||
'Looking for your custodian account...',
|
||||
),
|
||||
getCustodianAccounts: (
|
||||
token: string,
|
||||
apiUrl: string,
|
||||
custody: string,
|
||||
getNonImportedAccounts: boolean,
|
||||
) =>
|
||||
createAsyncAction(
|
||||
'getCustodianAccounts',
|
||||
[token, apiUrl, custody, getNonImportedAccounts],
|
||||
forceUpdateMetamaskState,
|
||||
'Getting custodian accounts...',
|
||||
),
|
||||
getCustodianAccountsByAddress: (
|
||||
jwt: string,
|
||||
apiUrl: string,
|
||||
address: string,
|
||||
custody: string,
|
||||
) =>
|
||||
createAsyncAction(
|
||||
'getCustodianAccountsByAddress',
|
||||
[jwt, apiUrl, address, custody],
|
||||
forceUpdateMetamaskState,
|
||||
'Getting custodian accounts...',
|
||||
),
|
||||
getCustodianTransactionDeepLink: (address: string, txId: string) =>
|
||||
createAsyncAction(
|
||||
'getCustodianTransactionDeepLink',
|
||||
[address, txId],
|
||||
forceUpdateMetamaskState,
|
||||
),
|
||||
getCustodianConfirmDeepLink: (txId: string) =>
|
||||
createAsyncAction(
|
||||
'getCustodianConfirmDeepLink',
|
||||
[txId],
|
||||
forceUpdateMetamaskState,
|
||||
),
|
||||
getCustodianSignMessageDeepLink: (from: string, custodyTxId: string) =>
|
||||
createAsyncAction(
|
||||
'getCustodianSignMessageDeepLink',
|
||||
[from, custodyTxId],
|
||||
forceUpdateMetamaskState,
|
||||
),
|
||||
getCustodianToken: (custody: string) =>
|
||||
createAsyncAction(
|
||||
'getCustodianToken',
|
||||
[custody],
|
||||
forceUpdateMetamaskState,
|
||||
),
|
||||
getCustodianJWTList: (custody: string) =>
|
||||
createAsyncAction(
|
||||
'getCustodianJWTList',
|
||||
[custody],
|
||||
forceUpdateMetamaskState,
|
||||
),
|
||||
setWaitForConfirmDeepLinkDialog: (waitForConfirmDeepLinkDialog: boolean) =>
|
||||
createAction(
|
||||
'setWaitForConfirmDeepLinkDialog',
|
||||
waitForConfirmDeepLinkDialog,
|
||||
),
|
||||
setComplianceAuthData: (clientId: string, projectId: string) =>
|
||||
createAsyncAction('setComplianceAuthData', [{ clientId, projectId }]),
|
||||
deleteComplianceAuthData: () =>
|
||||
createAsyncAction('deleteComplianceAuthData', []),
|
||||
generateComplianceReport: (address: string) =>
|
||||
createAction('generateComplianceReport', address),
|
||||
getComplianceHistoricalReportsByAddress: (
|
||||
address: string,
|
||||
projectId: string,
|
||||
) =>
|
||||
createAsyncAction('getComplianceHistoricalReportsByAddress', [
|
||||
address,
|
||||
projectId,
|
||||
]),
|
||||
syncReportsInProgress: (address: string, historicalReports: []) =>
|
||||
createAction('syncReportsInProgress', { address, historicalReports }),
|
||||
removeConnectInstitutionalFeature: (origin: string, projectId: string) =>
|
||||
createAction('removeConnectInstitutionalFeature', { origin, projectId }),
|
||||
removeAddTokenConnectRequest: (
|
||||
origin: string,
|
||||
apiUrl: string,
|
||||
token: string,
|
||||
) =>
|
||||
createAction('removeAddTokenConnectRequest', { origin, apiUrl, token }),
|
||||
setCustodianConnectRequest: (
|
||||
token: string,
|
||||
apiUrl: string,
|
||||
custodianType: string,
|
||||
custodianName: string,
|
||||
) =>
|
||||
createAsyncAction('setCustodianConnectRequest', [
|
||||
{ token, apiUrl, custodianType, custodianName },
|
||||
]),
|
||||
getCustodianConnectRequest: () =>
|
||||
createAsyncAction('getCustodianConnectRequest', []),
|
||||
getMmiConfiguration: () => createAsyncAction('getMmiConfiguration', []),
|
||||
getAllCustodianAccountsWithToken: (custodyType: string, token: string) =>
|
||||
createAsyncAction('getAllCustodianAccountsWithToken', [
|
||||
custodyType,
|
||||
token,
|
||||
]),
|
||||
setCustodianNewRefreshToken: (
|
||||
address: string,
|
||||
oldAuthDetails: string,
|
||||
oldApiUrl: string,
|
||||
newAuthDetails: string,
|
||||
newApiUrl: string,
|
||||
) =>
|
||||
createAsyncAction('setCustodianNewRefreshToken', [
|
||||
address,
|
||||
oldAuthDetails,
|
||||
oldApiUrl,
|
||||
newAuthDetails,
|
||||
newApiUrl,
|
||||
]),
|
||||
};
|
||||
}
|
@ -22,6 +22,10 @@ export interface TemporaryMessageDataType {
|
||||
metamaskId: number;
|
||||
data: string;
|
||||
};
|
||||
///: BEGIN:ONLY_INCLUDE_IN(mmi)
|
||||
custodyId?: string;
|
||||
status?: string;
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
}
|
||||
|
||||
interface MessagesIndexedById {
|
||||
@ -68,11 +72,14 @@ interface TemporaryBackgroundState {
|
||||
};
|
||||
gasFeeEstimates: GasFeeEstimates;
|
||||
gasEstimateType: GasEstimateType;
|
||||
///: BEGIN:ONLY_INCLUDE_IN(mmi)
|
||||
custodyAccountDetails?: { [key: string]: any };
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
}
|
||||
|
||||
type RootReducerReturnType = ReturnType<typeof rootReducer>;
|
||||
|
||||
type CombinedBackgroundAndReduxState = RootReducerReturnType & {
|
||||
export type CombinedBackgroundAndReduxState = RootReducerReturnType & {
|
||||
activeTab: {
|
||||
origin: string;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user