diff --git a/.storybook/test-data.js b/.storybook/test-data.js
index 43fe494dac79..35e037d45041 100644
--- a/.storybook/test-data.js
+++ b/.storybook/test-data.js
@@ -289,7 +289,6 @@ const state = {
},
version: '0.6.0',
},
- permissionName: 'wallet_snap_local:http://localhost:8080/',
sourceCode: '(...)',
status: 'stopped',
svgIcon: '',
@@ -330,7 +329,6 @@ const state = {
},
version: '0.6.0',
},
- permissionName: 'wallet_snap_npm:http://localhost:8080/',
sourceCode: '(...)',
status: 'stopped',
svgIcon: '',
diff --git a/app/_locales/de/messages.json b/app/_locales/de/messages.json
index 0080ba056675..6bfd407b9731 100644
--- a/app/_locales/de/messages.json
+++ b/app/_locales/de/messages.json
@@ -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.",
diff --git a/app/_locales/el/messages.json b/app/_locales/el/messages.json
index 716f4ce41144..6a5542a2aa0c 100644
--- a/app/_locales/el/messages.json
+++ b/app/_locales/el/messages.json
@@ -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": "Προγραμματισμός και εκτέλεση περιοδικών ενεργειών.",
diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json
index c5aacd5d5b69..772a593ddd28 100644
--- a/app/_locales/en/messages.json
+++ b/app/_locales/en/messages.json
@@ -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.",
diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json
index fac48c29a4a3..eb62c42f6541 100644
--- a/app/_locales/es/messages.json
+++ b/app/_locales/es/messages.json
@@ -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.",
diff --git a/app/_locales/fr/messages.json b/app/_locales/fr/messages.json
index e9af316c961f..51edc2ceee55 100644
--- a/app/_locales/fr/messages.json
+++ b/app/_locales/fr/messages.json
@@ -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.",
diff --git a/app/_locales/hi/messages.json b/app/_locales/hi/messages.json
index fdf132683109..2504e1bf10dd 100644
--- a/app/_locales/hi/messages.json
+++ b/app/_locales/hi/messages.json
@@ -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": "समय-समय पर आने वाले क्रियाओं को शेड्यूल और निष्पादित करें।",
diff --git a/app/_locales/id/messages.json b/app/_locales/id/messages.json
index 80f540915a10..a9a4dc57134c 100644
--- a/app/_locales/id/messages.json
+++ b/app/_locales/id/messages.json
@@ -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.",
diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json
index 7daf329c1bb6..42ee8847f4f8 100644
--- a/app/_locales/ja/messages.json
+++ b/app/_locales/ja/messages.json
@@ -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": "定期的なアクションのスケジュール設定と実行。",
diff --git a/app/_locales/ko/messages.json b/app/_locales/ko/messages.json
index 82e616329221..6f759435fc90 100644
--- a/app/_locales/ko/messages.json
+++ b/app/_locales/ko/messages.json
@@ -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": "정기적 활동 예약 및 실행",
diff --git a/app/_locales/pt/messages.json b/app/_locales/pt/messages.json
index 47472350ee74..f56009a184da 100644
--- a/app/_locales/pt/messages.json
+++ b/app/_locales/pt/messages.json
@@ -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.",
diff --git a/app/_locales/ru/messages.json b/app/_locales/ru/messages.json
index 3ecd3b04986d..071894ce74d1 100644
--- a/app/_locales/ru/messages.json
+++ b/app/_locales/ru/messages.json
@@ -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": "Планируйте и выполняйте периодические действия.",
diff --git a/app/_locales/tl/messages.json b/app/_locales/tl/messages.json
index e09a91f01fef..d9091ae02f26 100644
--- a/app/_locales/tl/messages.json
+++ b/app/_locales/tl/messages.json
@@ -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.",
diff --git a/app/_locales/tr/messages.json b/app/_locales/tr/messages.json
index 1474a9742f7e..eb7a36436ddd 100644
--- a/app/_locales/tr/messages.json
+++ b/app/_locales/tr/messages.json
@@ -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.",
diff --git a/app/_locales/vi/messages.json b/app/_locales/vi/messages.json
index 40a838cabe03..78ecbc5e9d2d 100644
--- a/app/_locales/vi/messages.json
+++ b/app/_locales/vi/messages.json
@@ -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ỳ.",
diff --git a/app/_locales/zh_CN/messages.json b/app/_locales/zh_CN/messages.json
index e803fecdb3fd..ed01186d65e6 100644
--- a/app/_locales/zh_CN/messages.json
+++ b/app/_locales/zh_CN/messages.json
@@ -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": "规划并执行定期操作。",
diff --git a/app/scripts/controllers/permissions/specifications.test.js b/app/scripts/controllers/permissions/specifications.test.js
index 3143c7f96ec0..0f3fb7a733c1 100644
--- a/app/scripts/controllers/permissions/specifications.test.js
+++ b/app/scripts/controllers/permissions/specifications.test.js
@@ -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', () => {
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 7887244d823e..983ee5119875 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -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);
diff --git a/app/scripts/migrations/081.test.js b/app/scripts/migrations/081.test.js
new file mode 100644
index 000000000000..2a75ffec6720
--- /dev/null
+++ b/app/scripts/migrations/081.test.js
@@ -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);
+ });
+});
diff --git a/app/scripts/migrations/081.ts b/app/scripts/migrations/081.ts
new file mode 100644
index 000000000000..0162a43b6e49
--- /dev/null
+++ b/app/scripts/migrations/081.ts
@@ -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;
+}) {
+ 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) {
+ 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).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)
+ .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).date = date;
+ (updatedPermissions.wallet_snap as Record).id = id;
+ subject.permissions = updatedPermissions;
+ }
+ }
+
+ return state;
+}
diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js
index 84b9b7e4cfa5..6bc0d0576f5f 100644
--- a/app/scripts/migrations/index.js
+++ b/app/scripts/migrations/index.js
@@ -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;
diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json
index 2d824d949339..5cf58f0f37b2 100644
--- a/lavamoat/browserify/beta/policy.json
+++ b/lavamoat/browserify/beta/policy.json
@@ -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": {
diff --git a/lavamoat/browserify/desktop/policy.json b/lavamoat/browserify/desktop/policy.json
index 17e096890659..28e091b8233b 100644
--- a/lavamoat/browserify/desktop/policy.json
+++ b/lavamoat/browserify/desktop/policy.json
@@ -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,
diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json
index 17e096890659..28e091b8233b 100644
--- a/lavamoat/browserify/flask/policy.json
+++ b/lavamoat/browserify/flask/policy.json
@@ -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,
diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json
index 2d824d949339..5cf58f0f37b2 100644
--- a/lavamoat/browserify/main/policy.json
+++ b/lavamoat/browserify/main/policy.json
@@ -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": {
diff --git a/lavamoat/build-system/policy.json b/lavamoat/build-system/policy.json
index 59bdb76bebfb..492fb362fe1d 100644
--- a/lavamoat/build-system/policy.json
+++ b/lavamoat/build-system/policy.json
@@ -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
diff --git a/package.json b/package.json
index 5f99891cdfd1..49e8cdaa6273 100644
--- a/package.json
+++ b/package.json
@@ -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",
diff --git a/shared/constants/permissions.ts b/shared/constants/permissions.ts
index fd57e4f5e4da..4de83b52f8fa 100644
--- a/shared/constants/permissions.ts
+++ b/shared/constants/permissions.ts
@@ -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.
diff --git a/test/e2e/fixture-builder.js b/test/e2e/fixture-builder.js
index 1313a21bc1bf..eff689cc2738 100644
--- a/test/e2e/fixture-builder.js
+++ b/test/e2e/fixture-builder.js
@@ -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',
- 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',
+ parentCapability: WALLET_SNAP_PERMISSION_KEY,
invoker: 'https://metamask.github.io',
- caveats: null,
date: 1664388714636,
},
},
diff --git a/test/e2e/snaps/enums.js b/test/e2e/snaps/enums.js
index 237a8f707809..c5992424c6d0 100644
--- a/test/e2e/snaps/enums.js
+++ b/test/e2e/snaps/enums.js
@@ -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/',
};
diff --git a/test/e2e/snaps/test-snap-confirm.spec.js b/test/e2e/snaps/test-snap-confirm.spec.js
deleted file mode 100644
index 4843dad42f66..000000000000
--- a/test/e2e/snaps/test-snap-confirm.spec.js
+++ /dev/null
@@ -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');
- },
- );
- });
-});
diff --git a/test/e2e/snaps/test-snap-rpc.spec.js b/test/e2e/snaps/test-snap-rpc.spec.js
index 22f6d6163729..19715ec36058 100644
--- a/test/e2e/snaps/test-snap-rpc.spec.js
+++ b/test/e2e/snaps/test-snap-rpc.spec.js
@@ -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: [
{
diff --git a/test/e2e/snaps/test-snap-update.spec.js b/test/e2e/snaps/test-snap-update.spec.js
index 5339ded07ee1..1120f20b8822 100644
--- a/test/e2e/snaps/test-snap-update.spec.js
+++ b/test/e2e/snaps/test-snap-update.spec.js
@@ -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"');
},
);
});
diff --git a/ui/components/app/permission-page-container/permission-page-container.component.js b/ui/components/app/permission-page-container/permission-page-container.component.js
index 60b39bd39d10..6b28f07cc74e 100644
--- a/ui/components/app/permission-page-container/permission-page-container.component.js
+++ b/ui/components/app/permission-page-container/permission-page-container.component.js
@@ -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 || {});
}
diff --git a/ui/components/app/permission-page-container/permission-page-container.container.js b/ui/components/app/permission-page-container/permission-page-container.container.js
index 031dfa6f05d8..47aaf070ecdf 100644
--- a/ui/components/app/permission-page-container/permission-page-container.container.js
+++ b/ui/components/app/permission-page-container/permission-page-container.container.js
@@ -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
};
};
diff --git a/ui/helpers/utils/permission.js b/ui/helpers/utils/permission.js
index b625c414d610..f17461fa069e 100644
--- a/ui/helpers/utils/permission.js
+++ b/ui/helpers/utils/permission.js
@@ -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,30 +141,29 @@ 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);
- const friendlyName = SNAPS_METADATA[snapId]?.name;
-
- if (friendlyName) {
+ return Object.keys(snaps).map((snapId) => {
+ const friendlyName = SNAPS_METADATA[snapId]?.name;
+ if (friendlyName) {
+ return {
+ ...baseDescription,
+ label: t('permission_accessNamedSnap', [
+
+ {friendlyName}
+ ,
+ ]),
+ };
+ }
return {
...baseDescription,
- label: t('permission_accessNamedSnap', [
-
- {friendlyName}
- ,
- ]),
+ label: t('permission_accessSnap', [snapId]),
};
- }
-
- 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)) {
diff --git a/ui/pages/settings/flask/view-snap/view-snap.js b/ui/pages/settings/flask/view-snap/view-snap.js
index 5952c0e033ed..33e7f7001564 100644
--- a/ui/pages/settings/flask/view-snap/view-snap.js
+++ b/ui/pages/settings/flask/view-snap/view-snap.js
@@ -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() {
{
- onDisconnect(origin, snap.permissionName);
+ onDisconnect(origin, snap.id);
}}
/>
diff --git a/ui/selectors/permissions.js b/ui/selectors/permissions.js
index 6459dc9c15f0..b9113a6e622e 100644
--- a/ui/selectors/permissions.js
+++ b/ui/selectors/permissions.js
@@ -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:
diff --git a/ui/store/actions.ts b/ui/store/actions.ts
index 6632a658e116..35296107edd5 100644
--- a/ui/store/actions.ts
+++ b/ui/store/actions.ts
@@ -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,
+): ThunkAction {
+ return (dispatch) => {
+ callBackgroundMethod(
+ 'updateCaveat',
+ [origin, target, caveatType, caveatValue],
+ (err) => {
+ if (err) {
+ dispatch(displayWarning(err));
+ }
+ },
+ );
+ };
+}
+///: END:ONLY_INCLUDE_IN
+
// Pending Approvals
/**
diff --git a/yarn.lock b/yarn.lock
index 5fd55e85ac65..fac25ff91f45 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -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: 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: 83b54946b948b0f97a5453328421666c8852b975bf045f6b23416579f1201feb390dc09941620fa4e480f76cd9a7b4f6e8f2c3e940ddd79f62491a81befe8c7c
+ 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