@metamask/permission-controller 12.1.1 → 12.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +28 -1
  2. package/dist/Caveat.cjs.map +1 -1
  3. package/dist/Caveat.mjs.map +1 -1
  4. package/dist/PermissionController.cjs +406 -642
  5. package/dist/PermissionController.cjs.map +1 -1
  6. package/dist/PermissionController.d.cts +10 -270
  7. package/dist/PermissionController.d.cts.map +1 -1
  8. package/dist/PermissionController.d.mts +10 -270
  9. package/dist/PermissionController.d.mts.map +1 -1
  10. package/dist/PermissionController.mjs +406 -642
  11. package/dist/PermissionController.mjs.map +1 -1
  12. package/dist/SubjectMetadataController.cjs +42 -40
  13. package/dist/SubjectMetadataController.cjs.map +1 -1
  14. package/dist/SubjectMetadataController.d.cts +1 -17
  15. package/dist/SubjectMetadataController.d.cts.map +1 -1
  16. package/dist/SubjectMetadataController.d.mts +1 -17
  17. package/dist/SubjectMetadataController.d.mts.map +1 -1
  18. package/dist/SubjectMetadataController.mjs +42 -40
  19. package/dist/SubjectMetadataController.mjs.map +1 -1
  20. package/dist/errors.cjs +8 -7
  21. package/dist/errors.cjs.map +1 -1
  22. package/dist/errors.d.cts +4 -9
  23. package/dist/errors.d.cts.map +1 -1
  24. package/dist/errors.d.mts +4 -9
  25. package/dist/errors.d.mts.map +1 -1
  26. package/dist/errors.mjs +1 -0
  27. package/dist/errors.mjs.map +1 -1
  28. package/dist/permission-middleware.cjs +1 -1
  29. package/dist/permission-middleware.cjs.map +1 -1
  30. package/dist/permission-middleware.d.cts +4 -3
  31. package/dist/permission-middleware.d.cts.map +1 -1
  32. package/dist/permission-middleware.d.mts +4 -3
  33. package/dist/permission-middleware.d.mts.map +1 -1
  34. package/dist/permission-middleware.mjs +1 -1
  35. package/dist/permission-middleware.mjs.map +1 -1
  36. package/dist/rpc-methods/revokePermissions.cjs.map +1 -1
  37. package/dist/rpc-methods/revokePermissions.d.cts +1 -1
  38. package/dist/rpc-methods/revokePermissions.d.cts.map +1 -1
  39. package/dist/rpc-methods/revokePermissions.d.mts +1 -1
  40. package/dist/rpc-methods/revokePermissions.d.mts.map +1 -1
  41. package/dist/rpc-methods/revokePermissions.mjs.map +1 -1
  42. package/dist/utils.cjs.map +1 -1
  43. package/dist/utils.d.cts.map +1 -1
  44. package/dist/utils.d.mts.map +1 -1
  45. package/dist/utils.mjs.map +1 -1
  46. package/package.json +9 -13
@@ -1,4 +1,16 @@
1
1
  "use strict";
2
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
+ };
7
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
8
+ if (kind === "m") throw new TypeError("Private method is not writable");
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
10
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
11
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
12
+ };
13
+ var _a, _SubjectMetadataController_subjectCacheLimit, _SubjectMetadataController_subjectsWithoutPermissionsEncounteredSinceStartup, _SubjectMetadataController_subjectHasPermissions, _SubjectMetadataController_getTrimmedState;
2
14
  Object.defineProperty(exports, "__esModule", { value: true });
3
15
  exports.SubjectMetadataController = exports.SubjectType = void 0;
4
16
  const base_controller_1 = require("@metamask/base-controller");
@@ -43,12 +55,15 @@ class SubjectMetadataController extends base_controller_1.BaseController {
43
55
  metadata: stateMetadata,
44
56
  messenger,
45
57
  state: {
46
- ...SubjectMetadataController.getTrimmedState(state, hasPermissions),
58
+ ...__classPrivateFieldGet(_a, _a, "m", _SubjectMetadataController_getTrimmedState).call(_a, state, hasPermissions),
47
59
  },
48
60
  });
49
- this.subjectHasPermissions = hasPermissions;
50
- this.subjectCacheLimit = subjectCacheLimit;
51
- this.subjectsWithoutPermissionsEncounteredSinceStartup = new Set();
61
+ _SubjectMetadataController_subjectCacheLimit.set(this, void 0);
62
+ _SubjectMetadataController_subjectsWithoutPermissionsEncounteredSinceStartup.set(this, void 0);
63
+ _SubjectMetadataController_subjectHasPermissions.set(this, void 0);
64
+ __classPrivateFieldSet(this, _SubjectMetadataController_subjectHasPermissions, hasPermissions, "f");
65
+ __classPrivateFieldSet(this, _SubjectMetadataController_subjectCacheLimit, subjectCacheLimit, "f");
66
+ __classPrivateFieldSet(this, _SubjectMetadataController_subjectsWithoutPermissionsEncounteredSinceStartup, new Set(), "f");
52
67
  this.messenger.registerActionHandler(`${this.name}:getSubjectMetadata`, this.getSubjectMetadata.bind(this));
53
68
  this.messenger.registerActionHandler(`${this.name}:addSubjectMetadata`, this.addSubjectMetadata.bind(this));
54
69
  }
