1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-22 09:57:02 +01:00

[FLASK] BREAKING - snaps-monorepo@0.30.0 (#17718)

* updated snap permission to wallet_snap, updated tests and added migration

* updated snap packages

* yarn.lock fix

* fixed errors

* override policy

* update policy

* undo override

* updated localization message descriptions

* updated lavamoat policy

* more policy updates

* update permission controller version

* update policy

* update fixture builder

* updated code to include permission value to satisfy wallet_snap permission description call

* fix import issue

* update test-snaps version

* added missing actions, added snap permission dedupe function

* prettier fix

* fix fencing

* add more fencing

* prettier fix

* fix fencing (again)

* added new action and selector and updated view snap accordingly

* update test snaps website version

* unfence request variable

* add fencing

* add optional chaining to fix type error

* update migration #

* remove old migration

* prettier fix

* fix migration test

* fix fencing

* added missing fencing

* updated code to workaround fencing

* update test-snaps site version and remove snap confirm test

* update snap packages

* update policies

* fix merge marker issue

* update test

* more fixes

* fix permissions

* update test

* fixed test

* Bump test-snaps and iframe-execution-environment

* remove unused snap permission from fixture builder

* update policies

* undo comment removal, update selector implementation

* removed unnecessary function, updated migration, updated caveat action

* remove optional chaining

* fix type issue

* more type fixes

* fix migration test

* remove isFlask check, make migration logic more robust

* update coverage

* Update LavaMoat policies

* Update test/e2e/snaps/enums.js

* add extra bail condition

* Revert "add extra bail condition"

This reverts commit b45c53dcfc6e6e35a5e283d4955d6d6ea9ca5965.

* Revert "Revert "add extra bail condition""

This reverts commit cd2ded677935c9cdab0c02b6af55474c83727f60.

* fix test

* add SnapController entry to state object

* updated permission name and caveat type with hardcoded values

* add extra test for non-flask scenario

* update lavamoat policies

* fix locale messages

* change coverage target

* re-enable rpc snap test

* revert locale message change

* fix el message

* reverted changes

---------

Co-authored-by: Frederik Bolding <frederik.bolding@gmail.com>
This commit is contained in:
Hassan Malik 2023-03-08 13:29:23 -05:00 committed by GitHub
parent 3a3e34a8c6
commit 7086494b72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 916 additions and 308 deletions

View File

@ -289,7 +289,6 @@ const state = {
},
version: '0.6.0',
},
permissionName: 'wallet_snap_local:http://localhost:8080/',
sourceCode: '(...)',
status: 'stopped',
svgIcon: '<svg>...</svg>',
@ -330,7 +329,6 @@ const state = {
},
version: '0.6.0',
},
permissionName: 'wallet_snap_npm:http://localhost:8080/',
sourceCode: '(...)',
status: 'stopped',
svgIcon: '<svg>...</svg>',

View File

