mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-21 17:37:01 +01:00
[MMI] Fix Connect MMI and Deep link Flows (#19881)
* Sending showCustodyConfirmLink as a prop and fixing other issues * Upgraded MMI extension monrepo and trying to fix the issue * prevents deeplink from closing * Fixed styles of Custody view and changed the place of it * Fixed CI issues * fixing eslint issues * Update LavaMoat policies * fixing tests * Fixed test * updated snapshots * reorder, otherwise it won't make sense * adds necessary methods * removes duplicated key value * updated snapshot --------- Co-authored-by: Antonio Regadas <antonio.regadas@consensys.net> Co-authored-by: MetaMask Bot <metamaskbot@users.noreply.github.com> Co-authored-by: António Regadas <apregadas@gmail.com>
This commit is contained in:
parent
4e89c6ca8c
commit
b5ece42ca1
6
app/_locales/en/messages.json
generated
6
app/_locales/en/messages.json
generated
@ -982,6 +982,12 @@
|
||||
"custodianAccount": {
|
||||
"message": "Custodian account"
|
||||
},
|
||||
"custodianAccountAddedDesc": {
|
||||
"message": "You can now use your custodian accounts in MetaMask Institutional."
|
||||
},
|
||||
"custodianAccountAddedTitle": {
|
||||
"message": "Selected custodian accounts have been added."
|
||||
},
|
||||
"custodianReplaceRefreshTokenChangedFailed": {
|
||||
"message": "Please go to $1 and click the 'Connect to MMI' button within their user interface to connect your accounts to MMI again."
|
||||
},
|
||||
|
@ -815,11 +815,18 @@
|
||||
},
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask-institutional/custody-controller": true,
|
||||
"@metamask-institutional/extension>@metamask-institutional/custody-controller": true,
|
||||
"@metamask-institutional/sdk": true,
|
||||
"@metamask-institutional/sdk>@metamask-institutional/types": true
|
||||
}
|
||||
},
|
||||
"@metamask-institutional/extension>@metamask-institutional/custody-controller": {
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask-institutional/custody-keyring": true,
|
||||
"@metamask/obs-store": true
|
||||
}
|
||||
},
|
||||
"@metamask-institutional/institutional-features": {
|
||||
"globals": {
|
||||
"chrome.runtime.id": true,
|
||||
|
@ -218,7 +218,7 @@
|
||||
"@material-ui/core": "^4.11.0",
|
||||
"@metamask-institutional/custody-controller": "0.2.6",
|
||||
"@metamask-institutional/custody-keyring": "^0.0.25",
|
||||
"@metamask-institutional/extension": "^0.1.3",
|
||||
"@metamask-institutional/extension": "^0.1.6",
|
||||
"@metamask-institutional/institutional-features": "^1.1.8",
|
||||
"@metamask-institutional/portfolio-dashboard": "^1.1.3",
|
||||
"@metamask-institutional/rpc-allowlist": "^1.0.0",
|
||||
|
@ -123,9 +123,10 @@ export default class ConfirmPageContainerContent extends Component {
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
noteComponent && (
|
||||
<Tab
|
||||
data-testid="note-tab"
|
||||
className="confirm-page-container-content__tab"
|
||||
name={t('note')}
|
||||
pillText={t('new')}
|
||||
tabKey="note"
|
||||
onClick={() => {
|
||||
this.context.trackEvent({
|
||||
category: 'Note to trader',
|
||||
|
@ -17,7 +17,10 @@ import {
|
||||
setPersonalMessageInProgress,
|
||||
} from '../../../store/institutional/institution-background';
|
||||
import { getEnvironmentType } from '../../../../app/scripts/lib/util';
|
||||
import { checkForUnapprovedMessages } from '../../../store/institutional/institution-actions';
|
||||
import {
|
||||
showCustodyConfirmLink,
|
||||
checkForUnapprovedMessages,
|
||||
} from '../../../store/institutional/institution-actions';
|
||||
import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../shared/constants/app';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
import {
|
||||
@ -75,52 +78,6 @@ function mapStateToProps(state, ownProps) {
|
||||
|
||||
let mapDispatchToProps = null;
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
function mmiMapDispatchToProps(dispatch) {
|
||||
const mmiActions = mmiActionsFactory();
|
||||
return {
|
||||
clearConfirmTransaction: () => dispatch(clearConfirmTransaction()),
|
||||
setMsgInProgress: (msgId) => dispatch(setPersonalMessageInProgress(msgId)),
|
||||
showCustodianDeepLink: ({
|
||||
custodyId,
|
||||
fromAddress,
|
||||
closeNotification,
|
||||
onDeepLinkFetched,
|
||||
onDeepLinkShown,
|
||||
}) =>
|
||||
showCustodianDeepLink({
|
||||
dispatch,
|
||||
mmiActions,
|
||||
txId: undefined,
|
||||
fromAddress,
|
||||
custodyId,
|
||||
isSignature: true,
|
||||
closeNotification,
|
||||
onDeepLinkFetched,
|
||||
onDeepLinkShown,
|
||||
}),
|
||||
showTransactionsFailedModal: ({
|
||||
errorMessage,
|
||||
closeNotification,
|
||||
operationFailed,
|
||||
}) =>
|
||||
dispatch(
|
||||
showModal({
|
||||
name: 'TRANSACTION_FAILED',
|
||||
errorMessage,
|
||||
closeNotification,
|
||||
operationFailed,
|
||||
}),
|
||||
),
|
||||
setWaitForConfirmDeepLinkDialog: (wait) =>
|
||||
dispatch(mmiActions.setWaitForConfirmDeepLinkDialog(wait)),
|
||||
goHome: () => dispatch(goHome()),
|
||||
};
|
||||
}
|
||||
|
||||
mapDispatchToProps = mmiMapDispatchToProps;
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
mapDispatchToProps = function (dispatch) {
|
||||
return {
|
||||
goHome: () => dispatch(goHome()),
|
||||
@ -150,6 +107,75 @@ mapDispatchToProps = function (dispatch) {
|
||||
};
|
||||
};
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
function mmiMapDispatchToProps(dispatch) {
|
||||
const mmiActions = mmiActionsFactory();
|
||||
return {
|
||||
setMsgInProgress: (msgId) => dispatch(setPersonalMessageInProgress(msgId)),
|
||||
showCustodianDeepLink: ({
|
||||
custodyId,
|
||||
fromAddress,
|
||||
closeNotification,
|
||||
onDeepLinkFetched,
|
||||
onDeepLinkShown,
|
||||
}) =>
|
||||
showCustodianDeepLink({
|
||||
dispatch,
|
||||
mmiActions,
|
||||
txId: undefined,
|
||||
fromAddress,
|
||||
custodyId,
|
||||
isSignature: true,
|
||||
closeNotification,
|
||||
onDeepLinkFetched,
|
||||
onDeepLinkShown,
|
||||
showCustodyConfirmLink,
|
||||
}),
|
||||
showTransactionsFailedModal: ({
|
||||
errorMessage,
|
||||
closeNotification,
|
||||
operationFailed,
|
||||
}) =>
|
||||
dispatch(
|
||||
showModal({
|
||||
name: 'TRANSACTION_FAILED',
|
||||
errorMessage,
|
||||
closeNotification,
|
||||
operationFailed,
|
||||
}),
|
||||
),
|
||||
setWaitForConfirmDeepLinkDialog: (wait) =>
|
||||
dispatch(mmiActions.setWaitForConfirmDeepLinkDialog(wait)),
|
||||
goHome: () => dispatch(goHome()),
|
||||
clearConfirmTransaction: () => dispatch(clearConfirmTransaction()),
|
||||
showRejectTransactionsConfirmationModal: ({
|
||||
onSubmit,
|
||||
unapprovedTxCount: messagesCount,
|
||||
}) => {
|
||||
return dispatch(
|
||||
showModal({
|
||||
name: 'REJECT_TRANSACTIONS',
|
||||
onSubmit,
|
||||
unapprovedTxCount: messagesCount,
|
||||
isRequestType: true,
|
||||
}),
|
||||
);
|
||||
},
|
||||
completedTx: (txId) => dispatch(completedTx(txId)),
|
||||
resolvePendingApproval: (id) => {
|
||||
dispatch(resolvePendingApproval(id));
|
||||
},
|
||||
rejectPendingApproval: (id, error) =>
|
||||
dispatch(rejectPendingApproval(id, error)),
|
||||
cancelAllApprovals: (messagesList) => {
|
||||
dispatch(rejectAllMessages(messagesList));
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
mapDispatchToProps = mmiMapDispatchToProps;
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
function mergeProps(stateProps, dispatchProps, ownProps) {
|
||||
const { txData } = ownProps;
|
||||
|
||||
|
@ -30,7 +30,10 @@ import {
|
||||
setTypedMessageInProgress,
|
||||
} from '../../../store/institutional/institution-background';
|
||||
import { getEnvironmentType } from '../../../../app/scripts/lib/util';
|
||||
import { checkForUnapprovedMessages } from '../../../store/institutional/institution-actions';
|
||||
import {
|
||||
showCustodyConfirmLink,
|
||||
checkForUnapprovedMessages,
|
||||
} from '../../../store/institutional/institution-actions';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
import {
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
@ -101,52 +104,6 @@ function mapStateToProps(state, ownProps) {
|
||||
|
||||
let mapDispatchToProps = null;
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
function mmiMapDispatchToProps(dispatch) {
|
||||
const mmiActions = mmiActionsFactory();
|
||||
return {
|
||||
clearConfirmTransaction: () => dispatch(clearConfirmTransaction()),
|
||||
setMsgInProgress: (msgId) => dispatch(setTypedMessageInProgress(msgId)),
|
||||
showCustodianDeepLink: ({
|
||||
custodyId,
|
||||
fromAddress,
|
||||
closeNotification,
|
||||
onDeepLinkFetched,
|
||||
onDeepLinkShown,
|
||||
}) =>
|
||||
showCustodianDeepLink({
|
||||
dispatch,
|
||||
mmiActions,
|
||||
txId: undefined,
|
||||
fromAddress,
|
||||
custodyId,
|
||||
isSignature: true,
|
||||
closeNotification,
|
||||
onDeepLinkFetched,
|
||||
onDeepLinkShown,
|
||||
}),
|
||||
showTransactionsFailedModal: ({
|
||||
errorMessage,
|
||||
closeNotification,
|
||||
operationFailed,
|
||||
}) =>
|
||||
dispatch(
|
||||
showModal({
|
||||
name: 'TRANSACTION_FAILED',
|
||||
errorMessage,
|
||||
closeNotification,
|
||||
operationFailed,
|
||||
}),
|
||||
),
|
||||
setWaitForConfirmDeepLinkDialog: (wait) =>
|
||||
dispatch(mmiActions.setWaitForConfirmDeepLinkDialog(wait)),
|
||||
goHome: () => dispatch(goHome()),
|
||||
};
|
||||
}
|
||||
|
||||
mapDispatchToProps = mmiMapDispatchToProps;
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
mapDispatchToProps = function (dispatch) {
|
||||
return {
|
||||
resolvePendingApproval: (id) => dispatch(resolvePendingApproval(id)),
|
||||
@ -173,6 +130,73 @@ mapDispatchToProps = function (dispatch) {
|
||||
};
|
||||
};
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
function mmiMapDispatchToProps(dispatch) {
|
||||
const mmiActions = mmiActionsFactory();
|
||||
return {
|
||||
setMsgInProgress: (msgId) => dispatch(setTypedMessageInProgress(msgId)),
|
||||
showCustodianDeepLink: ({
|
||||
custodyId,
|
||||
fromAddress,
|
||||
closeNotification,
|
||||
onDeepLinkFetched,
|
||||
onDeepLinkShown,
|
||||
}) =>
|
||||
showCustodianDeepLink({
|
||||
dispatch,
|
||||
mmiActions,
|
||||
txId: undefined,
|
||||
fromAddress,
|
||||
custodyId,
|
||||
isSignature: true,
|
||||
closeNotification,
|
||||
onDeepLinkFetched,
|
||||
onDeepLinkShown,
|
||||
showCustodyConfirmLink,
|
||||
}),
|
||||
showTransactionsFailedModal: ({
|
||||
errorMessage,
|
||||
closeNotification,
|
||||
operationFailed,
|
||||
}) =>
|
||||
dispatch(
|
||||
showModal({
|
||||
name: 'TRANSACTION_FAILED',
|
||||
errorMessage,
|
||||
closeNotification,
|
||||
operationFailed,
|
||||
}),
|
||||
),
|
||||
setWaitForConfirmDeepLinkDialog: (wait) =>
|
||||
dispatch(mmiActions.setWaitForConfirmDeepLinkDialog(wait)),
|
||||
goHome: () => dispatch(goHome()),
|
||||
resolvePendingApproval: (id) => dispatch(resolvePendingApproval(id)),
|
||||
completedTx: (id) => dispatch(completedTx(id)),
|
||||
rejectPendingApproval: (id, error) =>
|
||||
dispatch(rejectPendingApproval(id, error)),
|
||||
clearConfirmTransaction: () => dispatch(clearConfirmTransaction()),
|
||||
showRejectTransactionsConfirmationModal: ({
|
||||
onSubmit,
|
||||
unapprovedTxCount: unapprovedMessagesCount,
|
||||
}) => {
|
||||
return dispatch(
|
||||
showModal({
|
||||
name: 'REJECT_TRANSACTIONS',
|
||||
onSubmit,
|
||||
unapprovedTxCount: unapprovedMessagesCount,
|
||||
isRequestType: true,
|
||||
}),
|
||||
);
|
||||
},
|
||||
cancelAllApprovals: (unconfirmedMessagesList) => {
|
||||
dispatch(rejectAllMessages(unconfirmedMessagesList));
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
mapDispatchToProps = mmiMapDispatchToProps;
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
function mergeProps(stateProps, dispatchProps, ownProps) {
|
||||
const {
|
||||
allAccounts,
|
||||
|
@ -581,7 +581,7 @@ export default class ConfirmTransactionBase extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
handleCancel() {
|
||||
async handleCancel() {
|
||||
const {
|
||||
txData,
|
||||
cancelTransaction,
|
||||
@ -592,9 +592,8 @@ export default class ConfirmTransactionBase extends Component {
|
||||
|
||||
this._removeBeforeUnload();
|
||||
updateCustomNonce('');
|
||||
cancelTransaction(txData).then(() => {
|
||||
history.push(mostRecentOverviewPage);
|
||||
});
|
||||
await cancelTransaction(txData);
|
||||
history.push(mostRecentOverviewPage);
|
||||
}
|
||||
|
||||
handleSubmit() {
|
||||
@ -705,6 +704,7 @@ export default class ConfirmTransactionBase extends Component {
|
||||
toAccounts,
|
||||
toAddress,
|
||||
showCustodianDeepLink,
|
||||
clearConfirmTransaction,
|
||||
} = this.props;
|
||||
const { noteText } = this.state;
|
||||
|
||||
@ -761,7 +761,7 @@ export default class ConfirmTransactionBase extends Component {
|
||||
});
|
||||
},
|
||||
onDeepLinkShown: () => {
|
||||
this.props.clearConfirmTransaction();
|
||||
clearConfirmTransaction();
|
||||
this.setState({ submitting: false }, () => {
|
||||
history.push(mostRecentOverviewPage);
|
||||
updateCustomNonce('');
|
||||
|
@ -76,6 +76,7 @@ import { CUSTOM_GAS_ESTIMATE } from '../../../shared/constants/gas';
|
||||
import { getAccountType } from '../../selectors/selectors';
|
||||
import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../shared/constants/app';
|
||||
import { getIsNoteToTraderSupported } from '../../selectors/institutional/selectors';
|
||||
import { showCustodyConfirmLink } from '../../store/institutional/institution-actions';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
import {
|
||||
TransactionStatus,
|
||||
@ -330,15 +331,6 @@ export const mapDispatchToProps = (dispatch) => {
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
getCustodianConfirmDeepLink: (id) =>
|
||||
dispatch(mmiActions.getCustodianConfirmDeepLink(id)),
|
||||
showCustodyConfirmLink: ({ link, address, closeNotification, custodyId }) =>
|
||||
dispatch(
|
||||
mmiActions.showCustodyConfirmLink({
|
||||
link,
|
||||
address,
|
||||
closeNotification,
|
||||
custodyId,
|
||||
}),
|
||||
),
|
||||
showTransactionsFailedModal: (errorMessage, closeNotification) =>
|
||||
dispatch(
|
||||
showModal({
|
||||
@ -362,6 +354,7 @@ export const mapDispatchToProps = (dispatch) => {
|
||||
closeNotification,
|
||||
onDeepLinkFetched,
|
||||
onDeepLinkShown,
|
||||
showCustodyConfirmLink,
|
||||
}),
|
||||
setWaitForConfirmDeepLinkDialog: (wait) =>
|
||||
dispatch(mmiActions.setWaitForConfirmDeepLinkDialog(wait)),
|
||||
|
@ -234,7 +234,7 @@ describe('Confirm Transaction Base', () => {
|
||||
store,
|
||||
);
|
||||
|
||||
expect(getByTestId('transaction-note')).toBeInTheDocument();
|
||||
expect(getByTestId('note-tab')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('handleMainSubmit calls sendTransaction correctly', async () => {
|
||||
|
@ -1,16 +1,7 @@
|
||||
import React from 'react';
|
||||
import { Route, Switch } from 'react-router-dom';
|
||||
import Box from '../../components/ui/box';
|
||||
|
||||
import {
|
||||
CONNECT_HARDWARE_ROUTE,
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
CUSTODY_ACCOUNT_ROUTE,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
} from '../../helpers/constants/routes';
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
import CustodyPage from '../institutional/custody';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
import { CONNECT_HARDWARE_ROUTE } from '../../helpers/constants/routes';
|
||||
import ConnectHardwareForm from './connect-hardware';
|
||||
|
||||
export default function CreateAccountPage() {
|
||||
@ -22,11 +13,6 @@ export default function CreateAccountPage() {
|
||||
path={CONNECT_HARDWARE_ROUTE}
|
||||
component={ConnectHardwareForm}
|
||||
/>
|
||||
{
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
<Route exact path={CUSTODY_ACCOUNT_ROUTE} component={CustodyPage} />
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
}
|
||||
</Switch>
|
||||
</Box>
|
||||
);
|
||||
|
@ -138,7 +138,8 @@ const mapStateToProps = (state) => {
|
||||
selectedAddress,
|
||||
firstPermissionsRequestId,
|
||||
totalUnapprovedCount,
|
||||
hasApprovalFlows: getApprovalFlows(state).length > 0,
|
||||
hasApprovalFlows:
|
||||
Array.isArray(getApprovalFlows) && getApprovalFlows(state).length > 0,
|
||||
connectedStatusPopoverHasBeenShown,
|
||||
defaultHomeActiveTabName,
|
||||
firstTimeFlowType,
|
||||
|
@ -168,11 +168,13 @@ const ConfirmAddCustodianToken = () => {
|
||||
size={BUTTON_SIZES.LG}
|
||||
data-testid="cancel-btn"
|
||||
onClick={async () => {
|
||||
await mmiActions.removeAddTokenConnectRequest({
|
||||
origin: connectRequest.origin,
|
||||
apiUrl: connectRequest.apiUrl,
|
||||
token: connectRequest.token,
|
||||
});
|
||||
await dispatch(
|
||||
mmiActions.removeAddTokenConnectRequest({
|
||||
origin: connectRequest.origin,
|
||||
apiUrl: connectRequest.apiUrl,
|
||||
token: connectRequest.token,
|
||||
}),
|
||||
);
|
||||
|
||||
trackEvent({
|
||||
category: 'MMI',
|
||||
@ -220,11 +222,13 @@ const ConfirmAddCustodianToken = () => {
|
||||
}),
|
||||
);
|
||||
|
||||
await mmiActions.removeAddTokenConnectRequest({
|
||||
origin: connectRequest.origin,
|
||||
apiUrl: connectRequest.apiUrl,
|
||||
token: connectRequest.token,
|
||||
});
|
||||
await dispatch(
|
||||
mmiActions.removeAddTokenConnectRequest({
|
||||
origin: connectRequest.origin,
|
||||
apiUrl: connectRequest.apiUrl,
|
||||
token: connectRequest.token,
|
||||
}),
|
||||
);
|
||||
|
||||
trackEvent({
|
||||
category: 'MMI',
|
||||
|
@ -4,6 +4,16 @@ import configureMockStore from 'redux-mock-store';
|
||||
import { renderWithProvider } from '../../../../test/lib/render-helpers';
|
||||
import ConfirmAddCustodianToken from './confirm-add-custodian-token';
|
||||
|
||||
const mockedRemoveAddTokenConnectRequest = jest
|
||||
.fn()
|
||||
.mockReturnValue({ type: 'TYPE' });
|
||||
|
||||
jest.mock('../../../store/institutional/institution-background', () => ({
|
||||
mmiActionsFactory: () => ({
|
||||
removeAddTokenConnectRequest: mockedRemoveAddTokenConnectRequest,
|
||||
}),
|
||||
}));
|
||||
|
||||
describe('Confirm Add Custodian Token', () => {
|
||||
const mockStore = {
|
||||
metamask: {
|
||||
|
@ -20,72 +20,75 @@ exports[`CustodyPage renders CustodyPage 1`] = `
|
||||
|
||||
exports[`CustodyPage renders CustodyPage 2`] = `
|
||||
<div>
|
||||
|
||||
|
||||
<div
|
||||
class="mm-box mm-box--padding-4 mm-box--display-flex mm-box--flex-direction-column mm-box--background-color-background-default"
|
||||
style="box-shadow: var(--shadow-size-xs) var(--color-shadow-default);"
|
||||
class="mm-box page-container"
|
||||
>
|
||||
|
||||
|
||||
<div
|
||||
class="mm-box mm-box--margin-top-4 mm-box--margin-bottom-4 mm-box--display-flex mm-box--align-items-center"
|
||||
class="mm-box page-container__content mm-box--padding-4 mm-box--display-flex mm-box--flex-direction-column mm-box--width-full"
|
||||
>
|
||||
<button
|
||||
aria-label="Back"
|
||||
class="box mm-button-icon mm-button-icon--size-sm box--display-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-icon-default box--background-color-transparent box--rounded-lg"
|
||||
<div
|
||||
class="mm-box mm-box--margin-top-4 mm-box--margin-bottom-4 mm-box--display-flex mm-box--align-items-center"
|
||||
>
|
||||
<span
|
||||
class="box mm-icon mm-icon--size-sm box--display-inline-block box--flex-direction-row box--color-inherit"
|
||||
style="mask-image: url('./images/icons/arrow-left.svg');"
|
||||
/>
|
||||
</button>
|
||||
<p
|
||||
class="box mm-text mm-text--body-md box--flex-direction-row box--color-text-default"
|
||||
<button
|
||||
aria-label="Back"
|
||||
class="box mm-button-icon mm-button-icon--size-sm box--display-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-icon-default box--background-color-transparent box--rounded-lg"
|
||||
>
|
||||
<span
|
||||
class="box mm-icon mm-icon--size-sm box--display-inline-block box--flex-direction-row box--color-inherit"
|
||||
style="mask-image: url('./images/icons/arrow-left.svg');"
|
||||
/>
|
||||
</button>
|
||||
<p
|
||||
class="box mm-text mm-text--body-md box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
Back
|
||||
</p>
|
||||
</div>
|
||||
<h4
|
||||
class="box mm-text mm-text--body-lg-medium box--margin-top-4 box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
Back
|
||||
</p>
|
||||
</div>
|
||||
<h4
|
||||
class="box mm-text mm-text--body-lg-medium box--margin-top-4 box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
Custodial Accounts
|
||||
</h4>
|
||||
<h6
|
||||
class="box mm-text mm-text--body-md box--margin-top-2 box--margin-bottom-5 box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
Please choose the custodian you want to connect in order to add or refresh a token.
|
||||
</h6>
|
||||
<div
|
||||
class="mm-box"
|
||||
>
|
||||
<ul
|
||||
width="full"
|
||||
Custodial Accounts
|
||||
</h4>
|
||||
<h6
|
||||
class="box mm-text mm-text--body-md box--margin-top-2 box--margin-bottom-5 box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
<div
|
||||
class="mm-box mm-box--margin-bottom-4 mm-box--padding-4 mm-box--display-flex mm-box--flex-direction-row mm-box--justify-content-space-between mm-box--align-items-center mm-box--rounded-sm mm-box--border-color-border-default box--border-style-solid box--border-width-1"
|
||||
Please choose the custodian you want to connect in order to add or refresh a token.
|
||||
</h6>
|
||||
<div
|
||||
class="mm-box"
|
||||
>
|
||||
<ul
|
||||
width="full"
|
||||
>
|
||||
<div
|
||||
class="mm-box mm-box--display-flex mm-box--align-items-center"
|
||||
class="mm-box mm-box--margin-bottom-4 mm-box--padding-4 mm-box--display-flex mm-box--flex-direction-row mm-box--justify-content-space-between mm-box--align-items-center mm-box--rounded-sm mm-box--border-color-border-default box--border-style-solid box--border-width-1"
|
||||
>
|
||||
<img
|
||||
alt="Saturn Custody"
|
||||
height="32"
|
||||
src="https://saturn-custody-ui.dev.metamask-institutional.io/saturn.svg"
|
||||
width="32"
|
||||
/>
|
||||
<p
|
||||
class="box mm-text mm-text--body-md box--margin-left-2 box--flex-direction-row box--color-text-default"
|
||||
<div
|
||||
class="mm-box mm-box--display-flex mm-box--align-items-center"
|
||||
>
|
||||
Saturn Custody
|
||||
</p>
|
||||
<img
|
||||
alt="Saturn Custody"
|
||||
height="32"
|
||||
src="https://saturn-custody-ui.dev.metamask-institutional.io/saturn.svg"
|
||||
width="32"
|
||||
/>
|
||||
<p
|
||||
class="box mm-text mm-text--body-md box--margin-left-2 box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
Saturn Custody
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
class="box mm-text mm-button-base mm-button-base--size-sm mm-button-primary mm-text--body-md-medium box--padding-right-4 box--padding-left-4 box--display-inline-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-primary-inverse box--background-color-primary-default box--rounded-pill"
|
||||
data-testid="custody-connect-button"
|
||||
>
|
||||
Select
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
class="box mm-text mm-button-base mm-button-base--size-sm mm-button-primary mm-text--body-md-medium box--padding-right-4 box--padding-left-4 box--display-inline-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-primary-inverse box--background-color-primary-default box--rounded-pill"
|
||||
data-testid="custody-connect-button"
|
||||
>
|
||||
Select
|
||||
</button>
|
||||
</div>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -259,8 +259,7 @@ const CustodyPage = () => {
|
||||
if (Object.keys(connectRequestValue).length) {
|
||||
setConnectRequest(connectRequestValue);
|
||||
setCurrentJwt(
|
||||
connectRequestValue.token ||
|
||||
(await dispatch(mmiActions.getCustodianToken())),
|
||||
connectRequestValue.token || dispatch(mmiActions.getCustodianToken()),
|
||||
);
|
||||
setSelectedCustodianType(connectRequestValue.custodianType);
|
||||
setSelectedCustodianName(connectRequestValue.custodianName);
|
||||
@ -345,7 +344,7 @@ const CustodyPage = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box className="page-container">
|
||||
{connectError && (
|
||||
<Text textAlign={TextAlign.Center} marginTop={3} padding={[2, 7, 5]}>
|
||||
{connectError}
|
||||
@ -362,10 +361,8 @@ const CustodyPage = () => {
|
||||
padding={4}
|
||||
display={Display.Flex}
|
||||
flexDirection={FlexDirection.Column}
|
||||
backgroundColor={Color.backgroundDefault}
|
||||
style={{
|
||||
boxShadow: 'var(--shadow-size-xs) var(--color-shadow-default)',
|
||||
}}
|
||||
className="page-container__content"
|
||||
width={BlockSize.Full}
|
||||
>
|
||||
<Box
|
||||
display={Display.Flex}
|
||||
@ -405,10 +402,8 @@ const CustodyPage = () => {
|
||||
padding={4}
|
||||
display={Display.Flex}
|
||||
flexDirection={FlexDirection.Column}
|
||||
backgroundColor={Color.backgroundDefault}
|
||||
style={{
|
||||
boxShadow: 'var(--shadow-size-xs) var(--color-shadow-default)',
|
||||
}}
|
||||
className="page-container__content"
|
||||
width={BlockSize.Full}
|
||||
>
|
||||
<Box
|
||||
display={Display.Flex}
|
||||
@ -426,19 +421,19 @@ const CustodyPage = () => {
|
||||
/>
|
||||
<Text>{t('back')}</Text>
|
||||
</Box>
|
||||
<Text as="h4">
|
||||
{selectedCustodianImage && (
|
||||
<Box display={Display.Flex} alignItems={AlignItems.center}>
|
||||
{selectedCustodianImage && (
|
||||
<img
|
||||
width={32}
|
||||
height={32}
|
||||
src={selectedCustodianImage}
|
||||
alt={selectedCustodianDisplayName}
|
||||
/>
|
||||
)}
|
||||
<Text marginLeft={2}>{selectedCustodianDisplayName}</Text>
|
||||
<img
|
||||
width={32}
|
||||
height={32}
|
||||
src={selectedCustodianImage}
|
||||
alt={selectedCustodianDisplayName}
|
||||
/>
|
||||
<Text as="h4" marginLeft={2}>
|
||||
{selectedCustodianDisplayName}
|
||||
</Text>
|
||||
</Box>
|
||||
</Text>
|
||||
)}
|
||||
<Text marginTop={4}>
|
||||
{t('enterCustodianToken', [selectedCustodianDisplayName])}
|
||||
</Text>
|
||||
@ -454,35 +449,37 @@ const CustodyPage = () => {
|
||||
])}
|
||||
onUrlChange={(url) => setApiUrl(url)}
|
||||
/>
|
||||
<Box
|
||||
display={Display.Flex}
|
||||
flexDirection={FlexDirection.Row}
|
||||
justifyContent={JustifyContent.center}
|
||||
padding={0}
|
||||
>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box as="footer" className="page-container__footer" padding={4}>
|
||||
{loading ? (
|
||||
<PulseLoader />
|
||||
) : (
|
||||
<Box display={Display.Flex} gap={4}>
|
||||
<Button
|
||||
block
|
||||
variant={BUTTON_VARIANT.SECONDARY}
|
||||
marginRight={4}
|
||||
size={BUTTON_SIZES.LG}
|
||||
onClick={() => {
|
||||
cancelConnectCustodianToken();
|
||||
}}
|
||||
block
|
||||
>
|
||||
{t('cancel')}
|
||||
</Button>
|
||||
<Button
|
||||
block
|
||||
data-testid="jwt-form-connect-button"
|
||||
size={BUTTON_SIZES.LG}
|
||||
onClick={connect}
|
||||
disabled={
|
||||
!selectedCustodianName ||
|
||||
(addNewTokenClicked && !currentJwt)
|
||||
}
|
||||
block
|
||||
>
|
||||
{t('connect')}
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
@ -625,6 +622,7 @@ const CustodyPage = () => {
|
||||
className="custody-accounts-empty__footer"
|
||||
>
|
||||
<Button
|
||||
block
|
||||
size={BUTTON_SIZES.LG}
|
||||
type={BUTTON_VARIANT.SECONDARY}
|
||||
onClick={() => history.push(DEFAULT_ROUTE)}
|
||||
@ -634,7 +632,7 @@ const CustodyPage = () => {
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
</>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -57,6 +57,7 @@ import InteractiveReplacementTokenNotification from '../../components/institutio
|
||||
import ConfirmAddInstitutionalFeature from '../institutional/confirm-add-institutional-feature';
|
||||
import ConfirmAddCustodianToken from '../institutional/confirm-add-custodian-token';
|
||||
import InteractiveReplacementTokenPage from '../institutional/interactive-replacement-token-page';
|
||||
import CustodyPage from '../institutional/custody';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
import {
|
||||
@ -89,6 +90,7 @@ import {
|
||||
CONFIRM_INSTITUTIONAL_FEATURE_CONNECT,
|
||||
CONFIRM_ADD_CUSTODIAN_TOKEN,
|
||||
INTERACTIVE_REPLACEMENT_TOKEN_PAGE,
|
||||
CUSTODY_ACCOUNT_ROUTE,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
||||
NOTIFICATIONS_ROUTE,
|
||||
@ -337,6 +339,11 @@ export default class Routes extends Component {
|
||||
path={CONFIRM_ADD_CUSTODIAN_TOKEN}
|
||||
component={ConfirmAddCustodianToken}
|
||||
/>
|
||||
<Authenticated
|
||||
path={CUSTODY_ACCOUNT_ROUTE}
|
||||
component={CustodyPage}
|
||||
exact
|
||||
/>
|
||||
{
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
}
|
||||
|
@ -1065,8 +1065,9 @@ export function updateAndApproveTx(
|
||||
dispatch(completedTx(txMeta.id));
|
||||
dispatch(hideLoadingIndication());
|
||||
dispatch(updateCustomNonce(''));
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask)
|
||||
dispatch(closeCurrentNotificationWindow());
|
||||
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
return txMeta;
|
||||
})
|
||||
.catch((err) => {
|
||||
|
@ -146,7 +146,12 @@ describe('#InstitutionActions', () => {
|
||||
];
|
||||
|
||||
await store.dispatch(
|
||||
showCustodyConfirmLink('link', '0x1', false, 'custodyId'),
|
||||
showCustodyConfirmLink({
|
||||
link: 'link',
|
||||
address: '0x1',
|
||||
closeNotification: false,
|
||||
custodyId: 'custodyId',
|
||||
}),
|
||||
);
|
||||
|
||||
expect(store.getActions()).toStrictEqual(expectedActions);
|
||||
|
@ -28,12 +28,17 @@ export function showInteractiveReplacementTokenModal(): ThunkAction<
|
||||
};
|
||||
}
|
||||
|
||||
export function showCustodyConfirmLink(
|
||||
link: string,
|
||||
address: string,
|
||||
closeNotification: boolean,
|
||||
custodyId: string,
|
||||
): ThunkAction<void, MetaMaskReduxState, unknown, AnyAction> {
|
||||
export function showCustodyConfirmLink({
|
||||
link,
|
||||
address,
|
||||
closeNotification,
|
||||
custodyId,
|
||||
}: {
|
||||
link: string;
|
||||
address: string;
|
||||
closeNotification: boolean;
|
||||
custodyId: string;
|
||||
}): ThunkAction<void, MetaMaskReduxState, unknown, AnyAction> {
|
||||
return (dispatch) => {
|
||||
dispatch(
|
||||
showModal({
|
||||
|
@ -106,17 +106,14 @@ export function mmiActionsFactory() {
|
||||
};
|
||||
}
|
||||
|
||||
function createAction(name: string, payload: any): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
callBackgroundMethod(name, [payload], (error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
function createAction(name: string, payload: any) {
|
||||
return () => {
|
||||
callBackgroundMethod(name, [payload], (err) => {
|
||||
if (isErrorWithMessage(err)) {
|
||||
throw new Error(err.message);
|
||||
}
|
||||
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
|
77
yarn.lock
77
yarn.lock
@ -3693,7 +3693,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@metamask-institutional/custody-controller@npm:0.2.6, @metamask-institutional/custody-controller@npm:^0.2.5":
|
||||
"@metamask-institutional/custody-controller@npm:0.2.6":
|
||||
version: 0.2.6
|
||||
resolution: "@metamask-institutional/custody-controller@npm:0.2.6"
|
||||
dependencies:
|
||||
@ -3706,6 +3706,19 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@metamask-institutional/custody-controller@npm:^0.2.8":
|
||||
version: 0.2.8
|
||||
resolution: "@metamask-institutional/custody-controller@npm:0.2.8"
|
||||
dependencies:
|
||||
"@ethereumjs/util": ^8.0.5
|
||||
"@metamask-institutional/custody-keyring": ^0.0.25
|
||||
"@metamask-institutional/sdk": ^0.1.18
|
||||
"@metamask-institutional/types": ^1.0.3
|
||||
"@metamask/obs-store": ^8.0.0
|
||||
checksum: 5950dd7d6497edd90b17a9265bc2006791a8c2f53c3282bc6f5f85bf92bb794d6ac440bb0019b529fe225c28093471bee9104034b1b977ff6bc5ccb6c6287af7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@metamask-institutional/custody-keyring@npm:^0.0.22":
|
||||
version: 0.0.22
|
||||
resolution: "@metamask-institutional/custody-keyring@npm:0.0.22"
|
||||
@ -3738,20 +3751,20 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@metamask-institutional/extension@npm:^0.1.3":
|
||||
version: 0.1.3
|
||||
resolution: "@metamask-institutional/extension@npm:0.1.3"
|
||||
"@metamask-institutional/extension@npm:^0.1.6":
|
||||
version: 0.1.6
|
||||
resolution: "@metamask-institutional/extension@npm:0.1.6"
|
||||
dependencies:
|
||||
"@ethereumjs/util": ^8.0.5
|
||||
"@metamask-institutional/custody-controller": ^0.2.5
|
||||
"@metamask-institutional/custody-keyring": ^0.0.22
|
||||
"@metamask-institutional/portfolio-dashboard": ^1.1.3
|
||||
"@metamask-institutional/sdk": ^0.1.16
|
||||
"@metamask-institutional/transaction-update": ^0.1.20
|
||||
"@metamask-institutional/types": ^1.0.2
|
||||
"@metamask-institutional/custody-controller": ^0.2.8
|
||||
"@metamask-institutional/custody-keyring": ^0.0.25
|
||||
"@metamask-institutional/portfolio-dashboard": ^1.4.0
|
||||
"@metamask-institutional/sdk": ^0.1.18
|
||||
"@metamask-institutional/transaction-update": ^0.1.23
|
||||
"@metamask-institutional/types": ^1.0.3
|
||||
jest-create-mock-instance: ^2.0.0
|
||||
jest-fetch-mock: 3.0.3
|
||||
checksum: a9a4d3183b972b992649081f586a9d92e92d5366afb9be445fcdeb0b9afd99e765e6a8ad63abddc0d222a800c1a6b02e847e0f705908581950cf1bc791be50ca
|
||||
checksum: d62e30658fe6be6c6ee955148bbebf729f13070cb049f0080be3a0e2f97f9ba735fe390ad26855cdb2badcdf2bbc089e2dc9641caf5c1970adceb8e71199384f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -3766,10 +3779,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@metamask-institutional/portfolio-dashboard@npm:^1.1.3":
|
||||
version: 1.1.3
|
||||
resolution: "@metamask-institutional/portfolio-dashboard@npm:1.1.3"
|
||||
checksum: ea5918426372f66c5ba575551658ebf443b77e528317aede5d79a21208718d90e756fa86389c366162a58363b38e8d47bed0ebb27938285705723cfa35295287
|
||||
"@metamask-institutional/portfolio-dashboard@npm:^1.1.3, @metamask-institutional/portfolio-dashboard@npm:^1.4.0":
|
||||
version: 1.4.0
|
||||
resolution: "@metamask-institutional/portfolio-dashboard@npm:1.4.0"
|
||||
checksum: f6bc1801cd5ea945dacdd3404cb4d2da31049746eff7e5436091d238a4a39abae8522cd58958f3b1bc61a558bac2b1c4f38f024976dcf87025d6b9d51a78fbf0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -3780,7 +3793,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@metamask-institutional/sdk@npm:^0.1.14, @metamask-institutional/sdk@npm:^0.1.15, @metamask-institutional/sdk@npm:^0.1.16, @metamask-institutional/sdk@npm:^0.1.17, @metamask-institutional/sdk@npm:^0.1.18":
|
||||
"@metamask-institutional/sdk@npm:^0.1.14, @metamask-institutional/sdk@npm:^0.1.15, @metamask-institutional/sdk@npm:^0.1.17, @metamask-institutional/sdk@npm:^0.1.18":
|
||||
version: 0.1.18
|
||||
resolution: "@metamask-institutional/sdk@npm:0.1.18"
|
||||
dependencies:
|
||||
@ -3801,17 +3814,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@metamask-institutional/transaction-update@npm:^0.1.20, @metamask-institutional/transaction-update@npm:^0.1.21":
|
||||
version: 0.1.21
|
||||
resolution: "@metamask-institutional/transaction-update@npm:0.1.21"
|
||||
"@metamask-institutional/transaction-update@npm:^0.1.21, @metamask-institutional/transaction-update@npm:^0.1.23":
|
||||
version: 0.1.23
|
||||
resolution: "@metamask-institutional/transaction-update@npm:0.1.23"
|
||||
dependencies:
|
||||
"@metamask-institutional/custody-keyring": ^0.0.22
|
||||
"@metamask-institutional/sdk": ^0.1.15
|
||||
"@metamask-institutional/types": ^1.0.2
|
||||
"@metamask-institutional/websocket-client": ^0.1.23
|
||||
"@metamask-institutional/custody-keyring": ^0.0.25
|
||||
"@metamask-institutional/sdk": ^0.1.18
|
||||
"@metamask-institutional/types": ^1.0.3
|
||||
"@metamask-institutional/websocket-client": ^0.1.25
|
||||
"@metamask/obs-store": ^8.0.0
|
||||
ethereumjs-util: ^7.1.5
|
||||
checksum: 22190a114279e365cdb89a58ae75c610dfa77e7bca365c85544af5f9d6977da0d0f7410b6acc76defdc08b608f6981a54e4df63b66a2e7fd2cd869ce0cd85945
|
||||
checksum: 73fad3dde4358f4b4b94dba76775c25dc789570d0ec218a682e206739effa5e6f8a809210743e0f8fdbad58900fee6ea3b8accca6a9f74c7052f2e8a25392163
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -3822,15 +3835,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@metamask-institutional/websocket-client@npm:^0.1.23":
|
||||
version: 0.1.23
|
||||
resolution: "@metamask-institutional/websocket-client@npm:0.1.23"
|
||||
"@metamask-institutional/websocket-client@npm:^0.1.25":
|
||||
version: 0.1.25
|
||||
resolution: "@metamask-institutional/websocket-client@npm:0.1.25"
|
||||
dependencies:
|
||||
"@metamask-institutional/custody-keyring": ^0.0.22
|
||||
"@metamask-institutional/sdk": ^0.1.15
|
||||
"@metamask-institutional/types": ^1.0.2
|
||||
"@metamask-institutional/custody-keyring": ^0.0.25
|
||||
"@metamask-institutional/sdk": ^0.1.18
|
||||
"@metamask-institutional/types": ^1.0.3
|
||||
mock-socket: ^9.2.1
|
||||
checksum: 7b7f091ab43287aa12bdfb75ff9ffc4b2272f1e404a3eab3a3a962b777ef47d374fd62ec3227023b858ce5cedabc00b06a9efcd973dbd71226049835236cca5d
|
||||
checksum: f42334200fc46dab5b049330cb42881f8e08952a6ff15fceb9fd561653561de303d756fb9267c97e4bf658bf5e2ae040fb7370319208368049cd0c252bffb0ed
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -24625,7 +24638,7 @@ __metadata:
|
||||
"@material-ui/core": ^4.11.0
|
||||
"@metamask-institutional/custody-controller": 0.2.6
|
||||
"@metamask-institutional/custody-keyring": ^0.0.25
|
||||
"@metamask-institutional/extension": ^0.1.3
|
||||
"@metamask-institutional/extension": ^0.1.6
|
||||
"@metamask-institutional/institutional-features": ^1.1.8
|
||||
"@metamask-institutional/portfolio-dashboard": ^1.1.3
|
||||
"@metamask-institutional/rpc-allowlist": ^1.0.0
|
||||
|
Loading…
Reference in New Issue
Block a user