@@ -57,7 +72,7 @@ class SubjectMetadataController extends base_controller_1.BaseController {
57
72
  * encountered since startup, so as to not prematurely reach the cache limit.
58
73
  */
59
74
  clearState() {
60
- this.subjectsWithoutPermissionsEncounteredSinceStartup.clear();
75
+ __classPrivateFieldGet(this, _SubjectMetadataController_subjectsWithoutPermissionsEncounteredSinceStartup, "f").clear();
61
76
  this.update((_draftState) => {
62
77
  return { ...defaultState };
63
78
  });
@@ -78,25 +93,25 @@ class SubjectMetadataController extends base_controller_1.BaseController {
78
93
  const { origin } = metadata;
79
94
  const newMetadata = {
80
95
  ...metadata,
81
- extensionId: metadata.extensionId || null,
82
- iconUrl: metadata.iconUrl || null,
83
- name: metadata.name || null,
84
- subjectType: metadata.subjectType || null,
96
+ extensionId: metadata.extensionId ?? null,
97
+ iconUrl: metadata.iconUrl ?? null,
98
+ name: metadata.name ?? null,
99
+ subjectType: metadata.subjectType ?? null,
85
100
  };
86
101
  let originToForget = null;
87
102
  // We only delete the oldest encountered subject from the cache, again to
88
103
  // ensure that the user's experience isn't degraded by missing icons etc.
89
- if (this.subjectsWithoutPermissionsEncounteredSinceStartup.size >=
90
- this.subjectCacheLimit) {
91
- const cachedOrigin = this.subjectsWithoutPermissionsEncounteredSinceStartup
104
+ if (__classPrivateFieldGet(this, _SubjectMetadataController_subjectsWithoutPermissionsEncounteredSinceStartup, "f").size >=
105
+ __classPrivateFieldGet(this, _SubjectMetadataController_subjectCacheLimit, "f")) {
106
+ const cachedOrigin = __classPrivateFieldGet(this, _SubjectMetadataController_subjectsWithoutPermissionsEncounteredSinceStartup, "f")
92
107
  .values()
93
108
  .next().value;
94
- this.subjectsWithoutPermissionsEncounteredSinceStartup.delete(cachedOrigin);
95
- if (!this.subjectHasPermissions(cachedOrigin)) {
109
+ __classPrivateFieldGet(this, _SubjectMetadataController_subjectsWithoutPermissionsEncounteredSinceStartup, "f").delete(cachedOrigin);
110
+ if (!__classPrivateFieldGet(this, _SubjectMetadataController_subjectHasPermissions, "f").call(this, cachedOrigin)) {
96
111
  originToForget = cachedOrigin;
97
112
  }
98
113
  }
99
- this.subjectsWithoutPermissionsEncounteredSinceStartup.add(origin);
114
+ __classPrivateFieldGet(this, _SubjectMetadataController_subjectsWithoutPermissionsEncounteredSinceStartup, "f").add(origin);
100
115
  this.update((draftState) => {
101
116
  // @ts-expect-error TS2589: Type instantiation is excessively deep and possibly infinite
102
117
  draftState.subjectMetadata[origin] = newMetadata;
@@ -119,33 +134,20 @@ class SubjectMetadataController extends base_controller_1.BaseController {
119
134
  */
120
135
  trimMetadataState() {
121
136
  this.update(() => {
122
- return SubjectMetadataController.getTrimmedState(this.state, this.subjectHasPermissions);
137
+ return __classPrivateFieldGet(_a, _a, "m", _SubjectMetadataController_getTrimmedState).call(_a, this.state, __classPrivateFieldGet(this, _SubjectMetadataController_subjectHasPermissions, "f"));
123
138
  });
124
139
  }
125
- /**
126
- * Returns a new state object that only includes subjects with permissions.
127
- * This method is static because we want to call it in the constructor, before
128
- * the controller's state is initialized.
129
- *
130
- * @param state - The state object to trim.
131
- * @param hasPermissions - A function that returns a boolean indicating
132
- * whether a particular subject (identified by its origin) has any
133
- * permissions.
134
- * @returns The new state object. If the specified `state` object has no
135
- * subject metadata, the returned object will be equivalent to the default
136
- * state of this controller.
137
- */
138
- static getTrimmedState(state, hasPermissions) {
139
- const { subjectMetadata = {} } = state;
140
- return {
141
- subjectMetadata: Object.keys(subjectMetadata).reduce((newSubjectMetadata, origin) => {
142
- if (hasPermissions(origin)) {
143
- newSubjectMetadata[origin] = subjectMetadata[origin];
144
- }
145
- return newSubjectMetadata;
146
- }, {}),
147
- };
148
- }
149
140
  }
150
141
  exports.SubjectMetadataController = SubjectMetadataController;
142
+ _a = SubjectMetadataController, _SubjectMetadataController_subjectCacheLimit = new WeakMap(), _SubjectMetadataController_subjectsWithoutPermissionsEncounteredSinceStartup = new WeakMap(), _SubjectMetadataController_subjectHasPermissions = new WeakMap(), _SubjectMetadataController_getTrimmedState = function _SubjectMetadataController_getTrimmedState(state, hasPermissions) {
143
+ const { subjectMetadata = {} } = state;
144
+ return {
145
+ subjectMetadata: Object.keys(subjectMetadata).reduce((newSubjectMetadata, origin) => {
146
+ if (hasPermissions(origin)) {
147
+ newSubjectMetadata[origin] = subjectMetadata[origin];
148
+ }
149
+ return newSubjectMetadata;
150
+ }, {}),
151
+ };
152
+ };
151
153
  //# sourceMappingURL=SubjectMetadataController.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"SubjectMetadataController.cjs","sourceRoot":"","sources":["../src/SubjectMetadataController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { Json } from '@metamask/utils';\n\nimport type {\n GenericPermissionController,\n HasPermissions,\n PermissionSubjectMetadata,\n} from './PermissionController';\n\nconst controllerName = 'SubjectMetadataController';\n\ntype SubjectOrigin = string;\n\n/**\n * The different kinds of subjects that MetaMask may interact with, including\n * third parties and itself (e.g., when the background communicated with the UI).\n */\nexport enum SubjectType {\n Extension = 'extension',\n Internal = 'internal',\n Unknown = 'unknown',\n Website = 'website',\n Snap = 'snap',\n}\n\nexport type SubjectMetadata = PermissionSubjectMetadata & {\n [key: string]: Json;\n name: string | null;\n subjectType: SubjectType | null;\n extensionId: string | null;\n iconUrl: string | null;\n};\n\ntype SubjectMetadataToAdd = PermissionSubjectMetadata & {\n name?: string | null;\n subjectType?: SubjectType | null;\n extensionId?: string | null;\n iconUrl?: string | null;\n} & Record<string, Json>;\n\nexport type SubjectMetadataControllerState = {\n subjectMetadata: Record<SubjectOrigin, SubjectMetadata>;\n};\n\nconst stateMetadata = {\n subjectMetadata: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n};\n\nconst defaultState: SubjectMetadataControllerState = {\n subjectMetadata: {},\n};\n\nexport type GetSubjectMetadataState = ControllerGetStateAction<\n typeof controllerName,\n SubjectMetadataControllerState\n>;\n\nexport type GetSubjectMetadata = {\n type: `${typeof controllerName}:getSubjectMetadata`;\n handler: (origin: SubjectOrigin) => SubjectMetadata | undefined;\n};\n\nexport type AddSubjectMetadata = {\n type: `${typeof controllerName}:addSubjectMetadata`;\n handler: (metadata: SubjectMetadataToAdd) => void;\n};\n\nexport type SubjectMetadataControllerActions =\n | GetSubjectMetadataState\n | GetSubjectMetadata\n | AddSubjectMetadata;\n\nexport type SubjectMetadataStateChange = ControllerStateChangeEvent<\n typeof controllerName,\n SubjectMetadataControllerState\n>;\n\nexport type SubjectMetadataControllerEvents = SubjectMetadataStateChange;\n\ntype AllowedActions = HasPermissions;\n\nexport type SubjectMetadataControllerMessenger = Messenger<\n typeof controllerName,\n SubjectMetadataControllerActions | AllowedActions,\n SubjectMetadataControllerEvents\n>;\n\ntype SubjectMetadataControllerOptions = {\n messenger: SubjectMetadataControllerMessenger;\n subjectCacheLimit: number;\n state?: Partial<SubjectMetadataControllerState>;\n};\n\n/**\n * A controller for storing metadata associated with permission subjects. More\n * or less, a cache.\n */\nexport class SubjectMetadataController extends BaseController<\n typeof controllerName,\n SubjectMetadataControllerState,\n SubjectMetadataControllerMessenger\n> {\n private readonly subjectCacheLimit: number;\n\n private readonly subjectsWithoutPermissionsEncounteredSinceStartup: Set<string>;\n\n private readonly subjectHasPermissions: GenericPermissionController['hasPermissions'];\n\n constructor({\n messenger,\n subjectCacheLimit,\n state = {},\n }: SubjectMetadataControllerOptions) {\n if (!Number.isInteger(subjectCacheLimit) || subjectCacheLimit < 1) {\n throw new Error(\n `subjectCacheLimit must be a positive integer. Received: \"${subjectCacheLimit}\"`,\n );\n }\n\n const hasPermissions = (origin: string) => {\n return messenger.call('PermissionController:hasPermissions', origin);\n };\n\n super({\n name: controllerName,\n metadata: stateMetadata,\n messenger,\n state: {\n ...SubjectMetadataController.getTrimmedState(state, hasPermissions),\n },\n });\n\n this.subjectHasPermissions = hasPermissions;\n this.subjectCacheLimit = subjectCacheLimit;\n this.subjectsWithoutPermissionsEncounteredSinceStartup = new Set();\n\n this.messenger.registerActionHandler(\n `${this.name}:getSubjectMetadata`,\n this.getSubjectMetadata.bind(this),\n );\n\n this.messenger.registerActionHandler(\n `${this.name}:addSubjectMetadata`,\n this.addSubjectMetadata.bind(this),\n );\n }\n\n /**\n * Clears the state of this controller. Also resets the cache of subjects\n * encountered since startup, so as to not prematurely reach the cache limit.\n */\n clearState(): void {\n this.subjectsWithoutPermissionsEncounteredSinceStartup.clear();\n this.update((_draftState) => {\n return { ...defaultState };\n });\n }\n\n /**\n * Stores domain metadata for the given origin (subject). Deletes metadata for\n * subjects without permissions in a FIFO manner once more than\n * {@link SubjectMetadataController.subjectCacheLimit} distinct origins have\n * been added since boot.\n *\n * In order to prevent a degraded user experience,\n * metadata is never deleted for subjects with permissions, since metadata\n * cannot yet be requested on demand.\n *\n * @param metadata - The subject metadata to store.\n */\n addSubjectMetadata(metadata: SubjectMetadataToAdd): void {\n const { origin } = metadata;\n const newMetadata: SubjectMetadata = {\n ...metadata,\n extensionId: metadata.extensionId || null,\n iconUrl: metadata.iconUrl || null,\n name: metadata.name || null,\n subjectType: metadata.subjectType || null,\n };\n\n let originToForget: string | null = null;\n // We only delete the oldest encountered subject from the cache, again to\n // ensure that the user's experience isn't degraded by missing icons etc.\n if (\n this.subjectsWithoutPermissionsEncounteredSinceStartup.size >=\n this.subjectCacheLimit\n ) {\n const cachedOrigin =\n this.subjectsWithoutPermissionsEncounteredSinceStartup\n .values()\n .next().value;\n\n this.subjectsWithoutPermissionsEncounteredSinceStartup.delete(\n cachedOrigin,\n );\n\n if (!this.subjectHasPermissions(cachedOrigin)) {\n originToForget = cachedOrigin;\n }\n }\n\n this.subjectsWithoutPermissionsEncounteredSinceStartup.add(origin);\n\n this.update((draftState) => {\n // @ts-expect-error TS2589: Type instantiation is excessively deep and possibly infinite\n draftState.subjectMetadata[origin] = newMetadata;\n if (typeof originToForget === 'string') {\n delete draftState.subjectMetadata[originToForget];\n }\n });\n }\n\n /**\n * Gets the subject metadata for the given origin, if any.\n *\n * @param origin - The origin for which to get the subject metadata.\n * @returns The subject metadata, if any, or `undefined` otherwise.\n */\n getSubjectMetadata(origin: SubjectOrigin): SubjectMetadata | undefined {\n return this.state.subjectMetadata[origin];\n }\n\n /**\n * Deletes all subjects without permissions from the controller's state.\n */\n trimMetadataState(): void {\n this.update(() => {\n return SubjectMetadataController.getTrimmedState(\n this.state,\n this.subjectHasPermissions,\n );\n });\n }\n\n /**\n * Returns a new state object that only includes subjects with permissions.\n * This method is static because we want to call it in the constructor, before\n * the controller's state is initialized.\n *\n * @param state - The state object to trim.\n * @param hasPermissions - A function that returns a boolean indicating\n * whether a particular subject (identified by its origin) has any\n * permissions.\n * @returns The new state object. If the specified `state` object has no\n * subject metadata, the returned object will be equivalent to the default\n * state of this controller.\n */\n private static getTrimmedState(\n state: Partial<SubjectMetadataControllerState>,\n hasPermissions: SubjectMetadataController['subjectHasPermissions'],\n ): SubjectMetadataControllerState {\n const { subjectMetadata = {} } = state;\n\n return {\n subjectMetadata: Object.keys(subjectMetadata).reduce<\n Record<SubjectOrigin, SubjectMetadata>\n >((newSubjectMetadata, origin) => {\n if (hasPermissions(origin)) {\n newSubjectMetadata[origin] = subjectMetadata[origin];\n }\n return newSubjectMetadata;\n }, {}),\n };\n }\n}\n"]}
1
+ {"version":3,"file":"SubjectMetadataController.cjs","sourceRoot":"","sources":["../src/SubjectMetadataController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { Json } from '@metamask/utils';\n\nimport type {\n GenericPermissionController,\n HasPermissions,\n PermissionSubjectMetadata,\n} from './PermissionController';\n\nconst controllerName = 'SubjectMetadataController';\n\ntype SubjectOrigin = string;\n\n/**\n * The different kinds of subjects that MetaMask may interact with, including\n * third parties and itself (e.g., when the background communicated with the UI).\n */\nexport enum SubjectType {\n Extension = 'extension',\n Internal = 'internal',\n Unknown = 'unknown',\n Website = 'website',\n Snap = 'snap',\n}\n\nexport type SubjectMetadata = PermissionSubjectMetadata & {\n [key: string]: Json;\n name: string | null;\n subjectType: SubjectType | null;\n extensionId: string | null;\n iconUrl: string | null;\n};\n\ntype SubjectMetadataToAdd = PermissionSubjectMetadata & {\n name?: string | null;\n subjectType?: SubjectType | null;\n extensionId?: string | null;\n iconUrl?: string | null;\n} & Record<string, Json>;\n\nexport type SubjectMetadataControllerState = {\n subjectMetadata: Record<SubjectOrigin, SubjectMetadata>;\n};\n\nconst stateMetadata = {\n subjectMetadata: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n};\n\nconst defaultState: SubjectMetadataControllerState = {\n subjectMetadata: {},\n};\n\nexport type GetSubjectMetadataState = ControllerGetStateAction<\n typeof controllerName,\n SubjectMetadataControllerState\n>;\n\nexport type GetSubjectMetadata = {\n type: `${typeof controllerName}:getSubjectMetadata`;\n handler: (origin: SubjectOrigin) => SubjectMetadata | undefined;\n};\n\nexport type AddSubjectMetadata = {\n type: `${typeof controllerName}:addSubjectMetadata`;\n handler: (metadata: SubjectMetadataToAdd) => void;\n};\n\nexport type SubjectMetadataControllerActions =\n | GetSubjectMetadataState\n | GetSubjectMetadata\n | AddSubjectMetadata;\n\nexport type SubjectMetadataStateChange = ControllerStateChangeEvent<\n typeof controllerName,\n SubjectMetadataControllerState\n>;\n\nexport type SubjectMetadataControllerEvents = SubjectMetadataStateChange;\n\ntype AllowedActions = HasPermissions;\n\nexport type SubjectMetadataControllerMessenger = Messenger<\n typeof controllerName,\n SubjectMetadataControllerActions | AllowedActions,\n SubjectMetadataControllerEvents\n>;\n\ntype SubjectMetadataControllerOptions = {\n messenger: SubjectMetadataControllerMessenger;\n subjectCacheLimit: number;\n state?: Partial<SubjectMetadataControllerState>;\n};\n\n/**\n * A controller for storing metadata associated with permission subjects. More\n * or less, a cache.\n */\nexport class SubjectMetadataController extends BaseController<\n typeof controllerName,\n SubjectMetadataControllerState,\n SubjectMetadataControllerMessenger\n> {\n readonly #subjectCacheLimit: number;\n\n readonly #subjectsWithoutPermissionsEncounteredSinceStartup: Set<string>;\n\n readonly #subjectHasPermissions: GenericPermissionController['hasPermissions'];\n\n constructor({\n messenger,\n subjectCacheLimit,\n state = {},\n }: SubjectMetadataControllerOptions) {\n if (!Number.isInteger(subjectCacheLimit) || subjectCacheLimit < 1) {\n throw new Error(\n `subjectCacheLimit must be a positive integer. Received: \"${subjectCacheLimit}\"`,\n );\n }\n\n const hasPermissions = (origin: string): boolean => {\n return messenger.call('PermissionController:hasPermissions', origin);\n };\n\n super({\n name: controllerName,\n metadata: stateMetadata,\n messenger,\n state: {\n ...SubjectMetadataController.#getTrimmedState(state, hasPermissions),\n },\n });\n\n this.#subjectHasPermissions = hasPermissions;\n this.#subjectCacheLimit = subjectCacheLimit;\n this.#subjectsWithoutPermissionsEncounteredSinceStartup = new Set();\n\n this.messenger.registerActionHandler(\n `${this.name}:getSubjectMetadata`,\n this.getSubjectMetadata.bind(this),\n );\n\n this.messenger.registerActionHandler(\n `${this.name}:addSubjectMetadata`,\n this.addSubjectMetadata.bind(this),\n );\n }\n\n /**\n * Clears the state of this controller. Also resets the cache of subjects\n * encountered since startup, so as to not prematurely reach the cache limit.\n */\n clearState(): void {\n this.#subjectsWithoutPermissionsEncounteredSinceStartup.clear();\n this.update((_draftState) => {\n return { ...defaultState };\n });\n }\n\n /**\n * Stores domain metadata for the given origin (subject). Deletes metadata for\n * subjects without permissions in a FIFO manner once more than\n * {@link SubjectMetadataController.subjectCacheLimit} distinct origins have\n * been added since boot.\n *\n * In order to prevent a degraded user experience,\n * metadata is never deleted for subjects with permissions, since metadata\n * cannot yet be requested on demand.\n *\n * @param metadata - The subject metadata to store.\n */\n addSubjectMetadata(metadata: SubjectMetadataToAdd): void {\n const { origin } = metadata;\n const newMetadata: SubjectMetadata = {\n ...metadata,\n extensionId: metadata.extensionId ?? null,\n iconUrl: metadata.iconUrl ?? null,\n name: metadata.name ?? null,\n subjectType: metadata.subjectType ?? null,\n };\n\n let originToForget: string | null = null;\n // We only delete the oldest encountered subject from the cache, again to\n // ensure that the user's experience isn't degraded by missing icons etc.\n if (\n this.#subjectsWithoutPermissionsEncounteredSinceStartup.size >=\n this.#subjectCacheLimit\n ) {\n const cachedOrigin =\n this.#subjectsWithoutPermissionsEncounteredSinceStartup\n .values()\n .next().value;\n\n this.#subjectsWithoutPermissionsEncounteredSinceStartup.delete(\n cachedOrigin,\n );\n\n if (!this.#subjectHasPermissions(cachedOrigin)) {\n originToForget = cachedOrigin;\n }\n }\n\n this.#subjectsWithoutPermissionsEncounteredSinceStartup.add(origin);\n\n this.update((draftState) => {\n // @ts-expect-error TS2589: Type instantiation is excessively deep and possibly infinite\n draftState.subjectMetadata[origin] = newMetadata;\n if (typeof originToForget === 'string') {\n delete draftState.subjectMetadata[originToForget];\n }\n });\n }\n\n /**\n * Gets the subject metadata for the given origin, if any.\n *\n * @param origin - The origin for which to get the subject metadata.\n * @returns The subject metadata, if any, or `undefined` otherwise.\n */\n getSubjectMetadata(origin: SubjectOrigin): SubjectMetadata | undefined {\n return this.state.subjectMetadata[origin];\n }\n\n /**\n * Deletes all subjects without permissions from the controller's state.\n */\n trimMetadataState(): void {\n this.update(() => {\n return SubjectMetadataController.#getTrimmedState(\n this.state,\n this.#subjectHasPermissions,\n );\n });\n }\n\n /**\n * Returns a new state object that only includes subjects with permissions.\n * This method is static because we want to call it in the constructor, before\n * the controller's state is initialized.\n *\n * @param state - The state object to trim.\n * @param hasPermissions - A function that returns a boolean indicating\n * whether a particular subject (identified by its origin) has any\n * permissions.\n * @returns The new state object. If the specified `state` object has no\n * subject metadata, the returned object will be equivalent to the default\n * state of this controller.\n */\n static #getTrimmedState(\n state: Partial<SubjectMetadataControllerState>,\n hasPermissions: GenericPermissionController['hasPermissions'],\n ): SubjectMetadataControllerState {\n const { subjectMetadata = {} } = state;\n\n return {\n subjectMetadata: Object.keys(subjectMetadata).reduce<\n Record<SubjectOrigin, SubjectMetadata>\n >((newSubjectMetadata, origin) => {\n if (hasPermissions(origin)) {\n newSubjectMetadata[origin] = subjectMetadata[origin];\n }\n return newSubjectMetadata;\n }, {}),\n };\n }\n}\n"]}
@@ -56,9 +56,7 @@ type SubjectMetadataControllerOptions = {
56
56
  * or less, a cache.
57
57
  */
58
58
  export declare class SubjectMetadataController extends BaseController<typeof controllerName, SubjectMetadataControllerState, SubjectMetadataControllerMessenger> {
59
- private readonly subjectCacheLimit;
60
- private readonly subjectsWithoutPermissionsEncounteredSinceStartup;
61
- private readonly subjectHasPermissions;
59
+ #private;
62
60
  constructor({ messenger, subjectCacheLimit, state, }: SubjectMetadataControllerOptions);
63
61
  /**
64
62
  * Clears the state of this controller. Also resets the cache of subjects
@@ -89,20 +87,6 @@ export declare class SubjectMetadataController extends BaseController<typeof con
89
87
  * Deletes all subjects without permissions from the controller's state.
90
88
  */
91
89
  trimMetadataState(): void;
92
- /**
93
- * Returns a new state object that only includes subjects with permissions.
94
- * This method is static because we want to call it in the constructor, before
95
- * the controller's state is initialized.
96
- *
97
- * @param state - The state object to trim.
98
- * @param hasPermissions - A function that returns a boolean indicating
99
- * whether a particular subject (identified by its origin) has any
100
- * permissions.
101
- * @returns The new state object. If the specified `state` object has no
102
- * subject metadata, the returned object will be equivalent to the default
103
- * state of this controller.
104
- */
105
- private static getTrimmedState;
106
90
  }
107
91
  export {};
108
92
  //# sourceMappingURL=SubjectMetadataController.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SubjectMetadataController.d.cts","sourceRoot":"","sources":["../src/SubjectMetadataController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SubjectMetadataController.d.cts","sourceRoot":"","sources":["../src/SubjectMetadataController.ts"],"names":[],"mappings":"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"}
@@ -56,9 +56,7 @@ type SubjectMetadataControllerOptions = {
56
56
  * or less, a cache.
57
57
  */
58
58
  export declare class SubjectMetadataController extends BaseController<typeof controllerName, SubjectMetadataControllerState, SubjectMetadataControllerMessenger> {
59
- private readonly subjectCacheLimit;
60
- private readonly subjectsWithoutPermissionsEncounteredSinceStartup;
61
- private readonly subjectHasPermissions;
59
+ #private;
62
60
  constructor({ messenger, subjectCacheLimit, state, }: SubjectMetadataControllerOptions);
63
61
  /**
64
62
  * Clears the state of this controller. Also resets the cache of subjects
@@ -89,20 +87,6 @@ export declare class SubjectMetadataController extends BaseController<typeof con
89
87
  * Deletes all subjects without permissions from the controller's state.
90
88
  */
91
89
  trimMetadataState(): void;
92
- /**
93
- * Returns a new state object that only includes subjects with permissions.
94
- * This method is static because we want to call it in the constructor, before
95
- * the controller's state is initialized.
96
- *
97
- * @param state - The state object to trim.
98
- * @param hasPermissions - A function that returns a boolean indicating
99
- * whether a particular subject (identified by its origin) has any
100
- * permissions.
101
- * @returns The new state object. If the specified `state` object has no
102
- * subject metadata, the returned object will be equivalent to the default
103
- * state of this controller.
104
- */
105
- private static getTrimmedState;
106
90
  }
107
91
  export {};
108
92
  //# sourceMappingURL=SubjectMetadataController.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SubjectMetadataController.d.mts","sourceRoot":"","sources":["../src/SubjectMetadataController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AACrD,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAE5C,OAAO,KAAK,EAEV,cAAc,EACd,yBAAyB,EAC1B,mCAA+B;AAEhC,QAAA,MAAM,cAAc,8BAA8B,CAAC;AAEnD,KAAK,aAAa,GAAG,MAAM,CAAC;AAE5B;;;GAGG;AACH,oBAAY,WAAW;IACrB,SAAS,cAAc;IACvB,QAAQ,aAAa;IACrB,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,IAAI,SAAS;CACd;AAED,MAAM,MAAM,eAAe,GAAG,yBAAyB,GAAG;IACxD,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB,CAAC;AAEF,KAAK,oBAAoB,GAAG,yBAAyB,GAAG;IACtD,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAEzB,MAAM,MAAM,8BAA8B,GAAG;IAC3C,eAAe,EAAE,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC;CACzD,CAAC;AAeF,MAAM,MAAM,uBAAuB,GAAG,wBAAwB,CAC5D,OAAO,cAAc,EACrB,8BAA8B,CAC/B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,GAAG,OAAO,cAAc,qBAAqB,CAAC;IACpD,OAAO,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,eAAe,GAAG,SAAS,CAAC;CACjE,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,GAAG,OAAO,cAAc,qBAAqB,CAAC;IACpD,OAAO,EAAE,CAAC,QAAQ,EAAE,oBAAoB,KAAK,IAAI,CAAC;CACnD,CAAC;AAEF,MAAM,MAAM,gCAAgC,GACxC,uBAAuB,GACvB,kBAAkB,GAClB,kBAAkB,CAAC;AAEvB,MAAM,MAAM,0BAA0B,GAAG,0BAA0B,CACjE,OAAO,cAAc,EACrB,8BAA8B,CAC/B,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG,0BAA0B,CAAC;AAEzE,KAAK,cAAc,GAAG,cAAc,CAAC;AAErC,MAAM,MAAM,kCAAkC,GAAG,SAAS,CACxD,OAAO,cAAc,EACrB,gCAAgC,GAAG,cAAc,EACjD,+BAA+B,CAChC,CAAC;AAEF,KAAK,gCAAgC,GAAG;IACtC,SAAS,EAAE,kCAAkC,CAAC;IAC9C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC,8BAA8B,CAAC,CAAC;CACjD,CAAC;AAEF;;;GAGG;AACH,qBAAa,yBAA0B,SAAQ,cAAc,CAC3D,OAAO,cAAc,EACrB,8BAA8B,EAC9B,kCAAkC,CACnC;IACC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAE3C,OAAO,CAAC,QAAQ,CAAC,iDAAiD,CAAc;IAEhF,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAgD;gBAE1E,EACV,SAAS,EACT,iBAAiB,EACjB,KAAU,GACX,EAAE,gCAAgC;IAmCnC;;;OAGG;IACH,UAAU,IAAI,IAAI;IAOlB;;;;;;;;;;;OAWG;IACH,kBAAkB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI;IA0CxD;;;;;OAKG;IACH,kBAAkB,CAAC,MAAM,EAAE,aAAa,GAAG,eAAe,GAAG,SAAS;IAItE;;OAEG;IACH,iBAAiB,IAAI,IAAI;IASzB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;CAiB/B"}
1
+ {"version":3,"file":"SubjectMetadataController.d.mts","sourceRoot":"","sources":["../src/SubjectMetadataController.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,15 @@
1
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
+ };
6
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
7
+ if (kind === "m") throw new TypeError("Private method is not writable");
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
9
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
10
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
11
+ };
12
+ var _a, _SubjectMetadataController_subjectCacheLimit, _SubjectMetadataController_subjectsWithoutPermissionsEncounteredSinceStartup, _SubjectMetadataController_subjectHasPermissions, _SubjectMetadataController_getTrimmedState;
1
13
  import { BaseController } from "@metamask/base-controller";
2
14
  const controllerName = 'SubjectMetadataController';
3
15
  /**
@@ -40,12 +52,15 @@ export class SubjectMetadataController extends BaseController {
40
52
  metadata: stateMetadata,
41
53
  messenger,
42
54
  state: {
43
- ...SubjectMetadataController.getTrimmedState(state, hasPermissions),
55
+ ...__classPrivateFieldGet(_a, _a, "m", _SubjectMetadataController_getTrimmedState).call(_a, state, hasPermissions),
44
56
  },
45
57
  });
46
- this.subjectHasPermissions = hasPermissions;
47
- this.subjectCacheLimit = subjectCacheLimit;
48
- this.subjectsWithoutPermissionsEncounteredSinceStartup = new Set();
58
+ _SubjectMetadataController_subjectCacheLimit.set(this, void 0);
59
+ _SubjectMetadataController_subjectsWithoutPermissionsEncounteredSinceStartup.set(this, void 0);
60
+ _SubjectMetadataController_subjectHasPermissions.set(this, void 0);
61
+ __classPrivateFieldSet(this, _SubjectMetadataController_subjectHasPermissions, hasPermissions, "f");
62
+ __classPrivateFieldSet(this, _SubjectMetadataController_subjectCacheLimit, subjectCacheLimit, "f");
63
+ __classPrivateFieldSet(this, _SubjectMetadataController_subjectsWithoutPermissionsEncounteredSinceStartup, new Set(), "f");
49
64
  this.messenger.registerActionHandler(`${this.name}:getSubjectMetadata`, this.getSubjectMetadata.bind(this));
50
65
  this.messenger.registerActionHandler(`${this.name}:addSubjectMetadata`, this.addSubjectMetadata.bind(this));
51
66
  }
@@ -54,7 +69,7 @@ export class SubjectMetadataController extends BaseController {
54
69
  * encountered since startup, so as to not prematurely reach the cache limit.
55
70
  */
56
71
  clearState() {
57
- this.subjectsWithoutPermissionsEncounteredSinceStartup.clear();
72
+ __classPrivateFieldGet(this, _SubjectMetadataController_subjectsWithoutPermissionsEncounteredSinceStartup, "f").clear();
58
73
  this.update((_draftState) => {
59
74
  return { ...defaultState };
60
75
  });
@@ -75,25 +90,25 @@ export class SubjectMetadataController extends BaseController {
75
90
  const { origin } = metadata;
76
91
  const newMetadata = {
77
92
  ...metadata,
78
- extensionId: metadata.extensionId || null,
79
- iconUrl: metadata.iconUrl || null,
80
- name: metadata.name || null,
81
- subjectType: metadata.subjectType || null,
93
+ extensionId: metadata.extensionId ?? null,
94
+ iconUrl: metadata.iconUrl ?? null,
95
+ name: metadata.name ?? null,
96
+ subjectType: metadata.subjectType ?? null,
82
97
  };
83
98
  let originToForget = null;
84
99
  // We only delete the oldest encountered subject from the cache, again to
85
100
  // ensure that the user's experience isn't degraded by missing icons etc.
86
- if (this.subjectsWithoutPermissionsEncounteredSinceStartup.size >=
87
- this.subjectCacheLimit) {
88
- const cachedOrigin = this.subjectsWithoutPermissionsEncounteredSinceStartup
101
+ if (__classPrivateFieldGet(this, _SubjectMetadataController_subjectsWithoutPermissionsEncounteredSinceStartup, "f").size >=
102
+ __classPrivateFieldGet(this, _SubjectMetadataController_subjectCacheLimit, "f")) {
103
+ const cachedOrigin = __classPrivateFieldGet(this, _SubjectMetadataController_subjectsWithoutPermissionsEncounteredSinceStartup, "f")
89
104
  .values()
90
105
  .next().value;
91
- this.subjectsWithoutPermissionsEncounteredSinceStartup.delete(cachedOrigin);
92
- if (!this.subjectHasPermissions(cachedOrigin)) {
106
+ __classPrivateFieldGet(this, _SubjectMetadataController_subjectsWithoutPermissionsEncounteredSinceStartup, "f").delete(cachedOrigin);
107
+ if (!__classPrivateFieldGet(this, _SubjectMetadataController_subjectHasPermissions, "f").call(this, cachedOrigin)) {
93
108
  originToForget = cachedOrigin;
94
109
  }
95
110
  }
96
- this.subjectsWithoutPermissionsEncounteredSinceStartup.add(origin);
111
+ __classPrivateFieldGet(this, _SubjectMetadataController_subjectsWithoutPermissionsEncounteredSinceStartup, "f").add(origin);
97
112
  this.update((draftState) => {
98
113
  // @ts-expect-error TS2589: Type instantiation is excessively deep and possibly infinite
99
114
  draftState.subjectMetadata[origin] = newMetadata;
@@ -116,32 +131,19 @@ export class SubjectMetadataController extends BaseController {
116
131
  */
117
132
  trimMetadataState() {
118
133
  this.update(() => {
119
- return SubjectMetadataController.getTrimmedState(this.state, this.subjectHasPermissions);
134
+ return __classPrivateFieldGet(_a, _a, "m", _SubjectMetadataController_getTrimmedState).call(_a, this.state, __classPrivateFieldGet(this, _SubjectMetadataController_subjectHasPermissions, "f"));
120
135
  });
121
136
  }
122
- /**
123
- * Returns a new state object that only includes subjects with permissions.
124
- * This method is static because we want to call it in the constructor, before
125
- * the controller's state is initialized.
126
- *
127
- * @param state - The state object to trim.
128
- * @param hasPermissions - A function that returns a boolean indicating
129
- * whether a particular subject (identified by its origin) has any
130
- * permissions.
131
- * @returns The new state object. If the specified `state` object has no
132
- * subject metadata, the returned object will be equivalent to the default
133
- * state of this controller.
134
- */
135
- static getTrimmedState(state, hasPermissions) {
136
- const { subjectMetadata = {} } = state;
137
- return {
138
- subjectMetadata: Object.keys(subjectMetadata).reduce((newSubjectMetadata, origin) => {
139
- if (hasPermissions(origin)) {
140
- newSubjectMetadata[origin] = subjectMetadata[origin];
141
- }
142
- return newSubjectMetadata;
143
- }, {}),
144
- };
145
- }
146
137
  }
138
+ _a = SubjectMetadataController, _SubjectMetadataController_subjectCacheLimit = new WeakMap(), _SubjectMetadataController_subjectsWithoutPermissionsEncounteredSinceStartup = new WeakMap(), _SubjectMetadataController_subjectHasPermissions = new WeakMap(), _SubjectMetadataController_getTrimmedState = function _SubjectMetadataController_getTrimmedState(state, hasPermissions) {
139
+ const { subjectMetadata = {} } = state;
140
+ return {
141
+ subjectMetadata: Object.keys(subjectMetadata).reduce((newSubjectMetadata, origin) => {
142
+ if (hasPermissions(origin)) {
143
+ newSubjectMetadata[origin] = subjectMetadata[origin];
144
+ }
145
+ return newSubjectMetadata;
146
+ }, {}),
147
+ };
148
+ };
147
149
  //# sourceMappingURL=SubjectMetadataController.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"SubjectMetadataController.mjs","sourceRoot":"","sources":["../src/SubjectMetadataController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { Json } from '@metamask/utils';\n\nimport type {\n GenericPermissionController,\n HasPermissions,\n PermissionSubjectMetadata,\n} from './PermissionController';\n\nconst controllerName = 'SubjectMetadataController';\n\ntype SubjectOrigin = string;\n\n/**\n * The different kinds of subjects that MetaMask may interact with, including\n * third parties and itself (e.g., when the background communicated with the UI).\n */\nexport enum SubjectType {\n Extension = 'extension',\n Internal = 'internal',\n Unknown = 'unknown',\n Website = 'website',\n Snap = 'snap',\n}\n\nexport type SubjectMetadata = PermissionSubjectMetadata & {\n [key: string]: Json;\n name: string | null;\n subjectType: SubjectType | null;\n extensionId: string | null;\n iconUrl: string | null;\n};\n\ntype SubjectMetadataToAdd = PermissionSubjectMetadata & {\n name?: string | null;\n subjectType?: SubjectType | null;\n extensionId?: string | null;\n iconUrl?: string | null;\n} & Record<string, Json>;\n\nexport type SubjectMetadataControllerState = {\n subjectMetadata: Record<SubjectOrigin, SubjectMetadata>;\n};\n\nconst stateMetadata = {\n subjectMetadata: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n};\n\nconst defaultState: SubjectMetadataControllerState = {\n subjectMetadata: {},\n};\n\nexport type GetSubjectMetadataState = ControllerGetStateAction<\n typeof controllerName,\n SubjectMetadataControllerState\n>;\n\nexport type GetSubjectMetadata = {\n type: `${typeof controllerName}:getSubjectMetadata`;\n handler: (origin: SubjectOrigin) => SubjectMetadata | undefined;\n};\n\nexport type AddSubjectMetadata = {\n type: `${typeof controllerName}:addSubjectMetadata`;\n handler: (metadata: SubjectMetadataToAdd) => void;\n};\n\nexport type SubjectMetadataControllerActions =\n | GetSubjectMetadataState\n | GetSubjectMetadata\n | AddSubjectMetadata;\n\nexport type SubjectMetadataStateChange = ControllerStateChangeEvent<\n typeof controllerName,\n SubjectMetadataControllerState\n>;\n\nexport type SubjectMetadataControllerEvents = SubjectMetadataStateChange;\n\ntype AllowedActions = HasPermissions;\n\nexport type SubjectMetadataControllerMessenger = Messenger<\n typeof controllerName,\n SubjectMetadataControllerActions | AllowedActions,\n SubjectMetadataControllerEvents\n>;\n\ntype SubjectMetadataControllerOptions = {\n messenger: SubjectMetadataControllerMessenger;\n subjectCacheLimit: number;\n state?: Partial<SubjectMetadataControllerState>;\n};\n\n/**\n * A controller for storing metadata associated with permission subjects. More\n * or less, a cache.\n */\nexport class SubjectMetadataController extends BaseController<\n typeof controllerName,\n SubjectMetadataControllerState,\n SubjectMetadataControllerMessenger\n> {\n private readonly subjectCacheLimit: number;\n\n private readonly subjectsWithoutPermissionsEncounteredSinceStartup: Set<string>;\n\n private readonly subjectHasPermissions: GenericPermissionController['hasPermissions'];\n\n constructor({\n messenger,\n subjectCacheLimit,\n state = {},\n }: SubjectMetadataControllerOptions) {\n if (!Number.isInteger(subjectCacheLimit) || subjectCacheLimit < 1) {\n throw new Error(\n `subjectCacheLimit must be a positive integer. Received: \"${subjectCacheLimit}\"`,\n );\n }\n\n const hasPermissions = (origin: string) => {\n return messenger.call('PermissionController:hasPermissions', origin);\n };\n\n super({\n name: controllerName,\n metadata: stateMetadata,\n messenger,\n state: {\n ...SubjectMetadataController.getTrimmedState(state, hasPermissions),\n },\n });\n\n this.subjectHasPermissions = hasPermissions;\n this.subjectCacheLimit = subjectCacheLimit;\n this.subjectsWithoutPermissionsEncounteredSinceStartup = new Set();\n\n this.messenger.registerActionHandler(\n `${this.name}:getSubjectMetadata`,\n this.getSubjectMetadata.bind(this),\n );\n\n this.messenger.registerActionHandler(\n `${this.name}:addSubjectMetadata`,\n this.addSubjectMetadata.bind(this),\n );\n }\n\n /**\n * Clears the state of this controller. Also resets the cache of subjects\n * encountered since startup, so as to not prematurely reach the cache limit.\n */\n clearState(): void {\n this.subjectsWithoutPermissionsEncounteredSinceStartup.clear();\n this.update((_draftState) => {\n return { ...defaultState };\n });\n }\n\n /**\n * Stores domain metadata for the given origin (subject). Deletes metadata for\n * subjects without permissions in a FIFO manner once more than\n * {@link SubjectMetadataController.subjectCacheLimit} distinct origins have\n * been added since boot.\n *\n * In order to prevent a degraded user experience,\n * metadata is never deleted for subjects with permissions, since metadata\n * cannot yet be requested on demand.\n *\n * @param metadata - The subject metadata to store.\n */\n addSubjectMetadata(metadata: SubjectMetadataToAdd): void {\n const { origin } = metadata;\n const newMetadata: SubjectMetadata = {\n ...metadata,\n extensionId: metadata.extensionId || null,\n iconUrl: metadata.iconUrl || null,\n name: metadata.name || null,\n subjectType: metadata.subjectType || null,\n };\n\n let originToForget: string | null = null;\n // We only delete the oldest encountered subject from the cache, again to\n // ensure that the user's experience isn't degraded by missing icons etc.\n if (\n this.subjectsWithoutPermissionsEncounteredSinceStartup.size >=\n this.subjectCacheLimit\n ) {\n const cachedOrigin =\n this.subjectsWithoutPermissionsEncounteredSinceStartup\n .values()\n .next().value;\n\n this.subjectsWithoutPermissionsEncounteredSinceStartup.delete(\n cachedOrigin,\n );\n\n if (!this.subjectHasPermissions(cachedOrigin)) {\n originToForget = cachedOrigin;\n }\n }\n\n this.subjectsWithoutPermissionsEncounteredSinceStartup.add(origin);\n\n this.update((draftState) => {\n // @ts-expect-error TS2589: Type instantiation is excessively deep and possibly infinite\n draftState.subjectMetadata[origin] = newMetadata;\n if (typeof originToForget === 'string') {\n delete draftState.subjectMetadata[originToForget];\n }\n });\n }\n\n /**\n * Gets the subject metadata for the given origin, if any.\n *\n * @param origin - The origin for which to get the subject metadata.\n * @returns The subject metadata, if any, or `undefined` otherwise.\n */\n getSubjectMetadata(origin: SubjectOrigin): SubjectMetadata | undefined {\n return this.state.subjectMetadata[origin];\n }\n\n /**\n * Deletes all subjects without permissions from the controller's state.\n */\n trimMetadataState(): void {\n this.update(() => {\n return SubjectMetadataController.getTrimmedState(\n this.state,\n this.subjectHasPermissions,\n );\n });\n }\n\n /**\n * Returns a new state object that only includes subjects with permissions.\n * This method is static because we want to call it in the constructor, before\n * the controller's state is initialized.\n *\n * @param state - The state object to trim.\n * @param hasPermissions - A function that returns a boolean indicating\n * whether a particular subject (identified by its origin) has any\n * permissions.\n * @returns The new state object. If the specified `state` object has no\n * subject metadata, the returned object will be equivalent to the default\n * state of this controller.\n */\n private static getTrimmedState(\n state: Partial<SubjectMetadataControllerState>,\n hasPermissions: SubjectMetadataController['subjectHasPermissions'],\n ): SubjectMetadataControllerState {\n const { subjectMetadata = {} } = state;\n\n return {\n subjectMetadata: Object.keys(subjectMetadata).reduce<\n Record<SubjectOrigin, SubjectMetadata>\n >((newSubjectMetadata, origin) => {\n if (hasPermissions(origin)) {\n newSubjectMetadata[origin] = subjectMetadata[origin];\n }\n return newSubjectMetadata;\n }, {}),\n };\n }\n}\n"]}
1
+ {"version":3,"file":"SubjectMetadataController.mjs","sourceRoot":"","sources":["../src/SubjectMetadataController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { Json } from '@metamask/utils';\n\nimport type {\n GenericPermissionController,\n HasPermissions,\n PermissionSubjectMetadata,\n} from './PermissionController';\n\nconst controllerName = 'SubjectMetadataController';\n\ntype SubjectOrigin = string;\n\n/**\n * The different kinds of subjects that MetaMask may interact with, including\n * third parties and itself (e.g., when the background communicated with the UI).\n */\nexport enum SubjectType {\n Extension = 'extension',\n Internal = 'internal',\n Unknown = 'unknown',\n Website = 'website',\n Snap = 'snap',\n}\n\nexport type SubjectMetadata = PermissionSubjectMetadata & {\n [key: string]: Json;\n name: string | null;\n subjectType: SubjectType | null;\n extensionId: string | null;\n iconUrl: string | null;\n};\n\ntype SubjectMetadataToAdd = PermissionSubjectMetadata & {\n name?: string | null;\n subjectType?: SubjectType | null;\n extensionId?: string | null;\n iconUrl?: string | null;\n} & Record<string, Json>;\n\nexport type SubjectMetadataControllerState = {\n subjectMetadata: Record<SubjectOrigin, SubjectMetadata>;\n};\n\nconst stateMetadata = {\n subjectMetadata: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n};\n\nconst defaultState: SubjectMetadataControllerState = {\n subjectMetadata: {},\n};\n\nexport type GetSubjectMetadataState = ControllerGetStateAction<\n typeof controllerName,\n SubjectMetadataControllerState\n>;\n\nexport type GetSubjectMetadata = {\n type: `${typeof controllerName}:getSubjectMetadata`;\n handler: (origin: SubjectOrigin) => SubjectMetadata | undefined;\n};\n\nexport type AddSubjectMetadata = {\n type: `${typeof controllerName}:addSubjectMetadata`;\n handler: (metadata: SubjectMetadataToAdd) => void;\n};\n\nexport type SubjectMetadataControllerActions =\n | GetSubjectMetadataState\n | GetSubjectMetadata\n | AddSubjectMetadata;\n\nexport type SubjectMetadataStateChange = ControllerStateChangeEvent<\n typeof controllerName,\n SubjectMetadataControllerState\n>;\n\nexport type SubjectMetadataControllerEvents = SubjectMetadataStateChange;\n\ntype AllowedActions = HasPermissions;\n\nexport type SubjectMetadataControllerMessenger = Messenger<\n typeof controllerName,\n SubjectMetadataControllerActions | AllowedActions,\n SubjectMetadataControllerEvents\n>;\n\ntype SubjectMetadataControllerOptions = {\n messenger: SubjectMetadataControllerMessenger;\n subjectCacheLimit: number;\n state?: Partial<SubjectMetadataControllerState>;\n};\n\n/**\n * A controller for storing metadata associated with permission subjects. More\n * or less, a cache.\n */\nexport class SubjectMetadataController extends BaseController<\n typeof controllerName,\n SubjectMetadataControllerState,\n SubjectMetadataControllerMessenger\n> {\n readonly #subjectCacheLimit: number;\n\n readonly #subjectsWithoutPermissionsEncounteredSinceStartup: Set<string>;\n\n readonly #subjectHasPermissions: GenericPermissionController['hasPermissions'];\n\n constructor({\n messenger,\n subjectCacheLimit,\n state = {},\n }: SubjectMetadataControllerOptions) {\n if (!Number.isInteger(subjectCacheLimit) || subjectCacheLimit < 1) {\n throw new Error(\n `subjectCacheLimit must be a positive integer. Received: \"${subjectCacheLimit}\"`,\n );\n }\n\n const hasPermissions = (origin: string): boolean => {\n return messenger.call('PermissionController:hasPermissions', origin);\n };\n\n super({\n name: controllerName,\n metadata: stateMetadata,\n messenger,\n state: {\n ...SubjectMetadataController.#getTrimmedState(state, hasPermissions),\n },\n });\n\n this.#subjectHasPermissions = hasPermissions;\n this.#subjectCacheLimit = subjectCacheLimit;\n this.#subjectsWithoutPermissionsEncounteredSinceStartup = new Set();\n\n this.messenger.registerActionHandler(\n `${this.name}:getSubjectMetadata`,\n this.getSubjectMetadata.bind(this),\n );\n\n this.messenger.registerActionHandler(\n `${this.name}:addSubjectMetadata`,\n this.addSubjectMetadata.bind(this),\n );\n }\n\n /**\n * Clears the state of this controller. Also resets the cache of subjects\n * encountered since startup, so as to not prematurely reach the cache limit.\n */\n clearState(): void {\n this.#subjectsWithoutPermissionsEncounteredSinceStartup.clear();\n this.update((_draftState) => {\n return { ...defaultState };\n });\n }\n\n /**\n * Stores domain metadata for the given origin (subject). Deletes metadata for\n * subjects without permissions in a FIFO manner once more than\n * {@link SubjectMetadataController.subjectCacheLimit} distinct origins have\n * been added since boot.\n *\n * In order to prevent a degraded user experience,\n * metadata is never deleted for subjects with permissions, since metadata\n * cannot yet be requested on demand.\n *\n * @param metadata - The subject metadata to store.\n */\n addSubjectMetadata(metadata: SubjectMetadataToAdd): void {\n const { origin } = metadata;\n const newMetadata: SubjectMetadata = {\n ...metadata,\n extensionId: metadata.extensionId ?? null,\n iconUrl: metadata.iconUrl ?? null,\n name: metadata.name ?? null,\n subjectType: metadata.subjectType ?? null,\n };\n\n let originToForget: string | null = null;\n // We only delete the oldest encountered subject from the cache, again to\n // ensure that the user's experience isn't degraded by missing icons etc.\n if (\n this.#subjectsWithoutPermissionsEncounteredSinceStartup.size >=\n this.#subjectCacheLimit\n ) {\n const cachedOrigin =\n this.#subjectsWithoutPermissionsEncounteredSinceStartup\n .values()\n .next().value;\n\n this.#subjectsWithoutPermissionsEncounteredSinceStartup.delete(\n cachedOrigin,\n );\n\n if (!this.#subjectHasPermissions(cachedOrigin)) {\n originToForget = cachedOrigin;\n }\n }\n\n this.#subjectsWithoutPermissionsEncounteredSinceStartup.add(origin);\n\n this.update((draftState) => {\n // @ts-expect-error TS2589: Type instantiation is excessively deep and possibly infinite\n draftState.subjectMetadata[origin] = newMetadata;\n if (typeof originToForget === 'string') {\n delete draftState.subjectMetadata[originToForget];\n }\n });\n }\n\n /**\n * Gets the subject metadata for the given origin, if any.\n *\n * @param origin - The origin for which to get the subject metadata.\n * @returns The subject metadata, if any, or `undefined` otherwise.\n */\n getSubjectMetadata(origin: SubjectOrigin): SubjectMetadata | undefined {\n return this.state.subjectMetadata[origin];\n }\n\n /**\n * Deletes all subjects without permissions from the controller's state.\n */\n trimMetadataState(): void {\n this.update(() => {\n return SubjectMetadataController.#getTrimmedState(\n this.state,\n this.#subjectHasPermissions,\n );\n });\n }\n\n /**\n * Returns a new state object that only includes subjects with permissions.\n * This method is static because we want to call it in the constructor, before\n * the controller's state is initialized.\n *\n * @param state - The state object to trim.\n * @param hasPermissions - A function that returns a boolean indicating\n * whether a particular subject (identified by its origin) has any\n * permissions.\n * @returns The new state object. If the specified `state` object has no\n * subject metadata, the returned object will be equivalent to the default\n * state of this controller.\n */\n static #getTrimmedState(\n state: Partial<SubjectMetadataControllerState>,\n hasPermissions: GenericPermissionController['hasPermissions'],\n ): SubjectMetadataControllerState {\n const { subjectMetadata = {} } = state;\n\n return {\n subjectMetadata: Object.keys(subjectMetadata).reduce<\n Record<SubjectOrigin, SubjectMetadata>\n >((newSubjectMetadata, origin) => {\n if (hasPermissions(origin)) {\n newSubjectMetadata[origin] = subjectMetadata[origin];\n }\n return newSubjectMetadata;\n }, {}),\n };\n }\n}\n"]}
package/dist/errors.cjs CHANGED
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PermissionsRequestNotFoundError = exports.CaveatSpecificationMismatchError = exports.CaveatMergeTypeMismatchError = exports.DuplicateCaveatError = exports.ForbiddenCaveatError = exports.InvalidCaveatFieldsError = exports.CaveatInvalidJsonError = exports.CaveatMissingValueError = exports.InvalidCaveatTypeError = exports.InvalidCaveatError = exports.CaveatAlreadyExistsError = exports.CaveatDoesNotExistError = exports.InvalidCaveatsPropertyError = exports.UnrecognizedCaveatTypeError = exports.EndowmentPermissionDoesNotExistError = exports.PermissionDoesNotExistError = exports.InvalidApprovedPermissionError = exports.InvalidMergedPermissionsError = exports.CaveatMergerDoesNotExistError = exports.UnrecognizedSubjectError = exports.InvalidSubjectIdentifierError = exports.internalError = exports.userRejectedRequest = exports.invalidParams = exports.methodNotFound = exports.unauthorized = void 0;
4
4
  const rpc_errors_1 = require("@metamask/rpc-errors");
5
+ const rpc_errors_2 = require("@metamask/rpc-errors");
5
6
  /**
6
7
  * Utility function for building an "unauthorized" error.
7
8
  *
@@ -9,7 +10,7 @@ const rpc_errors_1 = require("@metamask/rpc-errors");
9
10
  * @returns The built error
10
11
  */
11
12
  function unauthorized(opts) {
12
- return rpc_errors_1.providerErrors.unauthorized({
13
+ return rpc_errors_2.providerErrors.unauthorized({
13
14
  message: 'Unauthorized to perform action. Try requesting the required permission(s) first. For more information, see: https://docs.metamask.io/guide/rpc-api.html#permissions',
14
15
  data: opts.data,
15
16
  });
@@ -28,7 +29,7 @@ function methodNotFound(method, data) {
28
29
  if (data !== undefined) {
29
30
  opts.data = data;
30
31
  }
31
- return rpc_errors_1.rpcErrors.methodNotFound(opts);
32
+ return rpc_errors_2.rpcErrors.methodNotFound(opts);
32
33
  }
33
34
  exports.methodNotFound = methodNotFound;
34
35
  /**
@@ -38,7 +39,7 @@ exports.methodNotFound = methodNotFound;
38
39
  * @returns The built error
39
40
  */
40
41
  function invalidParams(opts) {
41
- return rpc_errors_1.rpcErrors.invalidParams({
42
+ return rpc_errors_2.rpcErrors.invalidParams({
42
43
  data: opts.data,
43
44
  message: opts.message,
44
45
  });
@@ -51,7 +52,7 @@ exports.invalidParams = invalidParams;
51
52
  * @returns The built error
52
53
  */
53
54
  function userRejectedRequest(data) {
54
- return rpc_errors_1.providerErrors.userRejectedRequest({ data });
55
+ return rpc_errors_2.providerErrors.userRejectedRequest({ data });
55
56
  }
56
57
  exports.userRejectedRequest = userRejectedRequest;
57
58
  /**
@@ -62,7 +63,7 @@ exports.userRejectedRequest = userRejectedRequest;
62
63
  * @returns The built error
63
64
  */
64
65
  function internalError(message, data) {
65
- return rpc_errors_1.rpcErrors.internal({ message, data });
66
+ return rpc_errors_2.rpcErrors.internal({ message, data });
66
67
  }
67
68
  exports.internalError = internalError;
68
69
  class CustomError extends Error {
@@ -153,9 +154,9 @@ class CaveatAlreadyExistsError extends CustomError {
153
154
  }
154
155
  }
155
156
  exports.CaveatAlreadyExistsError = CaveatAlreadyExistsError;
156
- class InvalidCaveatError extends rpc_errors_1.JsonRpcError {
157
+ class InvalidCaveatError extends rpc_errors_2.JsonRpcError {
157
158
  constructor(receivedCaveat, origin, target) {
158
- super(rpc_errors_1.errorCodes.rpc.invalidParams, `Invalid caveat. Caveats must be plain objects.`, { receivedCaveat });
159
+ super(rpc_errors_2.errorCodes.rpc.invalidParams, `Invalid caveat. Caveats must be plain objects.`, { receivedCaveat });
159
160
  this.data = { origin, target };
160
161
  }
161
162
  }
@@ -1 +1 @@
1
- {"version":3,"file":"errors.cjs","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DataWithOptionalCause } from '@metamask/rpc-errors';\nimport {\n errorCodes,\n providerErrors,\n rpcErrors,\n JsonRpcError,\n} from '@metamask/rpc-errors';\n\nimport type { CaveatConstraint } from './Caveat';\nimport type { PermissionType } from './Permission';\nimport type { PermissionDiffMap } from './PermissionController';\n\ntype UnauthorizedArg = {\n data?: Record<string, unknown>;\n message?: string;\n};\n\n/**\n * Utility function for building an \"unauthorized\" error.\n *\n * @param opts - Optional arguments that add extra context\n * @returns The built error\n */\nexport function unauthorized(opts: UnauthorizedArg) {\n return providerErrors.unauthorized({\n message:\n 'Unauthorized to perform action. Try requesting the required permission(s) first. For more information, see: https://docs.metamask.io/guide/rpc-api.html#permissions',\n data: opts.data,\n });\n}\n\n/**\n * Utility function for building a \"method not found\" error.\n *\n * @param method - The method in question.\n * @param data - Optional data for context.\n * @returns The built error\n */\nexport function methodNotFound(method: string, data?: DataWithOptionalCause) {\n const message = `The method \"${method}\" does not exist / is not available.`;\n\n const opts: Parameters<typeof rpcErrors.methodNotFound>[0] = { message };\n if (data !== undefined) {\n opts.data = data;\n }\n return rpcErrors.methodNotFound(opts);\n}\n\ntype InvalidParamsArg = {\n message?: string;\n data?: DataWithOptionalCause;\n};\n\n/**\n * Utility function for building an \"invalid params\" error.\n *\n * @param opts - Optional arguments that add extra context\n * @returns The built error\n */\nexport function invalidParams(opts: InvalidParamsArg) {\n return rpcErrors.invalidParams({\n data: opts.data,\n message: opts.message,\n });\n}\n\n/**\n * Utility function for building an \"user rejected request\" error.\n *\n * @param data - Optional data to add extra context\n * @returns The built error\n */\nexport function userRejectedRequest<Data extends Record<string, unknown>>(\n data?: Data,\n): JsonRpcError<Data> {\n return providerErrors.userRejectedRequest({ data });\n}\n\n/**\n * Utility function for building an internal error.\n *\n * @param message - The error message\n * @param data - Optional data to add extra context\n * @returns The built error\n */\nexport function internalError<Data extends Record<string, unknown>>(\n message: string,\n data?: Data,\n): JsonRpcError<Data> {\n return rpcErrors.internal({ message, data });\n}\n\nclass CustomError extends Error {\n constructor(message?: string) {\n super(message);\n this.name = this.constructor.name;\n }\n}\n\nexport class InvalidSubjectIdentifierError extends CustomError {\n constructor(origin: unknown) {\n super(\n `Invalid subject identifier: \"${\n typeof origin === 'string' ? origin : typeof origin\n }\"`,\n );\n this.name = this.constructor.name;\n }\n}\n\nexport class UnrecognizedSubjectError extends CustomError {\n constructor(origin: string) {\n super(`Unrecognized subject: \"${origin}\" has no permissions.`);\n this.name = this.constructor.name;\n }\n}\n\nexport class CaveatMergerDoesNotExistError extends CustomError {\n constructor(caveatType: string) {\n super(`Caveat value merger does not exist for type: \"${caveatType}\"`);\n }\n}\n\nexport class InvalidMergedPermissionsError extends Error {\n public cause: Error;\n\n public data: {\n diff: PermissionDiffMap<string, CaveatConstraint>;\n };\n\n constructor(\n origin: string,\n cause: Error,\n diff: PermissionDiffMap<string, CaveatConstraint>,\n ) {\n super(\n `Invalid merged permissions for subject \"${origin}\":\\n${cause.message}`,\n );\n this.cause = cause;\n this.data = { diff };\n }\n}\n\nexport class InvalidApprovedPermissionError extends CustomError {\n public data: {\n origin: string;\n target: string;\n approvedPermission: Record<string, unknown>;\n };\n\n constructor(\n origin: string,\n target: string,\n approvedPermission: Record<string, unknown>,\n ) {\n super(\n `Invalid approved permission for origin \"${origin}\" and target \"${target}\".`,\n );\n this.data = { origin, target, approvedPermission };\n }\n}\nexport class PermissionDoesNotExistError extends CustomError {\n constructor(origin: string, target: string) {\n super(`Subject \"${origin}\" has no permission for \"${target}\".`);\n }\n}\n\nexport class EndowmentPermissionDoesNotExistError extends CustomError {\n public data?: { origin: string };\n\n constructor(target: string, origin?: string) {\n super(\n `${\n origin ? `Subject \"${origin}\"` : 'Unknown subject'\n } has no permission for \"${target}\".`,\n );\n if (origin) {\n this.data = { origin };\n }\n }\n}\n\nexport class UnrecognizedCaveatTypeError extends CustomError {\n public data: {\n caveatType: string;\n origin?: string;\n target?: string;\n };\n\n constructor(caveatType: string);\n\n constructor(caveatType: string, origin: string, target: string);\n\n constructor(caveatType: string, origin?: string, target?: string) {\n super(`Unrecognized caveat type: \"${caveatType}\"`);\n this.data = { caveatType };\n if (origin !== undefined) {\n this.data.origin = origin;\n }\n\n if (target !== undefined) {\n this.data.target = target;\n }\n }\n}\n\nexport class InvalidCaveatsPropertyError extends CustomError {\n public data: { origin: string; target: string; caveatsProperty: unknown };\n\n constructor(origin: string, target: string, caveatsProperty: unknown) {\n super(\n `The \"caveats\" property of permission for \"${target}\" of subject \"${origin}\" is invalid. It must be a non-empty array if specified.`,\n );\n this.data = { origin, target, caveatsProperty };\n }\n}\n\nexport class CaveatDoesNotExistError extends CustomError {\n constructor(origin: string, target: string, caveatType: string) {\n super(\n `Permission for \"${target}\" of subject \"${origin}\" has no caveat of type \"${caveatType}\".`,\n );\n }\n}\n\nexport class CaveatAlreadyExistsError extends CustomError {\n constructor(origin: string, target: string, caveatType: string) {\n super(\n `Permission for \"${target}\" of subject \"${origin}\" already has a caveat of type \"${caveatType}\".`,\n );\n }\n}\n\nexport class InvalidCaveatError extends JsonRpcError<\n DataWithOptionalCause | undefined\n> {\n public override data: { origin: string; target: string };\n\n constructor(receivedCaveat: unknown, origin: string, target: string) {\n super(\n errorCodes.rpc.invalidParams,\n `Invalid caveat. Caveats must be plain objects.`,\n { receivedCaveat },\n );\n this.data = { origin, target };\n }\n}\n\nexport class InvalidCaveatTypeError extends CustomError {\n public data: {\n caveat: Record<string, unknown>;\n origin: string;\n target: string;\n };\n\n constructor(caveat: Record<string, unknown>, origin: string, target: string) {\n super(`Caveat types must be strings. Received: \"${typeof caveat.type}\"`);\n this.data = { caveat, origin, target };\n }\n}\n\nexport class CaveatMissingValueError extends CustomError {\n public data: {\n caveat: Record<string, unknown>;\n origin: string;\n target: string;\n };\n\n constructor(caveat: Record<string, unknown>, origin: string, target: string) {\n super(`Caveat is missing \"value\" field.`);\n this.data = { caveat, origin, target };\n }\n}\n\nexport class CaveatInvalidJsonError extends CustomError {\n public data: {\n caveat: Record<string, unknown>;\n origin: string;\n target: string;\n };\n\n constructor(caveat: Record<string, unknown>, origin: string, target: string) {\n super(`Caveat \"value\" is invalid JSON.`);\n this.data = { caveat, origin, target };\n }\n}\n\nexport class InvalidCaveatFieldsError extends CustomError {\n public data: {\n caveat: Record<string, unknown>;\n origin: string;\n target: string;\n };\n\n constructor(caveat: Record<string, unknown>, origin: string, target: string) {\n super(\n `Caveat has unexpected number of fields: \"${Object.keys(caveat).length}\"`,\n );\n this.data = { caveat, origin, target };\n }\n}\n\nexport class ForbiddenCaveatError extends CustomError {\n public data: {\n caveatType: string;\n origin: string;\n target: string;\n };\n\n constructor(caveatType: string, origin: string, targetName: string) {\n super(\n `Permissions for target \"${targetName}\" may not have caveats of type \"${caveatType}\".`,\n );\n this.data = { caveatType, origin, target: targetName };\n }\n}\n\nexport class DuplicateCaveatError extends CustomError {\n public data: {\n caveatType: string;\n origin: string;\n target: string;\n };\n\n constructor(caveatType: string, origin: string, targetName: string) {\n super(\n `Permissions for target \"${targetName}\" contains multiple caveats of type \"${caveatType}\".`,\n );\n this.data = { caveatType, origin, target: targetName };\n }\n}\n\nexport class CaveatMergeTypeMismatchError extends CustomError {\n public data: {\n leftCaveatType: string;\n rightCaveatType: string;\n };\n\n constructor(leftCaveatType: string, rightCaveatType: string) {\n super(\n `Cannot merge caveats of different types: \"${leftCaveatType}\" and \"${rightCaveatType}\".`,\n );\n this.data = { leftCaveatType, rightCaveatType };\n }\n}\n\nexport class CaveatSpecificationMismatchError extends CustomError {\n public data: {\n caveatSpec: Record<string, unknown>;\n permissionType: PermissionType;\n };\n\n constructor(\n caveatSpec: Record<string, unknown>,\n permissionType: PermissionType,\n ) {\n super(\n `Caveat specification uses a mismatched type. Expected caveats for ${permissionType}`,\n );\n this.data = { caveatSpec, permissionType };\n }\n}\n\nexport class PermissionsRequestNotFoundError extends CustomError {\n constructor(id: string) {\n super(`Permissions request with id \"${id}\" not found.`);\n }\n}\n"]}
1
+ {"version":3,"file":"errors.cjs","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n DataWithOptionalCause,\n EthereumProviderError,\n OptionalDataWithOptionalCause,\n} from '@metamask/rpc-errors';\nimport {\n errorCodes,\n providerErrors,\n rpcErrors,\n JsonRpcError,\n} from '@metamask/rpc-errors';\n\nimport type { CaveatConstraint } from './Caveat';\nimport type { PermissionType } from './Permission';\nimport type { PermissionDiffMap } from './PermissionController';\n\ntype UnauthorizedArg = {\n data?: Record<string, unknown>;\n message?: string;\n};\n\n/**\n * Utility function for building an \"unauthorized\" error.\n *\n * @param opts - Optional arguments that add extra context\n * @returns The built error\n */\nexport function unauthorized(\n opts: UnauthorizedArg,\n): EthereumProviderError<UnauthorizedArg> {\n return providerErrors.unauthorized({\n message:\n 'Unauthorized to perform action. Try requesting the required permission(s) first. For more information, see: https://docs.metamask.io/guide/rpc-api.html#permissions',\n data: opts.data,\n });\n}\n\n/**\n * Utility function for building a \"method not found\" error.\n *\n * @param method - The method in question.\n * @param data - Optional data for context.\n * @returns The built error\n */\nexport function methodNotFound(\n method: string,\n data?: DataWithOptionalCause,\n): JsonRpcError<OptionalDataWithOptionalCause> {\n const message = `The method \"${method}\" does not exist / is not available.`;\n\n const opts: Parameters<typeof rpcErrors.methodNotFound>[0] = { message };\n if (data !== undefined) {\n opts.data = data;\n }\n return rpcErrors.methodNotFound(opts);\n}\n\ntype InvalidParamsArg = {\n message?: string;\n data?: DataWithOptionalCause;\n};\n\n/**\n * Utility function for building an \"invalid params\" error.\n *\n * @param opts - Optional arguments that add extra context\n * @returns The built error\n */\nexport function invalidParams(\n opts: InvalidParamsArg,\n): JsonRpcError<DataWithOptionalCause> {\n return rpcErrors.invalidParams({\n data: opts.data,\n message: opts.message,\n });\n}\n\n/**\n * Utility function for building an \"user rejected request\" error.\n *\n * @param data - Optional data to add extra context\n * @returns The built error\n */\nexport function userRejectedRequest<Data extends Record<string, unknown>>(\n data?: Data,\n): JsonRpcError<Data> {\n return providerErrors.userRejectedRequest({ data });\n}\n\n/**\n * Utility function for building an internal error.\n *\n * @param message - The error message\n * @param data - Optional data to add extra context\n * @returns The built error\n */\nexport function internalError<Data extends Record<string, unknown>>(\n message: string,\n data?: Data,\n): JsonRpcError<Data> {\n return rpcErrors.internal({ message, data });\n}\n\nclass CustomError extends Error {\n constructor(message?: string) {\n super(message);\n this.name = this.constructor.name;\n }\n}\n\nexport class InvalidSubjectIdentifierError extends CustomError {\n constructor(origin: unknown) {\n super(\n `Invalid subject identifier: \"${\n typeof origin === 'string' ? origin : typeof origin\n }\"`,\n );\n this.name = this.constructor.name;\n }\n}\n\nexport class UnrecognizedSubjectError extends CustomError {\n constructor(origin: string) {\n super(`Unrecognized subject: \"${origin}\" has no permissions.`);\n this.name = this.constructor.name;\n }\n}\n\nexport class CaveatMergerDoesNotExistError extends CustomError {\n constructor(caveatType: string) {\n super(`Caveat value merger does not exist for type: \"${caveatType}\"`);\n }\n}\n\nexport class InvalidMergedPermissionsError extends Error {\n public cause: Error;\n\n public data: {\n diff: PermissionDiffMap<string, CaveatConstraint>;\n };\n\n constructor(\n origin: string,\n cause: Error,\n diff: PermissionDiffMap<string, CaveatConstraint>,\n ) {\n super(\n `Invalid merged permissions for subject \"${origin}\":\\n${cause.message}`,\n );\n this.cause = cause;\n this.data = { diff };\n }\n}\n\nexport class InvalidApprovedPermissionError extends CustomError {\n public data: {\n origin: string;\n target: string;\n approvedPermission: Record<string, unknown>;\n };\n\n constructor(\n origin: string,\n target: string,\n approvedPermission: Record<string, unknown>,\n ) {\n super(\n `Invalid approved permission for origin \"${origin}\" and target \"${target}\".`,\n );\n this.data = { origin, target, approvedPermission };\n }\n}\nexport class PermissionDoesNotExistError extends CustomError {\n constructor(origin: string, target: string) {\n super(`Subject \"${origin}\" has no permission for \"${target}\".`);\n }\n}\n\nexport class EndowmentPermissionDoesNotExistError extends CustomError {\n public data?: { origin: string };\n\n constructor(target: string, origin?: string) {\n super(\n `${\n origin ? `Subject \"${origin}\"` : 'Unknown subject'\n } has no permission for \"${target}\".`,\n );\n if (origin) {\n this.data = { origin };\n }\n }\n}\n\nexport class UnrecognizedCaveatTypeError extends CustomError {\n public data: {\n caveatType: string;\n origin?: string;\n target?: string;\n };\n\n constructor(caveatType: string);\n\n constructor(caveatType: string, origin: string, target: string);\n\n constructor(caveatType: string, origin?: string, target?: string) {\n super(`Unrecognized caveat type: \"${caveatType}\"`);\n this.data = { caveatType };\n if (origin !== undefined) {\n this.data.origin = origin;\n }\n\n if (target !== undefined) {\n this.data.target = target;\n }\n }\n}\n\nexport class InvalidCaveatsPropertyError extends CustomError {\n public data: { origin: string; target: string; caveatsProperty: unknown };\n\n constructor(origin: string, target: string, caveatsProperty: unknown) {\n super(\n `The \"caveats\" property of permission for \"${target}\" of subject \"${origin}\" is invalid. It must be a non-empty array if specified.`,\n );\n this.data = { origin, target, caveatsProperty };\n }\n}\n\nexport class CaveatDoesNotExistError extends CustomError {\n constructor(origin: string, target: string, caveatType: string) {\n super(\n `Permission for \"${target}\" of subject \"${origin}\" has no caveat of type \"${caveatType}\".`,\n );\n }\n}\n\nexport class CaveatAlreadyExistsError extends CustomError {\n constructor(origin: string, target: string, caveatType: string) {\n super(\n `Permission for \"${target}\" of subject \"${origin}\" already has a caveat of type \"${caveatType}\".`,\n );\n }\n}\n\nexport class InvalidCaveatError extends JsonRpcError<\n DataWithOptionalCause | undefined\n> {\n public override data: { origin: string; target: string };\n\n constructor(receivedCaveat: unknown, origin: string, target: string) {\n super(\n errorCodes.rpc.invalidParams,\n `Invalid caveat. Caveats must be plain objects.`,\n { receivedCaveat },\n );\n this.data = { origin, target };\n }\n}\n\nexport class InvalidCaveatTypeError extends CustomError {\n public data: {\n caveat: Record<string, unknown>;\n origin: string;\n target: string;\n };\n\n constructor(caveat: Record<string, unknown>, origin: string, target: string) {\n super(`Caveat types must be strings. Received: \"${typeof caveat.type}\"`);\n this.data = { caveat, origin, target };\n }\n}\n\nexport class CaveatMissingValueError extends CustomError {\n public data: {\n caveat: Record<string, unknown>;\n origin: string;\n target: string;\n };\n\n constructor(caveat: Record<string, unknown>, origin: string, target: string) {\n super(`Caveat is missing \"value\" field.`);\n this.data = { caveat, origin, target };\n }\n}\n\nexport class CaveatInvalidJsonError extends CustomError {\n public data: {\n caveat: Record<string, unknown>;\n origin: string;\n target: string;\n };\n\n constructor(caveat: Record<string, unknown>, origin: string, target: string) {\n super(`Caveat \"value\" is invalid JSON.`);\n this.data = { caveat, origin, target };\n }\n}\n\nexport class InvalidCaveatFieldsError extends CustomError {\n public data: {\n caveat: Record<string, unknown>;\n origin: string;\n target: string;\n };\n\n constructor(caveat: Record<string, unknown>, origin: string, target: string) {\n super(\n `Caveat has unexpected number of fields: \"${Object.keys(caveat).length}\"`,\n );\n this.data = { caveat, origin, target };\n }\n}\n\nexport class ForbiddenCaveatError extends CustomError {\n public data: {\n caveatType: string;\n origin: string;\n target: string;\n };\n\n constructor(caveatType: string, origin: string, targetName: string) {\n super(\n `Permissions for target \"${targetName}\" may not have caveats of type \"${caveatType}\".`,\n );\n this.data = { caveatType, origin, target: targetName };\n }\n}\n\nexport class DuplicateCaveatError extends CustomError {\n public data: {\n caveatType: string;\n origin: string;\n target: string;\n };\n\n constructor(caveatType: string, origin: string, targetName: string) {\n super(\n `Permissions for target \"${targetName}\" contains multiple caveats of type \"${caveatType}\".`,\n );\n this.data = { caveatType, origin, target: targetName };\n }\n}\n\nexport class CaveatMergeTypeMismatchError extends CustomError {\n public data: {\n leftCaveatType: string;\n rightCaveatType: string;\n };\n\n constructor(leftCaveatType: string, rightCaveatType: string) {\n super(\n `Cannot merge caveats of different types: \"${leftCaveatType}\" and \"${rightCaveatType}\".`,\n );\n this.data = { leftCaveatType, rightCaveatType };\n }\n}\n\nexport class CaveatSpecificationMismatchError extends CustomError {\n public data: {\n caveatSpec: Record<string, unknown>;\n permissionType: PermissionType;\n };\n\n constructor(\n caveatSpec: Record<string, unknown>,\n permissionType: PermissionType,\n ) {\n super(\n `Caveat specification uses a mismatched type. Expected caveats for ${permissionType}`,\n );\n this.data = { caveatSpec, permissionType };\n }\n}\n\nexport class PermissionsRequestNotFoundError extends CustomError {\n constructor(id: string) {\n super(`Permissions request with id \"${id}\" not found.`);\n }\n}\n"]}