@ -2713,7 +2713,7 @@
},
"permission_accessNamedSnap": {
"message": "Mit $1 verbinden.",
"description": "The description for the `wallet_snap_*` permission. $1 is the human-readable name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the human-readable name of the snap."
},
"permission_accessNetwork": {
"message": "Zugriff auf das Internet.",
@ -2721,7 +2721,7 @@
},
"permission_accessSnap": {
"message": "Verbinden Sie sich mit dem $1-Snap.",
"description": "The description for the `wallet_snap_*` permission. $1 is the name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the name of the snap."
},
"permission_cronjob": {
"message": "Regelmäßige Transaktionen planen und ausführen.",

View File

@ -2713,7 +2713,7 @@
},
"permission_accessNamedSnap": {
"message": "Σύνδεση με $1.",
"description": "The description for the `wallet_snap_*` permission. $1 is the human-readable name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the human-readable name of the snap."
},
"permission_accessNetwork": {
"message": "Πρόσβαση στο Διαδίκτυο.",
@ -2721,7 +2721,7 @@
},
"permission_accessSnap": {
"message": "Συνδεθείτε στο Snap $1.",
"description": "The description for the `wallet_snap_*` permission. $1 is the name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the name of the snap."
},
"permission_cronjob": {
"message": "Προγραμματισμός και εκτέλεση περιοδικών ενεργειών.",

View File

@ -2740,7 +2740,7 @@
},
"permission_accessNamedSnap": {
"message": "Connect to $1.",
"description": "The description for the `wallet_snap_*` permission. $1 is the human-readable name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the human-readable name of the snap."
},
"permission_accessNetwork": {
"message": "Access the internet.",
@ -2748,7 +2748,7 @@
},
"permission_accessSnap": {
"message": "Connect to the $1 snap.",
"description": "The description for the `wallet_snap_*` permission. $1 is the name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the name of the snap."
},
"permission_cronjob": {
"message": "Schedule and execute periodic actions.",

View File

@ -2713,7 +2713,7 @@
},
"permission_accessNamedSnap": {
"message": "Conectarse a $1.",
"description": "The description for the `wallet_snap_*` permission. $1 is the human-readable name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the human-readable name of the snap."
},
"permission_accessNetwork": {
"message": "Acceso a internet.",
@ -2721,7 +2721,7 @@
},
"permission_accessSnap": {
"message": "Conéctese al complemento de $1.",
"description": "The description for the `wallet_snap_*` permission. $1 is the name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the name of the snap."
},
"permission_cronjob": {
"message": "Programar y ejecutar acciones periódicas.",

View File

@ -2713,7 +2713,7 @@
},
"permission_accessNamedSnap": {
"message": "Se connecter à $1.",
"description": "The description for the `wallet_snap_*` permission. $1 is the human-readable name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the human-readable name of the snap."
},
"permission_accessNetwork": {
"message": "Accéder à internet.",
@ -2721,7 +2721,7 @@
},
"permission_accessSnap": {
"message": "Connexion au Snap $1.",
"description": "The description for the `wallet_snap_*` permission. $1 is the name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the name of the snap."
},
"permission_cronjob": {
"message": "Planifiez et exécutez des actions périodiques.",

View File

@ -2713,7 +2713,7 @@
},
"permission_accessNamedSnap": {
"message": "$1 से कनेक्ट करें।",
"description": "The description for the `wallet_snap_*` permission. $1 is the human-readable name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the human-readable name of the snap."
},
"permission_accessNetwork": {
"message": "इंटरनेट एक्सेस करें।",
@ -2721,7 +2721,7 @@
},
"permission_accessSnap": {
"message": "$1 स्नैप से कनेक्ट करें।",
"description": "The description for the `wallet_snap_*` permission. $1 is the name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the name of the snap."
},
"permission_cronjob": {
"message": "समय-समय पर आने वाले क्रियाओं को शेड्यूल और निष्पादित करें।",

View File

@ -2713,7 +2713,7 @@
},
"permission_accessNamedSnap": {
"message": "Hubungkan ke $1.",
"description": "The description for the `wallet_snap_*` permission. $1 is the human-readable name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the human-readable name of the snap."
},
"permission_accessNetwork": {
"message": "Akses internet.",
@ -2721,7 +2721,7 @@
},
"permission_accessSnap": {
"message": "Hubungkan ke Snap $1.",
"description": "The description for the `wallet_snap_*` permission. $1 is the name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the name of the snap."
},
"permission_cronjob": {
"message": "Jadwalkan dan lakukan tindakan berkala.",

View File

@ -2713,7 +2713,7 @@
},
"permission_accessNamedSnap": {
"message": "$1 に接続。",
"description": "The description for the `wallet_snap_*` permission. $1 is the human-readable name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the human-readable name of the snap."
},
"permission_accessNetwork": {
"message": "インターネットにアクセスします。",
@ -2721,7 +2721,7 @@
},
"permission_accessSnap": {
"message": "$1 スナップに接続します。",
"description": "The description for the `wallet_snap_*` permission. $1 is the name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the name of the snap."
},
"permission_cronjob": {
"message": "定期的なアクションのスケジュール設定と実行。",

View File

@ -2713,7 +2713,7 @@
},
"permission_accessNamedSnap": {
"message": "$1 연결",
"description": "The description for the `wallet_snap_*` permission. $1 is the human-readable name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the human-readable name of the snap."
},
"permission_accessNetwork": {
"message": "인터넷에 액세스합니다.",
@ -2721,7 +2721,7 @@
},
"permission_accessSnap": {
"message": "$1 스냅에 연결하세요.",
"description": "The description for the `wallet_snap_*` permission. $1 is the name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the name of the snap."
},
"permission_cronjob": {
"message": "정기적 활동 예약 및 실행",

View File

@ -2713,7 +2713,7 @@
},
"permission_accessNamedSnap": {
"message": "Conectar a $1.",
"description": "The description for the `wallet_snap_*` permission. $1 is the human-readable name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the human-readable name of the snap."
},
"permission_accessNetwork": {
"message": "Acesse a internet.",
@ -2721,7 +2721,7 @@
},
"permission_accessSnap": {
"message": "Conecte-se ao snap $1.",
"description": "The description for the `wallet_snap_*` permission. $1 is the name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the name of the snap."
},
"permission_cronjob": {
"message": "Agende e execute ações periódicas.",

View File

@ -2713,7 +2713,7 @@
},
"permission_accessNamedSnap": {
"message": "Подключиться к $1.",
"description": "The description for the `wallet_snap_*` permission. $1 is the human-readable name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the human-readable name of the snap."
},
"permission_accessNetwork": {
"message": "Доступ в Интернет.",
@ -2721,7 +2721,7 @@
},
"permission_accessSnap": {
"message": "Подключение к спапу $1.",
"description": "The description for the `wallet_snap_*` permission. $1 is the name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the name of the snap."
},
"permission_cronjob": {
"message": "Планируйте и выполняйте периодические действия.",

View File

@ -2713,7 +2713,7 @@
},
"permission_accessNamedSnap": {
"message": "Kumonekta sa $1.",
"description": "The description for the `wallet_snap_*` permission. $1 is the human-readable name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the human-readable name of the snap."
},
"permission_accessNetwork": {
"message": "I-access ang Internet.",
@ -2721,7 +2721,7 @@
},
"permission_accessSnap": {
"message": "Kumonekta sa $1 snap.",
"description": "The description for the `wallet_snap_*` permission. $1 is the name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the name of the snap."
},
"permission_cronjob": {
"message": "Mag-iskedyul at magsagawa ng mga pana-panahong mga aksyon.",

View File

@ -2713,7 +2713,7 @@
},
"permission_accessNamedSnap": {
"message": "$1 alanına bağlanın.",
"description": "The description for the `wallet_snap_*` permission. $1 is the human-readable name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the human-readable name of the snap."
},
"permission_accessNetwork": {
"message": "İnternete erişim sağla.",
@ -2721,7 +2721,7 @@
},
"permission_accessSnap": {
"message": "$1 snap'e bağlan.",
"description": "The description for the `wallet_snap_*` permission. $1 is the name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the name of the snap."
},
"permission_cronjob": {
"message": "Periyodik eylemleri planla ve gerçekleştir.",

View File

@ -2713,7 +2713,7 @@
},
"permission_accessNamedSnap": {
"message": "Kết nối với $1.",
"description": "The description for the `wallet_snap_*` permission. $1 is the human-readable name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the human-readable name of the snap."
},
"permission_accessNetwork": {
"message": "Truy cập Internet.",
@ -2721,7 +2721,7 @@
},
"permission_accessSnap": {
"message": "Kết nối với Snap $1.",
"description": "The description for the `wallet_snap_*` permission. $1 is the name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the name of the snap."
},
"permission_cronjob": {
"message": "Lên lịch và thực hiện các hành động theo định kỳ.",

View File

@ -2713,7 +2713,7 @@
},
"permission_accessNamedSnap": {
"message": "连接至$1。",
"description": "The description for the `wallet_snap_*` permission. $1 is the human-readable name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the human-readable name of the snap."
},
"permission_accessNetwork": {
"message": "访问互联网。",
@ -2721,7 +2721,7 @@
},
"permission_accessSnap": {
"message": "连接到$1 Snap。",
"description": "The description for the `wallet_snap_*` permission. $1 is the name of the snap."
"description": "The description for the `wallet_snap` permission. $1 is the name of the snap."
},
"permission_cronjob": {
"message": "规划并执行定期操作。",

View File

@ -16,7 +16,7 @@ describe('PermissionController specifications', () => {
describe('caveat specifications', () => {
it('getCaveatSpecifications returns the expected specifications object', () => {
const caveatSpecifications = getCaveatSpecifications({});
expect(Object.keys(caveatSpecifications)).toHaveLength(7);
expect(Object.keys(caveatSpecifications)).toHaveLength(8);
expect(
caveatSpecifications[CaveatTypes.restrictReturnedAccounts].type,
).toStrictEqual(CaveatTypes.restrictReturnedAccounts);
@ -39,6 +39,9 @@ describe('PermissionController specifications', () => {
expect(caveatSpecifications.rpcOrigin.type).toStrictEqual(
SnapCaveatType.RpcOrigin,
);
expect(caveatSpecifications.snapIds.type).toStrictEqual(
SnapCaveatType.SnapIds,
);
});
describe('restrictReturnedAccounts', () => {

View File

@ -754,7 +754,7 @@ export default class MetamaskController extends EventEmitter {
///: BEGIN:ONLY_INCLUDE_IN(flask)
const snapExecutionServiceArgs = {
iframeUrl: new URL(
'https://metamask.github.io/iframe-execution-environment/0.12.0',
'https://metamask.github.io/iframe-execution-environment/0.13.0',
),
messenger: this.controllerMessenger.getRestricted({
name: 'ExecutionService',
@ -782,6 +782,8 @@ export default class MetamaskController extends EventEmitter {
`${this.permissionController.name}:revokeAllPermissions`,
`${this.permissionController.name}:revokePermissions`,
`${this.permissionController.name}:revokePermissionForAllSubjects`,
`${this.permissionController.name}:getSubjectNames`,
`${this.permissionController.name}:updateCaveat`,
`${this.approvalController.name}:addRequest`,
`${this.permissionController.name}:grantPermissions`,
`${this.subjectMetadataController.name}:getSubjectMetadata`,
@ -4674,6 +4676,24 @@ export default class MetamaskController extends EventEmitter {
}
};
///: BEGIN:ONLY_INCLUDE_IN(flask)
updateCaveat = (origin, target, caveatType, caveatValue) => {
try {
this.controllerMessenger.call(
'PermissionController:updateCaveat',
origin,
target,
caveatType,
caveatValue,
);
} catch (exp) {
if (!(exp instanceof PermissionsRequestNotFoundError)) {
throw exp;
}
}
};
///: END:ONLY_INCLUDE_IN
rejectPermissionsRequest = (requestId) => {
try {
this.permissionController.rejectPermissionsRequest(requestId);

View File

@ -0,0 +1,162 @@
import { migrate, version as newVersion } from './081';
describe('migration #81', () => {
it('should consolidate snap permissions as caveats under the wallet_snap permission', async () => {
const oldStorage = {
meta: {
version: 80,
},
data: {
SnapController: {},
PermissionController: {
subjects: {
'example.com': {
permissions: {
'wallet_snap_npm:foobar': {
caveats: null,
date: 2,
id: 'a7342F4b-beae-4525-a36c-c0635fd03359',
invoker: 'example.com',
parentCapability: 'wallet_snap_npm:foobar',
},
'wallet_snap_npm:baz': {
caveats: null,
date: 3,
id: 'x342A44-beae-4525-a36c-c0635fd03359',
invoker: 'example.com',
parentCapability: 'wallet_snap_npm:baz',
},
},
},
'aave.com': {
permissions: {
'wallet_snap_npm:filsnap': {
caveats: null,
date: 10,
id: 'a7342F4b-beae-4525-a36c-c0635fd03359',
invoker: 'aave.com',
parentCapability: 'wallet_snap_npm:foobar',
},
'wallet_snap_npm:btcsnap': {
caveats: null,
date: 3,
id: 'x342A44-beae-4525-a36c-c0635fd03359',
invoker: 'aave.com',
parentCapability: 'wallet_snap_npm:btcsnap',
},
},
},
},
},
},
};
const newStorage = await migrate(oldStorage);
expect(newStorage).toStrictEqual({
meta: { version: newVersion },
data: {
SnapController: {},
PermissionController: {
subjects: {
'example.com': {
permissions: {
wallet_snap: {
caveats: [
{
type: 'snapIds',
value: {
'npm:foobar': {},
'npm:baz': {},
},
},
],
date: 3,
id: 'x342A44-beae-4525-a36c-c0635fd03359',
invoker: 'example.com',
parentCapability: 'wallet_snap',
},
},
},
'aave.com': {
permissions: {
wallet_snap: {
caveats: [
{
type: 'snapIds',
value: {
'npm:btcsnap': {},
'npm:filsnap': {},
},
},
],
date: 10,
id: 'a7342F4b-beae-4525-a36c-c0635fd03359',
invoker: 'aave.com',
parentCapability: 'wallet_snap',
},
},
},
},
},
},
});
});
it('should leave state unchanged if there are no snap permissions', async () => {
const oldStorage = {
meta: {
version: 80,
},
data: {
SnapController: {},
PermissionController: {
subjects: {
'example.com': {
permissions: {
eth_accounts: {
date: 2,
id: 'a7342F4b-beae-4525-a36c-c0635fd03359',
invoker: 'example.com',
parentCapability: 'eth_accounts',
},
},
},
},
},
},
};
const newStorage = await migrate(oldStorage);
expect(newStorage.data).toStrictEqual(oldStorage.data);
});
it('should leave state unchanged if there is no SnapController installed (i.e. not a flask build)', async () => {
const oldStorage = {
meta: {
version: 80,
},
data: {
PermissionController: {
subjects: {
'example.com': {
permissions: {
eth_accounts: {
date: 2,
id: 'a7342F4b-beae-4525-a36c-c0635fd03359',
invoker: 'example.com',
parentCapability: 'eth_accounts',
},
},
},
},
},
},
};
const newStorage = await migrate(oldStorage);
expect(newStorage.data).toStrictEqual(oldStorage.data);
});
});

View File

@ -0,0 +1,140 @@
import { cloneDeep, isArray } from 'lodash';
import { hasProperty, isObject } from '@metamask/utils';
export const version = 81;
/**
* Prior to this migration, snap <> dapp permissions were wildcards i.e. `wallet_snap_*`.
* Now the permission has been changed to `wallet_snap` and the current snap permissions
* that are under wildcards will be added as caveats to a parent `wallet_snap` permission.
*
* @param originalVersionedData - Versioned MetaMask extension state, exactly what we persist to dist.
* @param originalVersionedData.meta - State metadata.
* @param originalVersionedData.meta.version - The current state version.
* @param originalVersionedData.data - The persisted MetaMask state, keyed by controller.
* @returns Updated versioned MetaMask extension state.
*/
export async function migrate(originalVersionedData: {
meta: { version: number };
data: Record<string, unknown>;
}) {
const versionedData = cloneDeep(originalVersionedData);
versionedData.meta.version = version;
const state = versionedData.data;
const newState = transformState(state);
versionedData.data = newState;
return versionedData;
}
// We return state AS IS if there is any corruption
function transformState(state: Record<string, unknown>) {
if (
!hasProperty(state, 'SnapController') ||
!hasProperty(state, 'PermissionController') ||
!isObject(state.PermissionController)
) {
return state;
}
const { PermissionController } = state;
const { subjects } = PermissionController;
if (!isObject(subjects)) {
return state;
}
const snapPrefix = 'wallet_snap_';
for (const [subjectName, subject] of Object.entries(subjects)) {
if (!isObject(subject) || !isObject(subject.permissions)) {
return state;
}
// We keep track of the latest permission's date and associated id
// to assign to the wallet_snap permission after iterating through all permissions
let date = 1;
let id;
const { permissions } = subject;
// New permissions object that we use to tack on the `wallet_snap` permission
const updatedPermissions = { ...permissions };
for (const [permissionName, permission] of Object.entries(permissions)) {
// check if the permission is namespaced
if (permissionName.startsWith(snapPrefix)) {
if (
!isObject(permission) ||
!hasProperty(permission, 'id') ||
!hasProperty(permission, 'date')
) {
return state;
}
// We create a wallet_snap key if we already don't have one
if (!hasProperty(updatedPermissions, 'wallet_snap')) {
updatedPermissions.wallet_snap = {
caveats: [{ type: 'snapIds', value: {} }],
invoker: subjectName,
parentCapability: 'wallet_snap',
};
}
// Check if the existing permission is valid
if (!isObject(updatedPermissions.wallet_snap)) {
return state;
}
if (
!isArray(
(updatedPermissions.wallet_snap as Record<string, unknown>).caveats,
)
) {
return state;
}
// Adding the snap name to the wallet_snap permission's caveat value
const snapId = permissionName.slice(snapPrefix.length);
const caveat = (
(updatedPermissions.wallet_snap as Record<string, any>)
.caveats as unknown[]
)[0];
if (!isObject(caveat)) {
return state;
}
if (
!hasProperty(caveat, 'type') ||
caveat.type !== 'snapIds' ||
!hasProperty(caveat, 'value') ||
!isObject(caveat.value)
) {
return state;
}
caveat.value[snapId] = {};
if (
typeof permission.date !== 'number' ||
typeof permission.id !== 'string'
) {
return state;
}
// updating the date & id as we iterate through all permissions
if (permission.date > date) {
date = permission.date;
id = permission.id;
}
// finally deleting the stale permission
delete updatedPermissions[permissionName];
}
}
// we reassign the date and id here after iterating through all permissions
// and update the subject with the updated permissions
if (updatedPermissions.wallet_snap) {
(updatedPermissions.wallet_snap as Record<string, unknown>).date = date;
(updatedPermissions.wallet_snap as Record<string, unknown>).id = id;
subject.permissions = updatedPermissions;
}
}
return state;
}

View File

@ -84,6 +84,7 @@ import m077 from './077';
import * as m078 from './078';
import m079 from './079';
import m080 from './080';
import * as m081 from './081';
const migrations = [
m002,
@ -165,6 +166,7 @@ const migrations = [
m078,
m079,
m080,
m081,
];
export default migrations;

View File

@ -1298,7 +1298,7 @@
"@metamask/permission-controller": {
"packages": {
"@metamask/base-controller": true,
"@metamask/controller-utils": true,
"@metamask/permission-controller>@metamask/controller-utils": true,
"@metamask/permission-controller>nanoid": true,
"deep-freeze-strict": true,
"eth-rpc-errors": true,
@ -1306,6 +1306,21 @@
"json-rpc-engine": true
}
},
"@metamask/permission-controller>@metamask/controller-utils": {
"globals": {
"console.error": true,
"fetch": true,
"setTimeout": true
},
"packages": {
"@metamask/controller-utils>isomorphic-fetch": true,
"browserify>buffer": true,
"eslint>fast-deep-equal": true,
"eth-ens-namehash": true,
"ethereumjs-util": true,
"ethjs>ethjs-unit": true
}
},
"@metamask/permission-controller>nanoid": {
"globals": {
"crypto.getRandomValues": true
@ -1347,7 +1362,8 @@
"packages": {
"@metamask/key-tree": true,
"@metamask/key-tree>@noble/hashes": true,
"@metamask/utils": true
"@metamask/utils": true,
"@metamask/utils>superstruct": true
}
},
"@metamask/rpc-methods>@metamask/browser-passworder": {

View File

@ -1364,7 +1364,7 @@
"@metamask/permission-controller": {
"packages": {
"@metamask/base-controller": true,
"@metamask/controller-utils": true,
"@metamask/permission-controller>@metamask/controller-utils": true,
"@metamask/permission-controller>nanoid": true,
"deep-freeze-strict": true,
"eth-rpc-errors": true,
@ -1372,6 +1372,21 @@
"json-rpc-engine": true
}
},
"@metamask/permission-controller>@metamask/controller-utils": {
"globals": {
"console.error": true,
"fetch": true,
"setTimeout": true
},
"packages": {
"@metamask/controller-utils>isomorphic-fetch": true,
"browserify>buffer": true,
"eslint>fast-deep-equal": true,
"eth-ens-namehash": true,
"ethereumjs-util": true,
"ethjs>ethjs-unit": true
}
},
"@metamask/permission-controller>nanoid": {
"globals": {
"crypto.getRandomValues": true
@ -1480,14 +1495,11 @@
}
},
"@metamask/rpc-methods": {
"globals": {
"console.warn": true
},
"packages": {
"@metamask/key-tree": true,
"@metamask/key-tree>@noble/hashes": true,
"@metamask/permission-controller": true,
"@metamask/rpc-methods>@metamask/browser-passworder": true,
"@metamask/rpc-methods>@metamask/permission-controller": true,
"@metamask/rpc-methods>nanoid": true,
"@metamask/snaps-ui": true,
"@metamask/snaps-utils": true,
@ -1510,6 +1522,36 @@
"browserify>buffer": true
}
},
"@metamask/rpc-methods>@metamask/permission-controller": {
"packages": {
"@metamask/rpc-methods>@metamask/permission-controller>@metamask/base-controller": true,
"@metamask/rpc-methods>@metamask/permission-controller>@metamask/controller-utils": true,
"@metamask/rpc-methods>nanoid": true,
"deep-freeze-strict": true,
"eth-rpc-errors": true,
"immer": true,
"json-rpc-engine": true
}
},
"@metamask/rpc-methods>@metamask/permission-controller>@metamask/base-controller": {
"packages": {
"immer": true
}
},
"@metamask/rpc-methods>@metamask/permission-controller>@metamask/controller-utils": {
"globals": {
"console.error": true,
"fetch": true,
"setTimeout": true
},
"packages": {
"browserify>buffer": true,
"eslint>fast-deep-equal": true,
"eth-ens-namehash": true,
"ethereumjs-util": true,
"ethjs>ethjs-unit": true
}
},
"@metamask/rpc-methods>nanoid": {
"globals": {
"crypto.getRandomValues": true
@ -1562,20 +1604,17 @@
"chrome.offscreen.createDocument": true,
"chrome.offscreen.hasDocument": true,
"clearTimeout": true,
"console.error": true,
"console.info": true,
"console.log": true,
"console.warn": true,
"document.getElementById": true,
"fetch.bind": true,
"setTimeout": true
},
"packages": {
"@metamask/base-controller": true,
"@metamask/permission-controller": true,
"@metamask/post-message-stream": true,
"@metamask/providers>@metamask/object-multiplex": true,
"@metamask/rpc-methods": true,
"@metamask/snaps-controllers>@metamask/base-controller": true,
"@metamask/snaps-controllers>@metamask/permission-controller": true,
"@metamask/snaps-controllers>@metamask/subject-metadata-controller": true,
"@metamask/snaps-controllers>@xstate/fsm": true,
"@metamask/snaps-controllers>concat-stream": true,
"@metamask/snaps-controllers>gunzip-maybe": true,
@ -1583,7 +1622,6 @@
"@metamask/snaps-controllers>readable-web-to-node-stream": true,
"@metamask/snaps-controllers>tar-stream": true,
"@metamask/snaps-utils": true,
"@metamask/subject-metadata-controller": true,
"@metamask/utils": true,
"eth-rpc-errors": true,
"json-rpc-engine": true,
@ -1591,6 +1629,41 @@
"pump": true
}
},
"@metamask/snaps-controllers>@metamask/base-controller": {
"packages": {
"immer": true
}
},
"@metamask/snaps-controllers>@metamask/base-controller>@metamask/controller-utils": {
"globals": {
"console.error": true,
"fetch": true,
"setTimeout": true
},
"packages": {
"browserify>buffer": true,
"eslint>fast-deep-equal": true,
"eth-ens-namehash": true,
"ethereumjs-util": true,
"ethjs>ethjs-unit": true
}
},
"@metamask/snaps-controllers>@metamask/permission-controller": {
"packages": {
"@metamask/snaps-controllers>@metamask/base-controller": true,
"@metamask/snaps-controllers>@metamask/base-controller>@metamask/controller-utils": true,
"@metamask/snaps-controllers>nanoid": true,
"deep-freeze-strict": true,
"eth-rpc-errors": true,
"immer": true,
"json-rpc-engine": true
}
},
"@metamask/snaps-controllers>@metamask/subject-metadata-controller": {
"packages": {
"@metamask/snaps-controllers>@metamask/base-controller": true
}
},
"@metamask/snaps-controllers>concat-stream": {
"packages": {
"@metamask/snaps-controllers>concat-stream>readable-stream": true,
@ -1747,6 +1820,9 @@
"globals": {
"TextDecoder": true,
"URL": true,
"console.error": true,
"console.log": true,
"console.warn": true,
"document.body.appendChild": true,
"document.createElement": true
},
@ -1754,6 +1830,7 @@
"@metamask/key-tree>@noble/hashes": true,
"@metamask/key-tree>@scure/base": true,
"@metamask/snaps-utils>cron-parser": true,
"@metamask/snaps-utils>fast-json-stable-stringify": true,
"@metamask/snaps-utils>rfdc": true,
"@metamask/snaps-utils>validate-npm-package-name": true,
"@metamask/utils": true,

View File

@ -1364,7 +1364,7 @@
"@metamask/permission-controller": {
"packages": {
"@metamask/base-controller": true,
"@metamask/controller-utils": true,
"@metamask/permission-controller>@metamask/controller-utils": true,
"@metamask/permission-controller>nanoid": true,
"deep-freeze-strict": true,
"eth-rpc-errors": true,
@ -1372,6 +1372,21 @@
"json-rpc-engine": true
}
},
"@metamask/permission-controller>@metamask/controller-utils": {
"globals": {
"console.error": true,
"fetch": true,
"setTimeout": true
},
"packages": {
"@metamask/controller-utils>isomorphic-fetch": true,
"browserify>buffer": true,
"eslint>fast-deep-equal": true,
"eth-ens-namehash": true,
"ethereumjs-util": true,
"ethjs>ethjs-unit": true
}
},
"@metamask/permission-controller>nanoid": {
"globals": {
"crypto.getRandomValues": true
@ -1480,14 +1495,11 @@
}
},
"@metamask/rpc-methods": {
"globals": {
"console.warn": true
},
"packages": {
"@metamask/key-tree": true,
"@metamask/key-tree>@noble/hashes": true,
"@metamask/permission-controller": true,
"@metamask/rpc-methods>@metamask/browser-passworder": true,
"@metamask/rpc-methods>@metamask/permission-controller": true,
"@metamask/rpc-methods>nanoid": true,
"@metamask/snaps-ui": true,
"@metamask/snaps-utils": true,
@ -1510,6 +1522,36 @@
"browserify>buffer": true
}
},
"@metamask/rpc-methods>@metamask/permission-controller": {
"packages": {
"@metamask/rpc-methods>@metamask/permission-controller>@metamask/base-controller": true,
"@metamask/rpc-methods>@metamask/permission-controller>@metamask/controller-utils": true,
"@metamask/rpc-methods>nanoid": true,
"deep-freeze-strict": true,
"eth-rpc-errors": true,
"immer": true,
"json-rpc-engine": true
}
},
"@metamask/rpc-methods>@metamask/permission-controller>@metamask/base-controller": {
"packages": {
"immer": true
}
},
"@metamask/rpc-methods>@metamask/permission-controller>@metamask/controller-utils": {
"globals": {
"console.error": true,
"fetch": true,
"setTimeout": true
},
"packages": {
"browserify>buffer": true,
"eslint>fast-deep-equal": true,
"eth-ens-namehash": true,
"ethereumjs-util": true,
"ethjs>ethjs-unit": true
}
},
"@metamask/rpc-methods>nanoid": {
"globals": {
"crypto.getRandomValues": true
@ -1562,20 +1604,17 @@
"chrome.offscreen.createDocument": true,
"chrome.offscreen.hasDocument": true,
"clearTimeout": true,
"console.error": true,
"console.info": true,
"console.log": true,
"console.warn": true,
"document.getElementById": true,
"fetch.bind": true,
"setTimeout": true
},
"packages": {
"@metamask/base-controller": true,
"@metamask/permission-controller": true,
"@metamask/post-message-stream": true,
"@metamask/providers>@metamask/object-multiplex": true,
"@metamask/rpc-methods": true,
"@metamask/snaps-controllers>@metamask/base-controller": true,
"@metamask/snaps-controllers>@metamask/permission-controller": true,
"@metamask/snaps-controllers>@metamask/subject-metadata-controller": true,
"@metamask/snaps-controllers>@xstate/fsm": true,
"@metamask/snaps-controllers>concat-stream": true,
"@metamask/snaps-controllers>gunzip-maybe": true,
@ -1583,7 +1622,6 @@
"@metamask/snaps-controllers>readable-web-to-node-stream": true,
"@metamask/snaps-controllers>tar-stream": true,
"@metamask/snaps-utils": true,
"@metamask/subject-metadata-controller": true,
"@metamask/utils": true,
"eth-rpc-errors": true,
"json-rpc-engine": true,
@ -1591,6 +1629,41 @@
"pump": true
}
},
"@metamask/snaps-controllers>@metamask/base-controller": {
"packages": {
"immer": true
}
},
"@metamask/snaps-controllers>@metamask/base-controller>@metamask/controller-utils": {
"globals": {
"console.error": true,
"fetch": true,
"setTimeout": true
},
"packages": {
"browserify>buffer": true,
"eslint>fast-deep-equal": true,
"eth-ens-namehash": true,
"ethereumjs-util": true,
"ethjs>ethjs-unit": true
}
},
"@metamask/snaps-controllers>@metamask/permission-controller": {
"packages": {
"@metamask/snaps-controllers>@metamask/base-controller": true,
"@metamask/snaps-controllers>@metamask/base-controller>@metamask/controller-utils": true,
"@metamask/snaps-controllers>nanoid": true,
"deep-freeze-strict": true,
"eth-rpc-errors": true,
"immer": true,
"json-rpc-engine": true
}
},
"@metamask/snaps-controllers>@metamask/subject-metadata-controller": {
"packages": {
"@metamask/snaps-controllers>@metamask/base-controller": true
}
},
"@metamask/snaps-controllers>concat-stream": {
"packages": {
"@metamask/snaps-controllers>concat-stream>readable-stream": true,
@ -1747,6 +1820,9 @@
"globals": {
"TextDecoder": true,
"URL": true,
"console.error": true,
"console.log": true,
"console.warn": true,
"document.body.appendChild": true,
"document.createElement": true
},
@ -1754,6 +1830,7 @@
"@metamask/key-tree>@noble/hashes": true,
"@metamask/key-tree>@scure/base": true,
"@metamask/snaps-utils>cron-parser": true,
"@metamask/snaps-utils>fast-json-stable-stringify": true,
"@metamask/snaps-utils>rfdc": true,
"@metamask/snaps-utils>validate-npm-package-name": true,
"@metamask/utils": true,

View File

@ -1298,7 +1298,7 @@
"@metamask/permission-controller": {
"packages": {
"@metamask/base-controller": true,
"@metamask/controller-utils": true,
"@metamask/permission-controller>@metamask/controller-utils": true,
"@metamask/permission-controller>nanoid": true,
"deep-freeze-strict": true,
"eth-rpc-errors": true,
@ -1306,6 +1306,21 @@
"json-rpc-engine": true
}
},
"@metamask/permission-controller>@metamask/controller-utils": {
"globals": {
"console.error": true,
"fetch": true,
"setTimeout": true
},
"packages": {
"@metamask/controller-utils>isomorphic-fetch": true,
"browserify>buffer": true,
"eslint>fast-deep-equal": true,
"eth-ens-namehash": true,
"ethereumjs-util": true,
"ethjs>ethjs-unit": true
}
},
"@metamask/permission-controller>nanoid": {
"globals": {
"crypto.getRandomValues": true
@ -1347,7 +1362,8 @@
"packages": {
"@metamask/key-tree": true,
"@metamask/key-tree>@noble/hashes": true,
"@metamask/utils": true
"@metamask/utils": true,
"@metamask/utils>superstruct": true
}
},
"@metamask/rpc-methods>@metamask/browser-passworder": {

View File

@ -2891,7 +2891,7 @@
"console": true
},
"packages": {
"eslint>ajv>fast-json-stable-stringify": true,
"@metamask/snaps-utils>fast-json-stable-stringify": true,
"eslint>ajv>json-schema-traverse": true,
"eslint>ajv>uri-js": true,
"eslint>fast-deep-equal": true

View File

@ -245,18 +245,18 @@
"@metamask/metamask-eth-abis": "^3.0.0",
"@metamask/notification-controller": "^1.0.0",
"@metamask/obs-store": "^5.0.0",
"@metamask/permission-controller": "^1.0.0",
"@metamask/permission-controller": "^2.0.0",
"@metamask/phishing-controller": "^2.0.0",
"@metamask/post-message-stream": "^6.0.0",
"@metamask/providers": "^10.2.1",
"@metamask/rate-limit-controller": "^1.0.0",
"@metamask/rpc-methods": "^0.28.0",
"@metamask/rpc-methods": "^0.30.0",
"@metamask/scure-bip39": "^2.0.3",
"@metamask/slip44": "^2.1.0",
"@metamask/smart-transactions-controller": "^3.1.0",
"@metamask/snaps-controllers": "^0.28.0",
"@metamask/snaps-ui": "^0.28.0",
"@metamask/snaps-utils": "^0.28.0",
"@metamask/snaps-controllers": "^0.30.0",
"@metamask/snaps-ui": "^0.30.0",
"@metamask/snaps-utils": "^0.30.0",
"@metamask/subject-metadata-controller": "^1.0.0",
"@metamask/utils": "^3.6.0",
"@ngraveio/bc-ur": "^1.1.6",

View File

@ -5,7 +5,6 @@ export const CaveatTypes = Object.freeze({
export const RestrictedMethods = Object.freeze({
eth_accounts: 'eth_accounts',
///: BEGIN:ONLY_INCLUDE_IN(flask)
snap_confirm: 'snap_confirm',
snap_dialog: 'snap_dialog',
snap_notify: 'snap_notify',
snap_manageState: 'snap_manageState',
@ -13,7 +12,7 @@ export const RestrictedMethods = Object.freeze({
snap_getBip32Entropy: 'snap_getBip32Entropy',
snap_getBip44Entropy: 'snap_getBip44Entropy',
snap_getEntropy: 'snap_getEntropy',
'wallet_snap_*': 'wallet_snap_*',
wallet_snap: 'wallet_snap',
///: END:ONLY_INCLUDE_IN
} as const);
@ -23,10 +22,6 @@ export const RestrictedMethods = Object.freeze({
* This is a fix for https://github.com/MetaMask/snaps-monorepo/issues/1103 and https://github.com/MetaMask/snaps-monorepo/issues/990.
* TODO: Disable endowment:long-running and eth_account in stable.
*/
export const PermissionNamespaces = Object.freeze({
wallet_snap_: 'wallet_snap_*',
} as const);
export const EndowmentPermissions = Object.freeze({
'endowment:network-access': 'endowment:network-access',
'endowment:transaction-insight': 'endowment:transaction-insight',
@ -34,6 +29,7 @@ export const EndowmentPermissions = Object.freeze({
'endowment:ethereum-provider': 'endowment:ethereum-provider',
'endowment:rpc': 'endowment:rpc',
'endowment:long-running': 'endowment:long-running',
'endowment:webassembly': 'endowment:webassembly',
} as const);
// Methods / permissions in external packages that we are temporarily excluding.

View File

@ -1,3 +1,7 @@
const {
WALLET_SNAP_PERMISSION_KEY,
SnapCaveatType,
} = require('@metamask/snaps-utils');
const { merge } = require('lodash');
const { CHAIN_IDS } = require('../../shared/constants/network');
@ -529,48 +533,22 @@ class FixtureBuilder {
'https://metamask.github.io': {
origin: 'https://metamask.github.io',
permissions: {
'wallet_snap_npm:@metamask/test-snap-bip32': {
[WALLET_SNAP_PERMISSION_KEY]: {
caveats: [
{
type: SnapCaveatType.SnapIds,
value: {
'npm@metamask/test-snap-bip32': {},
'npm@metamask/test-snap-bip44': {},
'npm@metamask/test-snap-error': {},
'npm@metamask/test-snap-managestate': {},
'npm@metamask/test-snap-notification': {},
},
},
],
id: 'CwdJq0x8N_b9FNxn6dVuP',
parentCapability: 'wallet_snap_npm:@metamask/test-snap-bip32',
parentCapability: WALLET_SNAP_PERMISSION_KEY,
invoker: 'https://metamask.github.io',
caveats: null,
date: 1664388714636,
},
'wallet_snap_npm:@metamask/test-snap-bip44': {
id: '8zH-0opWuZhvJew41FMVh',
parentCapability: 'wallet_snap_npm:@metamask/test-snap-bip44',
invoker: 'https://metamask.github.io',
caveats: null,
date: 1664388714636,
},
'wallet_snap_npm:@metamask/test-snap-confirm': {
id: 'Wb_1c9toBggBQWfOJwjMg',
parentCapability: 'wallet_snap_npm:@metamask/test-snap-confirm',
invoker: 'https://metamask.github.io',
caveats: null,
date: 1664388714636,
},
'wallet_snap_npm:@metamask/test-snap-error': {
id: '5FUZoCyimOWKTbuLCEOWa',
parentCapability: 'wallet_snap_npm:@metamask/test-snap-error',
invoker: 'https://metamask.github.io',
caveats: null,
date: 1664388714636,
},
'wallet_snap_npm:@metamask/test-snap-managestate': {
id: 'Z6XPdyuCHCf1pyqSiU7nh',
parentCapability:
'wallet_snap_npm:@metamask/test-snap-managestate',
invoker: 'https://metamask.github.io',
caveats: null,
date: 1664388714636,
},
'wallet_snap_npm:@metamask/test-snap-notification': {
id: '_xfRMXzq0bs8QcXRcvjcP',
parentCapability:
'wallet_snap_npm:@metamask/test-snap-notification',
invoker: 'https://metamask.github.io',
caveats: null,
date: 1664388714636,
},
},

View File

@ -1,3 +1,3 @@
module.exports = {
TEST_SNAPS_WEBSITE_URL: 'https://metamask.github.io/test-snaps/4.6.2/',
TEST_SNAPS_WEBSITE_URL: 'https://metamask.github.io/test-snaps/5.0.3/',
};

View File

@ -1,100 +0,0 @@
const { strict: assert } = require('assert');
const { withFixtures } = require('../helpers');
const FixtureBuilder = require('../fixture-builder');
const { TEST_SNAPS_WEBSITE_URL } = require('./enums');
describe('Test Snap Confirm', function () {
it('can pop up a snap confirm and get its result', async function () {
const ganacheOptions = {
accounts: [
{
secretKey:
'0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC',
balance: 25000000000000000000,
},
],
};
await withFixtures(
{
fixtures: new FixtureBuilder().build(),
ganacheOptions,
failOnConsoleError: false,
title: this.test.title,
},
async ({ driver }) => {
await driver.navigate();
// enter pw into extension
await driver.fill('#password', 'correct horse battery staple');
await driver.press('#password', driver.Key.ENTER);
// navigate to test snaps page and connect
await driver.driver.get(TEST_SNAPS_WEBSITE_URL);
await driver.delay(1000);
const snapButton1 = await driver.findElement('#connectConfirmSnap');
await driver.scrollToElement(snapButton1);
await driver.delay(1000);
await driver.clickElement('#connectConfirmSnap');
await driver.delay(1000);
// switch to metamask extension and click connect
let windowHandles = await driver.waitUntilXWindowHandles(
2,
1000,
10000,
);
await driver.switchToWindowWithTitle(
'MetaMask Notification',
windowHandles,
);
await driver.clickElement({
text: 'Connect',
tag: 'button',
});
await driver.delay(2000);
// approve install of snap
windowHandles = await driver.waitUntilXWindowHandles(2, 1000, 10000);
await driver.switchToWindowWithTitle(
'MetaMask Notification',
windowHandles,
);
await driver.clickElement({
text: 'Approve & install',
tag: 'button',
});
// delay for npm installation
await driver.delay(2000);
// switch back to test snaps page
windowHandles = await driver.waitUntilXWindowHandles(1, 1000, 10000);
await driver.switchToWindowWithTitle('Test Snaps', windowHandles);
// click send inputs on test snap page
const snapButton2 = await driver.findElement('#sendConfirmButton');
await driver.scrollToElement(snapButton2);
await driver.delay(1000);
await driver.clickElement('#sendConfirmButton');
// hit 'approve' on the custom confirm
windowHandles = await driver.waitUntilXWindowHandles(2, 1000, 10000);
await driver.switchToWindowWithTitle(
'MetaMask Notification',
windowHandles,
);
await driver.clickElement({
text: 'Approve',
tag: 'button',
});
// check the results of the custom confirm
windowHandles = await driver.waitUntilXWindowHandles(1, 1000, 10000);
await driver.switchToWindowWithTitle('Test Snaps', windowHandles);
const confirmResult = await driver.findElement('#confirmResult');
assert.equal(await confirmResult.getText(), 'true');
},
);
});
});

View File

@ -4,9 +4,7 @@ const FixtureBuilder = require('../fixture-builder');
const { TEST_SNAPS_WEBSITE_URL } = require('./enums');
describe('Test Snap RPC', function () {
// TODO: Re-enable this test once `test-snaps` is fixed.
// eslint-disable-next-line mocha/no-skipped-tests
it.skip('can use the cross-snap RPC endowment and produce a public key', async function () {
it('can use the cross-snap RPC endowment and produce a public key', async function () {
const ganacheOptions = {
accounts: [
{

View File

@ -115,7 +115,7 @@ describe('Test Snap update', function () {
// look for the correct version text
const versionResult = await driver.findElement('#updateSnapVersion');
await driver.delay(1000);
assert.equal(await versionResult.getText(), '"4.0.2"');
assert.equal(await versionResult.getText(), '"5.0.1"');
},
);
});

View File

@ -1,9 +1,19 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { isEqual } from 'lodash';
///: BEGIN:ONLY_INCLUDE_IN(flask)
import { isObject } from '@metamask/utils';
import {
SnapCaveatType,
WALLET_SNAP_PERMISSION_KEY,
} from '@metamask/rpc-methods';
///: END:ONLY_INCLUDE_IN
import { EVENT } from '../../../../shared/constants/metametrics';
import { PageContainerFooter } from '../../ui/page-container';
import PermissionsConnectFooter from '../permissions-connect-footer';
///: BEGIN:ONLY_INCLUDE_IN(flask)
import { RestrictedMethods } from '../../../../shared/constants/permissions';
///: END:ONLY_INCLUDE_IN
import { PermissionPageContainerContent } from '.';
export default class PermissionPageContainer extends Component {
@ -12,6 +22,9 @@ export default class PermissionPageContainer extends Component {
rejectPermissionsRequest: PropTypes.func.isRequired,
selectedIdentities: PropTypes.array,
allIdentitiesSelected: PropTypes.bool,
///: BEGIN:ONLY_INCLUDE_IN(flask)
currentPermissions: PropTypes.object,
///: END:ONLY_INCLUDE_IN
request: PropTypes.object,
requestMetadata: PropTypes.object,
targetSubjectMetadata: PropTypes.shape({
@ -28,6 +41,9 @@ export default class PermissionPageContainer extends Component {
requestMetadata: {},
selectedIdentities: [],
allIdentitiesSelected: false,
///: BEGIN:ONLY_INCLUDE_IN(flask)
currentPermissions: {},
///: END:ONLY_INCLUDE_IN
};
static contextTypes = {
@ -54,11 +70,46 @@ export default class PermissionPageContainer extends Component {
getRequestedMethodState(methodNames) {
return methodNames.reduce((acc, methodName) => {
///: BEGIN:ONLY_INCLUDE_IN(flask)
if (methodName === RestrictedMethods.wallet_snap) {
acc[methodName] = this.getDedupedSnapPermissions();
return acc;
}
///: END:ONLY_INCLUDE_IN
acc[methodName] = true;
return acc;
}, {});
}
///: BEGIN:ONLY_INCLUDE_IN(flask)
getDedupedSnapPermissions() {
const permission =
this.props.request.permissions[WALLET_SNAP_PERMISSION_KEY];
const requestedSnaps = permission?.caveats[0].value;
const currentSnaps =
this.props.currentPermissions[WALLET_SNAP_PERMISSION_KEY]?.caveats[0]
.value;
if (!isObject(currentSnaps)) {
return permission;
}
const requestedSnapKeys = requestedSnaps ? Object.keys(requestedSnaps) : [];
const currentSnapKeys = currentSnaps ? Object.keys(currentSnaps) : [];
const dedupedCaveats = requestedSnapKeys.reduce((acc, snapId) => {
if (!currentSnapKeys.includes(snapId)) {
acc[snapId] = {};
}
return acc;
}, {});
return {
...permission,
caveats: [{ type: SnapCaveatType.SnapIds, value: dedupedCaveats }],
};
}
///: END:ONLY_INCLUDE_IN
getRequestedMethodNames(props) {
return Object.keys(props.request.permissions || {});
}

View File

@ -1,10 +1,20 @@
import { connect } from 'react-redux';
import { getMetaMaskIdentities } from '../../../selectors';
import {
getMetaMaskIdentities,
///: BEGIN:ONLY_INCLUDE_IN(flask)
getPermissions,
///: END:ONLY_INCLUDE_IN
} from '../../../selectors';
import PermissionPageContainer from './permission-page-container.component';
const mapStateToProps = (state, ownProps) => {
const { selectedIdentities } = ownProps;
///: BEGIN:ONLY_INCLUDE_IN(flask)
const currentPermissions = getPermissions(
state,
ownProps.request.metadata?.origin,
);
///: END:ONLY_INCLUDE_IN
const allIdentities = getMetaMaskIdentities(state);
const allIdentitiesSelected =
Object.keys(selectedIdentities).length ===
@ -12,6 +22,9 @@ const mapStateToProps = (state, ownProps) => {
return {
allIdentitiesSelected,
///: BEGIN:ONLY_INCLUDE_IN(flask)
currentPermissions,
///: END:ONLY_INCLUDE_IN
};
};

View File

@ -10,7 +10,6 @@ import {
RestrictedMethods,
///: BEGIN:ONLY_INCLUDE_IN(flask)
EndowmentPermissions,
PermissionNamespaces,
///: END:ONLY_INCLUDE_IN
} from '../../../shared/constants/permissions';
///: BEGIN:ONLY_INCLUDE_IN(flask)
@ -142,15 +141,14 @@ const PERMISSION_DESCRIPTIONS = deepFreeze({
rightIcon: null,
weight: 3,
}),
[RestrictedMethods['wallet_snap_*']]: (t, permissionName) => {
[RestrictedMethods.wallet_snap]: (t, _, permissionValue) => {
const snaps = permissionValue.caveats[0].value;
const baseDescription = {
leftIcon: 'fas fa-bolt',
rightIcon: null,
};
const snapId = permissionName.split('_').slice(-1);
return Object.keys(snaps).map((snapId) => {
const friendlyName = SNAPS_METADATA[snapId]?.name;
if (friendlyName) {
return {
...baseDescription,
@ -161,11 +159,11 @@ const PERMISSION_DESCRIPTIONS = deepFreeze({
]),
};
}
return {
...baseDescription,
label: t('permission_accessSnap', [snapId]),
};
});
},
[EndowmentPermissions['endowment:network-access']]: (t) => ({
label: t('permission_accessNetwork'),
@ -276,13 +274,6 @@ export const getPermissionDescription = (
if (Object.hasOwnProperty.call(PERMISSION_DESCRIPTIONS, permissionName)) {
value = PERMISSION_DESCRIPTIONS[permissionName];
}
///: BEGIN:ONLY_INCLUDE_IN(flask)
for (const namespace of Object.keys(PermissionNamespaces)) {
if (permissionName.startsWith(namespace)) {
value = PERMISSION_DESCRIPTIONS[PermissionNamespaces[namespace]];
}
}
///: END:ONLY_INCLUDE_IN
const result = value(t, permissionName, permissionValue);
if (!Array.isArray(result)) {

View File

@ -1,6 +1,10 @@
import React, { useEffect, useState } from 'react';
import { useHistory, useLocation } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import {
SnapCaveatType,
WALLET_SNAP_PERMISSION_KEY,
} from '@metamask/rpc-methods';
import Button from '../../../../components/ui/button';
import Typography from '../../../../components/ui/typography';
import { useI18nContext } from '../../../../hooks/useI18nContext';
@ -23,11 +27,13 @@ import {
enableSnap,
removeSnap,
removePermissionsFor,
updateCaveat,
} from '../../../../store/actions';
import {
getSnaps,
getSubjectsWithPermission,
getSubjectsWithSnapPermission,
getPermissions,
getPermissionSubjects,
} from '../../../../selectors';
import { formatDate } from '../../../../helpers/utils/util';
@ -52,19 +58,14 @@ function ViewSnap() {
}, [history, snap]);
const connectedSubjects = useSelector((state) =>
getSubjectsWithPermission(state, snap?.permissionName),
getSubjectsWithSnapPermission(state, snap?.id),
);
const permissions = useSelector(
(state) => snap && getPermissions(state, snap.id),
);
const subjects = useSelector((state) => getPermissionSubjects(state));
const dispatch = useDispatch();
const onDisconnect = (connectedOrigin, snapPermissionName) => {
dispatch(
removePermissionsFor({
[connectedOrigin]: [snapPermissionName],
}),
);
};
const onToggle = () => {
if (snap.enabled) {
dispatch(disableSnap(snap.id));
@ -73,6 +74,30 @@ function ViewSnap() {
}
};
const onDisconnect = (connectedOrigin, snapId) => {
const caveatValue =
subjects[connectedOrigin].permissions[WALLET_SNAP_PERMISSION_KEY]
.caveats[0].value;
const newCaveatValue = { ...caveatValue };
delete newCaveatValue[snapId];
if (Object.keys(newCaveatValue) > 0) {
dispatch(
updateCaveat(
connectedOrigin,
WALLET_SNAP_PERMISSION_KEY,
SnapCaveatType.SnapIds,
newCaveatValue,
),
);
} else {
dispatch(
removePermissionsFor({
[connectedOrigin]: [WALLET_SNAP_PERMISSION_KEY],
}),
);
}
};
if (!snap) {
return null;
}
@ -171,7 +196,7 @@ function ViewSnap() {
<ConnectedSitesList
connectedSubjects={connectedSubjects}
onDisconnect={(origin) => {
onDisconnect(origin, snap.permissionName);
onDisconnect(origin, snap.id);
}}
/>
</Box>

View File

@ -1,3 +1,6 @@
///: BEGIN:ONLY_INCLUDE_IN(flask)
import { WALLET_SNAP_PERMISSION_KEY } from '@metamask/rpc-methods';
///: END:ONLY_INCLUDE_IN
import { CaveatTypes } from '../../shared/constants/permissions';
import {
getMetaMaskAccountsOrdered,
@ -118,6 +121,28 @@ export function getSubjectsWithPermission(state, permissionName) {
return connectedSubjects;
}
///: BEGIN:ONLY_INCLUDE_IN(flask)
export function getSubjectsWithSnapPermission(state, snapId) {
const subjects = getPermissionSubjects(state);
return Object.entries(subjects)
.filter(
([_origin, { permissions }]) =>
permissions[WALLET_SNAP_PERMISSION_KEY]?.caveats[0].value[snapId],
)
.map(([origin, _subject]) => {
const { extensionId, name, iconUrl } =
getTargetSubjectMetadata(state, origin) || {};
return {
extensionId,
origin,
name,
iconUrl,
};
});
}
///: END:ONLY_INCLUDE_IN
/**
* Returns an object mapping addresses to objects mapping origins to connected
* subject info. Subject info objects have the following properties:

View File

@ -3692,6 +3692,35 @@ export function removePermissionsFor(
};
}
///: BEGIN:ONLY_INCLUDE_IN(flask)
/**
* Updates the caveat value for the specified origin, permission and caveat type.
*
* @param origin
* @param target
* @param caveatType
* @param caveatValue
*/
export function updateCaveat(
origin: string,
target: string,
caveatType: string,
caveatValue: Record<string, Json>,
): ThunkAction<void, MetaMaskReduxState, unknown, AnyAction> {
return (dispatch) => {
callBackgroundMethod(
'updateCaveat',
[origin, target, caveatType, caveatValue],
(err) => {
if (err) {
dispatch(displayWarning(err));
}
},
);
};
}
///: END:ONLY_INCLUDE_IN
// Pending Approvals
/**

195
yarn.lock
View File

@ -3539,16 +3539,29 @@ __metadata:
languageName: node
linkType: hard
"@metamask/approval-controller@npm:^1.0.0, @metamask/approval-controller@npm:^1.0.1":
version: 1.0.1
resolution: "@metamask/approval-controller@npm:1.0.1"
"@metamask/approval-controller@npm:^1.0.0, @metamask/approval-controller@npm:^1.0.1, @metamask/approval-controller@npm:^1.1.0":
version: 1.1.0
resolution: "@metamask/approval-controller@npm:1.1.0"
dependencies:
"@metamask/base-controller": ^1.1.1
"@metamask/controller-utils": ^1.0.0
"@metamask/base-controller": ^1.1.2
"@metamask/controller-utils": ^2.0.0
eth-rpc-errors: ^4.0.0
immer: ^9.0.6
nanoid: ^3.1.31
checksum: 83b54946b948b0f97a5453328421666c8852b975bf045f6b23416579f1201feb390dc09941620fa4e480f76cd9a7b4f6e8f2c3e940ddd79f62491a81befe8c7c
checksum: 96a354ccd4765eb997f35ccbc86114c40e6da839e83b89bf64eedc986d74f28898c204eae5037978497f823fabc2a675c9c19c1ccae6535f70eb7ab0a72cbfc4
languageName: node
linkType: hard
"@metamask/approval-controller@npm:^2.0.0":
version: 2.0.0
resolution: "@metamask/approval-controller@npm:2.0.0"
dependencies:
"@metamask/base-controller": ^2.0.0
"@metamask/controller-utils": ^3.0.0
eth-rpc-errors: ^4.0.0
immer: ^9.0.6
nanoid: ^3.1.31
checksum: 1db5f9c21b04fa4688c17cdfb7da0a14b3fee084fbd8c0cfdcc41572e54140ce093c24b811b85e8ee9d3ccd8987db04d9150d7c6d5ab21daf72b4364a05f3428
languageName: node
linkType: hard
@ -3608,6 +3621,16 @@ __metadata:
languageName: node
linkType: hard
"@metamask/base-controller@npm:^2.0.0":
version: 2.0.0
resolution: "@metamask/base-controller@npm:2.0.0"
dependencies:
"@metamask/controller-utils": ^3.0.0
immer: ^9.0.6
checksum: afd7df59cbcd26261e3d015ac0669261efbfad8e106b55ae7184f7445979b867f78f0d56fe103566150236093847b3acc68473f979e46bd9c67f654857995458
languageName: node
linkType: hard
"@metamask/base-controller@npm:~1.0.0":
version: 1.0.0
resolution: "@metamask/base-controller@npm:1.0.0"
@ -3660,6 +3683,19 @@ __metadata:
languageName: node
linkType: hard
"@metamask/controller-utils@npm:^3.0.0":
version: 3.0.0
resolution: "@metamask/controller-utils@npm:3.0.0"
dependencies:
eth-ens-namehash: ^2.0.8
eth-rpc-errors: ^4.0.0
ethereumjs-util: ^7.0.10
ethjs-unit: ^0.1.6
fast-deep-equal: ^3.1.3
checksum: 44227aa9f716f86373a1a4fb86b7ae1c51199dd819f30a3a310a9f87838b7e11c1a3bb024572253bd3cb0258281596cfab8fbf317c3fe90962fa6cf426aa6858
languageName: node
linkType: hard
"@metamask/design-tokens@npm:^1.6.0, @metamask/design-tokens@npm:^1.9.0":
version: 1.11.1
resolution: "@metamask/design-tokens@npm:1.11.1"
@ -3910,7 +3946,7 @@ __metadata:
languageName: node
linkType: hard
"@metamask/key-tree@npm:^6.2.0, @metamask/key-tree@npm:^6.2.1":
"@metamask/key-tree@npm:^6.2.1":
version: 6.2.1
resolution: "@metamask/key-tree@npm:6.2.1"
dependencies:
@ -4033,7 +4069,7 @@ __metadata:
languageName: node
linkType: hard
"@metamask/permission-controller@npm:^1.0.0, @metamask/permission-controller@npm:^1.0.1":
"@metamask/permission-controller@npm:^1.0.1":
version: 1.0.2
resolution: "@metamask/permission-controller@npm:1.0.2"
dependencies:
@ -4053,6 +4089,46 @@ __metadata:
languageName: node
linkType: hard
"@metamask/permission-controller@npm:^2.0.0":
version: 2.0.0
resolution: "@metamask/permission-controller@npm:2.0.0"
dependencies:
"@metamask/approval-controller": ^1.1.0
"@metamask/base-controller": ^1.1.2
"@metamask/controller-utils": ^2.0.0
"@metamask/types": ^1.1.0
"@types/deep-freeze-strict": ^1.1.0
deep-freeze-strict: ^1.1.1
eth-rpc-errors: ^4.0.0
immer: ^9.0.6
json-rpc-engine: ^6.1.0
nanoid: ^3.1.31
peerDependencies:
"@metamask/approval-controller": ^1.1.0
checksum: 152be8429ceebf7dfbd415ff12746ee9c0216fa4dfb90f825532fd216f6b2aa66061748fb0685ec23ad6bde21212c6ccd32a4219b803913d45b70f8ded45ac2e
languageName: node
linkType: hard
"@metamask/permission-controller@npm:^3.0.0":
version: 3.0.0
resolution: "@metamask/permission-controller@npm:3.0.0"
dependencies:
"@metamask/approval-controller": ^2.0.0
"@metamask/base-controller": ^2.0.0
"@metamask/controller-utils": ^3.0.0
"@metamask/types": ^1.1.0
"@types/deep-freeze-strict": ^1.1.0
deep-freeze-strict: ^1.1.1
eth-rpc-errors: ^4.0.0
immer: ^9.0.6
json-rpc-engine: ^6.1.0
nanoid: ^3.1.31
peerDependencies:
"@metamask/approval-controller": ^2.0.0
checksum: 67e104d21b3f0258863ecaabd11cb587f10dbcc91ff9b081d8b9569d163d6d54dd5b8fb267d5416ab8e41c8c48b5103e92e013fd1916d492b72706cda2474962
languageName: node
linkType: hard
"@metamask/phishing-controller@npm:^2.0.0":
version: 2.0.0
resolution: "@metamask/phishing-controller@npm:2.0.0"
@ -4135,22 +4211,22 @@ __metadata:
languageName: node
linkType: hard
"@metamask/rpc-methods@npm:^0.28.0":
version: 0.28.0
resolution: "@metamask/rpc-methods@npm:0.28.0"
"@metamask/rpc-methods@npm:^0.30.0":
version: 0.30.0
resolution: "@metamask/rpc-methods@npm:0.30.0"
dependencies:
"@metamask/browser-passworder": ^4.0.2
"@metamask/key-tree": ^6.2.0
"@metamask/permission-controller": ^1.0.1
"@metamask/snaps-ui": ^0.28.0
"@metamask/snaps-utils": ^0.28.0
"@metamask/key-tree": ^6.2.1
"@metamask/permission-controller": ^3.0.0
"@metamask/snaps-ui": ^0.30.0
"@metamask/snaps-utils": ^0.30.0
"@metamask/types": ^1.1.0
"@metamask/utils": ^3.4.1
"@noble/hashes": ^1.1.3
eth-rpc-errors: ^4.0.2
nanoid: ^3.1.31
superstruct: ^1.0.3
checksum: 4dcdd25a8462a3ba38898637d2f64250c7d173c601f22133332c41401c13cb465ead719f3233f9749a894857f2ffc329936d3b84221ff60355473b3e9c212598
checksum: ae584a2ea403653199c17e4fe43bdf26d25f2dbab8609e48f85d6a1def762526370e145cf69dc5649ee501f6e170ea27161b3d908c62ff1e9617af5e23564793
languageName: node
linkType: hard
@ -4197,20 +4273,20 @@ __metadata:
languageName: node
linkType: hard
"@metamask/snaps-controllers@npm:^0.28.0":
version: 0.28.0
resolution: "@metamask/snaps-controllers@npm:0.28.0"
"@metamask/snaps-controllers@npm:^0.30.0":
version: 0.30.0
resolution: "@metamask/snaps-controllers@npm:0.30.0"
dependencies:
"@metamask/approval-controller": ^1.0.1
"@metamask/base-controller": ^1.1.1
"@metamask/approval-controller": ^2.0.0
"@metamask/base-controller": ^2.0.0
"@metamask/object-multiplex": ^1.1.0
"@metamask/permission-controller": ^1.0.1
"@metamask/permission-controller": ^3.0.0
"@metamask/post-message-stream": ^6.1.0
"@metamask/rpc-methods": ^0.28.0
"@metamask/snaps-execution-environments": ^0.28.0
"@metamask/snaps-registry": ^1.0.0
"@metamask/snaps-utils": ^0.28.0
"@metamask/subject-metadata-controller": ^1.0.1
"@metamask/rpc-methods": ^0.30.0
"@metamask/snaps-execution-environments": ^0.30.0
"@metamask/snaps-registry": ^1.1.0
"@metamask/snaps-utils": ^0.30.0
"@metamask/subject-metadata-controller": ^2.0.0
"@metamask/utils": ^3.4.1
"@xstate/fsm": ^2.0.0
concat-stream: ^2.0.0
@ -4224,18 +4300,19 @@ __metadata:
pump: ^3.0.0
readable-web-to-node-stream: ^3.0.2
tar-stream: ^2.2.0
checksum: 27b641ed7998e1cc52be354aab19ce6034aa2ec1df3f5f14e07d144ce029472f8f89b8896c32a3124489283ed26666f84b67412cdd213445e80975e2a324f3a2
checksum: 022f875037fd058c237b8cba80e47a5ef222d379a073af4a35242e15c8c83ac902050ab8ae51a80536254b4ccb7e73b854c49b3ff5fac51154071da46d879e20
languageName: node
linkType: hard
"@metamask/snaps-execution-environments@npm:^0.28.0":
version: 0.28.0
resolution: "@metamask/snaps-execution-environments@npm:0.28.0"
"@metamask/snaps-execution-environments@npm:^0.30.0":
version: 0.30.0
resolution: "@metamask/snaps-execution-environments@npm:0.30.0"
dependencies:
"@metamask/object-multiplex": ^1.2.0
"@metamask/post-message-stream": ^6.1.0
"@metamask/providers": ^10.2.0
"@metamask/snaps-utils": ^0.28.0
"@metamask/rpc-methods": ^0.30.0
"@metamask/snaps-utils": ^0.30.0
"@metamask/utils": ^3.4.1
eth-rpc-errors: ^4.0.3
json-rpc-engine: ^6.1.0
@ -4243,55 +4320,57 @@ __metadata:
ses: ^0.18.1
stream-browserify: ^3.0.0
superstruct: ^1.0.3
checksum: db4d26728141d236d64720120fe57540ab13399c10fa7fdc697f888bf0f780f33f6c462409657b3a531a91cc0545fbf759b66d4fd1242955d75ddb331bcabad4
checksum: ee81caec7bf77703510983f62f3f2cf94753b624ba14691ff80ca30efab9a07ca329b278cd08323c72bcb3aeef7e78d089af4d35d14a469afc4f7bb8bc7e5fa7
languageName: node
linkType: hard
"@metamask/snaps-registry@npm:^1.0.0":
version: 1.0.0
resolution: "@metamask/snaps-registry@npm:1.0.0"
"@metamask/snaps-registry@npm:^1.0.0, @metamask/snaps-registry@npm:^1.1.0":
version: 1.1.0
resolution: "@metamask/snaps-registry@npm:1.1.0"
dependencies:
"@metamask/utils": ^3.4.0
superstruct: ^1.0.3
checksum: 6a127d4d2db30e6f3966f4f82f3810a22a79db62c84b5db2b95d189dd36fe59aa5de59f01203095c9f7f07a44c1bf049c0fc046931269327d0693d1274f8f154
checksum: a67a9e7a30a2f7bc55d130b278573aa2bf043ab5c5935704ab8166898dadf37557284412f9b653f9ed52059a557a51b8472aabbe6887a06922d5526ead12199b
languageName: node
linkType: hard
"@metamask/snaps-ui@npm:^0.28.0":
version: 0.28.0
resolution: "@metamask/snaps-ui@npm:0.28.0"
"@metamask/snaps-ui@npm:^0.30.0":
version: 0.30.0
resolution: "@metamask/snaps-ui@npm:0.30.0"
dependencies:
"@metamask/utils": ^3.4.1
superstruct: ^1.0.3
checksum: 19d28b279f1516ca90cc6d2ec45507b13186ab2cbfa554f72ae8e4c9e1437b773ac67fe38350bee78f47dd063b1cc3f04274e388d00b09e5e6c5938b273d6616
checksum: a4612e08e830542b094bf995023221a24dfa45861d3ca919c1c11ae1bd3d6933789d40c667780145bcd3ff3053d0593e654ae1812ea9f3c7cc973d500cfb0a96
languageName: node
linkType: hard
"@metamask/snaps-utils@npm:^0.28.0":
version: 0.28.0
resolution: "@metamask/snaps-utils@npm:0.28.0"
"@metamask/snaps-utils@npm:^0.30.0":
version: 0.30.0
resolution: "@metamask/snaps-utils@npm:0.30.0"
dependencies:
"@babel/core": ^7.18.6
"@babel/types": ^7.18.7
"@metamask/permission-controller": ^3.0.0
"@metamask/providers": ^10.2.1
"@metamask/snaps-registry": ^1.0.0
"@metamask/snaps-ui": ^0.28.0
"@metamask/snaps-ui": ^0.30.0
"@metamask/utils": ^3.4.1
"@noble/hashes": ^1.1.3
"@scure/base": ^1.1.1
cron-parser: ^4.5.0
eth-rpc-errors: ^4.0.3
fast-deep-equal: ^3.1.3
fast-json-stable-stringify: ^2.1.0
rfdc: ^1.3.0
semver: ^7.3.7
ses: ^0.18.1
superstruct: ^1.0.3
validate-npm-package-name: ^5.0.0
checksum: 6c9653a9df3c77f5f2c69231d7e148d70fa001e42522e2e8f470f0e6fa1417b178d1b86515a231488a509589f98944cdf82a5ddc5e228f752d9ef81def393bb3
checksum: 56334795dee7deeddd63badd35870ebb51ba5336071146bd6f48a9f7c1d703515241ac9371d7a4e054d77d7c6d06f34530e7b9439074339a46fea89920d32bce
languageName: node
linkType: hard
"@metamask/subject-metadata-controller@npm:^1.0.0, @metamask/subject-metadata-controller@npm:^1.0.1":
"@metamask/subject-metadata-controller@npm:^1.0.0":
version: 1.0.1
resolution: "@metamask/subject-metadata-controller@npm:1.0.1"
dependencies:
@ -4303,6 +4382,18 @@ __metadata:
languageName: node
linkType: hard
"@metamask/subject-metadata-controller@npm:^2.0.0":
version: 2.0.0
resolution: "@metamask/subject-metadata-controller@npm:2.0.0"
dependencies:
"@metamask/base-controller": ^2.0.0
"@metamask/permission-controller": ^3.0.0
"@metamask/types": ^1.1.0
immer: ^9.0.6
checksum: 2997a7b6e2ae17e80c2f2a42fbcf7b6fdbcbebc782c9eedec98a4f38c1089192fde9a83c2021f7d602e1e67e2cc9af2fbc345bb3775a27970c92533fadfe8f96
languageName: node
linkType: hard
"@metamask/test-dapp@npm:^5.6.0":
version: 5.6.0
resolution: "@metamask/test-dapp@npm:5.6.0"
@ -24070,19 +24161,19 @@ __metadata:
"@metamask/metamask-eth-abis": ^3.0.0
"@metamask/notification-controller": ^1.0.0
"@metamask/obs-store": ^5.0.0
"@metamask/permission-controller": ^1.0.0
"@metamask/permission-controller": ^2.0.0
"@metamask/phishing-controller": ^2.0.0
"@metamask/phishing-warning": ^2.0.1
"@metamask/post-message-stream": ^6.0.0
"@metamask/providers": ^10.2.1
"@metamask/rate-limit-controller": ^1.0.0
"@metamask/rpc-methods": ^0.28.0
"@metamask/rpc-methods": ^0.30.0
"@metamask/scure-bip39": ^2.0.3
"@metamask/slip44": ^2.1.0
"@metamask/smart-transactions-controller": ^3.1.0
"@metamask/snaps-controllers": ^0.28.0
"@metamask/snaps-ui": ^0.28.0
"@metamask/snaps-utils": ^0.28.0
"@metamask/snaps-controllers": ^0.30.0
"@metamask/snaps-ui": ^0.30.0
"@metamask/snaps-utils": ^0.30.0
"@metamask/subject-metadata-controller": ^1.0.0
"@metamask/test-dapp": ^5.6.0
"@metamask/utils": ^3.6.0