mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Approval flow for add & switch network (#19656)
This commit is contained in:
parent
48465432d6
commit
a2dfe8d113
@ -22,6 +22,8 @@ const addEthereumChain = {
|
|||||||
findNetworkConfigurationBy: true,
|
findNetworkConfigurationBy: true,
|
||||||
setActiveNetwork: true,
|
setActiveNetwork: true,
|
||||||
requestUserApproval: true,
|
requestUserApproval: true,
|
||||||
|
startApprovalFlow: true,
|
||||||
|
endApprovalFlow: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
export default addEthereumChain;
|
export default addEthereumChain;
|
||||||
@ -38,6 +40,8 @@ async function addEthereumChainHandler(
|
|||||||
findNetworkConfigurationBy,
|
findNetworkConfigurationBy,
|
||||||
setActiveNetwork,
|
setActiveNetwork,
|
||||||
requestUserApproval,
|
requestUserApproval,
|
||||||
|
startApprovalFlow,
|
||||||
|
endApprovalFlow,
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
if (!req.params?.[0] || typeof req.params[0] !== 'object') {
|
if (!req.params?.[0] || typeof req.params[0] !== 'object') {
|
||||||
@ -242,6 +246,9 @@ async function addEthereumChainHandler(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
let networkConfigurationId;
|
let networkConfigurationId;
|
||||||
|
|
||||||
|
const { id: approvalFlowId } = await startApprovalFlow();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await requestUserApproval({
|
await requestUserApproval({
|
||||||
origin,
|
origin,
|
||||||
@ -269,6 +276,7 @@ async function addEthereumChainHandler(
|
|||||||
// Once the network has been added, the requested is considered successful
|
// Once the network has been added, the requested is considered successful
|
||||||
res.result = null;
|
res.result = null;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
endApprovalFlow({ id: approvalFlowId });
|
||||||
return end(error);
|
return end(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,14 +293,24 @@ async function addEthereumChainHandler(
|
|||||||
networkConfigurationId,
|
networkConfigurationId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
await setActiveNetwork(networkConfigurationId);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// For the purposes of this method, it does not matter if the user
|
// For the purposes of this method, it does not matter if the user
|
||||||
// declines to switch the selected network. However, other errors indicate
|
// declines to switch the selected network. However, other errors indicate
|
||||||
// that something is wrong.
|
// that something is wrong.
|
||||||
if (error.code !== errorCodes.provider.userRejectedRequest) {
|
return end(
|
||||||
|
error.code === errorCodes.provider.userRejectedRequest
|
||||||
|
? undefined
|
||||||
|
: error,
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
endApprovalFlow({ id: approvalFlowId });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await setActiveNetwork(networkConfigurationId);
|
||||||
|
} catch (error) {
|
||||||
return end(error);
|
return end(error);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return end();
|
return end();
|
||||||
}
|
}
|
||||||
|
@ -3909,6 +3909,16 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
this.approvalController.addAndShowApprovalRequest.bind(
|
this.approvalController.addAndShowApprovalRequest.bind(
|
||||||
this.approvalController,
|
this.approvalController,
|
||||||
),
|
),
|
||||||
|
startApprovalFlow: this.approvalController.startFlow.bind(
|
||||||
|
this.approvalController,
|
||||||
|
),
|
||||||
|
endApprovalFlow: this.approvalController.endFlow.bind(
|
||||||
|
this.approvalController,
|
||||||
|
),
|
||||||
|
setApprovalFlowLoadingText:
|
||||||
|
this.approvalController.setFlowLoadingText.bind(
|
||||||
|
this.approvalController,
|
||||||
|
),
|
||||||
sendMetrics: this.metaMetricsController.trackEvent.bind(
|
sendMetrics: this.metaMetricsController.trackEvent.bind(
|
||||||
this.metaMetricsController,
|
this.metaMetricsController,
|
||||||
),
|
),
|
||||||
|
@ -100,7 +100,7 @@
|
|||||||
"resolutions": {
|
"resolutions": {
|
||||||
"@babel/core": "patch:@babel/core@npm%3A7.21.5#./.yarn/patches/@babel-core-npm-7.21.5-c72c337956.patch",
|
"@babel/core": "patch:@babel/core@npm%3A7.21.5#./.yarn/patches/@babel-core-npm-7.21.5-c72c337956.patch",
|
||||||
"@babel/runtime": "patch:@babel/runtime@npm%3A7.18.9#./.yarn/patches/@babel-runtime-npm-7.18.9-28ca6b5f61.patch",
|
"@babel/runtime": "patch:@babel/runtime@npm%3A7.18.9#./.yarn/patches/@babel-runtime-npm-7.18.9-28ca6b5f61.patch",
|
||||||
"@metamask/approval-controller": "^3.0.0",
|
"@metamask/approval-controller": "^3.3.0",
|
||||||
"@types/react": "^16.9.53",
|
"@types/react": "^16.9.53",
|
||||||
"analytics-node/axios": "^0.21.2",
|
"analytics-node/axios": "^0.21.2",
|
||||||
"ganache-core/lodash": "^4.17.21",
|
"ganache-core/lodash": "^4.17.21",
|
||||||
@ -224,7 +224,7 @@
|
|||||||
"@metamask-institutional/transaction-update": "^0.1.21",
|
"@metamask-institutional/transaction-update": "^0.1.21",
|
||||||
"@metamask/address-book-controller": "^3.0.0",
|
"@metamask/address-book-controller": "^3.0.0",
|
||||||
"@metamask/announcement-controller": "^4.0.0",
|
"@metamask/announcement-controller": "^4.0.0",
|
||||||
"@metamask/approval-controller": "^3.1.0",
|
"@metamask/approval-controller": "^3.3.0",
|
||||||
"@metamask/assets-controllers": "^9.2.0",
|
"@metamask/assets-controllers": "^9.2.0",
|
||||||
"@metamask/base-controller": "^3.0.0",
|
"@metamask/base-controller": "^3.0.0",
|
||||||
"@metamask/browser-passworder": "^4.1.0",
|
"@metamask/browser-passworder": "^4.1.0",
|
||||||
|
@ -32,11 +32,14 @@ import {
|
|||||||
///: END:ONLY_INCLUDE_IN
|
///: END:ONLY_INCLUDE_IN
|
||||||
getUnapprovedTemplatedConfirmations,
|
getUnapprovedTemplatedConfirmations,
|
||||||
getUnapprovedTxCount,
|
getUnapprovedTxCount,
|
||||||
|
getApprovalFlows,
|
||||||
|
getTotalUnapprovedCount,
|
||||||
} from '../../selectors';
|
} from '../../selectors';
|
||||||
import NetworkDisplay from '../../components/app/network-display/network-display';
|
import NetworkDisplay from '../../components/app/network-display/network-display';
|
||||||
import Callout from '../../components/ui/callout';
|
import Callout from '../../components/ui/callout';
|
||||||
import SiteOrigin from '../../components/ui/site-origin';
|
import SiteOrigin from '../../components/ui/site-origin';
|
||||||
import { Icon, IconName } from '../../components/component-library';
|
import { Icon, IconName } from '../../components/component-library';
|
||||||
|
import Loading from '../../components/ui/loading-screen';
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
||||||
import SnapAuthorshipHeader from '../../components/app/snaps/snap-authorship-header';
|
import SnapAuthorshipHeader from '../../components/app/snaps/snap-authorship-header';
|
||||||
import { getSnapName } from '../../helpers/utils/util';
|
import { getSnapName } from '../../helpers/utils/util';
|
||||||
@ -176,6 +179,9 @@ export default function ConfirmationPage({
|
|||||||
isEqual,
|
isEqual,
|
||||||
);
|
);
|
||||||
const unapprovedTxsCount = useSelector(getUnapprovedTxCount);
|
const unapprovedTxsCount = useSelector(getUnapprovedTxCount);
|
||||||
|
const approvalFlows = useSelector(getApprovalFlows, isEqual);
|
||||||
|
const totalUnapprovedCount = useSelector(getTotalUnapprovedCount);
|
||||||
|
const [approvalFlowLoadingText, setApprovalFlowLoadingText] = useState(null);
|
||||||
const [currentPendingConfirmation, setCurrentPendingConfirmation] =
|
const [currentPendingConfirmation, setCurrentPendingConfirmation] =
|
||||||
useState(0);
|
useState(0);
|
||||||
const pendingConfirmation = pendingConfirmations[currentPendingConfirmation];
|
const pendingConfirmation = pendingConfirmations[currentPendingConfirmation];
|
||||||
@ -256,20 +262,36 @@ export default function ConfirmationPage({
|
|||||||
// viewed index, reset the index.
|
// viewed index, reset the index.
|
||||||
if (
|
if (
|
||||||
pendingConfirmations.length === 0 &&
|
pendingConfirmations.length === 0 &&
|
||||||
|
(approvalFlows.length === 0 || totalUnapprovedCount !== 0) &&
|
||||||
redirectToHomeOnZeroConfirmations
|
redirectToHomeOnZeroConfirmations
|
||||||
) {
|
) {
|
||||||
history.push(DEFAULT_ROUTE);
|
history.push(DEFAULT_ROUTE);
|
||||||
} else if (pendingConfirmations.length <= currentPendingConfirmation) {
|
} else if (
|
||||||
|
pendingConfirmations.length &&
|
||||||
|
pendingConfirmations.length <= currentPendingConfirmation
|
||||||
|
) {
|
||||||
setCurrentPendingConfirmation(pendingConfirmations.length - 1);
|
setCurrentPendingConfirmation(pendingConfirmations.length - 1);
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
pendingConfirmations,
|
pendingConfirmations,
|
||||||
|
approvalFlows,
|
||||||
|
totalUnapprovedCount,
|
||||||
history,
|
history,
|
||||||
currentPendingConfirmation,
|
currentPendingConfirmation,
|
||||||
redirectToHomeOnZeroConfirmations,
|
redirectToHomeOnZeroConfirmations,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const childFlow = approvalFlows[approvalFlows.length - 1];
|
||||||
|
|
||||||
|
setApprovalFlowLoadingText(childFlow?.loadingText ?? null);
|
||||||
|
}, [approvalFlows]);
|
||||||
|
|
||||||
if (!pendingConfirmation) {
|
if (!pendingConfirmation) {
|
||||||
|
if (approvalFlows.length > 0) {
|
||||||
|
return <Loading loadingMessage={approvalFlowLoadingText} />;
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ const mockBaseStore = {
|
|||||||
pendingApprovals: {
|
pendingApprovals: {
|
||||||
[mockApprovalId]: mockApproval,
|
[mockApprovalId]: mockApproval,
|
||||||
},
|
},
|
||||||
|
approvalFlows: [{ id: mockApprovalId, loadingText: null }],
|
||||||
subjectMetadata: {},
|
subjectMetadata: {},
|
||||||
providerConfig: {
|
providerConfig: {
|
||||||
type: 'rpc',
|
type: 'rpc',
|
||||||
|
@ -33,6 +33,7 @@ const mockBaseStore = {
|
|||||||
pendingApprovals: {
|
pendingApprovals: {
|
||||||
[mockApprovalId]: mockApproval,
|
[mockApprovalId]: mockApproval,
|
||||||
},
|
},
|
||||||
|
approvalFlows: [],
|
||||||
subjectMetadata: {},
|
subjectMetadata: {},
|
||||||
providerConfig: {
|
providerConfig: {
|
||||||
type: 'rpc',
|
type: 'rpc',
|
||||||
|
@ -84,6 +84,7 @@ import FlaskHomeFooter from './flask/flask-home-footer.component';
|
|||||||
function shouldCloseNotificationPopup({
|
function shouldCloseNotificationPopup({
|
||||||
isNotification,
|
isNotification,
|
||||||
totalUnapprovedCount,
|
totalUnapprovedCount,
|
||||||
|
hasApprovalFlows,
|
||||||
isSigningQRHardwareTransaction,
|
isSigningQRHardwareTransaction,
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
waitForConfirmDeepLinkDialog,
|
waitForConfirmDeepLinkDialog,
|
||||||
@ -93,6 +94,7 @@ function shouldCloseNotificationPopup({
|
|||||||
let shouldCLose =
|
let shouldCLose =
|
||||||
isNotification &&
|
isNotification &&
|
||||||
totalUnapprovedCount === 0 &&
|
totalUnapprovedCount === 0 &&
|
||||||
|
!hasApprovalFlows &&
|
||||||
!isSigningQRHardwareTransaction;
|
!isSigningQRHardwareTransaction;
|
||||||
|
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
@ -139,6 +141,7 @@ export default class Home extends PureComponent {
|
|||||||
originOfCurrentTab: PropTypes.string,
|
originOfCurrentTab: PropTypes.string,
|
||||||
disableWeb3ShimUsageAlert: PropTypes.func.isRequired,
|
disableWeb3ShimUsageAlert: PropTypes.func.isRequired,
|
||||||
pendingConfirmations: PropTypes.arrayOf(PropTypes.object).isRequired,
|
pendingConfirmations: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
|
hasApprovalFlows: PropTypes.bool.isRequired,
|
||||||
infuraBlocked: PropTypes.bool.isRequired,
|
infuraBlocked: PropTypes.bool.isRequired,
|
||||||
showWhatsNewPopup: PropTypes.bool.isRequired,
|
showWhatsNewPopup: PropTypes.bool.isRequired,
|
||||||
hideWhatsNewPopup: PropTypes.func.isRequired,
|
hideWhatsNewPopup: PropTypes.func.isRequired,
|
||||||
@ -287,6 +290,7 @@ export default class Home extends PureComponent {
|
|||||||
showAwaitingSwapScreen,
|
showAwaitingSwapScreen,
|
||||||
swapsFetchParams,
|
swapsFetchParams,
|
||||||
pendingConfirmations,
|
pendingConfirmations,
|
||||||
|
hasApprovalFlows,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
@ -307,7 +311,7 @@ export default class Home extends PureComponent {
|
|||||||
history.push(CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE);
|
history.push(CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE);
|
||||||
} else if (hasWatchNftPendingApprovals) {
|
} else if (hasWatchNftPendingApprovals) {
|
||||||
history.push(CONFIRM_ADD_SUGGESTED_NFT_ROUTE);
|
history.push(CONFIRM_ADD_SUGGESTED_NFT_ROUTE);
|
||||||
} else if (pendingConfirmations.length > 0) {
|
} else if (pendingConfirmations.length > 0 || hasApprovalFlows) {
|
||||||
history.push(CONFIRMATION_V_NEXT_ROUTE);
|
history.push(CONFIRMATION_V_NEXT_ROUTE);
|
||||||
}
|
}
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
|
@ -36,6 +36,7 @@ import {
|
|||||||
getRemoveNftMessage,
|
getRemoveNftMessage,
|
||||||
getSuggestedTokens,
|
getSuggestedTokens,
|
||||||
getSuggestedNfts,
|
getSuggestedNfts,
|
||||||
|
getApprovalFlows,
|
||||||
} from '../../selectors';
|
} from '../../selectors';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -137,6 +138,7 @@ const mapStateToProps = (state) => {
|
|||||||
selectedAddress,
|
selectedAddress,
|
||||||
firstPermissionsRequestId,
|
firstPermissionsRequestId,
|
||||||
totalUnapprovedCount,
|
totalUnapprovedCount,
|
||||||
|
hasApprovalFlows: getApprovalFlows(state).length > 0,
|
||||||
connectedStatusPopoverHasBeenShown,
|
connectedStatusPopoverHasBeenShown,
|
||||||
defaultHomeActiveTabName,
|
defaultHomeActiveTabName,
|
||||||
firstTimeFlowType,
|
firstTimeFlowType,
|
||||||
|
@ -106,6 +106,7 @@ describe('Routes Component', () => {
|
|||||||
swapsFeatureIsLive: true,
|
swapsFeatureIsLive: true,
|
||||||
},
|
},
|
||||||
pendingApprovals: {},
|
pendingApprovals: {},
|
||||||
|
approvalFlows: [],
|
||||||
announcements: {},
|
announcements: {},
|
||||||
},
|
},
|
||||||
send: {
|
send: {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ApprovalType } from '@metamask/controller-utils';
|
import { ApprovalType } from '@metamask/controller-utils';
|
||||||
import { hasPendingApprovals } from './approvals';
|
import { getApprovalFlows, hasPendingApprovals } from './approvals';
|
||||||
|
|
||||||
describe('approval selectors', () => {
|
describe('approval selectors', () => {
|
||||||
const mockedState = {
|
const mockedState = {
|
||||||
@ -13,6 +13,7 @@ describe('approval selectors', () => {
|
|||||||
type: ApprovalType.WatchAsset,
|
type: ApprovalType.WatchAsset,
|
||||||
requestData: {},
|
requestData: {},
|
||||||
requestState: null,
|
requestState: null,
|
||||||
|
expectsResult: false,
|
||||||
},
|
},
|
||||||
'2': {
|
'2': {
|
||||||
id: '2',
|
id: '2',
|
||||||
@ -21,13 +22,19 @@ describe('approval selectors', () => {
|
|||||||
type: ApprovalType.Transaction,
|
type: ApprovalType.Transaction,
|
||||||
requestData: {},
|
requestData: {},
|
||||||
requestState: null,
|
requestState: null,
|
||||||
|
expectsResult: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
unapprovedTxs: {
|
approvalFlows: [
|
||||||
'2': {
|
{
|
||||||
|
id: '1',
|
||||||
|
loadingText: 'loadingText1',
|
||||||
|
},
|
||||||
|
{
|
||||||
id: '2',
|
id: '2',
|
||||||
|
loadingText: 'loadingText2',
|
||||||
},
|
},
|
||||||
},
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -47,4 +54,12 @@ describe('approval selectors', () => {
|
|||||||
expect(result).toBe(false);
|
expect(result).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getApprovalFlows', () => {
|
||||||
|
it('should return existing approval flows', () => {
|
||||||
|
const result = getApprovalFlows(mockedState);
|
||||||
|
|
||||||
|
expect(result).toStrictEqual(mockedState.metamask.approvalFlows);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
import { ApprovalControllerState } from '@metamask/approval-controller';
|
import { ApprovalControllerState } from '@metamask/approval-controller';
|
||||||
import { ApprovalType } from '@metamask/controller-utils';
|
import { ApprovalType } from '@metamask/controller-utils';
|
||||||
import { TransactionMeta } from '../../shared/constants/transaction';
|
|
||||||
|
|
||||||
type ApprovalsMetaMaskState = {
|
type ApprovalsMetaMaskState = {
|
||||||
metamask: {
|
metamask: {
|
||||||
pendingApprovals: ApprovalControllerState['pendingApprovals'];
|
pendingApprovals: ApprovalControllerState['pendingApprovals'];
|
||||||
unapprovedTxs: {
|
approvalFlows: ApprovalControllerState['approvalFlows'];
|
||||||
[transactionId: string]: TransactionMeta;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -46,3 +43,7 @@ export const getApprovalRequestsByType = (
|
|||||||
|
|
||||||
return pendingApprovalRequests;
|
return pendingApprovalRequests;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function getApprovalFlows(state: ApprovalsMetaMaskState) {
|
||||||
|
return state.metamask.approvalFlows;
|
||||||
|
}
|
||||||
|
@ -35,6 +35,7 @@ import {
|
|||||||
getPermittedAccountsForCurrentTab,
|
getPermittedAccountsForCurrentTab,
|
||||||
getSelectedAddress,
|
getSelectedAddress,
|
||||||
hasTransactionPendingApprovals,
|
hasTransactionPendingApprovals,
|
||||||
|
getApprovalFlows,
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
||||||
getNotifications,
|
getNotifications,
|
||||||
///: END:ONLY_INCLUDE_IN
|
///: END:ONLY_INCLUDE_IN
|
||||||
@ -2382,9 +2383,12 @@ export function closeCurrentNotificationWindow(): ThunkAction<
|
|||||||
AnyAction
|
AnyAction
|
||||||
> {
|
> {
|
||||||
return (_, getState) => {
|
return (_, getState) => {
|
||||||
|
const state = getState();
|
||||||
|
const approvalFlows = getApprovalFlows(state);
|
||||||
if (
|
if (
|
||||||
getEnvironmentType() === ENVIRONMENT_TYPE_NOTIFICATION &&
|
getEnvironmentType() === ENVIRONMENT_TYPE_NOTIFICATION &&
|
||||||
!hasTransactionPendingApprovals(getState())
|
!hasTransactionPendingApprovals(state) &&
|
||||||
|
approvalFlows.length === 0
|
||||||
) {
|
) {
|
||||||
closeNotificationPopup();
|
closeNotificationPopup();
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,7 @@ interface TemporaryBackgroundState {
|
|||||||
networkId: string | null;
|
networkId: string | null;
|
||||||
networkStatus: NetworkStatus;
|
networkStatus: NetworkStatus;
|
||||||
pendingApprovals: ApprovalControllerState['pendingApprovals'];
|
pendingApprovals: ApprovalControllerState['pendingApprovals'];
|
||||||
|
approvalFlows: ApprovalControllerState['approvalFlows'];
|
||||||
knownMethodData?: {
|
knownMethodData?: {
|
||||||
[fourBytePrefix: string]: Record<string, unknown>;
|
[fourBytePrefix: string]: Record<string, unknown>;
|
||||||
};
|
};
|
||||||
|
10
yarn.lock
10
yarn.lock
@ -3857,16 +3857,16 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@metamask/approval-controller@npm:^3.0.0":
|
"@metamask/approval-controller@npm:^3.3.0":
|
||||||
version: 3.1.0
|
version: 3.3.0
|
||||||
resolution: "@metamask/approval-controller@npm:3.1.0"
|
resolution: "@metamask/approval-controller@npm:3.3.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@metamask/base-controller": ^3.0.0
|
"@metamask/base-controller": ^3.0.0
|
||||||
"@metamask/utils": ^5.0.2
|
"@metamask/utils": ^5.0.2
|
||||||
eth-rpc-errors: ^4.0.2
|
eth-rpc-errors: ^4.0.2
|
||||||
immer: ^9.0.6
|
immer: ^9.0.6
|
||||||
nanoid: ^3.1.31
|
nanoid: ^3.1.31
|
||||||
checksum: 2043e62e8815a600e839617b4df26515fc33f655e21562dc230cd6dbfc4677e955e1e45a5df8fbb2def2122b3578f6a632acb939f8175419febb1471d0c48ce0
|
checksum: 1fa6111a897d6f4aa369fd1a669fb5e16558277019f9d6c61449aea0d7b2672a62c189e5b3d9e84ab6e4d5826932c78d2bdb0f05aafb184a4ff07903c46abf2c
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -24482,7 +24482,7 @@ __metadata:
|
|||||||
"@metamask-institutional/transaction-update": ^0.1.21
|
"@metamask-institutional/transaction-update": ^0.1.21
|
||||||
"@metamask/address-book-controller": ^3.0.0
|
"@metamask/address-book-controller": ^3.0.0
|
||||||
"@metamask/announcement-controller": ^4.0.0
|
"@metamask/announcement-controller": ^4.0.0
|
||||||
"@metamask/approval-controller": ^3.1.0
|
"@metamask/approval-controller": ^3.3.0
|
||||||
"@metamask/assets-controllers": ^9.2.0
|
"@metamask/assets-controllers": ^9.2.0
|
||||||
"@metamask/auto-changelog": ^2.1.0
|
"@metamask/auto-changelog": ^2.1.0
|
||||||
"@metamask/base-controller": ^3.0.0
|
"@metamask/base-controller": ^3.0.0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user