@metamask-previews/permission-controller 12.1.0-preview-d4351f75 → 12.1.0-preview-98314cb

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.
@@ -49,14 +49,8 @@ class SubjectMetadataController extends base_controller_1.BaseController {
49
49
  this.subjectHasPermissions = hasPermissions;
50
50
  this.subjectCacheLimit = subjectCacheLimit;
51
51
  this.subjectsWithoutPermissionsEncounteredSinceStartup = new Set();
52
- this.messenger.registerActionHandler(
53
- // ESLint is confused by the string literal type.
54
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
55
- `${this.name}:getSubjectMetadata`, this.getSubjectMetadata.bind(this));
56
- this.messenger.registerActionHandler(
57
- // ESLint is confused by the string literal type.
58
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
59
- `${this.name}:addSubjectMetadata`, this.addSubjectMetadata.bind(this));
52
+ this.messenger.registerActionHandler(`${this.name}:getSubjectMetadata`, this.getSubjectMetadata.bind(this));
53
+ this.messenger.registerActionHandler(`${this.name}:addSubjectMetadata`, this.addSubjectMetadata.bind(this));
60
54
  }
61
55
  /**
62
56
  * Clears the state of this controller. Also resets the cache of subjects
@@ -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 // ESLint is confused by the string literal type.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n `${this.name}:getSubjectMetadata`,\n this.getSubjectMetadata.bind(this),\n );\n\n this.messenger.registerActionHandler(\n // ESLint is confused by the string literal type.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\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 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 +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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"}
@@ -1 +1 @@
1
- {"version":3,"file":"SubjectMetadataController.d.mts","sourceRoot":"","sources":["../src/SubjectMetadataController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SubjectMetadataController.d.mts","sourceRoot":"","sources":["../src/SubjectMetadataController.ts"],"names":[],"mappings":"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"}
@@ -46,14 +46,8 @@ export class SubjectMetadataController extends BaseController {
46
46
  this.subjectHasPermissions = hasPermissions;
47
47
  this.subjectCacheLimit = subjectCacheLimit;
48
48
  this.subjectsWithoutPermissionsEncounteredSinceStartup = new Set();
49
- this.messenger.registerActionHandler(
50
- // ESLint is confused by the string literal type.
51
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
52
- `${this.name}:getSubjectMetadata`, this.getSubjectMetadata.bind(this));
53
- this.messenger.registerActionHandler(
54
- // ESLint is confused by the string literal type.
55
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
56
- `${this.name}:addSubjectMetadata`, this.addSubjectMetadata.bind(this));
49
+ this.messenger.registerActionHandler(`${this.name}:getSubjectMetadata`, this.getSubjectMetadata.bind(this));
50
+ this.messenger.registerActionHandler(`${this.name}:addSubjectMetadata`, this.addSubjectMetadata.bind(this));
57
51
  }
58
52
  /**
59
53
  * Clears the state of this controller. Also resets the cache of subjects
@@ -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 // ESLint is confused by the string literal type.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n `${this.name}:getSubjectMetadata`,\n this.getSubjectMetadata.bind(this),\n );\n\n this.messenger.registerActionHandler(\n // ESLint is confused by the string literal type.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\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 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 +1 @@
1
- {"version":3,"file":"requestPermissions.cjs","sourceRoot":"","sources":["../../src/rpc-methods/requestPermissions.ts"],"names":[],"mappings":";;;AAAA,iEAA2D;AAI3D,0CAA0C;AAG1C,wCAAuC;AAE1B,QAAA,yBAAyB,GAIlC;IACF,WAAW,EAAE,CAAC,mBAAW,CAAC,kBAAkB,CAAC;IAC7C,cAAc,EAAE,gCAAgC;IAChD,SAAS,EAAE;QACT,2BAA2B,EAAE,IAAI;KAClC;CACF,CAAC;AAYF;;;;;;;;;;GAUG;AACH,KAAK,UAAU,gCAAgC,CAC7C,GAA2C,EAC3C,GAAmD,EACnD,KAAc,EACd,GAA6B,EAC7B,EAAE,2BAA2B,EAA2B;IAExD,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IAEvB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAA,gCAAa,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,OAAO,GAAG,CAAC,IAAA,sBAAa,EAAC,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,CAAC,oBAAoB,CAAC,GAAG,MAAM,CAAC;IACtC,MAAM,CAAC,kBAAkB,CAAC,GAAG,MAAM,2BAA2B,CAC5D,oBAAoB,CACrB,CAAC;IAEF,8DAA8D;IAC9D,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAC/C,OAAO,GAAG,EAAE,CAAC;AACf,CAAC","sourcesContent":["import { isPlainObject } from '@metamask/controller-utils';\nimport type { JsonRpcEngineEndCallback } from '@metamask/json-rpc-engine';\nimport type { JsonRpcRequest, PendingJsonRpcResponse } from '@metamask/utils';\n\nimport { invalidParams } from '../errors';\nimport type { PermissionConstraint, RequestedPermissions } from '../Permission';\nimport type { PermittedHandlerExport } from '../utils';\nimport { MethodNames } from '../utils';\n\nexport const requestPermissionsHandler: PermittedHandlerExport<\n RequestPermissionsHooks,\n [RequestedPermissions],\n PermissionConstraint[]\n> = {\n methodNames: [MethodNames.RequestPermissions],\n implementation: requestPermissionsImplementation,\n hookNames: {\n requestPermissionsForOrigin: true,\n },\n};\n\ntype RequestPermissions = (\n requestedPermissions: RequestedPermissions,\n) => Promise<\n [Record<string, PermissionConstraint>, { id: string; origin: string }]\n>;\n\nexport type RequestPermissionsHooks = {\n requestPermissionsForOrigin: RequestPermissions;\n};\n\n/**\n * Request Permissions implementation to be used in JsonRpcEngine middleware.\n *\n * @param req - The JsonRpcEngine request\n * @param res - The JsonRpcEngine result object\n * @param _next - JsonRpcEngine next() callback - unused\n * @param end - JsonRpcEngine end() callback\n * @param options - Method hooks passed to the method implementation\n * @param options.requestPermissionsForOrigin - The specific method hook needed for this method implementation\n * @returns A promise that resolves to nothing\n */\nasync function requestPermissionsImplementation(\n req: JsonRpcRequest<[RequestedPermissions]>,\n res: PendingJsonRpcResponse<PermissionConstraint[]>,\n _next: unknown,\n end: JsonRpcEngineEndCallback,\n { requestPermissionsForOrigin }: RequestPermissionsHooks,\n): Promise<void> {\n const { params } = req;\n\n if (!Array.isArray(params) || !isPlainObject(params[0])) {\n return end(invalidParams({ data: { request: req } }));\n }\n\n const [requestedPermissions] = params;\n const [grantedPermissions] = await requestPermissionsForOrigin(\n requestedPermissions,\n );\n\n // `wallet_requestPermission` is specified to return an array.\n res.result = Object.values(grantedPermissions);\n return end();\n}\n"]}
1
+ {"version":3,"file":"requestPermissions.cjs","sourceRoot":"","sources":["../../src/rpc-methods/requestPermissions.ts"],"names":[],"mappings":";;;AAAA,iEAA2D;AAI3D,0CAA0C;AAG1C,wCAAuC;AAE1B,QAAA,yBAAyB,GAIlC;IACF,WAAW,EAAE,CAAC,mBAAW,CAAC,kBAAkB,CAAC;IAC7C,cAAc,EAAE,gCAAgC;IAChD,SAAS,EAAE;QACT,2BAA2B,EAAE,IAAI;KAClC;CACF,CAAC;AAYF;;;;;;;;;;GAUG;AACH,KAAK,UAAU,gCAAgC,CAC7C,GAA2C,EAC3C,GAAmD,EACnD,KAAc,EACd,GAA6B,EAC7B,EAAE,2BAA2B,EAA2B;IAExD,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IAEvB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAA,gCAAa,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,OAAO,GAAG,CAAC,IAAA,sBAAa,EAAC,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,CAAC,oBAAoB,CAAC,GAAG,MAAM,CAAC;IACtC,MAAM,CAAC,kBAAkB,CAAC,GACxB,MAAM,2BAA2B,CAAC,oBAAoB,CAAC,CAAC;IAE1D,8DAA8D;IAC9D,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAC/C,OAAO,GAAG,EAAE,CAAC;AACf,CAAC","sourcesContent":["import { isPlainObject } from '@metamask/controller-utils';\nimport type { JsonRpcEngineEndCallback } from '@metamask/json-rpc-engine';\nimport type { JsonRpcRequest, PendingJsonRpcResponse } from '@metamask/utils';\n\nimport { invalidParams } from '../errors';\nimport type { PermissionConstraint, RequestedPermissions } from '../Permission';\nimport type { PermittedHandlerExport } from '../utils';\nimport { MethodNames } from '../utils';\n\nexport const requestPermissionsHandler: PermittedHandlerExport<\n RequestPermissionsHooks,\n [RequestedPermissions],\n PermissionConstraint[]\n> = {\n methodNames: [MethodNames.RequestPermissions],\n implementation: requestPermissionsImplementation,\n hookNames: {\n requestPermissionsForOrigin: true,\n },\n};\n\ntype RequestPermissions = (\n requestedPermissions: RequestedPermissions,\n) => Promise<\n [Record<string, PermissionConstraint>, { id: string; origin: string }]\n>;\n\nexport type RequestPermissionsHooks = {\n requestPermissionsForOrigin: RequestPermissions;\n};\n\n/**\n * Request Permissions implementation to be used in JsonRpcEngine middleware.\n *\n * @param req - The JsonRpcEngine request\n * @param res - The JsonRpcEngine result object\n * @param _next - JsonRpcEngine next() callback - unused\n * @param end - JsonRpcEngine end() callback\n * @param options - Method hooks passed to the method implementation\n * @param options.requestPermissionsForOrigin - The specific method hook needed for this method implementation\n * @returns A promise that resolves to nothing\n */\nasync function requestPermissionsImplementation(\n req: JsonRpcRequest<[RequestedPermissions]>,\n res: PendingJsonRpcResponse<PermissionConstraint[]>,\n _next: unknown,\n end: JsonRpcEngineEndCallback,\n { requestPermissionsForOrigin }: RequestPermissionsHooks,\n): Promise<void> {\n const { params } = req;\n\n if (!Array.isArray(params) || !isPlainObject(params[0])) {\n return end(invalidParams({ data: { request: req } }));\n }\n\n const [requestedPermissions] = params;\n const [grantedPermissions] =\n await requestPermissionsForOrigin(requestedPermissions);\n\n // `wallet_requestPermission` is specified to return an array.\n res.result = Object.values(grantedPermissions);\n return end();\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"requestPermissions.mjs","sourceRoot":"","sources":["../../src/rpc-methods/requestPermissions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,mCAAmC;AAI3D,OAAO,EAAE,aAAa,EAAE,sBAAkB;AAG1C,OAAO,EAAE,WAAW,EAAE,qBAAiB;AAEvC,MAAM,CAAC,MAAM,yBAAyB,GAIlC;IACF,WAAW,EAAE,CAAC,WAAW,CAAC,kBAAkB,CAAC;IAC7C,cAAc,EAAE,gCAAgC;IAChD,SAAS,EAAE;QACT,2BAA2B,EAAE,IAAI;KAClC;CACF,CAAC;AAYF;;;;;;;;;;GAUG;AACH,KAAK,UAAU,gCAAgC,CAC7C,GAA2C,EAC3C,GAAmD,EACnD,KAAc,EACd,GAA6B,EAC7B,EAAE,2BAA2B,EAA2B;IAExD,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IAEvB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,OAAO,GAAG,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,CAAC,oBAAoB,CAAC,GAAG,MAAM,CAAC;IACtC,MAAM,CAAC,kBAAkB,CAAC,GAAG,MAAM,2BAA2B,CAC5D,oBAAoB,CACrB,CAAC;IAEF,8DAA8D;IAC9D,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAC/C,OAAO,GAAG,EAAE,CAAC;AACf,CAAC","sourcesContent":["import { isPlainObject } from '@metamask/controller-utils';\nimport type { JsonRpcEngineEndCallback } from '@metamask/json-rpc-engine';\nimport type { JsonRpcRequest, PendingJsonRpcResponse } from '@metamask/utils';\n\nimport { invalidParams } from '../errors';\nimport type { PermissionConstraint, RequestedPermissions } from '../Permission';\nimport type { PermittedHandlerExport } from '../utils';\nimport { MethodNames } from '../utils';\n\nexport const requestPermissionsHandler: PermittedHandlerExport<\n RequestPermissionsHooks,\n [RequestedPermissions],\n PermissionConstraint[]\n> = {\n methodNames: [MethodNames.RequestPermissions],\n implementation: requestPermissionsImplementation,\n hookNames: {\n requestPermissionsForOrigin: true,\n },\n};\n\ntype RequestPermissions = (\n requestedPermissions: RequestedPermissions,\n) => Promise<\n [Record<string, PermissionConstraint>, { id: string; origin: string }]\n>;\n\nexport type RequestPermissionsHooks = {\n requestPermissionsForOrigin: RequestPermissions;\n};\n\n/**\n * Request Permissions implementation to be used in JsonRpcEngine middleware.\n *\n * @param req - The JsonRpcEngine request\n * @param res - The JsonRpcEngine result object\n * @param _next - JsonRpcEngine next() callback - unused\n * @param end - JsonRpcEngine end() callback\n * @param options - Method hooks passed to the method implementation\n * @param options.requestPermissionsForOrigin - The specific method hook needed for this method implementation\n * @returns A promise that resolves to nothing\n */\nasync function requestPermissionsImplementation(\n req: JsonRpcRequest<[RequestedPermissions]>,\n res: PendingJsonRpcResponse<PermissionConstraint[]>,\n _next: unknown,\n end: JsonRpcEngineEndCallback,\n { requestPermissionsForOrigin }: RequestPermissionsHooks,\n): Promise<void> {\n const { params } = req;\n\n if (!Array.isArray(params) || !isPlainObject(params[0])) {\n return end(invalidParams({ data: { request: req } }));\n }\n\n const [requestedPermissions] = params;\n const [grantedPermissions] = await requestPermissionsForOrigin(\n requestedPermissions,\n );\n\n // `wallet_requestPermission` is specified to return an array.\n res.result = Object.values(grantedPermissions);\n return end();\n}\n"]}
1
+ {"version":3,"file":"requestPermissions.mjs","sourceRoot":"","sources":["../../src/rpc-methods/requestPermissions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,mCAAmC;AAI3D,OAAO,EAAE,aAAa,EAAE,sBAAkB;AAG1C,OAAO,EAAE,WAAW,EAAE,qBAAiB;AAEvC,MAAM,CAAC,MAAM,yBAAyB,GAIlC;IACF,WAAW,EAAE,CAAC,WAAW,CAAC,kBAAkB,CAAC;IAC7C,cAAc,EAAE,gCAAgC;IAChD,SAAS,EAAE;QACT,2BAA2B,EAAE,IAAI;KAClC;CACF,CAAC;AAYF;;;;;;;;;;GAUG;AACH,KAAK,UAAU,gCAAgC,CAC7C,GAA2C,EAC3C,GAAmD,EACnD,KAAc,EACd,GAA6B,EAC7B,EAAE,2BAA2B,EAA2B;IAExD,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IAEvB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,OAAO,GAAG,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,CAAC,oBAAoB,CAAC,GAAG,MAAM,CAAC;IACtC,MAAM,CAAC,kBAAkB,CAAC,GACxB,MAAM,2BAA2B,CAAC,oBAAoB,CAAC,CAAC;IAE1D,8DAA8D;IAC9D,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAC/C,OAAO,GAAG,EAAE,CAAC;AACf,CAAC","sourcesContent":["import { isPlainObject } from '@metamask/controller-utils';\nimport type { JsonRpcEngineEndCallback } from '@metamask/json-rpc-engine';\nimport type { JsonRpcRequest, PendingJsonRpcResponse } from '@metamask/utils';\n\nimport { invalidParams } from '../errors';\nimport type { PermissionConstraint, RequestedPermissions } from '../Permission';\nimport type { PermittedHandlerExport } from '../utils';\nimport { MethodNames } from '../utils';\n\nexport const requestPermissionsHandler: PermittedHandlerExport<\n RequestPermissionsHooks,\n [RequestedPermissions],\n PermissionConstraint[]\n> = {\n methodNames: [MethodNames.RequestPermissions],\n implementation: requestPermissionsImplementation,\n hookNames: {\n requestPermissionsForOrigin: true,\n },\n};\n\ntype RequestPermissions = (\n requestedPermissions: RequestedPermissions,\n) => Promise<\n [Record<string, PermissionConstraint>, { id: string; origin: string }]\n>;\n\nexport type RequestPermissionsHooks = {\n requestPermissionsForOrigin: RequestPermissions;\n};\n\n/**\n * Request Permissions implementation to be used in JsonRpcEngine middleware.\n *\n * @param req - The JsonRpcEngine request\n * @param res - The JsonRpcEngine result object\n * @param _next - JsonRpcEngine next() callback - unused\n * @param end - JsonRpcEngine end() callback\n * @param options - Method hooks passed to the method implementation\n * @param options.requestPermissionsForOrigin - The specific method hook needed for this method implementation\n * @returns A promise that resolves to nothing\n */\nasync function requestPermissionsImplementation(\n req: JsonRpcRequest<[RequestedPermissions]>,\n res: PendingJsonRpcResponse<PermissionConstraint[]>,\n _next: unknown,\n end: JsonRpcEngineEndCallback,\n { requestPermissionsForOrigin }: RequestPermissionsHooks,\n): Promise<void> {\n const { params } = req;\n\n if (!Array.isArray(params) || !isPlainObject(params[0])) {\n return end(invalidParams({ data: { request: req } }));\n }\n\n const [requestedPermissions] = params;\n const [grantedPermissions] =\n await requestPermissionsForOrigin(requestedPermissions);\n\n // `wallet_requestPermission` is specified to return an array.\n res.result = Object.values(grantedPermissions);\n return end();\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/permission-controller",
3
- "version": "12.1.0-preview-d4351f75",
3
+ "version": "12.1.0-preview-98314cb",
4
4
  "description": "Mediates access to JSON-RPC methods, used to interact with pieces of the MetaMask stack, via middleware for json-rpc-engine",
5
5
  "keywords": [
6
6
  "MetaMask",