diff --git a/.yarn/patches/@metamask-permission-controller-npm-11.0.6-5b7ce789d2.patch b/.yarn/patches/@metamask-permission-controller-npm-11.0.6-5b7ce789d2.patch new file mode 100644 index 0000000000..b9884a3bbb --- /dev/null +++ b/.yarn/patches/@metamask-permission-controller-npm-11.0.6-5b7ce789d2.patch @@ -0,0 +1,749 @@ +diff --git a/dist/Caveat.cjs.map b/dist/Caveat.cjs.map +index 62a629c3f95451d215e51d4ef18ffc929803b251..d148b3098bbc34a850ac9ec1b0a6cdc4549ea67a 100644 +--- a/dist/Caveat.cjs.map ++++ b/dist/Caveat.cjs.map +@@ -1 +1 @@ +-{"version":3,"file":"Caveat.cjs","sourceRoot":"","sources":["../src/Caveat.ts"],"names":[],"mappings":";;;AACA,2CAA8C;AAE9C,yCAGkB;AAOlB,iDAA8C;AA+Q9C;;;;;GAKG;AACH,SAAgB,qCAAqC,CACnD,aAA4C;IAE5C,OAAO,IAAA,mBAAW,EAAC,aAAa,EAAE,WAAW,CAAC,CAAC;AACjD,CAAC;AAJD,sFAIC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,mBAAmB,CAGjC,oBAAwE,EACxE,UAA0C,EAAE,iCAAiC;AAC7E,oBAAkE;IAElE,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;IAC/B,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,oBAAoB,CAAC;KAC7B;IAED,IAAI,SAAS,GAAG,KAAK,EACnB,IAAuE,EACvE,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAEhC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;QAC5B,MAAM,aAAa,GACjB,oBAAoB,CAAC,MAAM,CAAC,IAAoC,CAAC,CAAC;QACpE,IAAI,CAAC,aAAa,EAAE;YAClB,MAAM,IAAI,oCAA2B,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;SACpD;QAED,IAAI,CAAC,qCAAqC,CAAC,aAAa,CAAC,EAAE;YACzD,MAAM,IAAI,yCAAgC,CACxC,aAAa,EACb,2BAAc,CAAC,gBAAgB,CAChC,CAAC;SACH;QACD,SAAS,GAAG,aAAa,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;KACxD;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAjCD,kDAiCC","sourcesContent":["import type { Json } from '@metamask/utils';\nimport { hasProperty } from '@metamask/utils';\n\nimport {\n CaveatSpecificationMismatchError,\n UnrecognizedCaveatTypeError,\n} from './errors';\nimport type {\n AsyncRestrictedMethod,\n RestrictedMethod,\n PermissionConstraint,\n RestrictedMethodParameters,\n} from './Permission';\nimport { PermissionType } from './Permission';\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport type { PermissionController } from './PermissionController';\n\nexport type CaveatConstraint = {\n /**\n * The type of the caveat. The type is presumed to be meaningful in the\n * context of the capability it is associated with.\n *\n * In MetaMask, every permission can only have one caveat of each type.\n */\n readonly type: string;\n\n /**\n * Any additional data necessary to enforce the caveat.\n */\n readonly value: Json;\n};\n\n/**\n * A `ZCAP-LD`-like caveat object. A caveat is associated with a particular\n * permission, and stored in its `caveats` array. Conceptually, a caveat is\n * an arbitrary attenuation of the authority granted by its associated\n * permission. It is the responsibility of the host to interpret and apply\n * the restriction represented by a caveat.\n *\n * @template Type - The type of the caveat.\n * @template Value - The value associated with the caveat.\n */\nexport type Caveat = {\n /**\n * The type of the caveat. The type is presumed to be meaningful in the\n * context of the capability it is associated with.\n *\n * In MetaMask, every permission can only have one caveat of each type.\n */\n readonly type: Type;\n\n /**\n * Any additional data necessary to enforce the caveat.\n */\n readonly value: Value;\n};\n\n// Next, we define types used for specifying caveats at the consumer layer,\n// and a function for applying caveats to a restricted method request. This is\n// Accomplished by decorating the restricted method implementation with the\n// the corresponding caveat functions.\n\n/**\n * A function for applying caveats to a restricted method request.\n *\n * @template ParentCaveat - The caveat type associated with this decorator.\n * @param decorated - The restricted method implementation to be decorated.\n * The method may have already been decorated with other caveats.\n * @param caveat - The caveat object.\n * @returns The decorated restricted method implementation.\n */\nexport type CaveatDecorator = (\n decorated: AsyncRestrictedMethod,\n caveat: ParentCaveat,\n) => AsyncRestrictedMethod;\n\n/**\n * Extracts a caveat value type from a caveat decorator.\n *\n * @template Decorator - The {@link CaveatDecorator} to extract a caveat value\n * type from.\n */\ntype ExtractCaveatValueFromDecorator<\n Decorator extends CaveatDecorator,\n> = Decorator extends (\n decorated: AsyncRestrictedMethod,\n caveat: infer ParentCaveat,\n) => AsyncRestrictedMethod\n ? ParentCaveat extends CaveatConstraint\n ? ParentCaveat['value']\n : never\n : never;\n\n/**\n * A function for validating caveats of a particular type.\n *\n * @see `validator` in {@link CaveatSpecificationBase} for more details.\n * @template ParentCaveat - The caveat type associated with this validator.\n * @param caveat - The caveat object to validate.\n * @param origin - The origin associated with the parent permission.\n * @param target - The target of the parent permission.\n */\nexport type CaveatValidator = (\n caveat: { type: ParentCaveat['type']; value: unknown },\n origin?: string,\n target?: string,\n) => void;\n\n/**\n * A map of caveat type strings to {@link CaveatDiff} values.\n */\nexport type CaveatDiffMap = {\n [CaveatType in ParentCaveat['type']]: ParentCaveat['value'];\n};\n\n/**\n * A function that merges two caveat values of the same type. The values must be\n * merged in the fashion of a right-biased union.\n *\n * @see `ARCHITECTURE.md` for more details.\n * @template Value - The type of the values to merge.\n * @param leftValue - The left-hand value.\n * @param rightValue - The right-hand value.\n * @returns `[newValue, diff]`, i.e. the merged value and the diff between the left value\n * and the new value. The diff must be expressed in the same type as the value itself.\n */\nexport type CaveatValueMerger = (\n leftValue: Value,\n rightValue: Value,\n) => [Value, Value] | [];\n\nexport type CaveatSpecificationBase = {\n /**\n * The string type of the caveat.\n */\n type: string;\n\n /**\n * The validator function used to validate caveats of the associated type\n * whenever they are constructed or mutated.\n *\n * The validator should throw an appropriate JSON-RPC error if validation fails.\n *\n * If no validator is specified, no validation of caveat values will be\n * performed. In instances where caveats are mutated but a permission's caveat\n * array has not changed, any corresponding permission validator will not be\n * called. For this reason, permission validators **must not** be relied upon\n * to validate caveats.\n */\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n validator?: CaveatValidator;\n\n /**\n * The merger function used to merge a pair of values of the associated caveat type\n * during incremental permission requests. The values must be merged in the fashion\n * of a right-biased union.\n *\n * @see `ARCHITECTURE.md` for more details.\n */\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n merger?: CaveatValueMerger;\n};\n\nexport type RestrictedMethodCaveatSpecificationConstraint =\n CaveatSpecificationBase & {\n /**\n * The decorator function used to apply the caveat to restricted method\n * requests.\n */\n decorator: CaveatDecorator;\n };\n\nexport type EndowmentCaveatSpecificationConstraint = CaveatSpecificationBase;\n\n/**\n * The constraint for caveat specification objects. Every {@link Caveat}\n * supported by a {@link PermissionController} must have an associated\n * specification, which is the source of truth for all caveat-related types.\n * In addition, a caveat specification may include a decorator function used\n * to apply the caveat's attenuation to a restricted method. It may also include\n * a validator function specified by the consumer.\n *\n * See the README for more details.\n */\nexport type CaveatSpecificationConstraint =\n | RestrictedMethodCaveatSpecificationConstraint\n | EndowmentCaveatSpecificationConstraint;\n\n/**\n * Options for {@link CaveatSpecificationBuilder} functions.\n */\ntype CaveatSpecificationBuilderOptions<\n DecoratorHooks extends Record,\n ValidatorHooks extends Record,\n> = {\n type?: string;\n decoratorHooks?: DecoratorHooks;\n validatorHooks?: ValidatorHooks;\n};\n\n/**\n * A function that builds caveat specifications. Modules that specify caveats\n * for external consumption should make this their primary / default export so\n * that host applications can use them to generate concrete specifications\n * tailored to their requirements.\n */\nexport type CaveatSpecificationBuilder<\n Options extends CaveatSpecificationBuilderOptions<\n Record,\n Record\n >,\n Specification extends CaveatSpecificationConstraint,\n> = (options: Options) => Specification;\n\n/**\n * A caveat specification export object, containing the\n * {@link CaveatSpecificationBuilder} function and \"hook name\" objects.\n */\nexport type CaveatSpecificationBuilderExportConstraint = {\n specificationBuilder: CaveatSpecificationBuilder<\n CaveatSpecificationBuilderOptions<\n Record,\n Record\n >,\n CaveatSpecificationConstraint\n >;\n decoratorHookNames?: Record;\n validatorHookNames?: Record;\n};\n\n/**\n * The specifications for all caveats supported by a particular\n * {@link PermissionController}.\n *\n * @template Specifications - The union of all {@link CaveatSpecificationConstraint} types.\n */\nexport type CaveatSpecificationMap<\n CaveatSpecification extends CaveatSpecificationConstraint,\n> = Record;\n\n/**\n * Extracts the union of all caveat types specified by the given\n * {@link CaveatSpecificationConstraint} type.\n *\n * @template CaveatSpecification - The {@link CaveatSpecificationConstraint} to extract a\n * caveat type union from.\n */\nexport type ExtractCaveats<\n CaveatSpecification extends CaveatSpecificationConstraint,\n> = CaveatSpecification extends RestrictedMethodCaveatSpecificationConstraint\n ? Caveat<\n CaveatSpecification['type'],\n ExtractCaveatValueFromDecorator<\n RestrictedMethodCaveatSpecificationConstraint['decorator']\n >\n >\n : Caveat;\n\n/**\n * Extracts the type of a specific {@link Caveat} from a union of caveat\n * specifications.\n *\n * @template CaveatSpecifications - The union of all caveat specifications.\n * @template CaveatType - The type of the caveat to extract.\n */\nexport type ExtractCaveat<\n CaveatSpecifications extends CaveatSpecificationConstraint,\n CaveatType extends string,\n> = Extract, { type: CaveatType }>;\n\n/**\n * Extracts the value type of a specific {@link Caveat} from a union of caveat\n * specifications.\n *\n * @template CaveatSpecifications - The union of all caveat specifications.\n * @template CaveatType - The type of the caveat whose value to extract.\n */\nexport type ExtractCaveatValue<\n CaveatSpecifications extends CaveatSpecificationConstraint,\n CaveatType extends string,\n> = ExtractCaveat['value'];\n\n/**\n * Determines whether a caveat specification is a restricted method caveat specification.\n *\n * @param specification - The caveat specification.\n * @returns True if the caveat specification is a restricted method caveat specification, otherwise false.\n */\nexport function isRestrictedMethodCaveatSpecification(\n specification: CaveatSpecificationConstraint,\n): specification is RestrictedMethodCaveatSpecificationConstraint {\n return hasProperty(specification, 'decorator');\n}\n\n/**\n * Decorate a restricted method implementation with its caveats.\n *\n * Note that all caveat functions (i.e. the argument and return value of the\n * decorator) must be awaited.\n *\n * @param methodImplementation - The restricted method implementation\n * @param permission - The origin's potential permission\n * @param caveatSpecifications - All caveat implementations\n * @returns The decorated method implementation\n */\nexport function decorateWithCaveats<\n CaveatSpecifications extends CaveatSpecificationConstraint,\n>(\n methodImplementation: RestrictedMethod,\n permission: Readonly, // bound to the requesting origin\n caveatSpecifications: CaveatSpecificationMap, // all caveat implementations\n): RestrictedMethod {\n const { caveats } = permission;\n if (!caveats) {\n return methodImplementation;\n }\n\n let decorated = async (\n args: Parameters>[0],\n ) => methodImplementation(args);\n\n for (const caveat of caveats) {\n const specification =\n caveatSpecifications[caveat.type as CaveatSpecifications['type']];\n if (!specification) {\n throw new UnrecognizedCaveatTypeError(caveat.type);\n }\n\n if (!isRestrictedMethodCaveatSpecification(specification)) {\n throw new CaveatSpecificationMismatchError(\n specification,\n PermissionType.RestrictedMethod,\n );\n }\n decorated = specification.decorator(decorated, caveat);\n }\n\n return decorated;\n}\n"]} +\ No newline at end of file ++{"version":3,"file":"Caveat.cjs","sourceRoot":"","sources":["../src/Caveat.ts"],"names":[],"mappings":";;;AACA,2CAA8C;AAE9C,yCAGkB;AAOlB,iDAA8C;AA6Q9C;;;;;GAKG;AACH,SAAgB,qCAAqC,CACnD,aAA4C;IAE5C,OAAO,IAAA,mBAAW,EAAC,aAAa,EAAE,WAAW,CAAC,CAAC;AACjD,CAAC;AAJD,sFAIC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,mBAAmB,CAGjC,oBAAwE,EACxE,UAA0C,EAAE,iCAAiC;AAC7E,oBAAkE;IAElE,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;IAC/B,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,oBAAoB,CAAC;KAC7B;IAED,IAAI,SAAS,GAAG,KAAK,EACnB,IAAuE,EACvE,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAEhC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;QAC5B,MAAM,aAAa,GACjB,oBAAoB,CAAC,MAAM,CAAC,IAAoC,CAAC,CAAC;QACpE,IAAI,CAAC,aAAa,EAAE;YAClB,MAAM,IAAI,oCAA2B,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;SACpD;QAED,IAAI,CAAC,qCAAqC,CAAC,aAAa,CAAC,EAAE;YACzD,MAAM,IAAI,yCAAgC,CACxC,aAAa,EACb,2BAAc,CAAC,gBAAgB,CAChC,CAAC;SACH;QACD,SAAS,GAAG,aAAa,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;KACxD;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAjCD,kDAiCC","sourcesContent":["import type { Json } from '@metamask/utils';\nimport { hasProperty } from '@metamask/utils';\n\nimport {\n CaveatSpecificationMismatchError,\n UnrecognizedCaveatTypeError,\n} from './errors';\nimport type {\n AsyncRestrictedMethod,\n RestrictedMethod,\n PermissionConstraint,\n RestrictedMethodParameters,\n} from './Permission';\nimport { PermissionType } from './Permission';\n\nexport type CaveatConstraint = {\n /**\n * The type of the caveat. The type is presumed to be meaningful in the\n * context of the capability it is associated with.\n *\n * In MetaMask, every permission can only have one caveat of each type.\n */\n readonly type: string;\n\n /**\n * Any additional data necessary to enforce the caveat.\n */\n readonly value: Json;\n};\n\n/**\n * A `ZCAP-LD`-like caveat object. A caveat is associated with a particular\n * permission, and stored in its `caveats` array. Conceptually, a caveat is\n * an arbitrary attenuation of the authority granted by its associated\n * permission. It is the responsibility of the host to interpret and apply\n * the restriction represented by a caveat.\n *\n * @template Type - The type of the caveat.\n * @template Value - The value associated with the caveat.\n */\nexport type Caveat = {\n /**\n * The type of the caveat. The type is presumed to be meaningful in the\n * context of the capability it is associated with.\n *\n * In MetaMask, every permission can only have one caveat of each type.\n */\n readonly type: Type;\n\n /**\n * Any additional data necessary to enforce the caveat.\n */\n readonly value: Value;\n};\n\n// Next, we define types used for specifying caveats at the consumer layer,\n// and a function for applying caveats to a restricted method request. This is\n// Accomplished by decorating the restricted method implementation with the\n// the corresponding caveat functions.\n\n/**\n * A function for applying caveats to a restricted method request.\n *\n * @template ParentCaveat - The caveat type associated with this decorator.\n * @param decorated - The restricted method implementation to be decorated.\n * The method may have already been decorated with other caveats.\n * @param caveat - The caveat object.\n * @returns The decorated restricted method implementation.\n */\nexport type CaveatDecorator = (\n decorated: AsyncRestrictedMethod,\n caveat: ParentCaveat,\n) => AsyncRestrictedMethod;\n\n/**\n * Extracts a caveat value type from a caveat decorator.\n *\n * @template Decorator - The {@link CaveatDecorator} to extract a caveat value\n * type from.\n */\ntype ExtractCaveatValueFromDecorator<\n Decorator extends CaveatDecorator,\n> = Decorator extends (\n decorated: AsyncRestrictedMethod,\n caveat: infer ParentCaveat,\n) => AsyncRestrictedMethod\n ? ParentCaveat extends CaveatConstraint\n ? ParentCaveat['value']\n : never\n : never;\n\n/**\n * A function for validating caveats of a particular type.\n *\n * @see `validator` in {@link CaveatSpecificationBase} for more details.\n * @template ParentCaveat - The caveat type associated with this validator.\n * @param caveat - The caveat object to validate.\n * @param origin - The origin associated with the parent permission.\n * @param target - The target of the parent permission.\n */\nexport type CaveatValidator = (\n caveat: { type: ParentCaveat['type']; value: unknown },\n origin?: string,\n target?: string,\n) => void;\n\n/**\n * A map of caveat type strings to {@link CaveatDiff} values.\n */\nexport type CaveatDiffMap = {\n [CaveatType in ParentCaveat['type']]: ParentCaveat['value'];\n};\n\n/**\n * A function that merges two caveat values of the same type. The values must be\n * merged in the fashion of a right-biased union.\n *\n * @see `ARCHITECTURE.md` for more details.\n * @template Value - The type of the values to merge.\n * @param leftValue - The left-hand value.\n * @param rightValue - The right-hand value.\n * @returns `[newValue, diff]`, i.e. the merged value and the diff between the left value\n * and the new value. The diff must be expressed in the same type as the value itself.\n */\nexport type CaveatValueMerger = (\n leftValue: Value,\n rightValue: Value,\n) => [Value, Value] | [];\n\nexport type CaveatSpecificationBase = {\n /**\n * The string type of the caveat.\n */\n type: string;\n\n /**\n * The validator function used to validate caveats of the associated type\n * whenever they are constructed or mutated.\n *\n * The validator should throw an appropriate JSON-RPC error if validation fails.\n *\n * If no validator is specified, no validation of caveat values will be\n * performed. In instances where caveats are mutated but a permission's caveat\n * array has not changed, any corresponding permission validator will not be\n * called. For this reason, permission validators **must not** be relied upon\n * to validate caveats.\n */\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n validator?: CaveatValidator;\n\n /**\n * The merger function used to merge a pair of values of the associated caveat type\n * during incremental permission requests. The values must be merged in the fashion\n * of a right-biased union.\n *\n * @see `ARCHITECTURE.md` for more details.\n */\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n merger?: CaveatValueMerger;\n};\n\nexport type RestrictedMethodCaveatSpecificationConstraint =\n CaveatSpecificationBase & {\n /**\n * The decorator function used to apply the caveat to restricted method\n * requests.\n */\n decorator: CaveatDecorator;\n };\n\nexport type EndowmentCaveatSpecificationConstraint = CaveatSpecificationBase;\n\n/**\n * The constraint for caveat specification objects. Every {@link Caveat}\n * supported by a {@link PermissionController} must have an associated\n * specification, which is the source of truth for all caveat-related types.\n * In addition, a caveat specification may include a decorator function used\n * to apply the caveat's attenuation to a restricted method. It may also include\n * a validator function specified by the consumer.\n *\n * See the README for more details.\n */\nexport type CaveatSpecificationConstraint =\n | RestrictedMethodCaveatSpecificationConstraint\n | EndowmentCaveatSpecificationConstraint;\n\n/**\n * Options for {@link CaveatSpecificationBuilder} functions.\n */\ntype CaveatSpecificationBuilderOptions<\n DecoratorHooks extends Record,\n ValidatorHooks extends Record,\n> = {\n type?: string;\n decoratorHooks?: DecoratorHooks;\n validatorHooks?: ValidatorHooks;\n};\n\n/**\n * A function that builds caveat specifications. Modules that specify caveats\n * for external consumption should make this their primary / default export so\n * that host applications can use them to generate concrete specifications\n * tailored to their requirements.\n */\nexport type CaveatSpecificationBuilder<\n Options extends CaveatSpecificationBuilderOptions<\n Record,\n Record\n >,\n Specification extends CaveatSpecificationConstraint,\n> = (options: Options) => Specification;\n\n/**\n * A caveat specification export object, containing the\n * {@link CaveatSpecificationBuilder} function and \"hook name\" objects.\n */\nexport type CaveatSpecificationBuilderExportConstraint = {\n specificationBuilder: CaveatSpecificationBuilder<\n CaveatSpecificationBuilderOptions<\n Record,\n Record\n >,\n CaveatSpecificationConstraint\n >;\n decoratorHookNames?: Record;\n validatorHookNames?: Record;\n};\n\n/**\n * The specifications for all caveats supported by a particular\n * {@link PermissionController}.\n *\n * @template Specifications - The union of all {@link CaveatSpecificationConstraint} types.\n */\nexport type CaveatSpecificationMap<\n CaveatSpecification extends CaveatSpecificationConstraint,\n> = Record;\n\n/**\n * Extracts the union of all caveat types specified by the given\n * {@link CaveatSpecificationConstraint} type.\n *\n * @template CaveatSpecification - The {@link CaveatSpecificationConstraint} to extract a\n * caveat type union from.\n */\nexport type ExtractCaveats<\n CaveatSpecification extends CaveatSpecificationConstraint,\n> = CaveatSpecification extends RestrictedMethodCaveatSpecificationConstraint\n ? Caveat<\n CaveatSpecification['type'],\n ExtractCaveatValueFromDecorator<\n RestrictedMethodCaveatSpecificationConstraint['decorator']\n >\n >\n : Caveat;\n\n/**\n * Extracts the type of a specific {@link Caveat} from a union of caveat\n * specifications.\n *\n * @template CaveatSpecifications - The union of all caveat specifications.\n * @template CaveatType - The type of the caveat to extract.\n */\nexport type ExtractCaveat<\n CaveatSpecifications extends CaveatSpecificationConstraint,\n CaveatType extends string,\n> = Extract, { type: CaveatType }>;\n\n/**\n * Extracts the value type of a specific {@link Caveat} from a union of caveat\n * specifications.\n *\n * @template CaveatSpecifications - The union of all caveat specifications.\n * @template CaveatType - The type of the caveat whose value to extract.\n */\nexport type ExtractCaveatValue<\n CaveatSpecifications extends CaveatSpecificationConstraint,\n CaveatType extends string,\n> = ExtractCaveat['value'];\n\n/**\n * Determines whether a caveat specification is a restricted method caveat specification.\n *\n * @param specification - The caveat specification.\n * @returns True if the caveat specification is a restricted method caveat specification, otherwise false.\n */\nexport function isRestrictedMethodCaveatSpecification(\n specification: CaveatSpecificationConstraint,\n): specification is RestrictedMethodCaveatSpecificationConstraint {\n return hasProperty(specification, 'decorator');\n}\n\n/**\n * Decorate a restricted method implementation with its caveats.\n *\n * Note that all caveat functions (i.e. the argument and return value of the\n * decorator) must be awaited.\n *\n * @param methodImplementation - The restricted method implementation\n * @param permission - The origin's potential permission\n * @param caveatSpecifications - All caveat implementations\n * @returns The decorated method implementation\n */\nexport function decorateWithCaveats<\n CaveatSpecifications extends CaveatSpecificationConstraint,\n>(\n methodImplementation: RestrictedMethod,\n permission: Readonly, // bound to the requesting origin\n caveatSpecifications: CaveatSpecificationMap, // all caveat implementations\n): RestrictedMethod {\n const { caveats } = permission;\n if (!caveats) {\n return methodImplementation;\n }\n\n let decorated = async (\n args: Parameters>[0],\n ) => methodImplementation(args);\n\n for (const caveat of caveats) {\n const specification =\n caveatSpecifications[caveat.type as CaveatSpecifications['type']];\n if (!specification) {\n throw new UnrecognizedCaveatTypeError(caveat.type);\n }\n\n if (!isRestrictedMethodCaveatSpecification(specification)) {\n throw new CaveatSpecificationMismatchError(\n specification,\n PermissionType.RestrictedMethod,\n );\n }\n decorated = specification.decorator(decorated, caveat);\n }\n\n return decorated;\n}\n"]} +\ No newline at end of file +diff --git a/dist/Caveat.d.cts.map b/dist/Caveat.d.cts.map +index 5c6a7d711bfcfc48061cc442558aaab285ead61c..f008732de51c89e0e8e1b7901b71deac84e0ed67 100644 +--- a/dist/Caveat.d.cts.map ++++ b/dist/Caveat.d.cts.map +@@ -1 +1 @@ +-{"version":3,"file":"Caveat.d.cts","sourceRoot":"","sources":["../src/Caveat.ts"],"names":[],"mappings":"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"} +\ No newline at end of file ++{"version":3,"file":"Caveat.d.cts","sourceRoot":"","sources":["../src/Caveat.ts"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/dist/Caveat.d.mts.map b/dist/Caveat.d.mts.map +index 6f650a0bb57ea215667576bc2d535049d409b64d..07a7eb6e83562ce58213fd152f406680574ac760 100644 +--- a/dist/Caveat.d.mts.map ++++ b/dist/Caveat.d.mts.map +@@ -1 +1 @@ +-{"version":3,"file":"Caveat.d.mts","sourceRoot":"","sources":["../src/Caveat.ts"],"names":[],"mappings":"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"} +\ No newline at end of file ++{"version":3,"file":"Caveat.d.mts","sourceRoot":"","sources":["../src/Caveat.ts"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/dist/Caveat.mjs.map b/dist/Caveat.mjs.map +index 18681ad0800ebe5a0640803c5237d1aa873c3a5b..9e66e53a5e5ea17592a9d17a88dde6e3b52a39b7 100644 +--- a/dist/Caveat.mjs.map ++++ b/dist/Caveat.mjs.map +@@ -1 +1 @@ +-{"version":3,"file":"Caveat.mjs","sourceRoot":"","sources":["../src/Caveat.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,wBAAwB;AAE9C,OAAO,EACL,gCAAgC,EAChC,2BAA2B,EAC5B,qBAAiB;AAOlB,OAAO,EAAE,cAAc,EAAE,yBAAqB;AA+Q9C;;;;;GAKG;AACH,MAAM,UAAU,qCAAqC,CACnD,aAA4C;IAE5C,OAAO,WAAW,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;AACjD,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,mBAAmB,CAGjC,oBAAwE,EACxE,UAA0C,EAAE,iCAAiC;AAC7E,oBAAkE;IAElE,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;IAC/B,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,oBAAoB,CAAC;KAC7B;IAED,IAAI,SAAS,GAAG,KAAK,EACnB,IAAuE,EACvE,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAEhC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;QAC5B,MAAM,aAAa,GACjB,oBAAoB,CAAC,MAAM,CAAC,IAAoC,CAAC,CAAC;QACpE,IAAI,CAAC,aAAa,EAAE;YAClB,MAAM,IAAI,2BAA2B,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;SACpD;QAED,IAAI,CAAC,qCAAqC,CAAC,aAAa,CAAC,EAAE;YACzD,MAAM,IAAI,gCAAgC,CACxC,aAAa,EACb,cAAc,CAAC,gBAAgB,CAChC,CAAC;SACH;QACD,SAAS,GAAG,aAAa,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;KACxD;IAED,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import type { Json } from '@metamask/utils';\nimport { hasProperty } from '@metamask/utils';\n\nimport {\n CaveatSpecificationMismatchError,\n UnrecognizedCaveatTypeError,\n} from './errors';\nimport type {\n AsyncRestrictedMethod,\n RestrictedMethod,\n PermissionConstraint,\n RestrictedMethodParameters,\n} from './Permission';\nimport { PermissionType } from './Permission';\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport type { PermissionController } from './PermissionController';\n\nexport type CaveatConstraint = {\n /**\n * The type of the caveat. The type is presumed to be meaningful in the\n * context of the capability it is associated with.\n *\n * In MetaMask, every permission can only have one caveat of each type.\n */\n readonly type: string;\n\n /**\n * Any additional data necessary to enforce the caveat.\n */\n readonly value: Json;\n};\n\n/**\n * A `ZCAP-LD`-like caveat object. A caveat is associated with a particular\n * permission, and stored in its `caveats` array. Conceptually, a caveat is\n * an arbitrary attenuation of the authority granted by its associated\n * permission. It is the responsibility of the host to interpret and apply\n * the restriction represented by a caveat.\n *\n * @template Type - The type of the caveat.\n * @template Value - The value associated with the caveat.\n */\nexport type Caveat = {\n /**\n * The type of the caveat. The type is presumed to be meaningful in the\n * context of the capability it is associated with.\n *\n * In MetaMask, every permission can only have one caveat of each type.\n */\n readonly type: Type;\n\n /**\n * Any additional data necessary to enforce the caveat.\n */\n readonly value: Value;\n};\n\n// Next, we define types used for specifying caveats at the consumer layer,\n// and a function for applying caveats to a restricted method request. This is\n// Accomplished by decorating the restricted method implementation with the\n// the corresponding caveat functions.\n\n/**\n * A function for applying caveats to a restricted method request.\n *\n * @template ParentCaveat - The caveat type associated with this decorator.\n * @param decorated - The restricted method implementation to be decorated.\n * The method may have already been decorated with other caveats.\n * @param caveat - The caveat object.\n * @returns The decorated restricted method implementation.\n */\nexport type CaveatDecorator = (\n decorated: AsyncRestrictedMethod,\n caveat: ParentCaveat,\n) => AsyncRestrictedMethod;\n\n/**\n * Extracts a caveat value type from a caveat decorator.\n *\n * @template Decorator - The {@link CaveatDecorator} to extract a caveat value\n * type from.\n */\ntype ExtractCaveatValueFromDecorator<\n Decorator extends CaveatDecorator,\n> = Decorator extends (\n decorated: AsyncRestrictedMethod,\n caveat: infer ParentCaveat,\n) => AsyncRestrictedMethod\n ? ParentCaveat extends CaveatConstraint\n ? ParentCaveat['value']\n : never\n : never;\n\n/**\n * A function for validating caveats of a particular type.\n *\n * @see `validator` in {@link CaveatSpecificationBase} for more details.\n * @template ParentCaveat - The caveat type associated with this validator.\n * @param caveat - The caveat object to validate.\n * @param origin - The origin associated with the parent permission.\n * @param target - The target of the parent permission.\n */\nexport type CaveatValidator = (\n caveat: { type: ParentCaveat['type']; value: unknown },\n origin?: string,\n target?: string,\n) => void;\n\n/**\n * A map of caveat type strings to {@link CaveatDiff} values.\n */\nexport type CaveatDiffMap = {\n [CaveatType in ParentCaveat['type']]: ParentCaveat['value'];\n};\n\n/**\n * A function that merges two caveat values of the same type. The values must be\n * merged in the fashion of a right-biased union.\n *\n * @see `ARCHITECTURE.md` for more details.\n * @template Value - The type of the values to merge.\n * @param leftValue - The left-hand value.\n * @param rightValue - The right-hand value.\n * @returns `[newValue, diff]`, i.e. the merged value and the diff between the left value\n * and the new value. The diff must be expressed in the same type as the value itself.\n */\nexport type CaveatValueMerger = (\n leftValue: Value,\n rightValue: Value,\n) => [Value, Value] | [];\n\nexport type CaveatSpecificationBase = {\n /**\n * The string type of the caveat.\n */\n type: string;\n\n /**\n * The validator function used to validate caveats of the associated type\n * whenever they are constructed or mutated.\n *\n * The validator should throw an appropriate JSON-RPC error if validation fails.\n *\n * If no validator is specified, no validation of caveat values will be\n * performed. In instances where caveats are mutated but a permission's caveat\n * array has not changed, any corresponding permission validator will not be\n * called. For this reason, permission validators **must not** be relied upon\n * to validate caveats.\n */\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n validator?: CaveatValidator;\n\n /**\n * The merger function used to merge a pair of values of the associated caveat type\n * during incremental permission requests. The values must be merged in the fashion\n * of a right-biased union.\n *\n * @see `ARCHITECTURE.md` for more details.\n */\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n merger?: CaveatValueMerger;\n};\n\nexport type RestrictedMethodCaveatSpecificationConstraint =\n CaveatSpecificationBase & {\n /**\n * The decorator function used to apply the caveat to restricted method\n * requests.\n */\n decorator: CaveatDecorator;\n };\n\nexport type EndowmentCaveatSpecificationConstraint = CaveatSpecificationBase;\n\n/**\n * The constraint for caveat specification objects. Every {@link Caveat}\n * supported by a {@link PermissionController} must have an associated\n * specification, which is the source of truth for all caveat-related types.\n * In addition, a caveat specification may include a decorator function used\n * to apply the caveat's attenuation to a restricted method. It may also include\n * a validator function specified by the consumer.\n *\n * See the README for more details.\n */\nexport type CaveatSpecificationConstraint =\n | RestrictedMethodCaveatSpecificationConstraint\n | EndowmentCaveatSpecificationConstraint;\n\n/**\n * Options for {@link CaveatSpecificationBuilder} functions.\n */\ntype CaveatSpecificationBuilderOptions<\n DecoratorHooks extends Record,\n ValidatorHooks extends Record,\n> = {\n type?: string;\n decoratorHooks?: DecoratorHooks;\n validatorHooks?: ValidatorHooks;\n};\n\n/**\n * A function that builds caveat specifications. Modules that specify caveats\n * for external consumption should make this their primary / default export so\n * that host applications can use them to generate concrete specifications\n * tailored to their requirements.\n */\nexport type CaveatSpecificationBuilder<\n Options extends CaveatSpecificationBuilderOptions<\n Record,\n Record\n >,\n Specification extends CaveatSpecificationConstraint,\n> = (options: Options) => Specification;\n\n/**\n * A caveat specification export object, containing the\n * {@link CaveatSpecificationBuilder} function and \"hook name\" objects.\n */\nexport type CaveatSpecificationBuilderExportConstraint = {\n specificationBuilder: CaveatSpecificationBuilder<\n CaveatSpecificationBuilderOptions<\n Record,\n Record\n >,\n CaveatSpecificationConstraint\n >;\n decoratorHookNames?: Record;\n validatorHookNames?: Record;\n};\n\n/**\n * The specifications for all caveats supported by a particular\n * {@link PermissionController}.\n *\n * @template Specifications - The union of all {@link CaveatSpecificationConstraint} types.\n */\nexport type CaveatSpecificationMap<\n CaveatSpecification extends CaveatSpecificationConstraint,\n> = Record;\n\n/**\n * Extracts the union of all caveat types specified by the given\n * {@link CaveatSpecificationConstraint} type.\n *\n * @template CaveatSpecification - The {@link CaveatSpecificationConstraint} to extract a\n * caveat type union from.\n */\nexport type ExtractCaveats<\n CaveatSpecification extends CaveatSpecificationConstraint,\n> = CaveatSpecification extends RestrictedMethodCaveatSpecificationConstraint\n ? Caveat<\n CaveatSpecification['type'],\n ExtractCaveatValueFromDecorator<\n RestrictedMethodCaveatSpecificationConstraint['decorator']\n >\n >\n : Caveat;\n\n/**\n * Extracts the type of a specific {@link Caveat} from a union of caveat\n * specifications.\n *\n * @template CaveatSpecifications - The union of all caveat specifications.\n * @template CaveatType - The type of the caveat to extract.\n */\nexport type ExtractCaveat<\n CaveatSpecifications extends CaveatSpecificationConstraint,\n CaveatType extends string,\n> = Extract, { type: CaveatType }>;\n\n/**\n * Extracts the value type of a specific {@link Caveat} from a union of caveat\n * specifications.\n *\n * @template CaveatSpecifications - The union of all caveat specifications.\n * @template CaveatType - The type of the caveat whose value to extract.\n */\nexport type ExtractCaveatValue<\n CaveatSpecifications extends CaveatSpecificationConstraint,\n CaveatType extends string,\n> = ExtractCaveat['value'];\n\n/**\n * Determines whether a caveat specification is a restricted method caveat specification.\n *\n * @param specification - The caveat specification.\n * @returns True if the caveat specification is a restricted method caveat specification, otherwise false.\n */\nexport function isRestrictedMethodCaveatSpecification(\n specification: CaveatSpecificationConstraint,\n): specification is RestrictedMethodCaveatSpecificationConstraint {\n return hasProperty(specification, 'decorator');\n}\n\n/**\n * Decorate a restricted method implementation with its caveats.\n *\n * Note that all caveat functions (i.e. the argument and return value of the\n * decorator) must be awaited.\n *\n * @param methodImplementation - The restricted method implementation\n * @param permission - The origin's potential permission\n * @param caveatSpecifications - All caveat implementations\n * @returns The decorated method implementation\n */\nexport function decorateWithCaveats<\n CaveatSpecifications extends CaveatSpecificationConstraint,\n>(\n methodImplementation: RestrictedMethod,\n permission: Readonly, // bound to the requesting origin\n caveatSpecifications: CaveatSpecificationMap, // all caveat implementations\n): RestrictedMethod {\n const { caveats } = permission;\n if (!caveats) {\n return methodImplementation;\n }\n\n let decorated = async (\n args: Parameters>[0],\n ) => methodImplementation(args);\n\n for (const caveat of caveats) {\n const specification =\n caveatSpecifications[caveat.type as CaveatSpecifications['type']];\n if (!specification) {\n throw new UnrecognizedCaveatTypeError(caveat.type);\n }\n\n if (!isRestrictedMethodCaveatSpecification(specification)) {\n throw new CaveatSpecificationMismatchError(\n specification,\n PermissionType.RestrictedMethod,\n );\n }\n decorated = specification.decorator(decorated, caveat);\n }\n\n return decorated;\n}\n"]} +\ No newline at end of file ++{"version":3,"file":"Caveat.mjs","sourceRoot":"","sources":["../src/Caveat.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,wBAAwB;AAE9C,OAAO,EACL,gCAAgC,EAChC,2BAA2B,EAC5B,qBAAiB;AAOlB,OAAO,EAAE,cAAc,EAAE,yBAAqB;AA6Q9C;;;;;GAKG;AACH,MAAM,UAAU,qCAAqC,CACnD,aAA4C;IAE5C,OAAO,WAAW,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;AACjD,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,mBAAmB,CAGjC,oBAAwE,EACxE,UAA0C,EAAE,iCAAiC;AAC7E,oBAAkE;IAElE,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;IAC/B,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,oBAAoB,CAAC;KAC7B;IAED,IAAI,SAAS,GAAG,KAAK,EACnB,IAAuE,EACvE,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAEhC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;QAC5B,MAAM,aAAa,GACjB,oBAAoB,CAAC,MAAM,CAAC,IAAoC,CAAC,CAAC;QACpE,IAAI,CAAC,aAAa,EAAE;YAClB,MAAM,IAAI,2BAA2B,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;SACpD;QAED,IAAI,CAAC,qCAAqC,CAAC,aAAa,CAAC,EAAE;YACzD,MAAM,IAAI,gCAAgC,CACxC,aAAa,EACb,cAAc,CAAC,gBAAgB,CAChC,CAAC;SACH;QACD,SAAS,GAAG,aAAa,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;KACxD;IAED,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import type { Json } from '@metamask/utils';\nimport { hasProperty } from '@metamask/utils';\n\nimport {\n CaveatSpecificationMismatchError,\n UnrecognizedCaveatTypeError,\n} from './errors';\nimport type {\n AsyncRestrictedMethod,\n RestrictedMethod,\n PermissionConstraint,\n RestrictedMethodParameters,\n} from './Permission';\nimport { PermissionType } from './Permission';\n\nexport type CaveatConstraint = {\n /**\n * The type of the caveat. The type is presumed to be meaningful in the\n * context of the capability it is associated with.\n *\n * In MetaMask, every permission can only have one caveat of each type.\n */\n readonly type: string;\n\n /**\n * Any additional data necessary to enforce the caveat.\n */\n readonly value: Json;\n};\n\n/**\n * A `ZCAP-LD`-like caveat object. A caveat is associated with a particular\n * permission, and stored in its `caveats` array. Conceptually, a caveat is\n * an arbitrary attenuation of the authority granted by its associated\n * permission. It is the responsibility of the host to interpret and apply\n * the restriction represented by a caveat.\n *\n * @template Type - The type of the caveat.\n * @template Value - The value associated with the caveat.\n */\nexport type Caveat = {\n /**\n * The type of the caveat. The type is presumed to be meaningful in the\n * context of the capability it is associated with.\n *\n * In MetaMask, every permission can only have one caveat of each type.\n */\n readonly type: Type;\n\n /**\n * Any additional data necessary to enforce the caveat.\n */\n readonly value: Value;\n};\n\n// Next, we define types used for specifying caveats at the consumer layer,\n// and a function for applying caveats to a restricted method request. This is\n// Accomplished by decorating the restricted method implementation with the\n// the corresponding caveat functions.\n\n/**\n * A function for applying caveats to a restricted method request.\n *\n * @template ParentCaveat - The caveat type associated with this decorator.\n * @param decorated - The restricted method implementation to be decorated.\n * The method may have already been decorated with other caveats.\n * @param caveat - The caveat object.\n * @returns The decorated restricted method implementation.\n */\nexport type CaveatDecorator = (\n decorated: AsyncRestrictedMethod,\n caveat: ParentCaveat,\n) => AsyncRestrictedMethod;\n\n/**\n * Extracts a caveat value type from a caveat decorator.\n *\n * @template Decorator - The {@link CaveatDecorator} to extract a caveat value\n * type from.\n */\ntype ExtractCaveatValueFromDecorator<\n Decorator extends CaveatDecorator,\n> = Decorator extends (\n decorated: AsyncRestrictedMethod,\n caveat: infer ParentCaveat,\n) => AsyncRestrictedMethod\n ? ParentCaveat extends CaveatConstraint\n ? ParentCaveat['value']\n : never\n : never;\n\n/**\n * A function for validating caveats of a particular type.\n *\n * @see `validator` in {@link CaveatSpecificationBase} for more details.\n * @template ParentCaveat - The caveat type associated with this validator.\n * @param caveat - The caveat object to validate.\n * @param origin - The origin associated with the parent permission.\n * @param target - The target of the parent permission.\n */\nexport type CaveatValidator = (\n caveat: { type: ParentCaveat['type']; value: unknown },\n origin?: string,\n target?: string,\n) => void;\n\n/**\n * A map of caveat type strings to {@link CaveatDiff} values.\n */\nexport type CaveatDiffMap = {\n [CaveatType in ParentCaveat['type']]: ParentCaveat['value'];\n};\n\n/**\n * A function that merges two caveat values of the same type. The values must be\n * merged in the fashion of a right-biased union.\n *\n * @see `ARCHITECTURE.md` for more details.\n * @template Value - The type of the values to merge.\n * @param leftValue - The left-hand value.\n * @param rightValue - The right-hand value.\n * @returns `[newValue, diff]`, i.e. the merged value and the diff between the left value\n * and the new value. The diff must be expressed in the same type as the value itself.\n */\nexport type CaveatValueMerger = (\n leftValue: Value,\n rightValue: Value,\n) => [Value, Value] | [];\n\nexport type CaveatSpecificationBase = {\n /**\n * The string type of the caveat.\n */\n type: string;\n\n /**\n * The validator function used to validate caveats of the associated type\n * whenever they are constructed or mutated.\n *\n * The validator should throw an appropriate JSON-RPC error if validation fails.\n *\n * If no validator is specified, no validation of caveat values will be\n * performed. In instances where caveats are mutated but a permission's caveat\n * array has not changed, any corresponding permission validator will not be\n * called. For this reason, permission validators **must not** be relied upon\n * to validate caveats.\n */\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n validator?: CaveatValidator;\n\n /**\n * The merger function used to merge a pair of values of the associated caveat type\n * during incremental permission requests. The values must be merged in the fashion\n * of a right-biased union.\n *\n * @see `ARCHITECTURE.md` for more details.\n */\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n merger?: CaveatValueMerger;\n};\n\nexport type RestrictedMethodCaveatSpecificationConstraint =\n CaveatSpecificationBase & {\n /**\n * The decorator function used to apply the caveat to restricted method\n * requests.\n */\n decorator: CaveatDecorator;\n };\n\nexport type EndowmentCaveatSpecificationConstraint = CaveatSpecificationBase;\n\n/**\n * The constraint for caveat specification objects. Every {@link Caveat}\n * supported by a {@link PermissionController} must have an associated\n * specification, which is the source of truth for all caveat-related types.\n * In addition, a caveat specification may include a decorator function used\n * to apply the caveat's attenuation to a restricted method. It may also include\n * a validator function specified by the consumer.\n *\n * See the README for more details.\n */\nexport type CaveatSpecificationConstraint =\n | RestrictedMethodCaveatSpecificationConstraint\n | EndowmentCaveatSpecificationConstraint;\n\n/**\n * Options for {@link CaveatSpecificationBuilder} functions.\n */\ntype CaveatSpecificationBuilderOptions<\n DecoratorHooks extends Record,\n ValidatorHooks extends Record,\n> = {\n type?: string;\n decoratorHooks?: DecoratorHooks;\n validatorHooks?: ValidatorHooks;\n};\n\n/**\n * A function that builds caveat specifications. Modules that specify caveats\n * for external consumption should make this their primary / default export so\n * that host applications can use them to generate concrete specifications\n * tailored to their requirements.\n */\nexport type CaveatSpecificationBuilder<\n Options extends CaveatSpecificationBuilderOptions<\n Record,\n Record\n >,\n Specification extends CaveatSpecificationConstraint,\n> = (options: Options) => Specification;\n\n/**\n * A caveat specification export object, containing the\n * {@link CaveatSpecificationBuilder} function and \"hook name\" objects.\n */\nexport type CaveatSpecificationBuilderExportConstraint = {\n specificationBuilder: CaveatSpecificationBuilder<\n CaveatSpecificationBuilderOptions<\n Record,\n Record\n >,\n CaveatSpecificationConstraint\n >;\n decoratorHookNames?: Record;\n validatorHookNames?: Record;\n};\n\n/**\n * The specifications for all caveats supported by a particular\n * {@link PermissionController}.\n *\n * @template Specifications - The union of all {@link CaveatSpecificationConstraint} types.\n */\nexport type CaveatSpecificationMap<\n CaveatSpecification extends CaveatSpecificationConstraint,\n> = Record;\n\n/**\n * Extracts the union of all caveat types specified by the given\n * {@link CaveatSpecificationConstraint} type.\n *\n * @template CaveatSpecification - The {@link CaveatSpecificationConstraint} to extract a\n * caveat type union from.\n */\nexport type ExtractCaveats<\n CaveatSpecification extends CaveatSpecificationConstraint,\n> = CaveatSpecification extends RestrictedMethodCaveatSpecificationConstraint\n ? Caveat<\n CaveatSpecification['type'],\n ExtractCaveatValueFromDecorator<\n RestrictedMethodCaveatSpecificationConstraint['decorator']\n >\n >\n : Caveat;\n\n/**\n * Extracts the type of a specific {@link Caveat} from a union of caveat\n * specifications.\n *\n * @template CaveatSpecifications - The union of all caveat specifications.\n * @template CaveatType - The type of the caveat to extract.\n */\nexport type ExtractCaveat<\n CaveatSpecifications extends CaveatSpecificationConstraint,\n CaveatType extends string,\n> = Extract, { type: CaveatType }>;\n\n/**\n * Extracts the value type of a specific {@link Caveat} from a union of caveat\n * specifications.\n *\n * @template CaveatSpecifications - The union of all caveat specifications.\n * @template CaveatType - The type of the caveat whose value to extract.\n */\nexport type ExtractCaveatValue<\n CaveatSpecifications extends CaveatSpecificationConstraint,\n CaveatType extends string,\n> = ExtractCaveat['value'];\n\n/**\n * Determines whether a caveat specification is a restricted method caveat specification.\n *\n * @param specification - The caveat specification.\n * @returns True if the caveat specification is a restricted method caveat specification, otherwise false.\n */\nexport function isRestrictedMethodCaveatSpecification(\n specification: CaveatSpecificationConstraint,\n): specification is RestrictedMethodCaveatSpecificationConstraint {\n return hasProperty(specification, 'decorator');\n}\n\n/**\n * Decorate a restricted method implementation with its caveats.\n *\n * Note that all caveat functions (i.e. the argument and return value of the\n * decorator) must be awaited.\n *\n * @param methodImplementation - The restricted method implementation\n * @param permission - The origin's potential permission\n * @param caveatSpecifications - All caveat implementations\n * @returns The decorated method implementation\n */\nexport function decorateWithCaveats<\n CaveatSpecifications extends CaveatSpecificationConstraint,\n>(\n methodImplementation: RestrictedMethod,\n permission: Readonly, // bound to the requesting origin\n caveatSpecifications: CaveatSpecificationMap, // all caveat implementations\n): RestrictedMethod {\n const { caveats } = permission;\n if (!caveats) {\n return methodImplementation;\n }\n\n let decorated = async (\n args: Parameters>[0],\n ) => methodImplementation(args);\n\n for (const caveat of caveats) {\n const specification =\n caveatSpecifications[caveat.type as CaveatSpecifications['type']];\n if (!specification) {\n throw new UnrecognizedCaveatTypeError(caveat.type);\n }\n\n if (!isRestrictedMethodCaveatSpecification(specification)) {\n throw new CaveatSpecificationMismatchError(\n specification,\n PermissionType.RestrictedMethod,\n );\n }\n decorated = specification.decorator(decorated, caveat);\n }\n\n return decorated;\n}\n"]} +\ No newline at end of file +diff --git a/dist/Permission.cjs.map b/dist/Permission.cjs.map +index 7abf343a1c58d1a3c318a0d86bceab75a6209835..bbe30e37c06f279b29e3a0c9184f444c1311c29c 100644 +--- a/dist/Permission.cjs.map ++++ b/dist/Permission.cjs.map +@@ -1 +1 @@ +-{"version":3,"file":"Permission.cjs","sourceRoot":"","sources":["../src/Permission.ts"],"names":[],"mappings":";;;AAMA,mCAAgC;AAkJhC;;;;;;;;GAQG;AACH,SAAgB,mBAAmB,CAEjC,OAA4C;IAC5C,MAAM,EAAE,OAAO,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAEpD,OAAO;QACL,EAAE,EAAE,IAAA,eAAM,GAAE;QACZ,gBAAgB,EAAE,MAAM;QACxB,OAAO;QACP,OAAO;QACP,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE;KACP,CAAC;AACxB,CAAC;AAZD,kDAYC;AAED;;;;;;GAMG;AACH,SAAgB,UAAU,CACxB,UAAgC,EAChC,UAAkB;IAElB,OAAO,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;AAC1E,CAAC;AALD,gCAKC;AAgKD;;GAEG;AACH,IAAY,cAYX;AAZD,WAAY,cAAc;IACxB;;;OAGG;IACH,uDAAqC,CAAA;IAErC;;;OAGG;IACH,yCAAuB,CAAA;AACzB,CAAC,EAZW,cAAc,8BAAd,cAAc,QAYzB;AA0MD;;;;;;;;GAQG;AACH,SAAgB,oBAAoB,CAIlC,aAA4B,EAC5B,YAAkB;IAIlB,OAAO,aAAa,CAAC,cAAc,KAAK,YAAY,CAAC;AACvD,CAAC;AAVD,oDAUC","sourcesContent":["import type {\n ActionConstraint,\n EventConstraint,\n} from '@metamask/base-controller';\nimport type { NonEmptyArray } from '@metamask/controller-utils';\nimport type { Json } from '@metamask/utils';\nimport { nanoid } from 'nanoid';\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport type { CaveatConstraint, Caveat } from './Caveat';\nimport type {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n PermissionController,\n PermissionsRequest,\n SideEffectMessenger,\n} from './PermissionController';\nimport type { SubjectType } from './SubjectMetadataController';\n\n/**\n * The origin of a subject.\n * Effectively the GUID of an entity that can have permissions.\n */\nexport type OriginString = string;\n\n/**\n * The name of a permission target.\n */\ntype TargetName = string;\n\n/**\n * A `ZCAP-LD`-like permission object. A permission is associated with a\n * particular `invoker`, which is the holder of the permission. Possessing the\n * permission grants access to a particular restricted resource, identified by\n * the `parentCapability`. The use of the restricted resource may be further\n * restricted by any `caveats` associated with the permission.\n *\n * See the README for details.\n */\nexport type PermissionConstraint = {\n /**\n * The context(s) in which this capability is meaningful.\n *\n * It is required by the standard, but we make it optional since there is only\n * one context in our usage (i.e. the user's MetaMask instance).\n */\n readonly '@context'?: NonEmptyArray;\n\n /**\n * The caveats of the permission.\n *\n * @see {@link Caveat} For more information.\n */\n readonly caveats: null | NonEmptyArray;\n\n /**\n * The creation date of the permission, in UNIX epoch time.\n */\n readonly date: number;\n\n /**\n * The GUID of the permission object.\n */\n readonly id: string;\n\n /**\n * The origin string of the subject that has the permission.\n */\n readonly invoker: OriginString;\n\n /**\n * A pointer to the resource that possession of the capability grants\n * access to, for example a JSON-RPC method or endowment.\n */\n readonly parentCapability: string;\n};\n\n/**\n * A `ZCAP-LD`-like permission object. A permission is associated with a\n * particular `invoker`, which is the holder of the permission. Possessing the\n * permission grants access to a particular restricted resource, identified by\n * the `parentCapability`. The use of the restricted resource may be further\n * restricted by any `caveats` associated with the permission.\n *\n * See the README for details.\n *\n * @template Name - The name of the permission that the target corresponds to.\n * @template AllowedCaveat - A union of the allowed {@link Caveat} types\n * for the permission.\n */\nexport type ValidPermission<\n Name extends TargetName,\n AllowedCaveat extends CaveatConstraint,\n> = PermissionConstraint & {\n /**\n * The caveats of the permission.\n *\n * @see {@link Caveat} For more information.\n */\n readonly caveats: AllowedCaveat extends never\n ? null\n : NonEmptyArray | null;\n\n /**\n * A pointer to the resource that possession of the capability grants\n * access to, for example a JSON-RPC method or endowment.\n */\n readonly parentCapability: Name;\n};\n\n/**\n * Internal utility for extracting the members types of an array. The type\n * evalutes to `never` if the specified type is the empty tuple or neither\n * an array nor a tuple.\n *\n * @template ArrayType - The array type whose members to extract.\n */\ntype ExtractArrayMembers = ArrayType extends []\n ? never\n : ArrayType extends unknown[] | readonly unknown[]\n ? ArrayType[number]\n : never;\n\n/**\n * A utility type for extracting the allowed caveat types for a particular\n * permission from a permission specification type.\n *\n * @template PermissionSpecification - The permission specification type to\n * extract valid caveat types from.\n */\nexport type ExtractAllowedCaveatTypes<\n PermissionSpecification extends PermissionSpecificationConstraint,\n> = ExtractArrayMembers;\n\n/**\n * The options object of {@link constructPermission}.\n *\n * @template TargetPermission - The {@link Permission} that will be constructed.\n */\nexport type PermissionOptions = {\n target: TargetPermission['parentCapability'];\n /**\n * The origin string of the subject that has the permission.\n */\n invoker: OriginString;\n\n /**\n * The caveats of the permission.\n * See {@link Caveat}.\n */\n caveats?: NonEmptyArray;\n};\n\n/**\n * The default permission factory function. Naively constructs a permission from\n * the inputs. Sets a default, random `id` if none is provided.\n *\n * @see {@link Permission} For more details.\n * @template TargetPermission- - The {@link Permission} that will be constructed.\n * @param options - The options for the permission.\n * @returns The new permission object.\n */\nexport function constructPermission<\n TargetPermission extends PermissionConstraint,\n>(options: PermissionOptions): TargetPermission {\n const { caveats = null, invoker, target } = options;\n\n return {\n id: nanoid(),\n parentCapability: target,\n invoker,\n caveats,\n date: new Date().getTime(),\n } as TargetPermission;\n}\n\n/**\n * Gets the caveat of the specified type belonging to the specified permission.\n *\n * @param permission - The permission whose caveat to retrieve.\n * @param caveatType - The type of the caveat to retrieve.\n * @returns The caveat, or undefined if no such caveat exists.\n */\nexport function findCaveat(\n permission: PermissionConstraint,\n caveatType: string,\n): CaveatConstraint | undefined {\n return permission.caveats?.find((caveat) => caveat.type === caveatType);\n}\n\n/**\n * A requested permission object. Just an object with any of the properties\n * of a {@link PermissionConstraint} object.\n */\ntype RequestedPermission = Partial;\n\n/**\n * A record of target names and their {@link RequestedPermission} objects.\n */\nexport type RequestedPermissions = Record;\n\n/**\n * The restricted method context object. Essentially a way to pass internal\n * arguments to restricted methods and caveat functions, most importantly the\n * requesting origin.\n */\ntype RestrictedMethodContext = Readonly<{\n origin: OriginString;\n [key: string]: unknown;\n}>;\n\nexport type RestrictedMethodParameters = Json[] | Record;\n\n/**\n * The arguments passed to a restricted method implementation.\n *\n * @template Params - The JSON-RPC parameters of the restricted method.\n */\nexport type RestrictedMethodOptions<\n Params extends RestrictedMethodParameters | null,\n> = {\n method: TargetName;\n params?: Params;\n context: RestrictedMethodContext;\n};\n\n/**\n * A synchronous restricted method implementation.\n *\n * @template Params - The JSON-RPC parameters of the restricted method.\n * @template Result - The JSON-RPC result of the restricted method.\n */\nexport type SyncRestrictedMethod<\n Params extends RestrictedMethodParameters,\n Result extends Json,\n> = (args: RestrictedMethodOptions) => Result;\n\n/**\n * An asynchronous restricted method implementation.\n *\n * @template Params - The JSON-RPC parameters of the restricted method.\n * @template Result - The JSON-RPC result of the restricted method.\n */\nexport type AsyncRestrictedMethod<\n Params extends RestrictedMethodParameters,\n Result extends Json,\n> = (args: RestrictedMethodOptions) => Promise;\n\n/**\n * A synchronous or asynchronous restricted method implementation.\n *\n * @template Params - The JSON-RPC parameters of the restricted method.\n * @template Result - The JSON-RPC result of the restricted method.\n */\nexport type RestrictedMethod<\n Params extends RestrictedMethodParameters,\n Result extends Json,\n> =\n | SyncRestrictedMethod\n | AsyncRestrictedMethod;\n\nexport type ValidRestrictedMethod<\n MethodImplementation extends RestrictedMethod<\n RestrictedMethodParameters,\n Json\n >,\n> = MethodImplementation extends (args: infer Options) => Json | Promise\n ? Options extends RestrictedMethodOptions\n ? MethodImplementation\n : never\n : never;\n\n/**\n * {@link EndowmentGetter} parameter object.\n */\nexport type EndowmentGetterParams = {\n /**\n * The origin of the requesting subject.\n */\n origin: string;\n\n /**\n * Any additional data associated with the request.\n */\n requestData?: unknown;\n\n [key: string]: unknown;\n};\n\n/**\n * A synchronous or asynchronous function that gets the endowments for a\n * particular endowment permission. The getter receives the origin of the\n * requesting subject and, optionally, additional request metadata.\n */\nexport type EndowmentGetter = (\n options: EndowmentGetterParams,\n) => Endowments | Promise;\n\nexport type PermissionFactory<\n TargetPermission extends PermissionConstraint,\n RequestData extends Record,\n> = (\n options: PermissionOptions,\n requestData?: RequestData,\n) => TargetPermission;\n\nexport type PermissionValidatorConstraint = (\n permission: PermissionConstraint,\n origin?: OriginString,\n target?: string,\n) => void;\n\n/**\n * The parameters passed to the side-effect function.\n */\nexport type SideEffectParams<\n Actions extends ActionConstraint,\n Events extends EventConstraint,\n> = {\n requestData: PermissionsRequest;\n messagingSystem: SideEffectMessenger;\n};\n\n/**\n * A function that will execute actions as a permission side-effect.\n */\nexport type SideEffectHandler<\n Actions extends ActionConstraint,\n Events extends EventConstraint,\n> = (params: SideEffectParams) => Promise;\n\n/**\n * The permissions side effects.\n */\nexport type PermissionSideEffect<\n Actions extends ActionConstraint,\n Events extends EventConstraint,\n> = {\n /**\n * A method triggered when the permission is accepted by the user\n */\n onPermitted: SideEffectHandler;\n /**\n * A method triggered if a `onPermitted` method rejected.\n */\n onFailure?: SideEffectHandler;\n};\n\n/**\n * The different possible types of permissions.\n */\nexport enum PermissionType {\n /**\n * A restricted JSON-RPC method. A subject must have the requisite permission\n * to call a restricted JSON-RPC method.\n */\n RestrictedMethod = 'RestrictedMethod',\n\n /**\n * An \"endowment\" granted to subjects that possess the requisite permission,\n * such as a global environment variable exposing a restricted API, etc.\n */\n Endowment = 'Endowment',\n}\n\n/**\n * The base constraint for permission specification objects. Every\n * {@link Permission} supported by a {@link PermissionController} must have an\n * associated specification, which is the source of truth for all permission-\n * related types. A permission specification includes the list of permitted\n * caveats, and any factory and validation functions specified by the consumer.\n * A concrete permission specification may specify further fields as necessary.\n *\n * See the README for more details.\n */\ntype PermissionSpecificationBase = {\n /**\n * The type of the specified permission.\n */\n permissionType: Type;\n\n /**\n * The name of the target resource of the permission.\n */\n targetName: string;\n\n /**\n * An array of the caveat types that may be added to instances of this\n * permission.\n */\n allowedCaveats: Readonly> | null;\n\n /**\n * The factory function used to get permission objects. Permissions returned\n * by this function are presumed to valid, and they will not be passed to the\n * validator function associated with this specification (if any). In other\n * words, the factory function should validate the permissions it creates.\n *\n * If no factory is specified, the {@link Permission} constructor will be\n * used, and the validator function (if specified) will be called on newly\n * constructed permissions.\n */\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n factory?: PermissionFactory>;\n\n /**\n * The validator function used to validate permissions of the associated type\n * whenever they are granted or their caveat arrays are mutated.\n *\n * Permission validators are **not** invoked when a caveat is mutated, provided\n * the caveat array has not changed. For this reason, permission validators\n * **must not** be used to validate caveats. To validate caveats, use the\n * corresponding caveat specification property.\n *\n * The validator should throw an appropriate JSON-RPC error if validation fails.\n */\n validator?: PermissionValidatorConstraint;\n\n /**\n * The side-effect triggered by the {@link PermissionController} once the user approved it.\n * The side-effect can only be an action allowed to be called inside the {@link PermissionController}.\n *\n * If the side-effect action fails, the permission that triggered it is revoked.\n */\n sideEffect?: PermissionSideEffect;\n\n /**\n * The Permission may be available to only a subset of the subject types. If so, specify the subject types as an array.\n * If a subject with a type not in this array tries to request the permission, the call will fail.\n *\n * Leaving this as undefined uses default behaviour where the permission is available to request for all subject types.\n */\n subjectTypes?: readonly SubjectType[];\n};\n\n/**\n * The constraint for restricted method permission specification objects.\n * Permissions that correspond to JSON-RPC methods are specified using objects\n * that conform to this type.\n *\n * See the README for more details.\n */\nexport type RestrictedMethodSpecificationConstraint =\n PermissionSpecificationBase & {\n /**\n * The implementation of the restricted method that the permission\n * corresponds to.\n */\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n methodImplementation: RestrictedMethod;\n };\n\n/**\n * The constraint for endowment permission specification objects. Permissions\n * that endow callers with some restricted resource are specified using objects\n * that conform to this type.\n *\n * See the README for more details.\n */\nexport type EndowmentSpecificationConstraint =\n PermissionSpecificationBase & {\n /**\n * The {@link EndowmentGetter} function for the permission. This function\n * will be called by the {@link PermissionController} whenever the\n * permission is invoked, after which the host can apply the endowments to\n * the requesting subject in the intended manner.\n */\n endowmentGetter: EndowmentGetter;\n };\n\n/**\n * The constraint for permission specification objects. Every {@link Permission}\n * supported by a {@link PermissionController} must have an associated\n * specification, which is the source of truth for all permission-related types.\n * All specifications must adhere to the {@link PermissionSpecificationBase}\n * interface, but specifications may have different fields depending on the\n * {@link PermissionType}.\n *\n * See the README for more details.\n */\nexport type PermissionSpecificationConstraint =\n | EndowmentSpecificationConstraint\n | RestrictedMethodSpecificationConstraint;\n\n/**\n * Options for {@link PermissionSpecificationBuilder} functions.\n */\ntype PermissionSpecificationBuilderOptions<\n FactoryHooks extends Record,\n MethodHooks extends Record,\n ValidatorHooks extends Record,\n> = {\n targetName?: string;\n allowedCaveats?: Readonly> | null;\n factoryHooks?: FactoryHooks;\n methodHooks?: MethodHooks;\n validatorHooks?: ValidatorHooks;\n};\n\n/**\n * A function that builds a permission specification. Modules that specify\n * permissions for external consumption should make this their primary /\n * default export so that host applications can use them to generate concrete\n * specifications tailored to their requirements.\n */\nexport type PermissionSpecificationBuilder<\n Type extends PermissionType,\n Options extends PermissionSpecificationBuilderOptions<\n Record,\n Record,\n Record\n >,\n Specification extends PermissionSpecificationConstraint & {\n permissionType: Type;\n },\n> = (options: Options) => Specification;\n\n/**\n * A restricted method permission export object, containing the\n * {@link PermissionSpecificationBuilder} function and \"hook name\" objects.\n */\nexport type PermissionSpecificationBuilderExportConstraint = {\n targetName: string;\n specificationBuilder: PermissionSpecificationBuilder<\n PermissionType,\n PermissionSpecificationBuilderOptions<\n Record,\n Record,\n Record\n >,\n PermissionSpecificationConstraint\n >;\n factoryHookNames?: Record;\n methodHookNames?: Record;\n validatorHookNames?: Record;\n};\n\ntype ValidRestrictedMethodSpecification<\n Specification extends RestrictedMethodSpecificationConstraint,\n> = Specification['methodImplementation'] extends ValidRestrictedMethod<\n Specification['methodImplementation']\n>\n ? Specification\n : never;\n\n/**\n * Constraint for {@link PermissionSpecificationConstraint} objects that\n * evaluates to `never` if the specification contains any invalid fields.\n *\n * @template Specification - The permission specification to validate.\n */\nexport type ValidPermissionSpecification<\n Specification extends PermissionSpecificationConstraint,\n> = Specification['targetName'] extends TargetName\n ? Specification['permissionType'] extends PermissionType.Endowment\n ? Specification\n : Specification['permissionType'] extends PermissionType.RestrictedMethod\n ? ValidRestrictedMethodSpecification<\n Extract\n >\n : never\n : never;\n\n/**\n * Checks that the specification has the expected permission type.\n *\n * @param specification - The specification to check.\n * @param expectedType - The expected permission type.\n * @template Specification - The specification to check.\n * @template Type - The expected permission type.\n * @returns Whether or not the specification is of the expected type.\n */\nexport function hasSpecificationType<\n Specification extends PermissionSpecificationConstraint,\n Type extends PermissionType,\n>(\n specification: Specification,\n expectedType: Type,\n): specification is Specification & {\n permissionType: Type;\n} {\n return specification.permissionType === expectedType;\n}\n\n/**\n * The specifications for all permissions supported by a particular\n * {@link PermissionController}.\n *\n * @template Specifications - The union of all {@link PermissionSpecificationConstraint} types.\n */\nexport type PermissionSpecificationMap<\n Specification extends PermissionSpecificationConstraint,\n> = {\n [Name in Specification['targetName']]: Specification extends {\n targetName: Name;\n }\n ? Specification\n : never;\n};\n\n/**\n * Extracts a specific {@link PermissionSpecificationConstraint} from a union of\n * permission specifications.\n *\n * @template Specification - The specification union type to extract from.\n * @template Name - The `targetName` of the specification to extract.\n */\nexport type ExtractPermissionSpecification<\n Specification extends PermissionSpecificationConstraint,\n Name extends Specification['targetName'],\n> = Specification extends {\n targetName: Name;\n}\n ? Specification\n : never;\n"]} +\ No newline at end of file ++{"version":3,"file":"Permission.cjs","sourceRoot":"","sources":["../src/Permission.ts"],"names":[],"mappings":";;;AAGA,mCAAgC;AA+IhC;;;;;;;;GAQG;AACH,SAAgB,mBAAmB,CAEjC,OAA4C;IAC5C,MAAM,EAAE,OAAO,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAEpD,OAAO;QACL,EAAE,EAAE,IAAA,eAAM,GAAE;QACZ,gBAAgB,EAAE,MAAM;QACxB,OAAO;QACP,OAAO;QACP,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE;KACP,CAAC;AACxB,CAAC;AAZD,kDAYC;AAED;;;;;;GAMG;AACH,SAAgB,UAAU,CACxB,UAAgC,EAChC,UAAkB;IAElB,OAAO,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;AAC1E,CAAC;AALD,gCAKC;AAgKD;;GAEG;AACH,IAAY,cAYX;AAZD,WAAY,cAAc;IACxB;;;OAGG;IACH,uDAAqC,CAAA;IAErC;;;OAGG;IACH,yCAAuB,CAAA;AACzB,CAAC,EAZW,cAAc,8BAAd,cAAc,QAYzB;AA2MD;;;;;;;;GAQG;AACH,SAAgB,oBAAoB,CAIlC,aAA4B,EAC5B,YAAkB;IAIlB,OAAO,aAAa,CAAC,cAAc,KAAK,YAAY,CAAC;AACvD,CAAC;AAVD,oDAUC","sourcesContent":["import type { NonEmptyArray } from '@metamask/controller-utils';\nimport type { ActionConstraint, EventConstraint } from '@metamask/messenger';\nimport type { Json } from '@metamask/utils';\nimport { nanoid } from 'nanoid';\n\nimport type { CaveatConstraint } from './Caveat';\nimport type {\n PermissionsRequest,\n SideEffectMessenger,\n} from './PermissionController';\nimport type { SubjectType } from './SubjectMetadataController';\n\n/**\n * The origin of a subject.\n * Effectively the GUID of an entity that can have permissions.\n */\nexport type OriginString = string;\n\n/**\n * The name of a permission target.\n */\ntype TargetName = string;\n\n/**\n * A `ZCAP-LD`-like permission object. A permission is associated with a\n * particular `invoker`, which is the holder of the permission. Possessing the\n * permission grants access to a particular restricted resource, identified by\n * the `parentCapability`. The use of the restricted resource may be further\n * restricted by any `caveats` associated with the permission.\n *\n * See the README for details.\n */\nexport type PermissionConstraint = {\n /**\n * The context(s) in which this capability is meaningful.\n *\n * It is required by the standard, but we make it optional since there is only\n * one context in our usage (i.e. the user's MetaMask instance).\n */\n readonly '@context'?: NonEmptyArray;\n\n /**\n * The caveats of the permission.\n *\n * @see {@link Caveat} For more information.\n */\n readonly caveats: null | NonEmptyArray;\n\n /**\n * The creation date of the permission, in UNIX epoch time.\n */\n readonly date: number;\n\n /**\n * The GUID of the permission object.\n */\n readonly id: string;\n\n /**\n * The origin string of the subject that has the permission.\n */\n readonly invoker: OriginString;\n\n /**\n * A pointer to the resource that possession of the capability grants\n * access to, for example a JSON-RPC method or endowment.\n */\n readonly parentCapability: string;\n};\n\n/**\n * A `ZCAP-LD`-like permission object. A permission is associated with a\n * particular `invoker`, which is the holder of the permission. Possessing the\n * permission grants access to a particular restricted resource, identified by\n * the `parentCapability`. The use of the restricted resource may be further\n * restricted by any `caveats` associated with the permission.\n *\n * See the README for details.\n *\n * @template Name - The name of the permission that the target corresponds to.\n * @template AllowedCaveat - A union of the allowed {@link Caveat} types\n * for the permission.\n */\nexport type ValidPermission<\n Name extends TargetName,\n AllowedCaveat extends CaveatConstraint,\n> = PermissionConstraint & {\n /**\n * The caveats of the permission.\n *\n * @see {@link Caveat} For more information.\n */\n readonly caveats: AllowedCaveat extends never\n ? null\n : NonEmptyArray | null;\n\n /**\n * A pointer to the resource that possession of the capability grants\n * access to, for example a JSON-RPC method or endowment.\n */\n readonly parentCapability: Name;\n};\n\n/**\n * Internal utility for extracting the members types of an array. The type\n * evalutes to `never` if the specified type is the empty tuple or neither\n * an array nor a tuple.\n *\n * @template ArrayType - The array type whose members to extract.\n */\ntype ExtractArrayMembers = ArrayType extends []\n ? never\n : ArrayType extends unknown[] | readonly unknown[]\n ? ArrayType[number]\n : never;\n\n/**\n * A utility type for extracting the allowed caveat types for a particular\n * permission from a permission specification type.\n *\n * @template PermissionSpecification - The permission specification type to\n * extract valid caveat types from.\n */\nexport type ExtractAllowedCaveatTypes<\n PermissionSpecification extends PermissionSpecificationConstraint,\n> = ExtractArrayMembers;\n\n/**\n * The options object of {@link constructPermission}.\n *\n * @template TargetPermission - The {@link Permission} that will be constructed.\n */\nexport type PermissionOptions = {\n target: TargetPermission['parentCapability'];\n /**\n * The origin string of the subject that has the permission.\n */\n invoker: OriginString;\n\n /**\n * The caveats of the permission.\n * See {@link Caveat}.\n */\n caveats?: NonEmptyArray;\n};\n\n/**\n * The default permission factory function. Naively constructs a permission from\n * the inputs. Sets a default, random `id` if none is provided.\n *\n * @see {@link Permission} For more details.\n * @template TargetPermission- - The {@link Permission} that will be constructed.\n * @param options - The options for the permission.\n * @returns The new permission object.\n */\nexport function constructPermission<\n TargetPermission extends PermissionConstraint,\n>(options: PermissionOptions): TargetPermission {\n const { caveats = null, invoker, target } = options;\n\n return {\n id: nanoid(),\n parentCapability: target,\n invoker,\n caveats,\n date: new Date().getTime(),\n } as TargetPermission;\n}\n\n/**\n * Gets the caveat of the specified type belonging to the specified permission.\n *\n * @param permission - The permission whose caveat to retrieve.\n * @param caveatType - The type of the caveat to retrieve.\n * @returns The caveat, or undefined if no such caveat exists.\n */\nexport function findCaveat(\n permission: PermissionConstraint,\n caveatType: string,\n): CaveatConstraint | undefined {\n return permission.caveats?.find((caveat) => caveat.type === caveatType);\n}\n\n/**\n * A requested permission object. Just an object with any of the properties\n * of a {@link PermissionConstraint} object.\n */\ntype RequestedPermission = Partial;\n\n/**\n * A record of target names and their {@link RequestedPermission} objects.\n */\nexport type RequestedPermissions = Record;\n\n/**\n * The restricted method context object. Essentially a way to pass internal\n * arguments to restricted methods and caveat functions, most importantly the\n * requesting origin.\n */\ntype RestrictedMethodContext = Readonly<{\n origin: OriginString;\n [key: string]: unknown;\n}>;\n\nexport type RestrictedMethodParameters = Json[] | Record;\n\n/**\n * The arguments passed to a restricted method implementation.\n *\n * @template Params - The JSON-RPC parameters of the restricted method.\n */\nexport type RestrictedMethodOptions<\n Params extends RestrictedMethodParameters | null,\n> = {\n method: TargetName;\n params?: Params;\n context: RestrictedMethodContext;\n};\n\n/**\n * A synchronous restricted method implementation.\n *\n * @template Params - The JSON-RPC parameters of the restricted method.\n * @template Result - The JSON-RPC result of the restricted method.\n */\nexport type SyncRestrictedMethod<\n Params extends RestrictedMethodParameters,\n Result extends Json,\n> = (args: RestrictedMethodOptions) => Result;\n\n/**\n * An asynchronous restricted method implementation.\n *\n * @template Params - The JSON-RPC parameters of the restricted method.\n * @template Result - The JSON-RPC result of the restricted method.\n */\nexport type AsyncRestrictedMethod<\n Params extends RestrictedMethodParameters,\n Result extends Json,\n> = (args: RestrictedMethodOptions) => Promise;\n\n/**\n * A synchronous or asynchronous restricted method implementation.\n *\n * @template Params - The JSON-RPC parameters of the restricted method.\n * @template Result - The JSON-RPC result of the restricted method.\n */\nexport type RestrictedMethod<\n Params extends RestrictedMethodParameters,\n Result extends Json,\n> =\n | SyncRestrictedMethod\n | AsyncRestrictedMethod;\n\nexport type ValidRestrictedMethod<\n MethodImplementation extends RestrictedMethod<\n RestrictedMethodParameters,\n Json\n >,\n> = MethodImplementation extends (args: infer Options) => Json | Promise\n ? Options extends RestrictedMethodOptions\n ? MethodImplementation\n : never\n : never;\n\n/**\n * {@link EndowmentGetter} parameter object.\n */\nexport type EndowmentGetterParams = {\n /**\n * The origin of the requesting subject.\n */\n origin: string;\n\n /**\n * Any additional data associated with the request.\n */\n requestData?: unknown;\n\n [key: string]: unknown;\n};\n\n/**\n * A synchronous or asynchronous function that gets the endowments for a\n * particular endowment permission. The getter receives the origin of the\n * requesting subject and, optionally, additional request metadata.\n */\nexport type EndowmentGetter = (\n options: EndowmentGetterParams,\n) => Endowments | Promise;\n\nexport type PermissionFactory<\n TargetPermission extends PermissionConstraint,\n RequestData extends Record,\n> = (\n options: PermissionOptions,\n requestData?: RequestData,\n) => TargetPermission;\n\nexport type PermissionValidatorConstraint = (\n permission: PermissionConstraint,\n origin?: OriginString,\n target?: string,\n) => void;\n\n/**\n * The parameters passed to the side-effect function.\n */\nexport type SideEffectParams<\n Actions extends ActionConstraint,\n Events extends EventConstraint,\n> = {\n requestData: PermissionsRequest;\n messenger: SideEffectMessenger;\n};\n\n/**\n * A function that will execute actions as a permission side-effect.\n */\nexport type SideEffectHandler<\n Actions extends ActionConstraint,\n Events extends EventConstraint,\n> = (params: SideEffectParams) => Promise;\n\n/**\n * The permissions side effects.\n */\nexport type PermissionSideEffect<\n Actions extends ActionConstraint,\n Events extends EventConstraint,\n> = {\n /**\n * A method triggered when the permission is accepted by the user\n */\n onPermitted: SideEffectHandler;\n /**\n * A method triggered if a `onPermitted` method rejected.\n */\n onFailure?: SideEffectHandler;\n};\n\n/**\n * The different possible types of permissions.\n */\nexport enum PermissionType {\n /**\n * A restricted JSON-RPC method. A subject must have the requisite permission\n * to call a restricted JSON-RPC method.\n */\n RestrictedMethod = 'RestrictedMethod',\n\n /**\n * An \"endowment\" granted to subjects that possess the requisite permission,\n * such as a global environment variable exposing a restricted API, etc.\n */\n Endowment = 'Endowment',\n}\n\n/**\n * The base constraint for permission specification objects. Every\n * {@link Permission} supported by a {@link PermissionController} must have an\n * associated specification, which is the source of truth for all permission-\n * related types. A permission specification includes the list of permitted\n * caveats, and any factory and validation functions specified by the consumer.\n * A concrete permission specification may specify further fields as necessary.\n *\n * See the README for more details.\n */\ntype PermissionSpecificationBase = {\n /**\n * The type of the specified permission.\n */\n permissionType: Type;\n\n /**\n * The name of the target resource of the permission.\n */\n targetName: string;\n\n /**\n * An array of the caveat types that may be added to instances of this\n * permission.\n */\n allowedCaveats: Readonly> | null;\n\n /**\n * The factory function used to get permission objects. Permissions returned\n * by this function are presumed to valid, and they will not be passed to the\n * validator function associated with this specification (if any). In other\n * words, the factory function should validate the permissions it creates.\n *\n * If no factory is specified, the {@link Permission} constructor will be\n * used, and the validator function (if specified) will be called on newly\n * constructed permissions.\n */\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n factory?: PermissionFactory>;\n\n /**\n * The validator function used to validate permissions of the associated type\n * whenever they are granted or their caveat arrays are mutated.\n *\n * Permission validators are **not** invoked when a caveat is mutated, provided\n * the caveat array has not changed. For this reason, permission validators\n * **must not** be used to validate caveats. To validate caveats, use the\n * corresponding caveat specification property.\n *\n * The validator should throw an appropriate JSON-RPC error if validation fails.\n */\n validator?: PermissionValidatorConstraint;\n\n /**\n * The side-effect triggered by the {@link PermissionController} once the user approved it.\n * The side-effect can only be an action allowed to be called inside the {@link PermissionController}.\n *\n * If the side-effect action fails, the permission that triggered it is revoked.\n */\n sideEffect?: PermissionSideEffect;\n\n /**\n * The Permission may be available to only a subset of the subject types. If so, specify the subject types as an array.\n * If a subject with a type not in this array tries to request the permission, the call will fail.\n *\n * Leaving this as undefined uses default behaviour where the permission is available to request for all subject types.\n */\n subjectTypes?: readonly SubjectType[];\n};\n\n/**\n * The constraint for restricted method permission specification objects.\n * Permissions that correspond to JSON-RPC methods are specified using objects\n * that conform to this type.\n *\n * See the README for more details.\n */\nexport type RestrictedMethodSpecificationConstraint =\n PermissionSpecificationBase & {\n /**\n * The implementation of the restricted method that the permission\n * corresponds to.\n */\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n methodImplementation: RestrictedMethod;\n };\n\n/**\n * The constraint for endowment permission specification objects. Permissions\n * that endow callers with some restricted resource are specified using objects\n * that conform to this type.\n *\n * See the README for more details.\n */\nexport type EndowmentSpecificationConstraint =\n PermissionSpecificationBase & {\n /**\n * The {@link EndowmentGetter} function for the permission. This function\n * will be called by the {@link PermissionController} whenever the\n * permission is invoked, after which the host can apply the endowments to\n * the requesting subject in the intended manner.\n */\n endowmentGetter: EndowmentGetter;\n };\n\n/**\n * The constraint for permission specification objects. Every {@link Permission}\n * supported by a {@link PermissionController} must have an associated\n * specification, which is the source of truth for all permission-related types.\n * All specifications must adhere to the {@link PermissionSpecificationBase}\n * interface, but specifications may have different fields depending on the\n * {@link PermissionType}.\n *\n * See the README for more details.\n */\nexport type PermissionSpecificationConstraint =\n | EndowmentSpecificationConstraint\n | RestrictedMethodSpecificationConstraint;\n\n/**\n * Options for {@link PermissionSpecificationBuilder} functions.\n */\ntype PermissionSpecificationBuilderOptions<\n FactoryHooks extends Record,\n MethodHooks extends Record,\n ValidatorHooks extends Record,\n> = {\n targetName?: string;\n allowedCaveats?: Readonly> | null;\n factoryHooks?: FactoryHooks;\n methodHooks?: MethodHooks;\n validatorHooks?: ValidatorHooks;\n};\n\n/**\n * A function that builds a permission specification. Modules that specify\n * permissions for external consumption should make this their primary /\n * default export so that host applications can use them to generate concrete\n * specifications tailored to their requirements.\n */\nexport type PermissionSpecificationBuilder<\n Type extends PermissionType,\n Options extends PermissionSpecificationBuilderOptions<\n Record,\n Record,\n Record\n >,\n Specification extends PermissionSpecificationConstraint & {\n permissionType: Type;\n },\n> = (options: Options) => Specification;\n\n/**\n * A restricted method permission export object, containing the\n * {@link PermissionSpecificationBuilder} function and \"hook name\" objects.\n */\nexport type PermissionSpecificationBuilderExportConstraint = {\n targetName: string;\n specificationBuilder: PermissionSpecificationBuilder<\n PermissionType,\n PermissionSpecificationBuilderOptions<\n Record,\n Record,\n Record\n >,\n PermissionSpecificationConstraint\n >;\n factoryHookNames?: Record;\n methodHookNames?: Record;\n validatorHookNames?: Record;\n};\n\ntype ValidRestrictedMethodSpecification<\n Specification extends RestrictedMethodSpecificationConstraint,\n> =\n Specification['methodImplementation'] extends ValidRestrictedMethod<\n Specification['methodImplementation']\n >\n ? Specification\n : never;\n\n/**\n * Constraint for {@link PermissionSpecificationConstraint} objects that\n * evaluates to `never` if the specification contains any invalid fields.\n *\n * @template Specification - The permission specification to validate.\n */\nexport type ValidPermissionSpecification<\n Specification extends PermissionSpecificationConstraint,\n> = Specification['targetName'] extends TargetName\n ? Specification['permissionType'] extends PermissionType.Endowment\n ? Specification\n : Specification['permissionType'] extends PermissionType.RestrictedMethod\n ? ValidRestrictedMethodSpecification<\n Extract\n >\n : never\n : never;\n\n/**\n * Checks that the specification has the expected permission type.\n *\n * @param specification - The specification to check.\n * @param expectedType - The expected permission type.\n * @template Specification - The specification to check.\n * @template Type - The expected permission type.\n * @returns Whether or not the specification is of the expected type.\n */\nexport function hasSpecificationType<\n Specification extends PermissionSpecificationConstraint,\n Type extends PermissionType,\n>(\n specification: Specification,\n expectedType: Type,\n): specification is Specification & {\n permissionType: Type;\n} {\n return specification.permissionType === expectedType;\n}\n\n/**\n * The specifications for all permissions supported by a particular\n * {@link PermissionController}.\n *\n * @template Specifications - The union of all {@link PermissionSpecificationConstraint} types.\n */\nexport type PermissionSpecificationMap<\n Specification extends PermissionSpecificationConstraint,\n> = {\n [Name in Specification['targetName']]: Specification extends {\n targetName: Name;\n }\n ? Specification\n : never;\n};\n\n/**\n * Extracts a specific {@link PermissionSpecificationConstraint} from a union of\n * permission specifications.\n *\n * @template Specification - The specification union type to extract from.\n * @template Name - The `targetName` of the specification to extract.\n */\nexport type ExtractPermissionSpecification<\n Specification extends PermissionSpecificationConstraint,\n Name extends Specification['targetName'],\n> = Specification extends {\n targetName: Name;\n}\n ? Specification\n : never;\n"]} +\ No newline at end of file +diff --git a/dist/Permission.d.cts b/dist/Permission.d.cts +index d7e972a08bc60305784d33f0e6271a2beeb4afdc..9727cf5091bb41570a4012ea6f117794203328f0 100644 +--- a/dist/Permission.d.cts ++++ b/dist/Permission.d.cts +@@ -1,5 +1,5 @@ +-import type { ActionConstraint, EventConstraint } from "@metamask/base-controller"; + import type { NonEmptyArray } from "@metamask/controller-utils"; ++import type { ActionConstraint, EventConstraint } from "@metamask/messenger"; + import type { Json } from "@metamask/utils"; + import type { CaveatConstraint } from "./Caveat.cjs"; + import type { PermissionsRequest, SideEffectMessenger } from "./PermissionController.cjs"; +@@ -209,7 +209,7 @@ export type PermissionValidatorConstraint = (permission: PermissionConstraint, o + */ + export type SideEffectParams = { + requestData: PermissionsRequest; +- messagingSystem: SideEffectMessenger; ++ messenger: SideEffectMessenger; + }; + /** + * A function that will execute actions as a permission side-effect. +diff --git a/dist/Permission.d.cts.map b/dist/Permission.d.cts.map +index a611427070c158328812893f4be7cc59be728062..2e8838ea25aff191d141b74f0d7f219328039505 100644 +--- a/dist/Permission.d.cts.map ++++ b/dist/Permission.d.cts.map +@@ -1 +1 @@ +-{"version":3,"file":"Permission.d.cts","sourceRoot":"","sources":["../src/Permission.ts"],"names":[],"mappings":"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"} +\ No newline at end of file ++{"version":3,"file":"Permission.d.cts","sourceRoot":"","sources":["../src/Permission.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,mCAAmC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,4BAA4B;AAC7E,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAG5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAiB;AACjD,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,EACpB,mCAA+B;AAChC,OAAO,KAAK,EAAE,WAAW,EAAE,wCAAoC;AAE/D;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC;AAElC;;GAEG;AACH,KAAK,UAAU,GAAG,MAAM,CAAC;AAEzB;;;;;;;;GAQG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAE5C;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,IAAI,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAEzD;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAE/B;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,eAAe,CACzB,IAAI,SAAS,UAAU,EACvB,aAAa,SAAS,gBAAgB,IACpC,oBAAoB,GAAG;IACzB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,aAAa,SAAS,KAAK,GACzC,IAAI,GACJ,aAAa,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;IAExC;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,EAAE,IAAI,CAAC;CACjC,CAAC;AAEF;;;;;;GAMG;AACH,KAAK,mBAAmB,CAAC,SAAS,IAAI,SAAS,SAAS,EAAE,GACtD,KAAK,GACL,SAAS,SAAS,OAAO,EAAE,GAAG,SAAS,OAAO,EAAE,GAC9C,SAAS,CAAC,MAAM,CAAC,GACjB,KAAK,CAAC;AAEZ;;;;;;GAMG;AACH,MAAM,MAAM,yBAAyB,CACnC,uBAAuB,SAAS,iCAAiC,IAC/D,mBAAmB,CAAC,uBAAuB,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAEnE;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,CAAC,gBAAgB,SAAS,oBAAoB,IAAI;IAC7E,MAAM,EAAE,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;IAC7C;;OAEG;IACH,OAAO,EAAE,YAAY,CAAC;IAEtB;;;OAGG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;CAC3C,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,gBAAgB,SAAS,oBAAoB,EAC7C,OAAO,EAAE,iBAAiB,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CAUhE;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,UAAU,EAAE,oBAAoB,EAChC,UAAU,EAAE,MAAM,GACjB,gBAAgB,GAAG,SAAS,CAE9B;AAED;;;GAGG;AACH,KAAK,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAEzD;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAC;AAE3E;;;;GAIG;AACH,KAAK,uBAAuB,GAAG,QAAQ,CAAC;IACtC,MAAM,EAAE,YAAY,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC,CAAC;AAEH,MAAM,MAAM,0BAA0B,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAEvE;;;;GAIG;AACH,MAAM,MAAM,uBAAuB,CACjC,MAAM,SAAS,0BAA0B,GAAG,IAAI,IAC9C;IACF,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,uBAAuB,CAAC;CAClC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,CAC9B,MAAM,SAAS,0BAA0B,EACzC,MAAM,SAAS,IAAI,IACjB,CAAC,IAAI,EAAE,uBAAuB,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC;AAEtD;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,CAC/B,MAAM,SAAS,0BAA0B,EACzC,MAAM,SAAS,IAAI,IACjB,CAAC,IAAI,EAAE,uBAAuB,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAE/D;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,CAC1B,MAAM,SAAS,0BAA0B,EACzC,MAAM,SAAS,IAAI,IAEjB,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,GACpC,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE1C,MAAM,MAAM,qBAAqB,CAC/B,oBAAoB,SAAS,gBAAgB,CAC3C,0BAA0B,EAC1B,IAAI,CACL,IACC,oBAAoB,SAAS,CAAC,IAAI,EAAE,MAAM,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAC1E,OAAO,SAAS,uBAAuB,CAAC,0BAA0B,CAAC,GACjE,oBAAoB,GACpB,KAAK,GACP,KAAK,CAAC;AAEV;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,eAAe,CAAC,UAAU,SAAS,IAAI,IAAI,CACrD,OAAO,EAAE,qBAAqB,KAC3B,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,MAAM,MAAM,iBAAiB,CAC3B,gBAAgB,SAAS,oBAAoB,EAC7C,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IACzC,CACF,OAAO,EAAE,iBAAiB,CAAC,gBAAgB,CAAC,EAC5C,WAAW,CAAC,EAAE,WAAW,KACtB,gBAAgB,CAAC;AAEtB,MAAM,MAAM,6BAA6B,GAAG,CAC1C,UAAU,EAAE,oBAAoB,EAChC,MAAM,CAAC,EAAE,YAAY,EACrB,MAAM,CAAC,EAAE,MAAM,KACZ,IAAI,CAAC;AAEV;;GAEG;AACH,MAAM,MAAM,gBAAgB,CAC1B,OAAO,SAAS,gBAAgB,EAChC,MAAM,SAAS,eAAe,IAC5B;IACF,WAAW,EAAE,kBAAkB,CAAC;IAChC,SAAS,EAAE,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;CACjD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,CAC3B,OAAO,SAAS,gBAAgB,EAChC,MAAM,SAAS,eAAe,IAC5B,CAAC,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpE;;GAEG;AACH,MAAM,MAAM,oBAAoB,CAC9B,OAAO,SAAS,gBAAgB,EAChC,MAAM,SAAS,eAAe,IAC5B;IACF;;OAEG;IACH,WAAW,EAAE,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAChD;;OAEG;IACH,SAAS,CAAC,EAAE,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;CAChD,CAAC;AAEF;;GAEG;AACH,oBAAY,cAAc;IACxB;;;OAGG;IACH,gBAAgB,qBAAqB;IAErC;;;OAGG;IACH,SAAS,cAAc;CACxB;AAED;;;;;;;;;GASG;AACH,KAAK,2BAA2B,CAAC,IAAI,SAAS,cAAc,IAAI;IAC9D;;OAEG;IACH,cAAc,EAAE,IAAI,CAAC;IAErB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,cAAc,EAAE,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;IAEvD;;;;;;;;;OASG;IAGH,OAAO,CAAC,EAAE,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAE1D;;;;;;;;;;OAUG;IACH,SAAS,CAAC,EAAE,6BAA6B,CAAC;IAE1C;;;;;OAKG;IACH,UAAU,CAAC,EAAE,oBAAoB,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC;IAErE;;;;;OAKG;IACH,YAAY,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;CACvC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,uCAAuC,GACjD,2BAA2B,CAAC,cAAc,CAAC,gBAAgB,CAAC,GAAG;IAC7D;;;OAGG;IAGH,oBAAoB,EAAE,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;CACnD,CAAC;AAEJ;;;;;;GAMG;AACH,MAAM,MAAM,gCAAgC,GAC1C,2BAA2B,CAAC,cAAc,CAAC,SAAS,CAAC,GAAG;IACtD;;;;;OAKG;IACH,eAAe,EAAE,eAAe,CAAC,IAAI,CAAC,CAAC;CACxC,CAAC;AAEJ;;;;;;;;;GASG;AACH,MAAM,MAAM,iCAAiC,GACzC,gCAAgC,GAChC,uCAAuC,CAAC;AAE5C;;GAEG;AACH,KAAK,qCAAqC,CACxC,YAAY,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5C,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3C,cAAc,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAC5C;IACF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;IACxD,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,8BAA8B,CACxC,IAAI,SAAS,cAAc,EAC3B,OAAO,SAAS,qCAAqC,CACnD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CACxB,EACD,aAAa,SAAS,iCAAiC,GAAG;IACxD,cAAc,EAAE,IAAI,CAAC;CACtB,IACC,CAAC,OAAO,EAAE,OAAO,KAAK,aAAa,CAAC;AAExC;;;GAGG;AACH,MAAM,MAAM,8CAA8C,GAAG;IAC3D,UAAU,EAAE,MAAM,CAAC;IACnB,oBAAoB,EAAE,8BAA8B,CAClD,cAAc,EACd,qCAAqC,CACnC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CACxB,EACD,iCAAiC,CAClC,CAAC;IACF,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACxC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACvC,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;CAC3C,CAAC;AAEF,KAAK,kCAAkC,CACrC,aAAa,SAAS,uCAAuC,IAE7D,aAAa,CAAC,sBAAsB,CAAC,SAAS,qBAAqB,CACjE,aAAa,CAAC,sBAAsB,CAAC,CACtC,GACG,aAAa,GACb,KAAK,CAAC;AAEZ;;;;;GAKG;AACH,MAAM,MAAM,4BAA4B,CACtC,aAAa,SAAS,iCAAiC,IACrD,aAAa,CAAC,YAAY,CAAC,SAAS,UAAU,GAC9C,aAAa,CAAC,gBAAgB,CAAC,SAAS,cAAc,CAAC,SAAS,GAC9D,aAAa,GACb,aAAa,CAAC,gBAAgB,CAAC,SAAS,cAAc,CAAC,gBAAgB,GACrE,kCAAkC,CAChC,OAAO,CAAC,aAAa,EAAE,uCAAuC,CAAC,CAChE,GACD,KAAK,GACT,KAAK,CAAC;AAEV;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,aAAa,SAAS,iCAAiC,EACvD,IAAI,SAAS,cAAc,EAE3B,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,IAAI,GACjB,aAAa,IAAI,aAAa,GAAG;IAClC,cAAc,EAAE,IAAI,CAAC;CACtB,CAEA;AAED;;;;;GAKG;AACH,MAAM,MAAM,0BAA0B,CACpC,aAAa,SAAS,iCAAiC,IACrD;KACD,IAAI,IAAI,aAAa,CAAC,YAAY,CAAC,GAAG,aAAa,SAAS;QAC3D,UAAU,EAAE,IAAI,CAAC;KAClB,GACG,aAAa,GACb,KAAK;CACV,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,8BAA8B,CACxC,aAAa,SAAS,iCAAiC,EACvD,IAAI,SAAS,aAAa,CAAC,YAAY,CAAC,IACtC,aAAa,SAAS;IACxB,UAAU,EAAE,IAAI,CAAC;CAClB,GACG,aAAa,GACb,KAAK,CAAC"} +\ No newline at end of file +diff --git a/dist/Permission.d.mts b/dist/Permission.d.mts +index 38e7dd1ff7781aaadcded071b74987f9ff4f0562..4643347c73468f4ee924b0570f40481c461f3817 100644 +--- a/dist/Permission.d.mts ++++ b/dist/Permission.d.mts +@@ -1,5 +1,5 @@ +-import type { ActionConstraint, EventConstraint } from "@metamask/base-controller"; + import type { NonEmptyArray } from "@metamask/controller-utils"; ++import type { ActionConstraint, EventConstraint } from "@metamask/messenger"; + import type { Json } from "@metamask/utils"; + import type { CaveatConstraint } from "./Caveat.mjs"; + import type { PermissionsRequest, SideEffectMessenger } from "./PermissionController.mjs"; +@@ -209,7 +209,7 @@ export type PermissionValidatorConstraint = (permission: PermissionConstraint, o + */ + export type SideEffectParams = { + requestData: PermissionsRequest; +- messagingSystem: SideEffectMessenger; ++ messenger: SideEffectMessenger; + }; + /** + * A function that will execute actions as a permission side-effect. +diff --git a/dist/Permission.d.mts.map b/dist/Permission.d.mts.map +index 6342e7caa3f0977fa280201a258d58467c187c1e..a69edbb7ad3823fa1a63288a5d8b616a6dc1b5eb 100644 +--- a/dist/Permission.d.mts.map ++++ b/dist/Permission.d.mts.map +@@ -1 +1 @@ +-{"version":3,"file":"Permission.d.mts","sourceRoot":"","sources":["../src/Permission.ts"],"names":[],"mappings":"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"} +\ No newline at end of file ++{"version":3,"file":"Permission.d.mts","sourceRoot":"","sources":["../src/Permission.ts"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/dist/Permission.mjs.map b/dist/Permission.mjs.map +index 6202c4a6baab1e4d56c0ff1c61aa0aec676d7405..3cd0b249ee7def6a65ae043f8b1983a3e1fce97c 100644 +--- a/dist/Permission.mjs.map ++++ b/dist/Permission.mjs.map +@@ -1 +1 @@ +-{"version":3,"file":"Permission.mjs","sourceRoot":"","sources":["../src/Permission.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,MAAM,EAAE,eAAe;AAkJhC;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAEjC,OAA4C;IAC5C,MAAM,EAAE,OAAO,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAEpD,OAAO;QACL,EAAE,EAAE,MAAM,EAAE;QACZ,gBAAgB,EAAE,MAAM;QACxB,OAAO;QACP,OAAO;QACP,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE;KACP,CAAC;AACxB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CACxB,UAAgC,EAChC,UAAkB;IAElB,OAAO,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;AAC1E,CAAC;AAgKD;;GAEG;AACH,MAAM,CAAN,IAAY,cAYX;AAZD,WAAY,cAAc;IACxB;;;OAGG;IACH,uDAAqC,CAAA;IAErC;;;OAGG;IACH,yCAAuB,CAAA;AACzB,CAAC,EAZW,cAAc,KAAd,cAAc,QAYzB;AA0MD;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAIlC,aAA4B,EAC5B,YAAkB;IAIlB,OAAO,aAAa,CAAC,cAAc,KAAK,YAAY,CAAC;AACvD,CAAC","sourcesContent":["import type {\n ActionConstraint,\n EventConstraint,\n} from '@metamask/base-controller';\nimport type { NonEmptyArray } from '@metamask/controller-utils';\nimport type { Json } from '@metamask/utils';\nimport { nanoid } from 'nanoid';\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport type { CaveatConstraint, Caveat } from './Caveat';\nimport type {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n PermissionController,\n PermissionsRequest,\n SideEffectMessenger,\n} from './PermissionController';\nimport type { SubjectType } from './SubjectMetadataController';\n\n/**\n * The origin of a subject.\n * Effectively the GUID of an entity that can have permissions.\n */\nexport type OriginString = string;\n\n/**\n * The name of a permission target.\n */\ntype TargetName = string;\n\n/**\n * A `ZCAP-LD`-like permission object. A permission is associated with a\n * particular `invoker`, which is the holder of the permission. Possessing the\n * permission grants access to a particular restricted resource, identified by\n * the `parentCapability`. The use of the restricted resource may be further\n * restricted by any `caveats` associated with the permission.\n *\n * See the README for details.\n */\nexport type PermissionConstraint = {\n /**\n * The context(s) in which this capability is meaningful.\n *\n * It is required by the standard, but we make it optional since there is only\n * one context in our usage (i.e. the user's MetaMask instance).\n */\n readonly '@context'?: NonEmptyArray;\n\n /**\n * The caveats of the permission.\n *\n * @see {@link Caveat} For more information.\n */\n readonly caveats: null | NonEmptyArray;\n\n /**\n * The creation date of the permission, in UNIX epoch time.\n */\n readonly date: number;\n\n /**\n * The GUID of the permission object.\n */\n readonly id: string;\n\n /**\n * The origin string of the subject that has the permission.\n */\n readonly invoker: OriginString;\n\n /**\n * A pointer to the resource that possession of the capability grants\n * access to, for example a JSON-RPC method or endowment.\n */\n readonly parentCapability: string;\n};\n\n/**\n * A `ZCAP-LD`-like permission object. A permission is associated with a\n * particular `invoker`, which is the holder of the permission. Possessing the\n * permission grants access to a particular restricted resource, identified by\n * the `parentCapability`. The use of the restricted resource may be further\n * restricted by any `caveats` associated with the permission.\n *\n * See the README for details.\n *\n * @template Name - The name of the permission that the target corresponds to.\n * @template AllowedCaveat - A union of the allowed {@link Caveat} types\n * for the permission.\n */\nexport type ValidPermission<\n Name extends TargetName,\n AllowedCaveat extends CaveatConstraint,\n> = PermissionConstraint & {\n /**\n * The caveats of the permission.\n *\n * @see {@link Caveat} For more information.\n */\n readonly caveats: AllowedCaveat extends never\n ? null\n : NonEmptyArray | null;\n\n /**\n * A pointer to the resource that possession of the capability grants\n * access to, for example a JSON-RPC method or endowment.\n */\n readonly parentCapability: Name;\n};\n\n/**\n * Internal utility for extracting the members types of an array. The type\n * evalutes to `never` if the specified type is the empty tuple or neither\n * an array nor a tuple.\n *\n * @template ArrayType - The array type whose members to extract.\n */\ntype ExtractArrayMembers = ArrayType extends []\n ? never\n : ArrayType extends unknown[] | readonly unknown[]\n ? ArrayType[number]\n : never;\n\n/**\n * A utility type for extracting the allowed caveat types for a particular\n * permission from a permission specification type.\n *\n * @template PermissionSpecification - The permission specification type to\n * extract valid caveat types from.\n */\nexport type ExtractAllowedCaveatTypes<\n PermissionSpecification extends PermissionSpecificationConstraint,\n> = ExtractArrayMembers;\n\n/**\n * The options object of {@link constructPermission}.\n *\n * @template TargetPermission - The {@link Permission} that will be constructed.\n */\nexport type PermissionOptions = {\n target: TargetPermission['parentCapability'];\n /**\n * The origin string of the subject that has the permission.\n */\n invoker: OriginString;\n\n /**\n * The caveats of the permission.\n * See {@link Caveat}.\n */\n caveats?: NonEmptyArray;\n};\n\n/**\n * The default permission factory function. Naively constructs a permission from\n * the inputs. Sets a default, random `id` if none is provided.\n *\n * @see {@link Permission} For more details.\n * @template TargetPermission- - The {@link Permission} that will be constructed.\n * @param options - The options for the permission.\n * @returns The new permission object.\n */\nexport function constructPermission<\n TargetPermission extends PermissionConstraint,\n>(options: PermissionOptions): TargetPermission {\n const { caveats = null, invoker, target } = options;\n\n return {\n id: nanoid(),\n parentCapability: target,\n invoker,\n caveats,\n date: new Date().getTime(),\n } as TargetPermission;\n}\n\n/**\n * Gets the caveat of the specified type belonging to the specified permission.\n *\n * @param permission - The permission whose caveat to retrieve.\n * @param caveatType - The type of the caveat to retrieve.\n * @returns The caveat, or undefined if no such caveat exists.\n */\nexport function findCaveat(\n permission: PermissionConstraint,\n caveatType: string,\n): CaveatConstraint | undefined {\n return permission.caveats?.find((caveat) => caveat.type === caveatType);\n}\n\n/**\n * A requested permission object. Just an object with any of the properties\n * of a {@link PermissionConstraint} object.\n */\ntype RequestedPermission = Partial;\n\n/**\n * A record of target names and their {@link RequestedPermission} objects.\n */\nexport type RequestedPermissions = Record;\n\n/**\n * The restricted method context object. Essentially a way to pass internal\n * arguments to restricted methods and caveat functions, most importantly the\n * requesting origin.\n */\ntype RestrictedMethodContext = Readonly<{\n origin: OriginString;\n [key: string]: unknown;\n}>;\n\nexport type RestrictedMethodParameters = Json[] | Record;\n\n/**\n * The arguments passed to a restricted method implementation.\n *\n * @template Params - The JSON-RPC parameters of the restricted method.\n */\nexport type RestrictedMethodOptions<\n Params extends RestrictedMethodParameters | null,\n> = {\n method: TargetName;\n params?: Params;\n context: RestrictedMethodContext;\n};\n\n/**\n * A synchronous restricted method implementation.\n *\n * @template Params - The JSON-RPC parameters of the restricted method.\n * @template Result - The JSON-RPC result of the restricted method.\n */\nexport type SyncRestrictedMethod<\n Params extends RestrictedMethodParameters,\n Result extends Json,\n> = (args: RestrictedMethodOptions) => Result;\n\n/**\n * An asynchronous restricted method implementation.\n *\n * @template Params - The JSON-RPC parameters of the restricted method.\n * @template Result - The JSON-RPC result of the restricted method.\n */\nexport type AsyncRestrictedMethod<\n Params extends RestrictedMethodParameters,\n Result extends Json,\n> = (args: RestrictedMethodOptions) => Promise;\n\n/**\n * A synchronous or asynchronous restricted method implementation.\n *\n * @template Params - The JSON-RPC parameters of the restricted method.\n * @template Result - The JSON-RPC result of the restricted method.\n */\nexport type RestrictedMethod<\n Params extends RestrictedMethodParameters,\n Result extends Json,\n> =\n | SyncRestrictedMethod\n | AsyncRestrictedMethod;\n\nexport type ValidRestrictedMethod<\n MethodImplementation extends RestrictedMethod<\n RestrictedMethodParameters,\n Json\n >,\n> = MethodImplementation extends (args: infer Options) => Json | Promise\n ? Options extends RestrictedMethodOptions\n ? MethodImplementation\n : never\n : never;\n\n/**\n * {@link EndowmentGetter} parameter object.\n */\nexport type EndowmentGetterParams = {\n /**\n * The origin of the requesting subject.\n */\n origin: string;\n\n /**\n * Any additional data associated with the request.\n */\n requestData?: unknown;\n\n [key: string]: unknown;\n};\n\n/**\n * A synchronous or asynchronous function that gets the endowments for a\n * particular endowment permission. The getter receives the origin of the\n * requesting subject and, optionally, additional request metadata.\n */\nexport type EndowmentGetter = (\n options: EndowmentGetterParams,\n) => Endowments | Promise;\n\nexport type PermissionFactory<\n TargetPermission extends PermissionConstraint,\n RequestData extends Record,\n> = (\n options: PermissionOptions,\n requestData?: RequestData,\n) => TargetPermission;\n\nexport type PermissionValidatorConstraint = (\n permission: PermissionConstraint,\n origin?: OriginString,\n target?: string,\n) => void;\n\n/**\n * The parameters passed to the side-effect function.\n */\nexport type SideEffectParams<\n Actions extends ActionConstraint,\n Events extends EventConstraint,\n> = {\n requestData: PermissionsRequest;\n messagingSystem: SideEffectMessenger;\n};\n\n/**\n * A function that will execute actions as a permission side-effect.\n */\nexport type SideEffectHandler<\n Actions extends ActionConstraint,\n Events extends EventConstraint,\n> = (params: SideEffectParams) => Promise;\n\n/**\n * The permissions side effects.\n */\nexport type PermissionSideEffect<\n Actions extends ActionConstraint,\n Events extends EventConstraint,\n> = {\n /**\n * A method triggered when the permission is accepted by the user\n */\n onPermitted: SideEffectHandler;\n /**\n * A method triggered if a `onPermitted` method rejected.\n */\n onFailure?: SideEffectHandler;\n};\n\n/**\n * The different possible types of permissions.\n */\nexport enum PermissionType {\n /**\n * A restricted JSON-RPC method. A subject must have the requisite permission\n * to call a restricted JSON-RPC method.\n */\n RestrictedMethod = 'RestrictedMethod',\n\n /**\n * An \"endowment\" granted to subjects that possess the requisite permission,\n * such as a global environment variable exposing a restricted API, etc.\n */\n Endowment = 'Endowment',\n}\n\n/**\n * The base constraint for permission specification objects. Every\n * {@link Permission} supported by a {@link PermissionController} must have an\n * associated specification, which is the source of truth for all permission-\n * related types. A permission specification includes the list of permitted\n * caveats, and any factory and validation functions specified by the consumer.\n * A concrete permission specification may specify further fields as necessary.\n *\n * See the README for more details.\n */\ntype PermissionSpecificationBase = {\n /**\n * The type of the specified permission.\n */\n permissionType: Type;\n\n /**\n * The name of the target resource of the permission.\n */\n targetName: string;\n\n /**\n * An array of the caveat types that may be added to instances of this\n * permission.\n */\n allowedCaveats: Readonly> | null;\n\n /**\n * The factory function used to get permission objects. Permissions returned\n * by this function are presumed to valid, and they will not be passed to the\n * validator function associated with this specification (if any). In other\n * words, the factory function should validate the permissions it creates.\n *\n * If no factory is specified, the {@link Permission} constructor will be\n * used, and the validator function (if specified) will be called on newly\n * constructed permissions.\n */\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n factory?: PermissionFactory>;\n\n /**\n * The validator function used to validate permissions of the associated type\n * whenever they are granted or their caveat arrays are mutated.\n *\n * Permission validators are **not** invoked when a caveat is mutated, provided\n * the caveat array has not changed. For this reason, permission validators\n * **must not** be used to validate caveats. To validate caveats, use the\n * corresponding caveat specification property.\n *\n * The validator should throw an appropriate JSON-RPC error if validation fails.\n */\n validator?: PermissionValidatorConstraint;\n\n /**\n * The side-effect triggered by the {@link PermissionController} once the user approved it.\n * The side-effect can only be an action allowed to be called inside the {@link PermissionController}.\n *\n * If the side-effect action fails, the permission that triggered it is revoked.\n */\n sideEffect?: PermissionSideEffect;\n\n /**\n * The Permission may be available to only a subset of the subject types. If so, specify the subject types as an array.\n * If a subject with a type not in this array tries to request the permission, the call will fail.\n *\n * Leaving this as undefined uses default behaviour where the permission is available to request for all subject types.\n */\n subjectTypes?: readonly SubjectType[];\n};\n\n/**\n * The constraint for restricted method permission specification objects.\n * Permissions that correspond to JSON-RPC methods are specified using objects\n * that conform to this type.\n *\n * See the README for more details.\n */\nexport type RestrictedMethodSpecificationConstraint =\n PermissionSpecificationBase & {\n /**\n * The implementation of the restricted method that the permission\n * corresponds to.\n */\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n methodImplementation: RestrictedMethod;\n };\n\n/**\n * The constraint for endowment permission specification objects. Permissions\n * that endow callers with some restricted resource are specified using objects\n * that conform to this type.\n *\n * See the README for more details.\n */\nexport type EndowmentSpecificationConstraint =\n PermissionSpecificationBase & {\n /**\n * The {@link EndowmentGetter} function for the permission. This function\n * will be called by the {@link PermissionController} whenever the\n * permission is invoked, after which the host can apply the endowments to\n * the requesting subject in the intended manner.\n */\n endowmentGetter: EndowmentGetter;\n };\n\n/**\n * The constraint for permission specification objects. Every {@link Permission}\n * supported by a {@link PermissionController} must have an associated\n * specification, which is the source of truth for all permission-related types.\n * All specifications must adhere to the {@link PermissionSpecificationBase}\n * interface, but specifications may have different fields depending on the\n * {@link PermissionType}.\n *\n * See the README for more details.\n */\nexport type PermissionSpecificationConstraint =\n | EndowmentSpecificationConstraint\n | RestrictedMethodSpecificationConstraint;\n\n/**\n * Options for {@link PermissionSpecificationBuilder} functions.\n */\ntype PermissionSpecificationBuilderOptions<\n FactoryHooks extends Record,\n MethodHooks extends Record,\n ValidatorHooks extends Record,\n> = {\n targetName?: string;\n allowedCaveats?: Readonly> | null;\n factoryHooks?: FactoryHooks;\n methodHooks?: MethodHooks;\n validatorHooks?: ValidatorHooks;\n};\n\n/**\n * A function that builds a permission specification. Modules that specify\n * permissions for external consumption should make this their primary /\n * default export so that host applications can use them to generate concrete\n * specifications tailored to their requirements.\n */\nexport type PermissionSpecificationBuilder<\n Type extends PermissionType,\n Options extends PermissionSpecificationBuilderOptions<\n Record,\n Record,\n Record\n >,\n Specification extends PermissionSpecificationConstraint & {\n permissionType: Type;\n },\n> = (options: Options) => Specification;\n\n/**\n * A restricted method permission export object, containing the\n * {@link PermissionSpecificationBuilder} function and \"hook name\" objects.\n */\nexport type PermissionSpecificationBuilderExportConstraint = {\n targetName: string;\n specificationBuilder: PermissionSpecificationBuilder<\n PermissionType,\n PermissionSpecificationBuilderOptions<\n Record,\n Record,\n Record\n >,\n PermissionSpecificationConstraint\n >;\n factoryHookNames?: Record;\n methodHookNames?: Record;\n validatorHookNames?: Record;\n};\n\ntype ValidRestrictedMethodSpecification<\n Specification extends RestrictedMethodSpecificationConstraint,\n> = Specification['methodImplementation'] extends ValidRestrictedMethod<\n Specification['methodImplementation']\n>\n ? Specification\n : never;\n\n/**\n * Constraint for {@link PermissionSpecificationConstraint} objects that\n * evaluates to `never` if the specification contains any invalid fields.\n *\n * @template Specification - The permission specification to validate.\n */\nexport type ValidPermissionSpecification<\n Specification extends PermissionSpecificationConstraint,\n> = Specification['targetName'] extends TargetName\n ? Specification['permissionType'] extends PermissionType.Endowment\n ? Specification\n : Specification['permissionType'] extends PermissionType.RestrictedMethod\n ? ValidRestrictedMethodSpecification<\n Extract\n >\n : never\n : never;\n\n/**\n * Checks that the specification has the expected permission type.\n *\n * @param specification - The specification to check.\n * @param expectedType - The expected permission type.\n * @template Specification - The specification to check.\n * @template Type - The expected permission type.\n * @returns Whether or not the specification is of the expected type.\n */\nexport function hasSpecificationType<\n Specification extends PermissionSpecificationConstraint,\n Type extends PermissionType,\n>(\n specification: Specification,\n expectedType: Type,\n): specification is Specification & {\n permissionType: Type;\n} {\n return specification.permissionType === expectedType;\n}\n\n/**\n * The specifications for all permissions supported by a particular\n * {@link PermissionController}.\n *\n * @template Specifications - The union of all {@link PermissionSpecificationConstraint} types.\n */\nexport type PermissionSpecificationMap<\n Specification extends PermissionSpecificationConstraint,\n> = {\n [Name in Specification['targetName']]: Specification extends {\n targetName: Name;\n }\n ? Specification\n : never;\n};\n\n/**\n * Extracts a specific {@link PermissionSpecificationConstraint} from a union of\n * permission specifications.\n *\n * @template Specification - The specification union type to extract from.\n * @template Name - The `targetName` of the specification to extract.\n */\nexport type ExtractPermissionSpecification<\n Specification extends PermissionSpecificationConstraint,\n Name extends Specification['targetName'],\n> = Specification extends {\n targetName: Name;\n}\n ? Specification\n : never;\n"]} +\ No newline at end of file ++{"version":3,"file":"Permission.mjs","sourceRoot":"","sources":["../src/Permission.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,eAAe;AA+IhC;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAEjC,OAA4C;IAC5C,MAAM,EAAE,OAAO,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAEpD,OAAO;QACL,EAAE,EAAE,MAAM,EAAE;QACZ,gBAAgB,EAAE,MAAM;QACxB,OAAO;QACP,OAAO;QACP,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE;KACP,CAAC;AACxB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CACxB,UAAgC,EAChC,UAAkB;IAElB,OAAO,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;AAC1E,CAAC;AAgKD;;GAEG;AACH,MAAM,CAAN,IAAY,cAYX;AAZD,WAAY,cAAc;IACxB;;;OAGG;IACH,uDAAqC,CAAA;IAErC;;;OAGG;IACH,yCAAuB,CAAA;AACzB,CAAC,EAZW,cAAc,KAAd,cAAc,QAYzB;AA2MD;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAIlC,aAA4B,EAC5B,YAAkB;IAIlB,OAAO,aAAa,CAAC,cAAc,KAAK,YAAY,CAAC;AACvD,CAAC","sourcesContent":["import type { NonEmptyArray } from '@metamask/controller-utils';\nimport type { ActionConstraint, EventConstraint } from '@metamask/messenger';\nimport type { Json } from '@metamask/utils';\nimport { nanoid } from 'nanoid';\n\nimport type { CaveatConstraint } from './Caveat';\nimport type {\n PermissionsRequest,\n SideEffectMessenger,\n} from './PermissionController';\nimport type { SubjectType } from './SubjectMetadataController';\n\n/**\n * The origin of a subject.\n * Effectively the GUID of an entity that can have permissions.\n */\nexport type OriginString = string;\n\n/**\n * The name of a permission target.\n */\ntype TargetName = string;\n\n/**\n * A `ZCAP-LD`-like permission object. A permission is associated with a\n * particular `invoker`, which is the holder of the permission. Possessing the\n * permission grants access to a particular restricted resource, identified by\n * the `parentCapability`. The use of the restricted resource may be further\n * restricted by any `caveats` associated with the permission.\n *\n * See the README for details.\n */\nexport type PermissionConstraint = {\n /**\n * The context(s) in which this capability is meaningful.\n *\n * It is required by the standard, but we make it optional since there is only\n * one context in our usage (i.e. the user's MetaMask instance).\n */\n readonly '@context'?: NonEmptyArray;\n\n /**\n * The caveats of the permission.\n *\n * @see {@link Caveat} For more information.\n */\n readonly caveats: null | NonEmptyArray;\n\n /**\n * The creation date of the permission, in UNIX epoch time.\n */\n readonly date: number;\n\n /**\n * The GUID of the permission object.\n */\n readonly id: string;\n\n /**\n * The origin string of the subject that has the permission.\n */\n readonly invoker: OriginString;\n\n /**\n * A pointer to the resource that possession of the capability grants\n * access to, for example a JSON-RPC method or endowment.\n */\n readonly parentCapability: string;\n};\n\n/**\n * A `ZCAP-LD`-like permission object. A permission is associated with a\n * particular `invoker`, which is the holder of the permission. Possessing the\n * permission grants access to a particular restricted resource, identified by\n * the `parentCapability`. The use of the restricted resource may be further\n * restricted by any `caveats` associated with the permission.\n *\n * See the README for details.\n *\n * @template Name - The name of the permission that the target corresponds to.\n * @template AllowedCaveat - A union of the allowed {@link Caveat} types\n * for the permission.\n */\nexport type ValidPermission<\n Name extends TargetName,\n AllowedCaveat extends CaveatConstraint,\n> = PermissionConstraint & {\n /**\n * The caveats of the permission.\n *\n * @see {@link Caveat} For more information.\n */\n readonly caveats: AllowedCaveat extends never\n ? null\n : NonEmptyArray | null;\n\n /**\n * A pointer to the resource that possession of the capability grants\n * access to, for example a JSON-RPC method or endowment.\n */\n readonly parentCapability: Name;\n};\n\n/**\n * Internal utility for extracting the members types of an array. The type\n * evalutes to `never` if the specified type is the empty tuple or neither\n * an array nor a tuple.\n *\n * @template ArrayType - The array type whose members to extract.\n */\ntype ExtractArrayMembers = ArrayType extends []\n ? never\n : ArrayType extends unknown[] | readonly unknown[]\n ? ArrayType[number]\n : never;\n\n/**\n * A utility type for extracting the allowed caveat types for a particular\n * permission from a permission specification type.\n *\n * @template PermissionSpecification - The permission specification type to\n * extract valid caveat types from.\n */\nexport type ExtractAllowedCaveatTypes<\n PermissionSpecification extends PermissionSpecificationConstraint,\n> = ExtractArrayMembers;\n\n/**\n * The options object of {@link constructPermission}.\n *\n * @template TargetPermission - The {@link Permission} that will be constructed.\n */\nexport type PermissionOptions = {\n target: TargetPermission['parentCapability'];\n /**\n * The origin string of the subject that has the permission.\n */\n invoker: OriginString;\n\n /**\n * The caveats of the permission.\n * See {@link Caveat}.\n */\n caveats?: NonEmptyArray;\n};\n\n/**\n * The default permission factory function. Naively constructs a permission from\n * the inputs. Sets a default, random `id` if none is provided.\n *\n * @see {@link Permission} For more details.\n * @template TargetPermission- - The {@link Permission} that will be constructed.\n * @param options - The options for the permission.\n * @returns The new permission object.\n */\nexport function constructPermission<\n TargetPermission extends PermissionConstraint,\n>(options: PermissionOptions): TargetPermission {\n const { caveats = null, invoker, target } = options;\n\n return {\n id: nanoid(),\n parentCapability: target,\n invoker,\n caveats,\n date: new Date().getTime(),\n } as TargetPermission;\n}\n\n/**\n * Gets the caveat of the specified type belonging to the specified permission.\n *\n * @param permission - The permission whose caveat to retrieve.\n * @param caveatType - The type of the caveat to retrieve.\n * @returns The caveat, or undefined if no such caveat exists.\n */\nexport function findCaveat(\n permission: PermissionConstraint,\n caveatType: string,\n): CaveatConstraint | undefined {\n return permission.caveats?.find((caveat) => caveat.type === caveatType);\n}\n\n/**\n * A requested permission object. Just an object with any of the properties\n * of a {@link PermissionConstraint} object.\n */\ntype RequestedPermission = Partial;\n\n/**\n * A record of target names and their {@link RequestedPermission} objects.\n */\nexport type RequestedPermissions = Record;\n\n/**\n * The restricted method context object. Essentially a way to pass internal\n * arguments to restricted methods and caveat functions, most importantly the\n * requesting origin.\n */\ntype RestrictedMethodContext = Readonly<{\n origin: OriginString;\n [key: string]: unknown;\n}>;\n\nexport type RestrictedMethodParameters = Json[] | Record;\n\n/**\n * The arguments passed to a restricted method implementation.\n *\n * @template Params - The JSON-RPC parameters of the restricted method.\n */\nexport type RestrictedMethodOptions<\n Params extends RestrictedMethodParameters | null,\n> = {\n method: TargetName;\n params?: Params;\n context: RestrictedMethodContext;\n};\n\n/**\n * A synchronous restricted method implementation.\n *\n * @template Params - The JSON-RPC parameters of the restricted method.\n * @template Result - The JSON-RPC result of the restricted method.\n */\nexport type SyncRestrictedMethod<\n Params extends RestrictedMethodParameters,\n Result extends Json,\n> = (args: RestrictedMethodOptions) => Result;\n\n/**\n * An asynchronous restricted method implementation.\n *\n * @template Params - The JSON-RPC parameters of the restricted method.\n * @template Result - The JSON-RPC result of the restricted method.\n */\nexport type AsyncRestrictedMethod<\n Params extends RestrictedMethodParameters,\n Result extends Json,\n> = (args: RestrictedMethodOptions) => Promise;\n\n/**\n * A synchronous or asynchronous restricted method implementation.\n *\n * @template Params - The JSON-RPC parameters of the restricted method.\n * @template Result - The JSON-RPC result of the restricted method.\n */\nexport type RestrictedMethod<\n Params extends RestrictedMethodParameters,\n Result extends Json,\n> =\n | SyncRestrictedMethod\n | AsyncRestrictedMethod;\n\nexport type ValidRestrictedMethod<\n MethodImplementation extends RestrictedMethod<\n RestrictedMethodParameters,\n Json\n >,\n> = MethodImplementation extends (args: infer Options) => Json | Promise\n ? Options extends RestrictedMethodOptions\n ? MethodImplementation\n : never\n : never;\n\n/**\n * {@link EndowmentGetter} parameter object.\n */\nexport type EndowmentGetterParams = {\n /**\n * The origin of the requesting subject.\n */\n origin: string;\n\n /**\n * Any additional data associated with the request.\n */\n requestData?: unknown;\n\n [key: string]: unknown;\n};\n\n/**\n * A synchronous or asynchronous function that gets the endowments for a\n * particular endowment permission. The getter receives the origin of the\n * requesting subject and, optionally, additional request metadata.\n */\nexport type EndowmentGetter = (\n options: EndowmentGetterParams,\n) => Endowments | Promise;\n\nexport type PermissionFactory<\n TargetPermission extends PermissionConstraint,\n RequestData extends Record,\n> = (\n options: PermissionOptions,\n requestData?: RequestData,\n) => TargetPermission;\n\nexport type PermissionValidatorConstraint = (\n permission: PermissionConstraint,\n origin?: OriginString,\n target?: string,\n) => void;\n\n/**\n * The parameters passed to the side-effect function.\n */\nexport type SideEffectParams<\n Actions extends ActionConstraint,\n Events extends EventConstraint,\n> = {\n requestData: PermissionsRequest;\n messenger: SideEffectMessenger;\n};\n\n/**\n * A function that will execute actions as a permission side-effect.\n */\nexport type SideEffectHandler<\n Actions extends ActionConstraint,\n Events extends EventConstraint,\n> = (params: SideEffectParams) => Promise;\n\n/**\n * The permissions side effects.\n */\nexport type PermissionSideEffect<\n Actions extends ActionConstraint,\n Events extends EventConstraint,\n> = {\n /**\n * A method triggered when the permission is accepted by the user\n */\n onPermitted: SideEffectHandler;\n /**\n * A method triggered if a `onPermitted` method rejected.\n */\n onFailure?: SideEffectHandler;\n};\n\n/**\n * The different possible types of permissions.\n */\nexport enum PermissionType {\n /**\n * A restricted JSON-RPC method. A subject must have the requisite permission\n * to call a restricted JSON-RPC method.\n */\n RestrictedMethod = 'RestrictedMethod',\n\n /**\n * An \"endowment\" granted to subjects that possess the requisite permission,\n * such as a global environment variable exposing a restricted API, etc.\n */\n Endowment = 'Endowment',\n}\n\n/**\n * The base constraint for permission specification objects. Every\n * {@link Permission} supported by a {@link PermissionController} must have an\n * associated specification, which is the source of truth for all permission-\n * related types. A permission specification includes the list of permitted\n * caveats, and any factory and validation functions specified by the consumer.\n * A concrete permission specification may specify further fields as necessary.\n *\n * See the README for more details.\n */\ntype PermissionSpecificationBase = {\n /**\n * The type of the specified permission.\n */\n permissionType: Type;\n\n /**\n * The name of the target resource of the permission.\n */\n targetName: string;\n\n /**\n * An array of the caveat types that may be added to instances of this\n * permission.\n */\n allowedCaveats: Readonly> | null;\n\n /**\n * The factory function used to get permission objects. Permissions returned\n * by this function are presumed to valid, and they will not be passed to the\n * validator function associated with this specification (if any). In other\n * words, the factory function should validate the permissions it creates.\n *\n * If no factory is specified, the {@link Permission} constructor will be\n * used, and the validator function (if specified) will be called on newly\n * constructed permissions.\n */\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n factory?: PermissionFactory>;\n\n /**\n * The validator function used to validate permissions of the associated type\n * whenever they are granted or their caveat arrays are mutated.\n *\n * Permission validators are **not** invoked when a caveat is mutated, provided\n * the caveat array has not changed. For this reason, permission validators\n * **must not** be used to validate caveats. To validate caveats, use the\n * corresponding caveat specification property.\n *\n * The validator should throw an appropriate JSON-RPC error if validation fails.\n */\n validator?: PermissionValidatorConstraint;\n\n /**\n * The side-effect triggered by the {@link PermissionController} once the user approved it.\n * The side-effect can only be an action allowed to be called inside the {@link PermissionController}.\n *\n * If the side-effect action fails, the permission that triggered it is revoked.\n */\n sideEffect?: PermissionSideEffect;\n\n /**\n * The Permission may be available to only a subset of the subject types. If so, specify the subject types as an array.\n * If a subject with a type not in this array tries to request the permission, the call will fail.\n *\n * Leaving this as undefined uses default behaviour where the permission is available to request for all subject types.\n */\n subjectTypes?: readonly SubjectType[];\n};\n\n/**\n * The constraint for restricted method permission specification objects.\n * Permissions that correspond to JSON-RPC methods are specified using objects\n * that conform to this type.\n *\n * See the README for more details.\n */\nexport type RestrictedMethodSpecificationConstraint =\n PermissionSpecificationBase & {\n /**\n * The implementation of the restricted method that the permission\n * corresponds to.\n */\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n methodImplementation: RestrictedMethod;\n };\n\n/**\n * The constraint for endowment permission specification objects. Permissions\n * that endow callers with some restricted resource are specified using objects\n * that conform to this type.\n *\n * See the README for more details.\n */\nexport type EndowmentSpecificationConstraint =\n PermissionSpecificationBase & {\n /**\n * The {@link EndowmentGetter} function for the permission. This function\n * will be called by the {@link PermissionController} whenever the\n * permission is invoked, after which the host can apply the endowments to\n * the requesting subject in the intended manner.\n */\n endowmentGetter: EndowmentGetter;\n };\n\n/**\n * The constraint for permission specification objects. Every {@link Permission}\n * supported by a {@link PermissionController} must have an associated\n * specification, which is the source of truth for all permission-related types.\n * All specifications must adhere to the {@link PermissionSpecificationBase}\n * interface, but specifications may have different fields depending on the\n * {@link PermissionType}.\n *\n * See the README for more details.\n */\nexport type PermissionSpecificationConstraint =\n | EndowmentSpecificationConstraint\n | RestrictedMethodSpecificationConstraint;\n\n/**\n * Options for {@link PermissionSpecificationBuilder} functions.\n */\ntype PermissionSpecificationBuilderOptions<\n FactoryHooks extends Record,\n MethodHooks extends Record,\n ValidatorHooks extends Record,\n> = {\n targetName?: string;\n allowedCaveats?: Readonly> | null;\n factoryHooks?: FactoryHooks;\n methodHooks?: MethodHooks;\n validatorHooks?: ValidatorHooks;\n};\n\n/**\n * A function that builds a permission specification. Modules that specify\n * permissions for external consumption should make this their primary /\n * default export so that host applications can use them to generate concrete\n * specifications tailored to their requirements.\n */\nexport type PermissionSpecificationBuilder<\n Type extends PermissionType,\n Options extends PermissionSpecificationBuilderOptions<\n Record,\n Record,\n Record\n >,\n Specification extends PermissionSpecificationConstraint & {\n permissionType: Type;\n },\n> = (options: Options) => Specification;\n\n/**\n * A restricted method permission export object, containing the\n * {@link PermissionSpecificationBuilder} function and \"hook name\" objects.\n */\nexport type PermissionSpecificationBuilderExportConstraint = {\n targetName: string;\n specificationBuilder: PermissionSpecificationBuilder<\n PermissionType,\n PermissionSpecificationBuilderOptions<\n Record,\n Record,\n Record\n >,\n PermissionSpecificationConstraint\n >;\n factoryHookNames?: Record;\n methodHookNames?: Record;\n validatorHookNames?: Record;\n};\n\ntype ValidRestrictedMethodSpecification<\n Specification extends RestrictedMethodSpecificationConstraint,\n> =\n Specification['methodImplementation'] extends ValidRestrictedMethod<\n Specification['methodImplementation']\n >\n ? Specification\n : never;\n\n/**\n * Constraint for {@link PermissionSpecificationConstraint} objects that\n * evaluates to `never` if the specification contains any invalid fields.\n *\n * @template Specification - The permission specification to validate.\n */\nexport type ValidPermissionSpecification<\n Specification extends PermissionSpecificationConstraint,\n> = Specification['targetName'] extends TargetName\n ? Specification['permissionType'] extends PermissionType.Endowment\n ? Specification\n : Specification['permissionType'] extends PermissionType.RestrictedMethod\n ? ValidRestrictedMethodSpecification<\n Extract\n >\n : never\n : never;\n\n/**\n * Checks that the specification has the expected permission type.\n *\n * @param specification - The specification to check.\n * @param expectedType - The expected permission type.\n * @template Specification - The specification to check.\n * @template Type - The expected permission type.\n * @returns Whether or not the specification is of the expected type.\n */\nexport function hasSpecificationType<\n Specification extends PermissionSpecificationConstraint,\n Type extends PermissionType,\n>(\n specification: Specification,\n expectedType: Type,\n): specification is Specification & {\n permissionType: Type;\n} {\n return specification.permissionType === expectedType;\n}\n\n/**\n * The specifications for all permissions supported by a particular\n * {@link PermissionController}.\n *\n * @template Specifications - The union of all {@link PermissionSpecificationConstraint} types.\n */\nexport type PermissionSpecificationMap<\n Specification extends PermissionSpecificationConstraint,\n> = {\n [Name in Specification['targetName']]: Specification extends {\n targetName: Name;\n }\n ? Specification\n : never;\n};\n\n/**\n * Extracts a specific {@link PermissionSpecificationConstraint} from a union of\n * permission specifications.\n *\n * @template Specification - The specification union type to extract from.\n * @template Name - The `targetName` of the specification to extract.\n */\nexport type ExtractPermissionSpecification<\n Specification extends PermissionSpecificationConstraint,\n Name extends Specification['targetName'],\n> = Specification extends {\n targetName: Name;\n}\n ? Specification\n : never;\n"]} +\ No newline at end of file +diff --git a/dist/PermissionController.cjs b/dist/PermissionController.cjs +index 164fdfb74c29e865e47c62de0ba555da446186c0..568743265af2de8d8f44ac306d5bb6f0acc54feb 100644 +--- a/dist/PermissionController.cjs ++++ b/dist/PermissionController.cjs +@@ -10,7 +10,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { + var _PermissionController_instances, _PermissionController_expectGetCaveatMerger, _PermissionController_applyGrantedPermissions, _PermissionController_mergeIncrementalPermissions, _PermissionController_mergePermission, _PermissionController_mergeCaveat, _PermissionController_handleApprovedPermissions; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.PermissionController = exports.CaveatMutatorOperation = void 0; +-const base_controller_1 = require("@metamask/base-controller"); ++const next_1 = require("@metamask/base-controller/next"); + const controller_utils_1 = require("@metamask/controller-utils"); + const rpc_errors_1 = require("@metamask/rpc-errors"); + const utils_1 = require("@metamask/utils"); +@@ -33,7 +33,14 @@ const controllerName = 'PermissionController'; + * @returns The state metadata + */ + function getStateMetadata() { +- return { subjects: { anonymous: true, persist: true } }; ++ return { ++ subjects: { ++ includeInStateLogs: true, ++ includeInDebugSnapshot: true, ++ persist: true, ++ usedInUi: true, ++ }, ++ }; + } + /** + * Get the default state of the {@link PermissionController}. +@@ -67,7 +74,7 @@ var CaveatMutatorOperation; + * @template ControllerCaveatSpecification - A union of the types of all + * caveat specifications available to the controller. + */ +-class PermissionController extends base_controller_1.BaseController { ++class PermissionController extends next_1.BaseController { + /** + * The names of all JSON-RPC methods that will be ignored by the controller. + * +@@ -175,24 +182,23 @@ class PermissionController extends base_controller_1.BaseController { + }); + } + /** +- * Constructor helper for registering the controller's messaging system +- * actions. ++ * Constructor helper for registering the controller's messenger actions. + */ + registerMessageHandlers() { +- this.messagingSystem.registerActionHandler(`${controllerName}:clearPermissions`, () => this.clearState()); +- this.messagingSystem.registerActionHandler(`${controllerName}:getEndowments`, (origin, targetName, requestData) => this.getEndowments(origin, targetName, requestData)); +- this.messagingSystem.registerActionHandler(`${controllerName}:getSubjectNames`, () => this.getSubjectNames()); +- this.messagingSystem.registerActionHandler(`${controllerName}:getPermissions`, (origin) => this.getPermissions(origin)); +- this.messagingSystem.registerActionHandler(`${controllerName}:hasPermission`, (origin, targetName) => this.hasPermission(origin, targetName)); +- this.messagingSystem.registerActionHandler(`${controllerName}:hasPermissions`, (origin) => this.hasPermissions(origin)); +- this.messagingSystem.registerActionHandler(`${controllerName}:grantPermissions`, this.grantPermissions.bind(this)); +- this.messagingSystem.registerActionHandler(`${controllerName}:grantPermissionsIncremental`, this.grantPermissionsIncremental.bind(this)); +- this.messagingSystem.registerActionHandler(`${controllerName}:requestPermissions`, (subject, permissions) => this.requestPermissions(subject, permissions)); +- this.messagingSystem.registerActionHandler(`${controllerName}:requestPermissionsIncremental`, (subject, permissions) => this.requestPermissionsIncremental(subject, permissions)); +- this.messagingSystem.registerActionHandler(`${controllerName}:revokeAllPermissions`, (origin) => this.revokeAllPermissions(origin)); +- this.messagingSystem.registerActionHandler(`${controllerName}:revokePermissionForAllSubjects`, (target) => this.revokePermissionForAllSubjects(target)); +- this.messagingSystem.registerActionHandler(`${controllerName}:revokePermissions`, this.revokePermissions.bind(this)); +- this.messagingSystem.registerActionHandler(`${controllerName}:updateCaveat`, (origin, target, caveatType, caveatValue) => { ++ this.messenger.registerActionHandler(`${controllerName}:clearPermissions`, () => this.clearState()); ++ this.messenger.registerActionHandler(`${controllerName}:getEndowments`, (origin, targetName, requestData) => this.getEndowments(origin, targetName, requestData)); ++ this.messenger.registerActionHandler(`${controllerName}:getSubjectNames`, () => this.getSubjectNames()); ++ this.messenger.registerActionHandler(`${controllerName}:getPermissions`, (origin) => this.getPermissions(origin)); ++ this.messenger.registerActionHandler(`${controllerName}:hasPermission`, (origin, targetName) => this.hasPermission(origin, targetName)); ++ this.messenger.registerActionHandler(`${controllerName}:hasPermissions`, (origin) => this.hasPermissions(origin)); ++ this.messenger.registerActionHandler(`${controllerName}:grantPermissions`, this.grantPermissions.bind(this)); ++ this.messenger.registerActionHandler(`${controllerName}:grantPermissionsIncremental`, this.grantPermissionsIncremental.bind(this)); ++ this.messenger.registerActionHandler(`${controllerName}:requestPermissions`, (subject, permissions) => this.requestPermissions(subject, permissions)); ++ this.messenger.registerActionHandler(`${controllerName}:requestPermissionsIncremental`, (subject, permissions) => this.requestPermissionsIncremental(subject, permissions)); ++ this.messenger.registerActionHandler(`${controllerName}:revokeAllPermissions`, (origin) => this.revokeAllPermissions(origin)); ++ this.messenger.registerActionHandler(`${controllerName}:revokePermissionForAllSubjects`, (target) => this.revokePermissionForAllSubjects(target)); ++ this.messenger.registerActionHandler(`${controllerName}:revokePermissions`, this.revokePermissions.bind(this)); ++ this.messenger.registerActionHandler(`${controllerName}:updateCaveat`, (origin, target, caveatType, caveatValue) => { + this.updateCaveat(origin, target, caveatType, caveatValue); + }); + } +@@ -779,7 +785,7 @@ class PermissionController extends base_controller_1.BaseController { + const { allowedCaveats, validator, targetName } = specification; + if (specification.subjectTypes?.length && + specification.subjectTypes.length > 0) { +- const metadata = this.messagingSystem.call('SubjectMetadataController:getSubjectMetadata', origin); ++ const metadata = this.messenger.call('SubjectMetadataController:getSubjectMetadata', origin); + if (!metadata || + metadata.subjectType === null || + !specification.subjectTypes.includes(metadata.subjectType)) { +@@ -1067,7 +1073,7 @@ class PermissionController extends base_controller_1.BaseController { + */ + async requestUserApproval(permissionsRequest) { + const { origin, id } = permissionsRequest.metadata; +- const approvedRequest = await this.messagingSystem.call('ApprovalController:addRequest', { ++ const approvedRequest = await this.messenger.call('ApprovalController:addRequest', { + id, + origin, + requestData: permissionsRequest, +@@ -1100,7 +1106,7 @@ class PermissionController extends base_controller_1.BaseController { + } + /** + * Executes the side-effects of the approved permissions while handling the errors if any. +- * It will pass an instance of the {@link messagingSystem} and the request data associated with the permission request to the handlers through its params. ++ * It will pass an instance of the {@link messenger} and the request data associated with the permission request to the handlers through its params. + * + * @param sideEffects - the side-effect record created by {@link getSideEffects} + * @param requestData - the permissions requestData. +@@ -1110,7 +1116,7 @@ class PermissionController extends base_controller_1.BaseController { + const { permittedHandlers, failureHandlers } = sideEffects; + const params = { + requestData, +- messagingSystem: this.messagingSystem, ++ messenger: this.messenger, + }; + const promiseResults = await Promise.allSettled(Object.values(permittedHandlers).map((permittedHandler) => permittedHandler(params))); + // lib.es2020.promise.d.ts does not export its types so we're using a simple type. +@@ -1193,7 +1199,7 @@ class PermissionController extends base_controller_1.BaseController { + return; + } + try { +- await this.messagingSystem.call('ApprovalController:acceptRequest', id, request); ++ await this.messenger.call('ApprovalController:acceptRequest', id, request); + } + catch (error) { + // If accepting unexpectedly fails, reject the request and re-throw the +@@ -1225,7 +1231,7 @@ class PermissionController extends base_controller_1.BaseController { + * @returns Whether the specified request exists. + */ + hasApprovalRequest(options) { +- return this.messagingSystem.call('ApprovalController:hasRequest', options); ++ return this.messenger.call('ApprovalController:hasRequest', options); + } + /** + * Rejects the permissions request with the specified id, with the specified +@@ -1239,7 +1245,7 @@ class PermissionController extends base_controller_1.BaseController { + * @returns Nothing + */ + _rejectPermissionsRequest(id, error) { +- return this.messagingSystem.call('ApprovalController:rejectRequest', id, error); ++ return this.messenger.call('ApprovalController:rejectRequest', id, error); + } + /** + * Gets the subject's endowments per the specified endowment permission. +diff --git a/dist/PermissionController.cjs.map b/dist/PermissionController.cjs.map +index f024e93ce34a947eb31cffde3c44cf92f1aa4feb..fbbe9633746bba1ee2763cb046a46e5e67b081d7 100644 +--- a/dist/PermissionController.cjs.map ++++ b/dist/PermissionController.cjs.map +@@ -1 +1 @@ +-{"version":3,"file":"PermissionController.cjs","sourceRoot":"","sources":["../src/PermissionController.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-enable @typescript-eslint/no-unused-vars */\nimport type {\n AcceptRequest as AcceptApprovalRequest,\n AddApprovalRequest,\n HasApprovalRequest,\n RejectRequest as RejectApprovalRequest,\n} from '@metamask/approval-controller';\nimport type {\n StateMetadata,\n RestrictedMessenger,\n ActionConstraint,\n EventConstraint,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { NonEmptyArray } from '@metamask/controller-utils';\nimport {\n isNonEmptyArray,\n isPlainObject,\n isValidJson,\n} from '@metamask/controller-utils';\nimport { JsonRpcError } from '@metamask/rpc-errors';\nimport { hasProperty } from '@metamask/utils';\nimport type { Json, Mutable } from '@metamask/utils';\nimport deepFreeze from 'deep-freeze-strict';\nimport { castDraft, produce as immerProduce, type Draft } from 'immer';\nimport { nanoid } from 'nanoid';\n\nimport type {\n CaveatConstraint,\n CaveatDiffMap,\n CaveatSpecificationConstraint,\n CaveatSpecificationMap,\n CaveatValueMerger,\n ExtractCaveat,\n ExtractCaveats,\n ExtractCaveatValue,\n} from './Caveat';\nimport {\n decorateWithCaveats,\n isRestrictedMethodCaveatSpecification,\n} from './Caveat';\nimport {\n CaveatAlreadyExistsError,\n CaveatDoesNotExistError,\n CaveatInvalidJsonError,\n CaveatMergerDoesNotExistError,\n CaveatMergeTypeMismatchError,\n CaveatMissingValueError,\n CaveatSpecificationMismatchError,\n DuplicateCaveatError,\n EndowmentPermissionDoesNotExistError,\n ForbiddenCaveatError,\n internalError,\n InvalidApprovedPermissionError,\n InvalidCaveatError,\n InvalidCaveatFieldsError,\n InvalidCaveatsPropertyError,\n InvalidCaveatTypeError,\n InvalidMergedPermissionsError,\n invalidParams,\n InvalidSubjectIdentifierError,\n methodNotFound,\n PermissionDoesNotExistError,\n PermissionsRequestNotFoundError,\n unauthorized,\n UnrecognizedCaveatTypeError,\n UnrecognizedSubjectError,\n userRejectedRequest,\n} from './errors';\nimport type {\n EndowmentSpecificationConstraint,\n ExtractAllowedCaveatTypes,\n ExtractPermissionSpecification,\n OriginString,\n PermissionConstraint,\n PermissionSpecificationConstraint,\n PermissionSpecificationMap,\n RequestedPermissions,\n RestrictedMethod,\n RestrictedMethodParameters,\n RestrictedMethodSpecificationConstraint,\n SideEffectHandler,\n ValidPermission,\n ValidPermissionSpecification,\n} from './Permission';\nimport {\n constructPermission,\n findCaveat,\n hasSpecificationType,\n PermissionType,\n} from './Permission';\nimport { getPermissionMiddlewareFactory } from './permission-middleware';\nimport type { GetSubjectMetadata } from './SubjectMetadataController';\nimport { collectUniqueAndPairedCaveats, MethodNames } from './utils';\n\n/**\n * Flags for controlling the validation behavior of certain internal methods.\n */\ntype PermissionValidationFlags = {\n invokePermissionValidator: boolean;\n performCaveatValidation: boolean;\n};\n\n/**\n * Metadata associated with {@link PermissionController} subjects.\n */\nexport type PermissionSubjectMetadata = {\n origin: OriginString;\n};\n\n/**\n * Metadata associated with permission requests.\n */\nexport type PermissionsRequestMetadata = PermissionSubjectMetadata & {\n id: string;\n [key: string]: Json;\n};\n\n/**\n * A diff produced by an incremental permissions request.\n */\nexport type PermissionDiffMap<\n TargetName extends string,\n AllowedCaveats extends CaveatConstraint,\n> = Record>;\n\n/**\n * Used for prompting the user about a proposed new permission.\n * Includes information about the grantee subject, requested permissions, the\n * diff relative to the previously granted permissions (if relevant), and any\n * additional information added by the consumer.\n *\n * All properties except `diff` and `permissions` are passed to any factories\n * for the requested permissions.\n */\nexport type PermissionsRequest = {\n metadata: PermissionsRequestMetadata;\n permissions: RequestedPermissions;\n [key: string]: Json;\n} & {\n diff?: {\n currentPermissions: SubjectPermissions;\n permissionDiffMap: PermissionDiffMap;\n };\n};\n\n/**\n * Metadata associated with an approved permission request.\n */\ntype ApprovedPermissionsMetadata = {\n data?: Record;\n id: string;\n origin: OriginString;\n};\n\nexport type SideEffects = {\n permittedHandlers: Record<\n string,\n SideEffectHandler\n >;\n failureHandlers: Record<\n string,\n SideEffectHandler\n >;\n};\n\n/**\n * The name of the {@link PermissionController}.\n */\nconst controllerName = 'PermissionController';\n\n/**\n * Permissions associated with a {@link PermissionController} subject.\n */\nexport type SubjectPermissions =\n Record;\n\n/**\n * Permissions and metadata associated with a {@link PermissionController}\n * subject.\n */\nexport type PermissionSubjectEntry<\n SubjectPermission extends PermissionConstraint,\n> = {\n origin: SubjectPermission['invoker'];\n permissions: SubjectPermissions;\n};\n\n/**\n * All subjects of a {@link PermissionController}.\n *\n * @template SubjectPermission - The permissions of the subject.\n */\nexport type PermissionControllerSubjects<\n SubjectPermission extends PermissionConstraint,\n> = Record<\n SubjectPermission['invoker'],\n PermissionSubjectEntry\n>;\n\n/**\n * The state of a {@link PermissionController}.\n *\n * @template Permission - The controller's permission type union.\n */\nexport type PermissionControllerState =\n Permission extends PermissionConstraint\n ? {\n subjects: PermissionControllerSubjects;\n }\n : never;\n\n/**\n * Get the state metadata of the {@link PermissionController}.\n *\n * @template Permission - The controller's permission type union.\n * @returns The state metadata\n */\nfunction getStateMetadata() {\n return { subjects: { anonymous: true, persist: true } } as StateMetadata<\n PermissionControllerState\n >;\n}\n\n/**\n * Get the default state of the {@link PermissionController}.\n *\n * @template Permission - The controller's permission type union.\n * @returns The default state of the controller\n */\nfunction getDefaultState() {\n return { subjects: {} } as PermissionControllerState;\n}\n\n/**\n * Gets the state of the {@link PermissionController}.\n */\nexport type GetPermissionControllerState = ControllerGetStateAction<\n typeof controllerName,\n PermissionControllerState\n>;\n\n/**\n * Gets the names of all subjects from the {@link PermissionController}.\n */\nexport type GetSubjects = {\n type: `${typeof controllerName}:getSubjectNames`;\n handler: () => (keyof PermissionControllerSubjects)[];\n};\n\n/**\n * Gets the permissions for specified subject\n */\nexport type GetPermissions = {\n type: `${typeof controllerName}:getPermissions`;\n handler: GenericPermissionController['getPermissions'];\n};\n\n/**\n * Checks whether the specified subject has any permissions.\n */\nexport type HasPermissions = {\n type: `${typeof controllerName}:hasPermissions`;\n handler: GenericPermissionController['hasPermissions'];\n};\n\n/**\n * Checks whether the specified subject has a specific permission.\n */\nexport type HasPermission = {\n type: `${typeof controllerName}:hasPermission`;\n handler: GenericPermissionController['hasPermission'];\n};\n\n/**\n * Directly grants given permissions for a specificed origin without requesting user approval\n */\nexport type GrantPermissions = {\n type: `${typeof controllerName}:grantPermissions`;\n handler: GenericPermissionController['grantPermissions'];\n};\n\n/**\n * Directly grants given permissions for a specificed origin without requesting user approval\n */\nexport type GrantPermissionsIncremental = {\n type: `${typeof controllerName}:grantPermissionsIncremental`;\n handler: GenericPermissionController['grantPermissionsIncremental'];\n};\n\n/**\n * Requests given permissions for a specified origin\n */\nexport type RequestPermissions = {\n type: `${typeof controllerName}:requestPermissions`;\n handler: GenericPermissionController['requestPermissions'];\n};\n\n/**\n * Requests given permissions for a specified origin\n */\nexport type RequestPermissionsIncremental = {\n type: `${typeof controllerName}:requestPermissionsIncremental`;\n handler: GenericPermissionController['requestPermissionsIncremental'];\n};\n\n/**\n * Removes the specified permissions for each origin.\n */\nexport type RevokePermissions = {\n type: `${typeof controllerName}:revokePermissions`;\n handler: GenericPermissionController['revokePermissions'];\n};\n\n/**\n * Removes all permissions for a given origin\n */\nexport type RevokeAllPermissions = {\n type: `${typeof controllerName}:revokeAllPermissions`;\n handler: GenericPermissionController['revokeAllPermissions'];\n};\n\n/**\n * Revokes all permissions corresponding to the specified target for all subjects.\n * Does nothing if no subjects or no such permission exists.\n */\nexport type RevokePermissionForAllSubjects = {\n type: `${typeof controllerName}:revokePermissionForAllSubjects`;\n handler: GenericPermissionController['revokePermissionForAllSubjects'];\n};\n\n/**\n * Updates a caveat value for a specified caveat type belonging to a specific target and origin.\n */\nexport type UpdateCaveat = {\n type: `${typeof controllerName}:updateCaveat`;\n handler: GenericPermissionController['updateCaveat'];\n};\n\n/**\n * Clears all permissions from the {@link PermissionController}.\n */\nexport type ClearPermissions = {\n type: `${typeof controllerName}:clearPermissions`;\n handler: () => void;\n};\n\n/**\n * Gets the endowments for the given subject and permission.\n */\nexport type GetEndowments = {\n type: `${typeof controllerName}:getEndowments`;\n handler: GenericPermissionController['getEndowments'];\n};\n\n/**\n * The {@link Messenger} actions of the {@link PermissionController}.\n */\nexport type PermissionControllerActions =\n | ClearPermissions\n | GetEndowments\n | GetPermissionControllerState\n | GetSubjects\n | GetPermissions\n | HasPermission\n | HasPermissions\n | GrantPermissions\n | GrantPermissionsIncremental\n | RequestPermissions\n | RequestPermissionsIncremental\n | RevokeAllPermissions\n | RevokePermissionForAllSubjects\n | RevokePermissions\n | UpdateCaveat;\n\n/**\n * The generic state change event of the {@link PermissionController}.\n */\nexport type PermissionControllerStateChange = ControllerStateChangeEvent<\n typeof controllerName,\n PermissionControllerState\n>;\n\n/**\n * The {@link Messenger} events of the {@link PermissionController}.\n *\n * The permission controller only emits its generic state change events.\n * Consumers should use selector subscriptions to subscribe to relevant\n * substate.\n */\nexport type PermissionControllerEvents = PermissionControllerStateChange;\n\n/**\n * The external {@link Messenger} actions available to the\n * {@link PermissionController}.\n */\ntype AllowedActions =\n | AddApprovalRequest\n | HasApprovalRequest\n | AcceptApprovalRequest\n | RejectApprovalRequest\n | GetSubjectMetadata;\n\n/**\n * The messenger of the {@link PermissionController}.\n */\nexport type PermissionControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n PermissionControllerActions | AllowedActions,\n PermissionControllerEvents,\n AllowedActions['type'],\n never\n>;\n\nexport type SideEffectMessenger<\n Actions extends ActionConstraint,\n Events extends EventConstraint,\n> = RestrictedMessenger<\n typeof controllerName,\n Actions | AllowedActions,\n Events,\n AllowedActions['type'] | Actions['type'],\n Events['type']\n>;\n\n/**\n * A generic {@link PermissionController}.\n */\nexport type GenericPermissionController = PermissionController<\n PermissionSpecificationConstraint,\n CaveatSpecificationConstraint\n>;\n\n/**\n * Describes the possible results of a {@link CaveatMutator} function.\n */\nexport enum CaveatMutatorOperation {\n Noop,\n UpdateValue,\n DeleteCaveat,\n RevokePermission,\n}\n\n/**\n * Given a caveat value, returns a {@link CaveatMutatorOperation} and, optionally,\n * a new caveat value.\n *\n * @see {@link PermissionController.updatePermissionsByCaveat} for more details.\n * @template Caveat - The caveat type for which this mutator is intended.\n * @param caveatValue - The existing value of the caveat being mutated.\n * @returns A tuple of the mutation result and, optionally, the new caveat\n * value.\n */\nexport type CaveatMutator = (\n caveatValue: TargetCaveat['value'],\n) => CaveatMutatorResult;\n\ntype CaveatMutatorResult =\n | Readonly<{\n operation: CaveatMutatorOperation.UpdateValue;\n value: CaveatConstraint['value'];\n }>\n | Readonly<{\n operation: Exclude<\n CaveatMutatorOperation,\n CaveatMutatorOperation.UpdateValue\n >;\n }>;\n\ntype MergeCaveatResult =\n CaveatType extends undefined\n ? [CaveatConstraint, CaveatConstraint['value']]\n : [CaveatConstraint, CaveatConstraint['value']] | [];\n\n/**\n * Extracts the permission(s) specified by the given permission and caveat\n * specifications.\n *\n * @template ControllerPermissionSpecification - The permission specification(s)\n * to extract from.\n * @template ControllerCaveatSpecification - The caveat specification(s) to\n * extract from. Necessary because {@link Permission} has a generic parameter\n * that describes the allowed caveats for the permission.\n */\nexport type ExtractPermission<\n ControllerPermissionSpecification extends PermissionSpecificationConstraint,\n ControllerCaveatSpecification extends CaveatSpecificationConstraint,\n> = ControllerPermissionSpecification extends ValidPermissionSpecification\n ? ValidPermission<\n ControllerPermissionSpecification['targetName'],\n ExtractCaveats\n >\n : never;\n\n/**\n * Extracts the restricted method permission(s) specified by the given\n * permission and caveat specifications.\n *\n * @template ControllerPermissionSpecification - The permission specification(s)\n * to extract from.\n * @template ControllerCaveatSpecification - The caveat specification(s) to\n * extract from. Necessary because {@link Permission} has a generic parameter\n * that describes the allowed caveats for the permission.\n */\nexport type ExtractRestrictedMethodPermission<\n ControllerPermissionSpecification extends PermissionSpecificationConstraint,\n ControllerCaveatSpecification extends CaveatSpecificationConstraint,\n> = ExtractPermission<\n Extract<\n ControllerPermissionSpecification,\n RestrictedMethodSpecificationConstraint\n >,\n ControllerCaveatSpecification\n>;\n\n/**\n * Extracts the endowment permission(s) specified by the given permission and\n * caveat specifications.\n *\n * @template ControllerPermissionSpecification - The permission specification(s)\n * to extract from.\n * @template ControllerCaveatSpecification - The caveat specification(s) to\n * extract from. Necessary because {@link Permission} has a generic parameter\n * that describes the allowed caveats for the permission.\n */\nexport type ExtractEndowmentPermission<\n ControllerPermissionSpecification extends PermissionSpecificationConstraint,\n ControllerCaveatSpecification extends CaveatSpecificationConstraint,\n> = ExtractPermission<\n Extract,\n ControllerCaveatSpecification\n>;\n\n/**\n * Options for the {@link PermissionController} constructor.\n *\n * @template ControllerPermissionSpecification - A union of the types of all\n * permission specifications available to the controller. Any referenced caveats\n * must be included in the controller's caveat specifications.\n * @template ControllerCaveatSpecification - A union of the types of all\n * caveat specifications available to the controller.\n */\nexport type PermissionControllerOptions<\n ControllerPermissionSpecification extends PermissionSpecificationConstraint,\n ControllerCaveatSpecification extends CaveatSpecificationConstraint,\n> = {\n messenger: PermissionControllerMessenger;\n caveatSpecifications: CaveatSpecificationMap;\n permissionSpecifications: PermissionSpecificationMap;\n unrestrictedMethods: readonly string[];\n state?: Partial<\n PermissionControllerState<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n >;\n};\n\n/**\n * The permission controller. See the [Architecture](../ARCHITECTURE.md)\n * document for details.\n *\n * Assumes the existence of an {@link ApprovalController} reachable via the\n * {@link Messenger}.\n *\n * @template ControllerPermissionSpecification - A union of the types of all\n * permission specifications available to the controller. Any referenced caveats\n * must be included in the controller's caveat specifications.\n * @template ControllerCaveatSpecification - A union of the types of all\n * caveat specifications available to the controller.\n */\nexport class PermissionController<\n ControllerPermissionSpecification extends PermissionSpecificationConstraint,\n ControllerCaveatSpecification extends CaveatSpecificationConstraint,\n> extends BaseController<\n typeof controllerName,\n PermissionControllerState<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >,\n PermissionControllerMessenger\n> {\n private readonly _caveatSpecifications: Readonly<\n CaveatSpecificationMap\n >;\n\n private readonly _permissionSpecifications: Readonly<\n PermissionSpecificationMap\n >;\n\n private readonly _unrestrictedMethods: ReadonlySet;\n\n /**\n * The names of all JSON-RPC methods that will be ignored by the controller.\n *\n * @returns The names of all unrestricted JSON-RPC methods\n */\n public get unrestrictedMethods(): ReadonlySet {\n return this._unrestrictedMethods;\n }\n\n /**\n * Returns a `json-rpc-engine` middleware function factory, so that the rules\n * described by the state of this controller can be applied to incoming\n * JSON-RPC requests.\n *\n * The middleware **must** be added in the correct place in the middleware\n * stack in order for it to work. See the README for an example.\n */\n public createPermissionMiddleware: ReturnType<\n typeof getPermissionMiddlewareFactory\n >;\n\n /**\n * Constructs the PermissionController.\n *\n * @param options - Permission controller options.\n * @param options.caveatSpecifications - The specifications of all caveats\n * available to the controller. See {@link CaveatSpecificationMap} and the\n * documentation for more details.\n * @param options.permissionSpecifications - The specifications of all\n * permissions available to the controller. See\n * {@link PermissionSpecificationMap} and the README for more details.\n * @param options.unrestrictedMethods - The callable names of all JSON-RPC\n * methods ignored by the new controller.\n * @param options.messenger - The messenger. See\n * {@link BaseController} for more information.\n * @param options.state - Existing state to hydrate the controller with at\n * initialization.\n */\n constructor(\n options: PermissionControllerOptions<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >,\n ) {\n const {\n caveatSpecifications,\n permissionSpecifications,\n unrestrictedMethods,\n messenger,\n state = {},\n } = options;\n\n super({\n name: controllerName,\n metadata:\n getStateMetadata<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >(),\n messenger,\n state: {\n ...getDefaultState<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >(),\n ...state,\n },\n });\n\n this._unrestrictedMethods = new Set(unrestrictedMethods);\n this._caveatSpecifications = deepFreeze({ ...caveatSpecifications });\n\n this.validatePermissionSpecifications(\n permissionSpecifications,\n this._caveatSpecifications,\n );\n\n this._permissionSpecifications = deepFreeze({\n ...permissionSpecifications,\n });\n\n this.registerMessageHandlers();\n this.createPermissionMiddleware = getPermissionMiddlewareFactory({\n executeRestrictedMethod: this._executeRestrictedMethod.bind(this),\n getRestrictedMethod: this.getRestrictedMethod.bind(this),\n isUnrestrictedMethod: this.unrestrictedMethods.has.bind(\n this.unrestrictedMethods,\n ),\n });\n }\n\n /**\n * Gets a permission specification.\n *\n * @param targetName - The name of the permission specification to get.\n * @returns The permission specification with the specified target name.\n */\n private getPermissionSpecification<\n TargetName extends ControllerPermissionSpecification['targetName'],\n >(\n targetName: TargetName,\n ): ExtractPermissionSpecification<\n ControllerPermissionSpecification,\n TargetName\n > {\n return this._permissionSpecifications[targetName];\n }\n\n /**\n * Gets a caveat specification.\n *\n * @param caveatType - The type of the caveat specification to get.\n * @returns The caveat specification with the specified type.\n */\n private getCaveatSpecification<\n CaveatType extends ControllerCaveatSpecification['type'],\n >(caveatType: CaveatType) {\n return this._caveatSpecifications[caveatType];\n }\n\n /**\n * Gets the merger function for the specified caveat. Throws if no\n * merger exists.\n *\n * @param caveatType - The type of the caveat whose merger to get.\n * @returns The caveat value merger function for the specified caveat type.\n */\n #expectGetCaveatMerger<\n CaveatType extends ControllerCaveatSpecification['type'],\n >(caveatType: CaveatType): CaveatValueMerger {\n const { merger } = this.getCaveatSpecification(caveatType);\n\n if (merger === undefined) {\n throw new CaveatMergerDoesNotExistError(caveatType);\n }\n return merger;\n }\n\n /**\n * Constructor helper for validating permission specifications.\n *\n * Throws an error if validation fails.\n *\n * @param permissionSpecifications - The permission specifications passed to\n * this controller's constructor.\n * @param caveatSpecifications - The caveat specifications passed to this\n * controller.\n */\n private validatePermissionSpecifications(\n permissionSpecifications: PermissionSpecificationMap,\n caveatSpecifications: CaveatSpecificationMap,\n ) {\n Object.entries(\n permissionSpecifications,\n ).forEach(\n ([\n targetName,\n { permissionType, targetName: innerTargetName, allowedCaveats },\n ]) => {\n if (!permissionType || !hasProperty(PermissionType, permissionType)) {\n throw new Error(`Invalid permission type: \"${permissionType}\"`);\n }\n\n if (!targetName) {\n throw new Error(`Invalid permission target name: \"${targetName}\"`);\n }\n\n if (targetName !== innerTargetName) {\n throw new Error(\n `Invalid permission specification: target name \"${targetName}\" must match specification.targetName value \"${innerTargetName}\".`,\n );\n }\n\n if (allowedCaveats) {\n allowedCaveats.forEach((caveatType) => {\n if (!hasProperty(caveatSpecifications, caveatType)) {\n throw new UnrecognizedCaveatTypeError(caveatType);\n }\n\n const specification =\n caveatSpecifications[\n caveatType as ControllerCaveatSpecification['type']\n ];\n const isRestrictedMethodCaveat =\n isRestrictedMethodCaveatSpecification(specification);\n\n if (\n (permissionType === PermissionType.RestrictedMethod &&\n !isRestrictedMethodCaveat) ||\n (permissionType === PermissionType.Endowment &&\n isRestrictedMethodCaveat)\n ) {\n throw new CaveatSpecificationMismatchError(\n specification,\n permissionType,\n );\n }\n });\n }\n },\n );\n }\n\n /**\n * Constructor helper for registering the controller's messaging system\n * actions.\n */\n private registerMessageHandlers(): void {\n this.messagingSystem.registerActionHandler(\n `${controllerName}:clearPermissions` as const,\n () => this.clearState(),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getEndowments` as const,\n (origin: string, targetName: string, requestData?: unknown) =>\n this.getEndowments(origin, targetName, requestData),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getSubjectNames` as const,\n () => this.getSubjectNames(),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getPermissions` as const,\n (origin: OriginString) => this.getPermissions(origin),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:hasPermission` as const,\n (origin: OriginString, targetName: string) =>\n this.hasPermission(origin, targetName),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:hasPermissions` as const,\n (origin: OriginString) => this.hasPermissions(origin),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:grantPermissions` as const,\n this.grantPermissions.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:grantPermissionsIncremental` as const,\n this.grantPermissionsIncremental.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:requestPermissions` as const,\n (subject: PermissionSubjectMetadata, permissions: RequestedPermissions) =>\n this.requestPermissions(subject, permissions),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:requestPermissionsIncremental` as const,\n (subject: PermissionSubjectMetadata, permissions: RequestedPermissions) =>\n this.requestPermissionsIncremental(subject, permissions),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:revokeAllPermissions` as const,\n (origin: OriginString) => this.revokeAllPermissions(origin),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:revokePermissionForAllSubjects` as const,\n (\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n ) => this.revokePermissionForAllSubjects(target),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:revokePermissions` as const,\n this.revokePermissions.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateCaveat` as const,\n (origin, target, caveatType, caveatValue) => {\n this.updateCaveat(\n origin,\n target,\n caveatType as ExtractAllowedCaveatTypes,\n caveatValue,\n );\n },\n );\n }\n\n /**\n * Clears the state of the controller.\n */\n clearState(): void {\n this.update((_draftState) => {\n return {\n ...getDefaultState<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >(),\n };\n });\n }\n\n /**\n * Gets the permission specification corresponding to the given permission\n * type and target name. Throws an error if the target name does not\n * correspond to a permission, or if the specification is not of the\n * given permission type.\n *\n * @template Type - The type of the permission specification to get.\n * @param permissionType - The type of the permission specification to get.\n * @param targetName - The name of the permission whose specification to get.\n * @param requestingOrigin - The origin of the requesting subject, if any.\n * Will be added to any thrown errors.\n * @returns The specification object corresponding to the given type and\n * target name.\n */\n private getTypedPermissionSpecification(\n permissionType: Type,\n targetName: string,\n requestingOrigin?: string,\n ): ControllerPermissionSpecification & { permissionType: Type } {\n const failureError =\n permissionType === PermissionType.RestrictedMethod\n ? methodNotFound(\n targetName,\n requestingOrigin ? { origin: requestingOrigin } : undefined,\n )\n : new EndowmentPermissionDoesNotExistError(\n targetName,\n requestingOrigin,\n );\n\n if (!this.targetExists(targetName)) {\n throw failureError;\n }\n\n const specification = this.getPermissionSpecification(targetName);\n if (!hasSpecificationType(specification, permissionType)) {\n throw failureError;\n }\n\n return specification;\n }\n\n /**\n * Gets the implementation of the specified restricted method.\n *\n * A JSON-RPC error is thrown if the method does not exist.\n *\n * @see {@link PermissionController.executeRestrictedMethod} and\n * {@link PermissionController.createPermissionMiddleware} for internal usage.\n * @param method - The name of the restricted method.\n * @param origin - The origin associated with the request for the restricted\n * method, if any.\n * @returns The restricted method implementation.\n */\n getRestrictedMethod(\n method: string,\n origin?: string,\n ): RestrictedMethod {\n return this.getTypedPermissionSpecification(\n PermissionType.RestrictedMethod,\n method,\n origin,\n ).methodImplementation;\n }\n\n /**\n * Gets a list of all origins of subjects.\n *\n * @returns The origins (i.e. IDs) of all subjects.\n */\n getSubjectNames(): OriginString[] {\n return Object.keys(this.state.subjects);\n }\n\n /**\n * Gets the permission for the specified target of the subject corresponding\n * to the specified origin.\n *\n * @param origin - The origin of the subject.\n * @param targetName - The method name as invoked by a third party (i.e., not\n * a method key).\n * @returns The permission if it exists, or undefined otherwise.\n */\n getPermission<\n SubjectPermission extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >,\n >(\n origin: OriginString,\n targetName: SubjectPermission['parentCapability'],\n ): SubjectPermission | undefined {\n return this.state.subjects[origin]?.permissions[targetName] as\n | SubjectPermission\n | undefined;\n }\n\n /**\n * Gets all permissions for the specified subject, if any.\n *\n * @param origin - The origin of the subject.\n * @returns The permissions of the subject, if any.\n */\n getPermissions(\n origin: OriginString,\n ):\n | SubjectPermissions<\n ValidPermission>\n >\n | undefined {\n return this.state.subjects[origin]?.permissions;\n }\n\n /**\n * Checks whether the subject with the specified origin has the specified\n * permission.\n *\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @returns Whether the subject has the permission.\n */\n hasPermission(\n origin: OriginString,\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n ): boolean {\n return Boolean(this.getPermission(origin, target));\n }\n\n /**\n * Checks whether the subject with the specified origin has any permissions.\n * Use this if you want to know if a subject \"exists\".\n *\n * @param origin - The origin of the subject to check.\n * @returns Whether the subject has any permissions.\n */\n hasPermissions(origin: OriginString): boolean {\n return Boolean(this.state.subjects[origin]);\n }\n\n /**\n * Revokes all permissions from the specified origin.\n *\n * Throws an error of the origin has no permissions.\n *\n * @param origin - The origin whose permissions to revoke.\n */\n revokeAllPermissions(origin: OriginString): void {\n this.update((draftState) => {\n if (!draftState.subjects[origin]) {\n throw new UnrecognizedSubjectError(origin);\n }\n delete draftState.subjects[origin];\n });\n }\n\n /**\n * Revokes the specified permission from the subject with the specified\n * origin.\n *\n * Throws an error if the subject or the permission does not exist.\n *\n * @param origin - The origin of the subject whose permission to revoke.\n * @param target - The target name of the permission to revoke.\n */\n revokePermission(\n origin: OriginString,\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n ): void {\n this.revokePermissions({ [origin]: [target] });\n }\n\n /**\n * Revokes the specified permissions from the specified subjects.\n *\n * Throws an error if any of the subjects or permissions do not exist.\n *\n * @param subjectsAndPermissions - An object mapping subject origins\n * to arrays of permission target names to revoke.\n */\n revokePermissions(\n subjectsAndPermissions: Record<\n OriginString,\n NonEmptyArray<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability']\n >\n >,\n ): void {\n this.update((draftState) => {\n Object.keys(subjectsAndPermissions).forEach((origin) => {\n if (!hasProperty(draftState.subjects, origin)) {\n throw new UnrecognizedSubjectError(origin);\n }\n\n subjectsAndPermissions[origin].forEach((target) => {\n const { permissions } = draftState.subjects[origin];\n if (!hasProperty(permissions as Record, target)) {\n throw new PermissionDoesNotExistError(origin, target);\n }\n\n this.deletePermission(draftState.subjects, origin, target);\n });\n });\n });\n }\n\n /**\n * Revokes all permissions corresponding to the specified target for all subjects.\n * Does nothing if no subjects or no such permission exists.\n *\n * @param target - The name of the target to revoke all permissions for.\n */\n revokePermissionForAllSubjects(\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n ): void {\n if (this.getSubjectNames().length === 0) {\n return;\n }\n\n this.update((draftState) => {\n Object.entries(draftState.subjects).forEach(([origin, subject]) => {\n const { permissions } = subject;\n\n if (hasProperty(permissions as Record, target)) {\n this.deletePermission(draftState.subjects, origin, target);\n }\n });\n });\n }\n\n /**\n * Deletes the permission identified by the given origin and target. If the\n * permission is the single remaining permission of its subject, the subject\n * is also deleted.\n *\n * @param subjects - The draft permission controller subjects.\n * @param origin - The origin of the subject associated with the permission\n * to delete.\n * @param target - The target name of the permission to delete.\n */\n private deletePermission(\n subjects: Draft>,\n origin: OriginString,\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n ): void {\n const { permissions } = subjects[origin];\n if (Object.keys(permissions).length > 1) {\n delete permissions[target];\n } else {\n delete subjects[origin];\n }\n }\n\n /**\n * Checks whether the permission of the subject corresponding to the given\n * origin has a caveat of the specified type.\n *\n * Throws an error if the subject does not have a permission with the\n * specified target name.\n *\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to check for.\n * @returns Whether the permission has the specified caveat.\n */\n hasCaveat<\n TargetName extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n CaveatType extends ExtractAllowedCaveatTypes,\n >(origin: OriginString, target: TargetName, caveatType: CaveatType): boolean {\n return Boolean(this.getCaveat(origin, target, caveatType));\n }\n\n /**\n * Gets the caveat of the specified type, if any, for the permission of\n * the subject corresponding to the given origin.\n *\n * Throws an error if the subject does not have a permission with the\n * specified target name.\n *\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to get.\n * @returns The caveat, or `undefined` if no such caveat exists.\n */\n getCaveat<\n TargetName extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n CaveatType extends ExtractAllowedCaveatTypes,\n >(\n origin: OriginString,\n target: TargetName,\n caveatType: CaveatType,\n ): ExtractCaveat | undefined {\n const permission = this.getPermission(origin, target);\n if (!permission) {\n throw new PermissionDoesNotExistError(origin, target);\n }\n\n return findCaveat(permission, caveatType) as\n | ExtractCaveat\n | undefined;\n }\n\n /**\n * Adds a caveat of the specified type, with the specified caveat value, to\n * the permission corresponding to the given subject origin and permission\n * target.\n *\n * For modifying existing caveats, use\n * {@link PermissionController.updateCaveat}.\n *\n * Throws an error if no such permission exists, or if the caveat already\n * exists.\n *\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to add.\n * @param caveatValue - The value of the caveat to add.\n */\n addCaveat<\n TargetName extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n CaveatType extends ExtractAllowedCaveatTypes,\n >(\n origin: OriginString,\n target: TargetName,\n caveatType: CaveatType,\n caveatValue: ExtractCaveatValue,\n ): void {\n if (this.hasCaveat(origin, target, caveatType)) {\n throw new CaveatAlreadyExistsError(origin, target, caveatType);\n }\n\n this.setCaveat(origin, target, caveatType, caveatValue);\n }\n\n /**\n * Updates the value of the caveat of the specified type belonging to the\n * permission corresponding to the given subject origin and permission\n * target.\n *\n * For adding new caveats, use\n * {@link PermissionController.addCaveat}.\n *\n * Throws an error if no such permission or caveat exists.\n *\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to update.\n * @param caveatValue - The new value of the caveat.\n */\n updateCaveat<\n TargetName extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n CaveatType extends ExtractAllowedCaveatTypes,\n CaveatValue extends ExtractCaveatValue<\n ControllerCaveatSpecification,\n CaveatType\n >,\n >(\n origin: OriginString,\n target: TargetName,\n caveatType: CaveatType,\n caveatValue: CaveatValue,\n ): void {\n if (!this.hasCaveat(origin, target, caveatType)) {\n throw new CaveatDoesNotExistError(origin, target, caveatType);\n }\n\n this.setCaveat(origin, target, caveatType, caveatValue);\n }\n\n /**\n * Sets the specified caveat on the specified permission. Overwrites existing\n * caveats of the same type in-place (preserving array order), and adds the\n * caveat to the end of the array otherwise.\n *\n * Throws an error if the permission does not exist or fails to validate after\n * its caveats have been modified.\n *\n * @see {@link PermissionController.addCaveat}\n * @see {@link PermissionController.updateCaveat}\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to set.\n * @param caveatValue - The value of the caveat to set.\n */\n private setCaveat<\n TargetName extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n CaveatType extends ExtractAllowedCaveatTypes,\n >(\n origin: OriginString,\n target: TargetName,\n caveatType: CaveatType,\n caveatValue: ExtractCaveatValue,\n ): void {\n this.update((draftState) => {\n const subject = draftState.subjects[origin];\n\n // Unreachable because `hasCaveat` is always called before this, and it\n // throws if permissions are missing. TypeScript needs this, however.\n /* istanbul ignore if */\n if (!subject) {\n throw new UnrecognizedSubjectError(origin);\n }\n\n const permission = subject.permissions[target];\n\n /* istanbul ignore if: practically impossible, but TypeScript wants it */\n if (!permission) {\n throw new PermissionDoesNotExistError(origin, target);\n }\n\n const caveat = {\n type: caveatType,\n value: caveatValue,\n };\n this.validateCaveat(caveat, origin, target);\n\n let addedCaveat = false;\n if (permission.caveats) {\n const caveatIndex = permission.caveats.findIndex(\n (existingCaveat) => existingCaveat.type === caveat.type,\n );\n\n if (caveatIndex === -1) {\n permission.caveats.push(caveat);\n addedCaveat = true;\n } else {\n permission.caveats.splice(caveatIndex, 1, caveat);\n }\n } else {\n // At this point, we don't know if the specific permission is allowed\n // to have caveats, but it should be impossible to call this method\n // for a permission that may not have any caveats. If all else fails,\n // the permission validator is also called.\n // @ts-expect-error See above comment\n permission.caveats = [caveat];\n addedCaveat = true;\n }\n\n // Mutating a caveat does not warrant permission validation, but mutating\n // the caveat array does.\n if (addedCaveat) {\n this.validateModifiedPermission(permission, origin, {\n invokePermissionValidator: true,\n performCaveatValidation: false, // We just validated the caveat\n });\n }\n });\n }\n\n /**\n * Updates all caveats with the specified type for all subjects and\n * permissions by applying the specified mutator function to them.\n *\n * ATTN: Permissions can be revoked entirely by the action of this method,\n * read on for details.\n *\n * Caveat mutators are functions that receive a caveat value and return a\n * tuple consisting of a {@link CaveatMutatorOperation} and, optionally, a new\n * value to update the existing caveat with.\n *\n * For each caveat, depending on the mutator result, this method will:\n * - Do nothing ({@link CaveatMutatorOperation.Noop})\n * - Update the value of the caveat ({@link CaveatMutatorOperation.UpdateValue}). The caveat specification validator, if any, will be called after updating the value.\n * - Delete the caveat ({@link CaveatMutatorOperation.DeleteCaveat}). The permission specification validator, if any, will be called after deleting the caveat.\n * - Revoke the parent permission ({@link CaveatMutatorOperation.RevokePermission})\n *\n * This method throws if the validation of any caveat or permission fails.\n *\n * @param targetCaveatType - The type of the caveats to update.\n * @param mutator - The mutator function which will be applied to all caveat\n * values.\n */\n updatePermissionsByCaveat<\n CaveatType extends ExtractCaveats['type'],\n TargetCaveat extends ExtractCaveat<\n ControllerCaveatSpecification,\n CaveatType\n >,\n >(targetCaveatType: CaveatType, mutator: CaveatMutator): void {\n if (Object.keys(this.state.subjects).length === 0) {\n return;\n }\n\n this.update((draftState) => {\n Object.values(draftState.subjects).forEach((subject) => {\n Object.values(subject.permissions).forEach((permission) => {\n const { caveats } = permission;\n const targetCaveat = caveats?.find(\n ({ type }) => type === targetCaveatType,\n );\n if (!targetCaveat) {\n return;\n }\n\n // The mutator may modify the caveat value in place, and must always\n // return a valid mutation result.\n const mutatorResult = mutator(targetCaveat.value);\n const { operation } = mutatorResult;\n switch (operation) {\n case CaveatMutatorOperation.Noop:\n break;\n\n case CaveatMutatorOperation.UpdateValue:\n // Typecast: `Mutable` is used here to assign to a readonly\n // property. `targetConstraint` should already be mutable because\n // it's part of a draft, but for some reason it's not. We can't\n // use the more-correct `Draft` type here either because it\n // results in an error.\n (targetCaveat as Mutable).value =\n mutatorResult.value;\n\n this.validateCaveat(\n targetCaveat,\n subject.origin,\n permission.parentCapability,\n );\n break;\n\n case CaveatMutatorOperation.DeleteCaveat:\n this.deleteCaveat(permission, targetCaveatType, subject.origin);\n break;\n\n case CaveatMutatorOperation.RevokePermission:\n this.deletePermission(\n draftState.subjects,\n subject.origin,\n permission.parentCapability,\n );\n break;\n\n default: {\n // Overriding as `never` is the expected result of exhaustiveness checking,\n // and is intended to represent unchecked exception cases.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n throw new Error(`Unrecognized mutation result: \"${operation}\"`);\n }\n }\n });\n });\n });\n }\n\n /**\n * Removes the caveat of the specified type from the permission corresponding\n * to the given subject origin and target name.\n *\n * Throws an error if no such permission or caveat exists.\n *\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to remove.\n */\n removeCaveat<\n TargetName extends ControllerPermissionSpecification['targetName'],\n CaveatType extends ExtractAllowedCaveatTypes,\n >(origin: OriginString, target: TargetName, caveatType: CaveatType): void {\n this.update((draftState) => {\n const permission = draftState.subjects[origin]?.permissions[target];\n if (!permission) {\n throw new PermissionDoesNotExistError(origin, target);\n }\n\n if (!permission.caveats) {\n throw new CaveatDoesNotExistError(origin, target, caveatType);\n }\n\n this.deleteCaveat(permission, caveatType, origin);\n });\n }\n\n /**\n * Deletes the specified caveat from the specified permission. If no caveats\n * remain after deletion, the permission's caveat property is set to `null`.\n * The permission is validated after being modified.\n *\n * Throws an error if the permission does not have a caveat with the specified\n * type.\n *\n * @param permission - The permission whose caveat to delete.\n * @param caveatType - The type of the caveat to delete.\n * @param origin - The origin the permission subject.\n */\n private deleteCaveat<\n CaveatType extends ExtractCaveats['type'],\n >(\n permission: Draft,\n caveatType: CaveatType,\n origin: OriginString,\n ): void {\n /* istanbul ignore if: not possible in our usage */\n if (!permission.caveats) {\n throw new CaveatDoesNotExistError(\n origin,\n permission.parentCapability,\n caveatType,\n );\n }\n\n const caveatIndex = permission.caveats.findIndex(\n (existingCaveat) => existingCaveat.type === caveatType,\n );\n\n if (caveatIndex === -1) {\n throw new CaveatDoesNotExistError(\n origin,\n permission.parentCapability,\n caveatType,\n );\n }\n\n if (permission.caveats.length === 1) {\n permission.caveats = null;\n } else {\n permission.caveats.splice(caveatIndex, 1);\n }\n\n this.validateModifiedPermission(permission, origin, {\n invokePermissionValidator: true,\n performCaveatValidation: false, // No caveat object was mutated\n });\n }\n\n /**\n * Validates the specified modified permission. Should **always** be invoked\n * on a permission when its caveat array has been mutated.\n *\n * Just like {@link PermissionController.validatePermission}, except that the\n * corresponding target name and specification are retrieved first, and an\n * error is thrown if the target name does not exist.\n *\n * @param permission - The modified permission to validate.\n * @param origin - The origin associated with the permission.\n * @param validationFlags - Validation flags. See {@link PermissionController.validatePermission}.\n */\n private validateModifiedPermission(\n permission: Draft,\n origin: OriginString,\n validationFlags: PermissionValidationFlags,\n ): void {\n /* istanbul ignore if: this should be impossible */\n if (!this.targetExists(permission.parentCapability)) {\n throw new Error(\n `Fatal: Existing permission target \"${permission.parentCapability}\" has no specification.`,\n );\n }\n\n this.validatePermission(\n this.getPermissionSpecification(permission.parentCapability),\n permission as PermissionConstraint,\n origin,\n validationFlags,\n );\n }\n\n /**\n * Verifies the existence the specified permission target, i.e. whether it has\n * a specification.\n *\n * @param target - The requested permission target.\n * @returns Whether the permission target exists.\n */\n private targetExists(\n target: string,\n ): target is ControllerPermissionSpecification['targetName'] {\n return hasProperty(this._permissionSpecifications, target);\n }\n\n /**\n * Grants _approved_ permissions to the specified subject. Every permission and\n * caveat is stringently validated—including by calling their specification\n * validators—and an error is thrown if validation fails.\n *\n * ATTN: This method does **not** prompt the user for approval. User consent must\n * first be obtained through some other means.\n *\n * @see {@link PermissionController.requestPermissions} For initiating a\n * permissions request requiring user approval.\n * @param options - Options bag.\n * @param options.approvedPermissions - The requested permissions approved by\n * the user.\n * @param options.requestData - Permission request data. Passed to permission\n * factory functions.\n * @param options.preserveExistingPermissions - Whether to preserve the\n * subject's existing permissions.\n * @param options.subject - The subject to grant permissions to.\n * @returns The subject's new permission state. It may or may not have changed.\n */\n grantPermissions({\n approvedPermissions,\n requestData,\n preserveExistingPermissions = true,\n subject,\n }: {\n approvedPermissions: RequestedPermissions;\n subject: PermissionSubjectMetadata;\n preserveExistingPermissions?: boolean;\n requestData?: Record;\n }): Partial<\n SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n > {\n return this.#applyGrantedPermissions({\n approvedPermissions,\n subject,\n mergePermissions: false,\n preserveExistingPermissions,\n requestData,\n });\n }\n\n /**\n * Incrementally grants _approved_ permissions to the specified subject. Every\n * permission and caveat is stringently validated—including by calling their\n * specification validators—and an error is thrown if validation fails.\n *\n * ATTN: This method does **not** prompt the user for approval. User consent must\n * first be obtained through some other means.\n *\n * @see {@link PermissionController.requestPermissionsIncremental} For initiating\n * an incremental permissions request requiring user approval.\n * @param options - Options bag.\n * @param options.approvedPermissions - The requested permissions approved by\n * the user.\n * @param options.requestData - Permission request data. Passed to permission\n * factory functions.\n * @param options.subject - The subject to grant permissions to.\n * @returns The subject's new permission state. It may or may not have changed.\n */\n grantPermissionsIncremental({\n approvedPermissions,\n requestData,\n subject,\n }: {\n approvedPermissions: RequestedPermissions;\n subject: PermissionSubjectMetadata;\n requestData?: Record;\n }): Partial<\n SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n > {\n return this.#applyGrantedPermissions({\n approvedPermissions,\n subject,\n mergePermissions: true,\n preserveExistingPermissions: true,\n requestData,\n });\n }\n\n #applyGrantedPermissions({\n approvedPermissions,\n subject,\n mergePermissions,\n preserveExistingPermissions,\n requestData,\n }: {\n approvedPermissions: RequestedPermissions;\n subject: PermissionSubjectMetadata;\n mergePermissions: boolean;\n preserveExistingPermissions: boolean;\n requestData?: Record;\n }): Partial<\n SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n > {\n const { origin } = subject;\n\n if (!origin || typeof origin !== 'string') {\n throw new InvalidSubjectIdentifierError(origin);\n }\n\n const permissions = (\n preserveExistingPermissions\n ? {\n ...this.getPermissions(origin),\n }\n : {}\n ) as SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >;\n\n for (const [requestedTarget, approvedPermission] of Object.entries(\n approvedPermissions,\n )) {\n if (!this.targetExists(requestedTarget)) {\n throw methodNotFound(requestedTarget);\n }\n\n if (\n approvedPermission.parentCapability !== undefined &&\n requestedTarget !== approvedPermission.parentCapability\n ) {\n throw new InvalidApprovedPermissionError(\n origin,\n requestedTarget,\n approvedPermission,\n );\n }\n\n // We have verified that the target exists, and reassign it to change its\n // type.\n const targetName = requestedTarget as ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'];\n const specification = this.getPermissionSpecification(targetName);\n\n // The requested caveats are validated here.\n const caveats = this.constructCaveats(\n origin,\n targetName,\n approvedPermission.caveats,\n );\n\n const permissionOptions = {\n caveats,\n invoker: origin,\n target: targetName,\n };\n\n let permission: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >;\n if (specification.factory) {\n permission = specification.factory(permissionOptions, requestData);\n } else {\n permission = constructPermission(permissionOptions);\n }\n\n if (mergePermissions) {\n permission = this.#mergePermission(\n permissions[targetName],\n permission,\n )[0];\n }\n\n this.validatePermission(specification, permission, origin, {\n invokePermissionValidator: true,\n performCaveatValidation: true,\n });\n permissions[targetName] = permission;\n }\n\n this.setValidatedPermissions(origin, permissions);\n return permissions;\n }\n\n /**\n * Validates the specified permission by:\n * - Ensuring that if `subjectTypes` is specified, the subject requesting the permission is of a type in the list.\n * - Ensuring that its `caveats` property is either `null` or a non-empty array.\n * - Ensuring that it only includes caveats allowed by its specification.\n * - Ensuring that it includes no duplicate caveats (by caveat type).\n * - Validating each caveat object, if `performCaveatValidation` is `true`.\n * - Calling the validator of its specification, if one exists and `invokePermissionValidator` is `true`.\n *\n * An error is thrown if validation fails.\n *\n * @param specification - The specification of the permission.\n * @param permission - The permission to validate.\n * @param origin - The origin associated with the permission.\n * @param validationOptions - Validation options.\n * @param validationOptions.invokePermissionValidator - Whether to invoke the\n * permission's consumer-specified validator function, if any.\n * @param validationOptions.performCaveatValidation - Whether to invoke\n * {@link PermissionController.validateCaveat} on each of the permission's\n * caveats.\n */\n private validatePermission(\n specification: PermissionSpecificationConstraint,\n permission: PermissionConstraint,\n origin: OriginString,\n {\n invokePermissionValidator,\n performCaveatValidation,\n }: PermissionValidationFlags,\n ): void {\n const { allowedCaveats, validator, targetName } = specification;\n\n if (\n specification.subjectTypes?.length &&\n specification.subjectTypes.length > 0\n ) {\n const metadata = this.messagingSystem.call(\n 'SubjectMetadataController:getSubjectMetadata',\n origin,\n );\n\n if (\n !metadata ||\n metadata.subjectType === null ||\n !specification.subjectTypes.includes(metadata.subjectType)\n ) {\n throw specification.permissionType === PermissionType.RestrictedMethod\n ? methodNotFound(targetName, { origin })\n : new EndowmentPermissionDoesNotExistError(targetName, origin);\n }\n }\n\n if (hasProperty(permission, 'caveats')) {\n const { caveats } = permission;\n\n if (caveats !== null && !(Array.isArray(caveats) && caveats.length > 0)) {\n throw new InvalidCaveatsPropertyError(origin, targetName, caveats);\n }\n\n const seenCaveatTypes = new Set();\n caveats?.forEach((caveat) => {\n if (performCaveatValidation) {\n this.validateCaveat(caveat, origin, targetName);\n }\n\n if (!allowedCaveats?.includes(caveat.type)) {\n throw new ForbiddenCaveatError(caveat.type, origin, targetName);\n }\n\n if (seenCaveatTypes.has(caveat.type)) {\n throw new DuplicateCaveatError(caveat.type, origin, targetName);\n }\n seenCaveatTypes.add(caveat.type);\n });\n }\n\n if (invokePermissionValidator && validator) {\n validator(permission, origin, targetName);\n }\n }\n\n /**\n * Assigns the specified permissions to the subject with the given origin.\n * Overwrites all existing permissions, and creates a subject entry if it\n * doesn't already exist.\n *\n * ATTN: Assumes that the new permissions have been validated.\n *\n * @param origin - The origin of the grantee subject.\n * @param permissions - The new permissions for the grantee subject.\n */\n private setValidatedPermissions(\n origin: OriginString,\n permissions: Record<\n string,\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >,\n ): void {\n this.update((draftState) => {\n if (!draftState.subjects[origin]) {\n draftState.subjects[origin] = { origin, permissions: {} };\n }\n\n draftState.subjects[origin].permissions = castDraft(permissions);\n });\n }\n\n /**\n * Validates the requested caveats for the permission of the specified\n * subject origin and target name and returns the validated caveat array.\n *\n * Throws an error if validation fails.\n *\n * @param origin - The origin of the permission subject.\n * @param target - The permission target name.\n * @param requestedCaveats - The requested caveats to construct.\n * @returns The constructed caveats.\n */\n private constructCaveats(\n origin: OriginString,\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n requestedCaveats?: unknown[] | null,\n ): NonEmptyArray> | undefined {\n const caveatArray = requestedCaveats?.map((requestedCaveat) => {\n this.validateCaveat(requestedCaveat, origin, target);\n\n // Reassign so that we have a fresh object.\n const { type, value } = requestedCaveat as CaveatConstraint;\n return { type, value } as ExtractCaveats;\n });\n\n return caveatArray && isNonEmptyArray(caveatArray)\n ? caveatArray\n : undefined;\n }\n\n /**\n * This methods validates that the specified caveat is an object with the\n * expected properties and types. It also ensures that a caveat specification\n * exists for the requested caveat type, and calls the specification\n * validator, if it exists, on the caveat object.\n *\n * Throws an error if validation fails.\n *\n * @param caveat - The caveat object to validate.\n * @param origin - The origin associated with the subject of the parent\n * permission.\n * @param target - The target name associated with the parent permission.\n */\n private validateCaveat(\n caveat: unknown,\n origin: OriginString,\n target: string,\n ): void {\n if (!isPlainObject(caveat)) {\n throw new InvalidCaveatError(caveat, origin, target);\n }\n\n if (Object.keys(caveat).length !== 2) {\n throw new InvalidCaveatFieldsError(caveat, origin, target);\n }\n\n if (typeof caveat.type !== 'string') {\n throw new InvalidCaveatTypeError(caveat, origin, target);\n }\n\n const specification = this.getCaveatSpecification(caveat.type);\n if (!specification) {\n throw new UnrecognizedCaveatTypeError(caveat.type, origin, target);\n }\n\n if (!hasProperty(caveat, 'value') || caveat.value === undefined) {\n throw new CaveatMissingValueError(caveat, origin, target);\n }\n\n if (!isValidJson(caveat.value)) {\n throw new CaveatInvalidJsonError(caveat, origin, target);\n }\n\n // Typecast: TypeScript still believes that the caveat is a PlainObject.\n specification.validator?.(caveat as CaveatConstraint, origin, target);\n }\n\n /**\n * Initiates a permission request that requires user approval.\n *\n * Either this or {@link PermissionController.requestPermissionsIncremental}\n * should always be used to grant additional permissions to a subject,\n * unless user approval has been obtained through some other means.\n *\n * Permissions are validated at every step of the approval process, and this\n * method will reject if validation fails.\n *\n * @see {@link ApprovalController} For the user approval logic.\n * @see {@link PermissionController.acceptPermissionsRequest} For the method\n * that _accepts_ the request and resolves the user approval promise.\n * @see {@link PermissionController.rejectPermissionsRequest} For the method\n * that _rejects_ the request and the user approval promise.\n * @param subject - The grantee subject.\n * @param requestedPermissions - The requested permissions.\n * @param options - Additional options.\n * @param options.id - The id of the permissions request. Defaults to a unique\n * id.\n * @param options.preserveExistingPermissions - Whether to preserve the\n * subject's existing permissions. Defaults to `true`.\n * @param options.metadata - Additional metadata about the permission request.\n * @returns The granted permissions and request metadata.\n */\n async requestPermissions(\n subject: PermissionSubjectMetadata,\n requestedPermissions: RequestedPermissions,\n options: {\n id?: string;\n preserveExistingPermissions?: boolean;\n metadata?: Record;\n } = {},\n ): Promise<\n [\n Partial<\n SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n >,\n ApprovedPermissionsMetadata,\n ]\n > {\n const { origin } = subject;\n const { id = nanoid(), preserveExistingPermissions = true } = options;\n this.validateRequestedPermissions(origin, requestedPermissions);\n\n const metadata = {\n ...options.metadata,\n id,\n origin,\n };\n\n const permissionsRequest: PermissionsRequest = {\n metadata,\n permissions: requestedPermissions,\n };\n\n const approvedRequest = await this.requestUserApproval(permissionsRequest);\n return await this.#handleApprovedPermissions({\n subject,\n metadata,\n preserveExistingPermissions,\n approvedRequest,\n });\n }\n\n /**\n * Initiates an incremental permission request that prompts for user approval.\n * Incremental permission requests allow the caller to replace existing and/or\n * add brand new permissions and caveats for the specified subject.\n *\n * Incremental permission request are merged with the subject's existing permissions\n * through a right-biased union, where the incremental permission are the right-hand\n * side of the merger. If both sides of the merger specify the same caveats for a\n * given permission, the caveats are merged using their specification's caveat value\n * merger property.\n *\n * Either this or {@link PermissionController.requestPermissions} should\n * always be used to grant additional permissions to a subject, unless user\n * approval has been obtained through some other means.\n *\n * Permissions are validated at every step of the approval process, and this\n * method will reject if validation fails.\n *\n * @see {@link ApprovalController} For the user approval logic.\n * @see {@link PermissionController.acceptPermissionsRequest} For the method\n * that _accepts_ the request and resolves the user approval promise.\n * @see {@link PermissionController.rejectPermissionsRequest} For the method\n * that _rejects_ the request and the user approval promise.\n * @param subject - The grantee subject.\n * @param requestedPermissions - The requested permissions.\n * @param options - Additional options.\n * @param options.id - The id of the permissions request. Defaults to a unique\n * id.\n * @param options.metadata - Additional metadata about the permission request.\n * @returns The granted permissions and request metadata.\n */\n async requestPermissionsIncremental(\n subject: PermissionSubjectMetadata,\n requestedPermissions: RequestedPermissions,\n options: {\n id?: string;\n metadata?: Record;\n } = {},\n ): Promise<\n | [\n Partial<\n SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n >,\n ApprovedPermissionsMetadata,\n ]\n | []\n > {\n const { origin } = subject;\n const { id = nanoid() } = options;\n this.validateRequestedPermissions(origin, requestedPermissions);\n\n const currentPermissions = this.getPermissions(origin) ?? {};\n const [newPermissions, permissionDiffMap] =\n this.#mergeIncrementalPermissions(\n currentPermissions,\n requestedPermissions,\n );\n\n // The second undefined check is just for type narrowing purposes. These values\n // will always be jointly defined or undefined.\n if (newPermissions === undefined || permissionDiffMap === undefined) {\n return [];\n }\n\n try {\n // It does not spark joy to run this validation again after the merger operation.\n // But, optimizing this procedure is probably not worth it, especially considering\n // that the worst-case scenario for validation degrades to the below function call.\n this.validateRequestedPermissions(origin, newPermissions);\n } catch (error) {\n if (error instanceof Error) {\n throw new InvalidMergedPermissionsError(\n origin,\n error,\n permissionDiffMap,\n );\n }\n /* istanbul ignore next: This should be impossible */\n throw internalError('Unrecognized error type', { error });\n }\n\n const metadata = {\n ...options.metadata,\n id,\n origin,\n };\n\n const permissionsRequest: PermissionsRequest = {\n metadata,\n permissions: newPermissions,\n diff: {\n currentPermissions,\n permissionDiffMap,\n },\n };\n\n const approvedRequest = await this.requestUserApproval(permissionsRequest);\n return await this.#handleApprovedPermissions({\n subject,\n metadata,\n preserveExistingPermissions: false,\n approvedRequest,\n });\n }\n\n /**\n * Validates requested permissions. Throws if validation fails.\n *\n * This method ensures that the requested permissions are a properly\n * formatted {@link RequestedPermissions} object, and performs the same\n * validation as {@link PermissionController.grantPermissions}, except that\n * consumer-specified permission validator functions are not called, since\n * they are only called on fully constructed, approved permissions that are\n * otherwise completely valid.\n *\n * Unrecognzied properties on requested permissions are ignored.\n *\n * @param origin - The origin of the grantee subject.\n * @param requestedPermissions - The requested permissions.\n */\n private validateRequestedPermissions(\n origin: OriginString,\n requestedPermissions: unknown,\n ): void {\n if (!isPlainObject(requestedPermissions)) {\n throw invalidParams({\n message: `Requested permissions for origin \"${origin}\" is not a plain object.`,\n data: { origin, requestedPermissions },\n });\n }\n\n if (Object.keys(requestedPermissions).length === 0) {\n throw invalidParams({\n message: `Permissions request for origin \"${origin}\" contains no permissions.`,\n data: { requestedPermissions },\n });\n }\n\n for (const targetName of Object.keys(requestedPermissions)) {\n const permission = requestedPermissions[targetName];\n\n if (!this.targetExists(targetName)) {\n throw methodNotFound(targetName, { origin, requestedPermissions });\n }\n\n if (\n !isPlainObject(permission) ||\n (permission.parentCapability !== undefined &&\n targetName !== permission.parentCapability)\n ) {\n throw invalidParams({\n message: `Permissions request for origin \"${origin}\" contains invalid requested permission(s).`,\n data: { origin, requestedPermissions },\n });\n }\n\n // Here we validate the permission without invoking its validator, if any.\n // The validator will be invoked after the permission has been approved.\n this.validatePermission(\n this.getPermissionSpecification(targetName),\n // Typecast: The permission is still a \"PlainObject\" here.\n permission as PermissionConstraint,\n origin,\n { invokePermissionValidator: false, performCaveatValidation: true },\n );\n }\n }\n\n /**\n * Merges a set of incrementally requested permissions into the existing permissions of\n * the requesting subject. The merge is a right-biased union, where the existing\n * permissions are the left-hand side, and the incrementally requested permissions are\n * the right-hand side.\n *\n * @param existingPermissions - The subject's existing permissions.\n * @param incrementalRequestedPermissions - The requested permissions to merge.\n * @returns The merged permissions and the resulting diff.\n */\n #mergeIncrementalPermissions(\n existingPermissions: Exclude<\n ReturnType,\n undefined\n >,\n incrementalRequestedPermissions: RequestedPermissions,\n ):\n | [\n SubjectPermissions<\n ValidPermission>\n >,\n PermissionDiffMap,\n ]\n | [] {\n const permissionDiffMap: PermissionDiffMap = {};\n\n // Use immer's produce as a convenience for calculating the new permissions\n // without mutating the existing permissions or committing the results to state.\n const newPermissions = immerProduce(\n existingPermissions,\n (draftExistingPermissions) => {\n const leftPermissions =\n draftExistingPermissions as RequestedPermissions;\n\n Object.entries(incrementalRequestedPermissions).forEach(\n ([targetName, rightPermission]) => {\n const leftPermission: Partial | undefined =\n leftPermissions[targetName];\n\n const [newPermission, caveatsDiff] = this.#mergePermission(\n leftPermission ?? {},\n rightPermission,\n );\n\n if (\n leftPermission === undefined ||\n Object.keys(caveatsDiff).length > 0\n ) {\n leftPermissions[targetName] = newPermission;\n permissionDiffMap[targetName] = caveatsDiff;\n }\n // Otherwise, leave the left permission as-is; its authority has\n // not changed.\n },\n );\n },\n );\n\n if (Object.keys(permissionDiffMap).length === 0) {\n return [];\n }\n return [newPermissions, permissionDiffMap];\n }\n\n /**\n * Performs a right-biased union between two permissions. The task of merging caveats\n * of the same type between the two permissions is delegated to the corresponding\n * caveat type's merger implementation.\n *\n * Throws if the left-hand and right-hand permissions both have a caveat whose\n * specification does not provide a caveat value merger function.\n *\n * @param leftPermission - The left-hand permission to merge.\n * @param rightPermission - The right-hand permission to merge.\n * @returns The merged permission.\n */\n #mergePermission<\n PermissionType extends Partial | PermissionConstraint,\n >(\n leftPermission: PermissionType | undefined,\n rightPermission: PermissionType,\n ): [PermissionType, CaveatDiffMap] {\n const { caveatPairs, leftUniqueCaveats, rightUniqueCaveats } =\n collectUniqueAndPairedCaveats(leftPermission, rightPermission);\n\n const [mergedCaveats, caveatDiffMap] = caveatPairs.reduce(\n ([caveats, diffMap], [leftCaveat, rightCaveat]) => {\n const [newCaveat, diff] = this.#mergeCaveat(leftCaveat, rightCaveat);\n\n if (newCaveat !== undefined && diff !== undefined) {\n caveats.push(newCaveat);\n diffMap[newCaveat.type] = diff;\n } else {\n caveats.push(leftCaveat);\n }\n\n return [caveats, diffMap];\n },\n [[], {}] as [CaveatConstraint[], CaveatDiffMap],\n );\n\n const mergedRightUniqueCaveats = rightUniqueCaveats.map((caveat) => {\n const [newCaveat, diff] = this.#mergeCaveat(undefined, caveat);\n\n caveatDiffMap[newCaveat.type] = diff;\n return newCaveat;\n });\n\n const allCaveats = [\n ...mergedCaveats,\n ...leftUniqueCaveats,\n ...mergedRightUniqueCaveats,\n ];\n\n const newPermission = {\n ...leftPermission,\n ...rightPermission,\n ...(allCaveats.length > 0\n ? { caveats: allCaveats as NonEmptyArray }\n : {}),\n };\n\n return [newPermission, caveatDiffMap];\n }\n\n /**\n * Merges two caveats of the same type. The task of merging the values of the\n * two caveats is delegated to the corresponding caveat type's merger implementation.\n *\n * @param leftCaveat - The left-hand caveat to merge.\n * @param rightCaveat - The right-hand caveat to merge.\n * @returns The merged caveat and the diff between the two caveats.\n */\n #mergeCaveat<\n RightCaveat extends CaveatConstraint,\n LeftCaveat extends RightCaveat | undefined,\n >(\n leftCaveat: LeftCaveat,\n rightCaveat: RightCaveat,\n ): MergeCaveatResult {\n /* istanbul ignore if: This should be impossible */\n if (leftCaveat !== undefined && leftCaveat.type !== rightCaveat.type) {\n throw new CaveatMergeTypeMismatchError(leftCaveat.type, rightCaveat.type);\n }\n\n const merger = this.#expectGetCaveatMerger(rightCaveat.type);\n\n if (leftCaveat === undefined) {\n return [\n {\n ...rightCaveat,\n },\n rightCaveat.value,\n ];\n }\n\n const [newValue, diff] = merger(leftCaveat.value, rightCaveat.value);\n\n return newValue !== undefined && diff !== undefined\n ? [\n {\n type: rightCaveat.type,\n value: newValue,\n },\n diff,\n ]\n : ([] as MergeCaveatResult);\n }\n\n /**\n * Adds a request to the {@link ApprovalController} using the\n * {@link AddApprovalRequest} action. Also validates the resulting approved\n * permissions request, and throws an error if validation fails.\n *\n * @param permissionsRequest - The permissions request object.\n * @returns The approved permissions request object.\n */\n private async requestUserApproval(permissionsRequest: PermissionsRequest) {\n const { origin, id } = permissionsRequest.metadata;\n const approvedRequest = await this.messagingSystem.call(\n 'ApprovalController:addRequest',\n {\n id,\n origin,\n requestData: permissionsRequest,\n type: MethodNames.RequestPermissions,\n },\n true,\n );\n\n this.validateApprovedPermissions(approvedRequest, { id, origin });\n return approvedRequest as PermissionsRequest;\n }\n\n /**\n * Accepts a permissions request that has been approved by the user. This\n * method should be called after the user has approved the request and the\n * {@link ApprovalController} has resolved the user approval promise.\n *\n * @param options - Options bag.\n * @param options.subject - The subject to grant permissions to.\n * @param options.metadata - The metadata of the approved permissions request.\n * @param options.preserveExistingPermissions - Whether to preserve the\n * subject's existing permissions.\n * @param options.approvedRequest - The approved permissions request to handle.\n * @returns The granted permissions and request metadata.\n */\n async #handleApprovedPermissions({\n subject,\n metadata,\n preserveExistingPermissions,\n approvedRequest,\n }: {\n subject: PermissionSubjectMetadata;\n metadata: PermissionsRequest['metadata'];\n preserveExistingPermissions: boolean;\n approvedRequest: PermissionsRequest;\n }): Promise<\n [ReturnType, ApprovedPermissionsMetadata]\n > {\n const { permissions: approvedPermissions, ...requestData } =\n approvedRequest;\n const approvedMetadata: ApprovedPermissionsMetadata = { ...metadata };\n\n const sideEffects = this.getSideEffects(approvedPermissions);\n if (Object.values(sideEffects.permittedHandlers).length > 0) {\n const sideEffectsData = await this.executeSideEffects(\n sideEffects,\n approvedRequest,\n );\n\n approvedMetadata.data = Object.keys(sideEffects.permittedHandlers).reduce(\n (acc, permission, i) => ({ [permission]: sideEffectsData[i], ...acc }),\n {},\n );\n }\n\n return [\n this.grantPermissions({\n subject,\n approvedPermissions,\n preserveExistingPermissions,\n requestData,\n }),\n approvedMetadata,\n ];\n }\n\n /**\n * Reunites all the side-effects (onPermitted and onFailure) of the requested permissions inside a record of arrays.\n *\n * @param permissions - The approved permissions.\n * @returns The {@link SideEffects} object containing the handlers arrays.\n */\n private getSideEffects(permissions: RequestedPermissions) {\n return Object.keys(permissions).reduce(\n (sideEffectList, targetName) => {\n if (this.targetExists(targetName)) {\n const specification = this.getPermissionSpecification(targetName);\n\n if (specification.sideEffect) {\n sideEffectList.permittedHandlers[targetName] =\n specification.sideEffect.onPermitted;\n\n if (specification.sideEffect.onFailure) {\n sideEffectList.failureHandlers[targetName] =\n specification.sideEffect.onFailure;\n }\n }\n }\n return sideEffectList;\n },\n { permittedHandlers: {}, failureHandlers: {} },\n );\n }\n\n /**\n * Executes the side-effects of the approved permissions while handling the errors if any.\n * It will pass an instance of the {@link messagingSystem} and the request data associated with the permission request to the handlers through its params.\n *\n * @param sideEffects - the side-effect record created by {@link getSideEffects}\n * @param requestData - the permissions requestData.\n * @returns the value returned by all the `onPermitted` handlers in an array.\n */\n private async executeSideEffects(\n sideEffects: SideEffects,\n requestData: PermissionsRequest,\n ) {\n const { permittedHandlers, failureHandlers } = sideEffects;\n const params = {\n requestData,\n messagingSystem: this.messagingSystem,\n };\n\n const promiseResults = await Promise.allSettled(\n Object.values(permittedHandlers).map((permittedHandler) =>\n permittedHandler(params),\n ),\n );\n\n // lib.es2020.promise.d.ts does not export its types so we're using a simple type.\n const rejectedHandlers = promiseResults.filter(\n (promise) => promise.status === 'rejected',\n ) as { status: 'rejected'; reason: Error }[];\n\n if (rejectedHandlers.length > 0) {\n const failureHandlersList = Object.values(failureHandlers);\n if (failureHandlersList.length > 0) {\n try {\n await Promise.all(\n failureHandlersList.map((failureHandler) => failureHandler(params)),\n );\n } catch (error) {\n throw internalError('Unexpected error in side-effects', { error });\n }\n }\n const reasons = rejectedHandlers.map((handler) => handler.reason);\n\n reasons.forEach((reason) => {\n console.error(reason);\n });\n\n throw reasons.length > 1\n ? internalError(\n 'Multiple errors occurred during side-effects execution',\n { errors: reasons },\n )\n : reasons[0];\n }\n\n // lib.es2020.promise.d.ts does not export its types so we're using a simple type.\n return (promiseResults as { status: 'fulfilled'; value: unknown }[]).map(\n ({ value }) => value,\n );\n }\n\n /**\n * Validates an approved {@link PermissionsRequest} object. The approved\n * request must have the required `metadata` and `permissions` properties,\n * the `id` and `origin` of the `metadata` must match the original request\n * metadata, and the requested permissions must be valid per\n * {@link PermissionController.validateRequestedPermissions}. Any extra\n * metadata properties are ignored.\n *\n * An error is thrown if validation fails.\n *\n * @param approvedRequest - The approved permissions request object.\n * @param originalMetadata - The original request metadata.\n */\n private validateApprovedPermissions(\n approvedRequest: unknown,\n originalMetadata: PermissionsRequestMetadata,\n ) {\n const { id, origin } = originalMetadata;\n\n if (\n !isPlainObject(approvedRequest) ||\n !isPlainObject(approvedRequest.metadata)\n ) {\n throw internalError(\n `Approved permissions request for subject \"${origin}\" is invalid.`,\n { data: { approvedRequest } },\n );\n }\n\n const {\n metadata: { id: newId, origin: newOrigin },\n permissions,\n } = approvedRequest;\n\n if (newId !== id) {\n throw internalError(\n `Approved permissions request for subject \"${origin}\" mutated its id.`,\n { originalId: id, mutatedId: newId },\n );\n }\n\n if (newOrigin !== origin) {\n throw internalError(\n `Approved permissions request for subject \"${origin}\" mutated its origin.`,\n { originalOrigin: origin, mutatedOrigin: newOrigin },\n );\n }\n\n try {\n this.validateRequestedPermissions(origin, permissions);\n } catch (error) {\n if (error instanceof Error) {\n // Re-throw as an internal error; we should never receive invalid approved\n // permissions.\n throw internalError(\n `Invalid approved permissions request: ${error.message}`,\n error instanceof JsonRpcError ? error.data : undefined,\n );\n }\n /* istanbul ignore next: This should be impossible */\n throw internalError('Unrecognized error type', { error });\n }\n }\n\n /**\n * Accepts a permissions request created by\n * {@link PermissionController.requestPermissions}.\n *\n * @param request - The permissions request.\n */\n async acceptPermissionsRequest(request: PermissionsRequest): Promise {\n const { id } = request.metadata;\n\n if (!this.hasApprovalRequest({ id })) {\n throw new PermissionsRequestNotFoundError(id);\n }\n\n if (Object.keys(request.permissions).length === 0) {\n this._rejectPermissionsRequest(\n id,\n invalidParams({\n message: 'Must request at least one permission.',\n }),\n );\n return;\n }\n\n try {\n await this.messagingSystem.call(\n 'ApprovalController:acceptRequest',\n id,\n request,\n );\n } catch (error) {\n // If accepting unexpectedly fails, reject the request and re-throw the\n // error\n this._rejectPermissionsRequest(id, error);\n throw error;\n }\n }\n\n /**\n * Rejects a permissions request created by\n * {@link PermissionController.requestPermissions}.\n *\n * @param id - The id of the request to be rejected.\n */\n async rejectPermissionsRequest(id: string): Promise {\n if (!this.hasApprovalRequest({ id })) {\n throw new PermissionsRequestNotFoundError(id);\n }\n\n this._rejectPermissionsRequest(id, userRejectedRequest());\n }\n\n /**\n * Checks whether the {@link ApprovalController} has a particular permissions\n * request.\n *\n * @see {@link PermissionController.acceptPermissionsRequest} and\n * {@link PermissionController.rejectPermissionsRequest} for usage.\n * @param options - The {@link HasApprovalRequest} options.\n * @param options.id - The id of the approval request to check for.\n * @returns Whether the specified request exists.\n */\n private hasApprovalRequest(options: { id: string }): boolean {\n return this.messagingSystem.call('ApprovalController:hasRequest', options);\n }\n\n /**\n * Rejects the permissions request with the specified id, with the specified\n * error as the reason. This method is effectively a wrapper around a\n * messenger call for the `ApprovalController:rejectRequest` action.\n *\n * @see {@link PermissionController.acceptPermissionsRequest} and\n * {@link PermissionController.rejectPermissionsRequest} for usage.\n * @param id - The id of the request to reject.\n * @param error - The error associated with the rejection.\n * @returns Nothing\n */\n private _rejectPermissionsRequest(id: string, error: unknown): void {\n return this.messagingSystem.call(\n 'ApprovalController:rejectRequest',\n id,\n error,\n );\n }\n\n /**\n * Gets the subject's endowments per the specified endowment permission.\n * Throws if the subject does not have the required permission or if the\n * permission is not an endowment permission.\n *\n * @param origin - The origin of the subject whose endowments to retrieve.\n * @param targetName - The name of the endowment permission. This must be a\n * valid permission target name.\n * @param requestData - Additional data associated with the request, if any.\n * Forwarded to the endowment getter function for the permission.\n * @returns The endowments, if any.\n */\n async getEndowments(\n origin: string,\n targetName: ExtractEndowmentPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n requestData?: unknown,\n ): Promise {\n if (!this.hasPermission(origin, targetName)) {\n throw unauthorized({ data: { origin, targetName } });\n }\n\n return this.getTypedPermissionSpecification(\n PermissionType.Endowment,\n targetName,\n origin,\n ).endowmentGetter({ origin, requestData });\n }\n\n /**\n * Executes a restricted method as the subject with the given origin.\n * The specified params, if any, will be passed to the method implementation.\n *\n * ATTN: Great caution should be exercised in the use of this method.\n * Methods that cause side effects or affect application state should\n * be avoided.\n *\n * This method will first attempt to retrieve the requested restricted method\n * implementation, throwing if it does not exist. The method will then be\n * invoked as though the subject with the specified origin had invoked it with\n * the specified parameters. This means that any existing caveats will be\n * applied to the restricted method, and this method will throw if the\n * restricted method or its caveat decorators throw.\n *\n * In addition, this method will throw if the subject does not have a\n * permission for the specified restricted method.\n *\n * @param origin - The origin of the subject to execute the method on behalf\n * of.\n * @param targetName - The name of the method to execute. This must be a valid\n * permission target name.\n * @param params - The parameters to pass to the method implementation.\n * @returns The result of the executed method.\n */\n async executeRestrictedMethod(\n origin: OriginString,\n targetName: ExtractRestrictedMethodPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n params?: RestrictedMethodParameters,\n ): Promise {\n // Throws if the method does not exist\n const methodImplementation = this.getRestrictedMethod(targetName, origin);\n\n const result = await this._executeRestrictedMethod(\n methodImplementation,\n { origin },\n targetName,\n params,\n );\n\n if (result === undefined) {\n throw new Error(\n `Internal request for method \"${targetName}\" as origin \"${origin}\" returned no result.`,\n );\n }\n\n return result;\n }\n\n /**\n * An internal method used in the controller's `json-rpc-engine` middleware\n * and {@link PermissionController.executeRestrictedMethod}. Calls the\n * specified restricted method implementation after decorating it with the\n * caveats of its permission. Throws if the subject does not have the\n * requisite permission.\n *\n * ATTN: Parameter validation is the responsibility of the caller, or\n * the restricted method implementation in the case of `params`.\n *\n * @see {@link PermissionController.executeRestrictedMethod} and\n * {@link PermissionController.createPermissionMiddleware} for usage.\n * @param methodImplementation - The implementation of the method to call.\n * @param subject - Metadata about the subject that made the request.\n * @param method - The method name\n * @param params - Params needed for executing the restricted method\n * @returns The result of the restricted method implementation\n */\n private _executeRestrictedMethod(\n methodImplementation: RestrictedMethod,\n subject: PermissionSubjectMetadata,\n method: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n params: RestrictedMethodParameters = [],\n ): ReturnType> {\n const { origin } = subject;\n\n const permission = this.getPermission(origin, method);\n if (!permission) {\n throw unauthorized({ data: { origin, method } });\n }\n\n return decorateWithCaveats(\n methodImplementation,\n permission,\n this._caveatSpecifications,\n )({ method, params, context: { origin } });\n }\n}\n"]} +\ No newline at end of file ++{"version":3,"file":"PermissionController.cjs","sourceRoot":"","sources":["../src/PermissionController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AcceptRequest as AcceptApprovalRequest,\n AddApprovalRequest,\n HasApprovalRequest,\n RejectRequest as RejectApprovalRequest,\n} from '@metamask/approval-controller';\nimport type {\n StateMetadata,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller/next';\nimport { BaseController } from '@metamask/base-controller/next';\nimport type { NonEmptyArray } from '@metamask/controller-utils';\nimport {\n isNonEmptyArray,\n isPlainObject,\n isValidJson,\n} from '@metamask/controller-utils';\nimport type {\n Messenger,\n ActionConstraint,\n EventConstraint,\n} from '@metamask/messenger';\nimport { JsonRpcError } from '@metamask/rpc-errors';\nimport { hasProperty } from '@metamask/utils';\nimport type { Json, Mutable } from '@metamask/utils';\nimport deepFreeze from 'deep-freeze-strict';\nimport { castDraft, produce as immerProduce, type Draft } from 'immer';\nimport { nanoid } from 'nanoid';\n\nimport type {\n CaveatConstraint,\n CaveatDiffMap,\n CaveatSpecificationConstraint,\n CaveatSpecificationMap,\n CaveatValueMerger,\n ExtractCaveat,\n ExtractCaveats,\n ExtractCaveatValue,\n} from './Caveat';\nimport {\n decorateWithCaveats,\n isRestrictedMethodCaveatSpecification,\n} from './Caveat';\nimport {\n CaveatAlreadyExistsError,\n CaveatDoesNotExistError,\n CaveatInvalidJsonError,\n CaveatMergerDoesNotExistError,\n CaveatMergeTypeMismatchError,\n CaveatMissingValueError,\n CaveatSpecificationMismatchError,\n DuplicateCaveatError,\n EndowmentPermissionDoesNotExistError,\n ForbiddenCaveatError,\n internalError,\n InvalidApprovedPermissionError,\n InvalidCaveatError,\n InvalidCaveatFieldsError,\n InvalidCaveatsPropertyError,\n InvalidCaveatTypeError,\n InvalidMergedPermissionsError,\n invalidParams,\n InvalidSubjectIdentifierError,\n methodNotFound,\n PermissionDoesNotExistError,\n PermissionsRequestNotFoundError,\n unauthorized,\n UnrecognizedCaveatTypeError,\n UnrecognizedSubjectError,\n userRejectedRequest,\n} from './errors';\nimport type {\n EndowmentSpecificationConstraint,\n ExtractAllowedCaveatTypes,\n ExtractPermissionSpecification,\n OriginString,\n PermissionConstraint,\n PermissionSpecificationConstraint,\n PermissionSpecificationMap,\n RequestedPermissions,\n RestrictedMethod,\n RestrictedMethodParameters,\n RestrictedMethodSpecificationConstraint,\n SideEffectHandler,\n ValidPermission,\n ValidPermissionSpecification,\n} from './Permission';\nimport {\n constructPermission,\n findCaveat,\n hasSpecificationType,\n PermissionType,\n} from './Permission';\nimport { getPermissionMiddlewareFactory } from './permission-middleware';\nimport type { GetSubjectMetadata } from './SubjectMetadataController';\nimport { collectUniqueAndPairedCaveats, MethodNames } from './utils';\n\n/**\n * Flags for controlling the validation behavior of certain internal methods.\n */\ntype PermissionValidationFlags = {\n invokePermissionValidator: boolean;\n performCaveatValidation: boolean;\n};\n\n/**\n * Metadata associated with {@link PermissionController} subjects.\n */\nexport type PermissionSubjectMetadata = {\n origin: OriginString;\n};\n\n/**\n * Metadata associated with permission requests.\n */\nexport type PermissionsRequestMetadata = PermissionSubjectMetadata & {\n id: string;\n [key: string]: Json;\n};\n\n/**\n * A diff produced by an incremental permissions request.\n */\nexport type PermissionDiffMap<\n TargetName extends string,\n AllowedCaveats extends CaveatConstraint,\n> = Record>;\n\n/**\n * Used for prompting the user about a proposed new permission.\n * Includes information about the grantee subject, requested permissions, the\n * diff relative to the previously granted permissions (if relevant), and any\n * additional information added by the consumer.\n *\n * All properties except `diff` and `permissions` are passed to any factories\n * for the requested permissions.\n */\nexport type PermissionsRequest = {\n metadata: PermissionsRequestMetadata;\n permissions: RequestedPermissions;\n [key: string]: Json;\n} & {\n diff?: {\n currentPermissions: SubjectPermissions;\n permissionDiffMap: PermissionDiffMap;\n };\n};\n\n/**\n * Metadata associated with an approved permission request.\n */\ntype ApprovedPermissionsMetadata = {\n data?: Record;\n id: string;\n origin: OriginString;\n};\n\nexport type SideEffects = {\n permittedHandlers: Record<\n string,\n SideEffectHandler\n >;\n failureHandlers: Record<\n string,\n SideEffectHandler\n >;\n};\n\n/**\n * The name of the {@link PermissionController}.\n */\nconst controllerName = 'PermissionController';\n\n/**\n * Permissions associated with a {@link PermissionController} subject.\n */\nexport type SubjectPermissions =\n Record;\n\n/**\n * Permissions and metadata associated with a {@link PermissionController}\n * subject.\n */\nexport type PermissionSubjectEntry<\n SubjectPermission extends PermissionConstraint,\n> = {\n origin: SubjectPermission['invoker'];\n permissions: SubjectPermissions;\n};\n\n/**\n * All subjects of a {@link PermissionController}.\n *\n * @template SubjectPermission - The permissions of the subject.\n */\nexport type PermissionControllerSubjects<\n SubjectPermission extends PermissionConstraint,\n> = Record<\n SubjectPermission['invoker'],\n PermissionSubjectEntry\n>;\n\n/**\n * The state of a {@link PermissionController}.\n *\n * @template Permission - The controller's permission type union.\n */\nexport type PermissionControllerState =\n Permission extends PermissionConstraint\n ? {\n subjects: PermissionControllerSubjects;\n }\n : never;\n\n/**\n * Get the state metadata of the {@link PermissionController}.\n *\n * @template Permission - The controller's permission type union.\n * @returns The state metadata\n */\nfunction getStateMetadata() {\n return {\n subjects: {\n includeInStateLogs: true,\n includeInDebugSnapshot: true,\n persist: true,\n usedInUi: true,\n },\n } as StateMetadata>;\n}\n\n/**\n * Get the default state of the {@link PermissionController}.\n *\n * @template Permission - The controller's permission type union.\n * @returns The default state of the controller\n */\nfunction getDefaultState() {\n return { subjects: {} } as PermissionControllerState;\n}\n\n/**\n * Gets the state of the {@link PermissionController}.\n */\nexport type GetPermissionControllerState = ControllerGetStateAction<\n typeof controllerName,\n PermissionControllerState\n>;\n\n/**\n * Gets the names of all subjects from the {@link PermissionController}.\n */\nexport type GetSubjects = {\n type: `${typeof controllerName}:getSubjectNames`;\n handler: () => (keyof PermissionControllerSubjects)[];\n};\n\n/**\n * Gets the permissions for specified subject\n */\nexport type GetPermissions = {\n type: `${typeof controllerName}:getPermissions`;\n handler: GenericPermissionController['getPermissions'];\n};\n\n/**\n * Checks whether the specified subject has any permissions.\n */\nexport type HasPermissions = {\n type: `${typeof controllerName}:hasPermissions`;\n handler: GenericPermissionController['hasPermissions'];\n};\n\n/**\n * Checks whether the specified subject has a specific permission.\n */\nexport type HasPermission = {\n type: `${typeof controllerName}:hasPermission`;\n handler: GenericPermissionController['hasPermission'];\n};\n\n/**\n * Directly grants given permissions for a specified origin without requesting user approval\n */\nexport type GrantPermissions = {\n type: `${typeof controllerName}:grantPermissions`;\n handler: GenericPermissionController['grantPermissions'];\n};\n\n/**\n * Directly grants given permissions for a specified origin without requesting user approval\n */\nexport type GrantPermissionsIncremental = {\n type: `${typeof controllerName}:grantPermissionsIncremental`;\n handler: GenericPermissionController['grantPermissionsIncremental'];\n};\n\n/**\n * Requests given permissions for a specified origin\n */\nexport type RequestPermissions = {\n type: `${typeof controllerName}:requestPermissions`;\n handler: GenericPermissionController['requestPermissions'];\n};\n\n/**\n * Requests given permissions for a specified origin\n */\nexport type RequestPermissionsIncremental = {\n type: `${typeof controllerName}:requestPermissionsIncremental`;\n handler: GenericPermissionController['requestPermissionsIncremental'];\n};\n\n/**\n * Removes the specified permissions for each origin.\n */\nexport type RevokePermissions = {\n type: `${typeof controllerName}:revokePermissions`;\n handler: GenericPermissionController['revokePermissions'];\n};\n\n/**\n * Removes all permissions for a given origin\n */\nexport type RevokeAllPermissions = {\n type: `${typeof controllerName}:revokeAllPermissions`;\n handler: GenericPermissionController['revokeAllPermissions'];\n};\n\n/**\n * Revokes all permissions corresponding to the specified target for all subjects.\n * Does nothing if no subjects or no such permission exists.\n */\nexport type RevokePermissionForAllSubjects = {\n type: `${typeof controllerName}:revokePermissionForAllSubjects`;\n handler: GenericPermissionController['revokePermissionForAllSubjects'];\n};\n\n/**\n * Updates a caveat value for a specified caveat type belonging to a specific target and origin.\n */\nexport type UpdateCaveat = {\n type: `${typeof controllerName}:updateCaveat`;\n handler: GenericPermissionController['updateCaveat'];\n};\n\n/**\n * Clears all permissions from the {@link PermissionController}.\n */\nexport type ClearPermissions = {\n type: `${typeof controllerName}:clearPermissions`;\n handler: () => void;\n};\n\n/**\n * Gets the endowments for the given subject and permission.\n */\nexport type GetEndowments = {\n type: `${typeof controllerName}:getEndowments`;\n handler: GenericPermissionController['getEndowments'];\n};\n\n/**\n * The {@link Messenger} actions of the {@link PermissionController}.\n */\nexport type PermissionControllerActions =\n | ClearPermissions\n | GetEndowments\n | GetPermissionControllerState\n | GetSubjects\n | GetPermissions\n | HasPermission\n | HasPermissions\n | GrantPermissions\n | GrantPermissionsIncremental\n | RequestPermissions\n | RequestPermissionsIncremental\n | RevokeAllPermissions\n | RevokePermissionForAllSubjects\n | RevokePermissions\n | UpdateCaveat;\n\n/**\n * The generic state change event of the {@link PermissionController}.\n */\nexport type PermissionControllerStateChange = ControllerStateChangeEvent<\n typeof controllerName,\n PermissionControllerState\n>;\n\n/**\n * The {@link Messenger} events of the {@link PermissionController}.\n *\n * The permission controller only emits its generic state change events.\n * Consumers should use selector subscriptions to subscribe to relevant\n * substate.\n */\nexport type PermissionControllerEvents = PermissionControllerStateChange;\n\n/**\n * The external {@link Messenger} actions available to the\n * {@link PermissionController}.\n */\ntype AllowedActions =\n | AddApprovalRequest\n | HasApprovalRequest\n | AcceptApprovalRequest\n | RejectApprovalRequest\n | GetSubjectMetadata;\n\n/**\n * The messenger of the {@link PermissionController}.\n */\nexport type PermissionControllerMessenger = Messenger<\n typeof controllerName,\n PermissionControllerActions | AllowedActions,\n PermissionControllerEvents\n>;\n\nexport type SideEffectMessenger<\n Actions extends ActionConstraint,\n Events extends EventConstraint,\n> = Messenger;\n\n/**\n * A generic {@link PermissionController}.\n */\nexport type GenericPermissionController = PermissionController<\n PermissionSpecificationConstraint,\n CaveatSpecificationConstraint\n>;\n\n/**\n * Describes the possible results of a {@link CaveatMutator} function.\n */\nexport enum CaveatMutatorOperation {\n Noop,\n UpdateValue,\n DeleteCaveat,\n RevokePermission,\n}\n\n/**\n * Given a caveat value, returns a {@link CaveatMutatorOperation} and, optionally,\n * a new caveat value.\n *\n * @see {@link PermissionController.updatePermissionsByCaveat} for more details.\n * @template Caveat - The caveat type for which this mutator is intended.\n * @param caveatValue - The existing value of the caveat being mutated.\n * @returns A tuple of the mutation result and, optionally, the new caveat\n * value.\n */\nexport type CaveatMutator = (\n caveatValue: TargetCaveat['value'],\n) => CaveatMutatorResult;\n\ntype CaveatMutatorResult =\n | Readonly<{\n operation: CaveatMutatorOperation.UpdateValue;\n value: CaveatConstraint['value'];\n }>\n | Readonly<{\n operation: Exclude<\n CaveatMutatorOperation,\n CaveatMutatorOperation.UpdateValue\n >;\n }>;\n\ntype MergeCaveatResult =\n CaveatType extends undefined\n ? [CaveatConstraint, CaveatConstraint['value']]\n : [CaveatConstraint, CaveatConstraint['value']] | [];\n\n/**\n * Extracts the permission(s) specified by the given permission and caveat\n * specifications.\n *\n * @template ControllerPermissionSpecification - The permission specification(s)\n * to extract from.\n * @template ControllerCaveatSpecification - The caveat specification(s) to\n * extract from. Necessary because {@link Permission} has a generic parameter\n * that describes the allowed caveats for the permission.\n */\nexport type ExtractPermission<\n ControllerPermissionSpecification extends PermissionSpecificationConstraint,\n ControllerCaveatSpecification extends CaveatSpecificationConstraint,\n> =\n ControllerPermissionSpecification extends ValidPermissionSpecification\n ? ValidPermission<\n ControllerPermissionSpecification['targetName'],\n ExtractCaveats\n >\n : never;\n\n/**\n * Extracts the restricted method permission(s) specified by the given\n * permission and caveat specifications.\n *\n * @template ControllerPermissionSpecification - The permission specification(s)\n * to extract from.\n * @template ControllerCaveatSpecification - The caveat specification(s) to\n * extract from. Necessary because {@link Permission} has a generic parameter\n * that describes the allowed caveats for the permission.\n */\nexport type ExtractRestrictedMethodPermission<\n ControllerPermissionSpecification extends PermissionSpecificationConstraint,\n ControllerCaveatSpecification extends CaveatSpecificationConstraint,\n> = ExtractPermission<\n Extract<\n ControllerPermissionSpecification,\n RestrictedMethodSpecificationConstraint\n >,\n ControllerCaveatSpecification\n>;\n\n/**\n * Extracts the endowment permission(s) specified by the given permission and\n * caveat specifications.\n *\n * @template ControllerPermissionSpecification - The permission specification(s)\n * to extract from.\n * @template ControllerCaveatSpecification - The caveat specification(s) to\n * extract from. Necessary because {@link Permission} has a generic parameter\n * that describes the allowed caveats for the permission.\n */\nexport type ExtractEndowmentPermission<\n ControllerPermissionSpecification extends PermissionSpecificationConstraint,\n ControllerCaveatSpecification extends CaveatSpecificationConstraint,\n> = ExtractPermission<\n Extract,\n ControllerCaveatSpecification\n>;\n\n/**\n * Options for the {@link PermissionController} constructor.\n *\n * @template ControllerPermissionSpecification - A union of the types of all\n * permission specifications available to the controller. Any referenced caveats\n * must be included in the controller's caveat specifications.\n * @template ControllerCaveatSpecification - A union of the types of all\n * caveat specifications available to the controller.\n */\nexport type PermissionControllerOptions<\n ControllerPermissionSpecification extends PermissionSpecificationConstraint,\n ControllerCaveatSpecification extends CaveatSpecificationConstraint,\n> = {\n messenger: PermissionControllerMessenger;\n caveatSpecifications: CaveatSpecificationMap;\n permissionSpecifications: PermissionSpecificationMap;\n unrestrictedMethods: readonly string[];\n state?: Partial<\n PermissionControllerState<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n >;\n};\n\n/**\n * The permission controller. See the [Architecture](../ARCHITECTURE.md)\n * document for details.\n *\n * Assumes the existence of an {@link ApprovalController} reachable via the\n * {@link Messenger}.\n *\n * @template ControllerPermissionSpecification - A union of the types of all\n * permission specifications available to the controller. Any referenced caveats\n * must be included in the controller's caveat specifications.\n * @template ControllerCaveatSpecification - A union of the types of all\n * caveat specifications available to the controller.\n */\nexport class PermissionController<\n ControllerPermissionSpecification extends PermissionSpecificationConstraint,\n ControllerCaveatSpecification extends CaveatSpecificationConstraint,\n> extends BaseController<\n typeof controllerName,\n PermissionControllerState<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >,\n PermissionControllerMessenger\n> {\n private readonly _caveatSpecifications: Readonly<\n CaveatSpecificationMap\n >;\n\n private readonly _permissionSpecifications: Readonly<\n PermissionSpecificationMap\n >;\n\n private readonly _unrestrictedMethods: ReadonlySet;\n\n /**\n * The names of all JSON-RPC methods that will be ignored by the controller.\n *\n * @returns The names of all unrestricted JSON-RPC methods\n */\n public get unrestrictedMethods(): ReadonlySet {\n return this._unrestrictedMethods;\n }\n\n /**\n * Returns a `json-rpc-engine` middleware function factory, so that the rules\n * described by the state of this controller can be applied to incoming\n * JSON-RPC requests.\n *\n * The middleware **must** be added in the correct place in the middleware\n * stack in order for it to work. See the README for an example.\n */\n public createPermissionMiddleware: ReturnType<\n typeof getPermissionMiddlewareFactory\n >;\n\n /**\n * Constructs the PermissionController.\n *\n * @param options - Permission controller options.\n * @param options.caveatSpecifications - The specifications of all caveats\n * available to the controller. See {@link CaveatSpecificationMap} and the\n * documentation for more details.\n * @param options.permissionSpecifications - The specifications of all\n * permissions available to the controller. See\n * {@link PermissionSpecificationMap} and the README for more details.\n * @param options.unrestrictedMethods - The callable names of all JSON-RPC\n * methods ignored by the new controller.\n * @param options.messenger - The messenger. See\n * {@link BaseController} for more information.\n * @param options.state - Existing state to hydrate the controller with at\n * initialization.\n */\n constructor(\n options: PermissionControllerOptions<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >,\n ) {\n const {\n caveatSpecifications,\n permissionSpecifications,\n unrestrictedMethods,\n messenger,\n state = {},\n } = options;\n\n super({\n name: controllerName,\n metadata:\n getStateMetadata<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >(),\n messenger,\n state: {\n ...getDefaultState<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >(),\n ...state,\n },\n });\n\n this._unrestrictedMethods = new Set(unrestrictedMethods);\n this._caveatSpecifications = deepFreeze({ ...caveatSpecifications });\n\n this.validatePermissionSpecifications(\n permissionSpecifications,\n this._caveatSpecifications,\n );\n\n this._permissionSpecifications = deepFreeze({\n ...permissionSpecifications,\n });\n\n this.registerMessageHandlers();\n this.createPermissionMiddleware = getPermissionMiddlewareFactory({\n executeRestrictedMethod: this._executeRestrictedMethod.bind(this),\n getRestrictedMethod: this.getRestrictedMethod.bind(this),\n isUnrestrictedMethod: this.unrestrictedMethods.has.bind(\n this.unrestrictedMethods,\n ),\n });\n }\n\n /**\n * Gets a permission specification.\n *\n * @param targetName - The name of the permission specification to get.\n * @returns The permission specification with the specified target name.\n */\n private getPermissionSpecification<\n TargetName extends ControllerPermissionSpecification['targetName'],\n >(\n targetName: TargetName,\n ): ExtractPermissionSpecification<\n ControllerPermissionSpecification,\n TargetName\n > {\n return this._permissionSpecifications[targetName];\n }\n\n /**\n * Gets a caveat specification.\n *\n * @param caveatType - The type of the caveat specification to get.\n * @returns The caveat specification with the specified type.\n */\n private getCaveatSpecification<\n CaveatType extends ControllerCaveatSpecification['type'],\n >(caveatType: CaveatType) {\n return this._caveatSpecifications[caveatType];\n }\n\n /**\n * Gets the merger function for the specified caveat. Throws if no\n * merger exists.\n *\n * @param caveatType - The type of the caveat whose merger to get.\n * @returns The caveat value merger function for the specified caveat type.\n */\n #expectGetCaveatMerger<\n CaveatType extends ControllerCaveatSpecification['type'],\n >(caveatType: CaveatType): CaveatValueMerger {\n const { merger } = this.getCaveatSpecification(caveatType);\n\n if (merger === undefined) {\n throw new CaveatMergerDoesNotExistError(caveatType);\n }\n return merger;\n }\n\n /**\n * Constructor helper for validating permission specifications.\n *\n * Throws an error if validation fails.\n *\n * @param permissionSpecifications - The permission specifications passed to\n * this controller's constructor.\n * @param caveatSpecifications - The caveat specifications passed to this\n * controller.\n */\n private validatePermissionSpecifications(\n permissionSpecifications: PermissionSpecificationMap,\n caveatSpecifications: CaveatSpecificationMap,\n ) {\n Object.entries(\n permissionSpecifications,\n ).forEach(\n ([\n targetName,\n { permissionType, targetName: innerTargetName, allowedCaveats },\n ]) => {\n if (!permissionType || !hasProperty(PermissionType, permissionType)) {\n throw new Error(`Invalid permission type: \"${permissionType}\"`);\n }\n\n if (!targetName) {\n throw new Error(`Invalid permission target name: \"${targetName}\"`);\n }\n\n if (targetName !== innerTargetName) {\n throw new Error(\n `Invalid permission specification: target name \"${targetName}\" must match specification.targetName value \"${innerTargetName}\".`,\n );\n }\n\n if (allowedCaveats) {\n allowedCaveats.forEach((caveatType) => {\n if (!hasProperty(caveatSpecifications, caveatType)) {\n throw new UnrecognizedCaveatTypeError(caveatType);\n }\n\n const specification =\n caveatSpecifications[\n caveatType as ControllerCaveatSpecification['type']\n ];\n const isRestrictedMethodCaveat =\n isRestrictedMethodCaveatSpecification(specification);\n\n if (\n (permissionType === PermissionType.RestrictedMethod &&\n !isRestrictedMethodCaveat) ||\n (permissionType === PermissionType.Endowment &&\n isRestrictedMethodCaveat)\n ) {\n throw new CaveatSpecificationMismatchError(\n specification,\n permissionType,\n );\n }\n });\n }\n },\n );\n }\n\n /**\n * Constructor helper for registering the controller's messenger actions.\n */\n private registerMessageHandlers(): void {\n this.messenger.registerActionHandler(\n `${controllerName}:clearPermissions` as const,\n () => this.clearState(),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:getEndowments` as const,\n (origin: string, targetName: string, requestData?: unknown) =>\n this.getEndowments(origin, targetName, requestData),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:getSubjectNames` as const,\n () => this.getSubjectNames(),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:getPermissions` as const,\n (origin: OriginString) => this.getPermissions(origin),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:hasPermission` as const,\n (origin: OriginString, targetName: string) =>\n this.hasPermission(origin, targetName),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:hasPermissions` as const,\n (origin: OriginString) => this.hasPermissions(origin),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:grantPermissions` as const,\n this.grantPermissions.bind(this),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:grantPermissionsIncremental` as const,\n this.grantPermissionsIncremental.bind(this),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:requestPermissions` as const,\n (subject: PermissionSubjectMetadata, permissions: RequestedPermissions) =>\n this.requestPermissions(subject, permissions),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:requestPermissionsIncremental` as const,\n (subject: PermissionSubjectMetadata, permissions: RequestedPermissions) =>\n this.requestPermissionsIncremental(subject, permissions),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:revokeAllPermissions` as const,\n (origin: OriginString) => this.revokeAllPermissions(origin),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:revokePermissionForAllSubjects` as const,\n (\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n ) => this.revokePermissionForAllSubjects(target),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:revokePermissions` as const,\n this.revokePermissions.bind(this),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:updateCaveat` as const,\n (origin, target, caveatType, caveatValue) => {\n this.updateCaveat(\n origin,\n target,\n caveatType as ExtractAllowedCaveatTypes,\n caveatValue,\n );\n },\n );\n }\n\n /**\n * Clears the state of the controller.\n */\n clearState(): void {\n this.update((_draftState) => {\n return {\n ...getDefaultState<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >(),\n };\n });\n }\n\n /**\n * Gets the permission specification corresponding to the given permission\n * type and target name. Throws an error if the target name does not\n * correspond to a permission, or if the specification is not of the\n * given permission type.\n *\n * @template Type - The type of the permission specification to get.\n * @param permissionType - The type of the permission specification to get.\n * @param targetName - The name of the permission whose specification to get.\n * @param requestingOrigin - The origin of the requesting subject, if any.\n * Will be added to any thrown errors.\n * @returns The specification object corresponding to the given type and\n * target name.\n */\n private getTypedPermissionSpecification(\n permissionType: Type,\n targetName: string,\n requestingOrigin?: string,\n ): ControllerPermissionSpecification & { permissionType: Type } {\n const failureError =\n permissionType === PermissionType.RestrictedMethod\n ? methodNotFound(\n targetName,\n requestingOrigin ? { origin: requestingOrigin } : undefined,\n )\n : new EndowmentPermissionDoesNotExistError(\n targetName,\n requestingOrigin,\n );\n\n if (!this.targetExists(targetName)) {\n throw failureError;\n }\n\n const specification = this.getPermissionSpecification(targetName);\n if (!hasSpecificationType(specification, permissionType)) {\n throw failureError;\n }\n\n return specification;\n }\n\n /**\n * Gets the implementation of the specified restricted method.\n *\n * A JSON-RPC error is thrown if the method does not exist.\n *\n * @see {@link PermissionController.executeRestrictedMethod} and\n * {@link PermissionController.createPermissionMiddleware} for internal usage.\n * @param method - The name of the restricted method.\n * @param origin - The origin associated with the request for the restricted\n * method, if any.\n * @returns The restricted method implementation.\n */\n getRestrictedMethod(\n method: string,\n origin?: string,\n ): RestrictedMethod {\n return this.getTypedPermissionSpecification(\n PermissionType.RestrictedMethod,\n method,\n origin,\n ).methodImplementation;\n }\n\n /**\n * Gets a list of all origins of subjects.\n *\n * @returns The origins (i.e. IDs) of all subjects.\n */\n getSubjectNames(): OriginString[] {\n return Object.keys(this.state.subjects);\n }\n\n /**\n * Gets the permission for the specified target of the subject corresponding\n * to the specified origin.\n *\n * @param origin - The origin of the subject.\n * @param targetName - The method name as invoked by a third party (i.e., not\n * a method key).\n * @returns The permission if it exists, or undefined otherwise.\n */\n getPermission<\n SubjectPermission extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >,\n >(\n origin: OriginString,\n targetName: SubjectPermission['parentCapability'],\n ): SubjectPermission | undefined {\n return this.state.subjects[origin]?.permissions[targetName] as\n | SubjectPermission\n | undefined;\n }\n\n /**\n * Gets all permissions for the specified subject, if any.\n *\n * @param origin - The origin of the subject.\n * @returns The permissions of the subject, if any.\n */\n getPermissions(\n origin: OriginString,\n ):\n | SubjectPermissions<\n ValidPermission>\n >\n | undefined {\n return this.state.subjects[origin]?.permissions;\n }\n\n /**\n * Checks whether the subject with the specified origin has the specified\n * permission.\n *\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @returns Whether the subject has the permission.\n */\n hasPermission(\n origin: OriginString,\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n ): boolean {\n return Boolean(this.getPermission(origin, target));\n }\n\n /**\n * Checks whether the subject with the specified origin has any permissions.\n * Use this if you want to know if a subject \"exists\".\n *\n * @param origin - The origin of the subject to check.\n * @returns Whether the subject has any permissions.\n */\n hasPermissions(origin: OriginString): boolean {\n return Boolean(this.state.subjects[origin]);\n }\n\n /**\n * Revokes all permissions from the specified origin.\n *\n * Throws an error of the origin has no permissions.\n *\n * @param origin - The origin whose permissions to revoke.\n */\n revokeAllPermissions(origin: OriginString): void {\n this.update((draftState) => {\n if (!draftState.subjects[origin]) {\n throw new UnrecognizedSubjectError(origin);\n }\n delete draftState.subjects[origin];\n });\n }\n\n /**\n * Revokes the specified permission from the subject with the specified\n * origin.\n *\n * Throws an error if the subject or the permission does not exist.\n *\n * @param origin - The origin of the subject whose permission to revoke.\n * @param target - The target name of the permission to revoke.\n */\n revokePermission(\n origin: OriginString,\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n ): void {\n this.revokePermissions({ [origin]: [target] });\n }\n\n /**\n * Revokes the specified permissions from the specified subjects.\n *\n * Throws an error if any of the subjects or permissions do not exist.\n *\n * @param subjectsAndPermissions - An object mapping subject origins\n * to arrays of permission target names to revoke.\n */\n revokePermissions(\n subjectsAndPermissions: Record<\n OriginString,\n NonEmptyArray<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability']\n >\n >,\n ): void {\n this.update((draftState) => {\n Object.keys(subjectsAndPermissions).forEach((origin) => {\n if (!hasProperty(draftState.subjects, origin)) {\n throw new UnrecognizedSubjectError(origin);\n }\n\n subjectsAndPermissions[origin].forEach((target) => {\n const { permissions } = draftState.subjects[origin];\n if (!hasProperty(permissions as Record, target)) {\n throw new PermissionDoesNotExistError(origin, target);\n }\n\n this.deletePermission(draftState.subjects, origin, target);\n });\n });\n });\n }\n\n /**\n * Revokes all permissions corresponding to the specified target for all subjects.\n * Does nothing if no subjects or no such permission exists.\n *\n * @param target - The name of the target to revoke all permissions for.\n */\n revokePermissionForAllSubjects(\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n ): void {\n if (this.getSubjectNames().length === 0) {\n return;\n }\n\n this.update((draftState) => {\n Object.entries(draftState.subjects).forEach(([origin, subject]) => {\n const { permissions } = subject;\n\n if (hasProperty(permissions as Record, target)) {\n this.deletePermission(draftState.subjects, origin, target);\n }\n });\n });\n }\n\n /**\n * Deletes the permission identified by the given origin and target. If the\n * permission is the single remaining permission of its subject, the subject\n * is also deleted.\n *\n * @param subjects - The draft permission controller subjects.\n * @param origin - The origin of the subject associated with the permission\n * to delete.\n * @param target - The target name of the permission to delete.\n */\n private deletePermission(\n subjects: Draft>,\n origin: OriginString,\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n ): void {\n const { permissions } = subjects[origin];\n if (Object.keys(permissions).length > 1) {\n delete permissions[target];\n } else {\n delete subjects[origin];\n }\n }\n\n /**\n * Checks whether the permission of the subject corresponding to the given\n * origin has a caveat of the specified type.\n *\n * Throws an error if the subject does not have a permission with the\n * specified target name.\n *\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to check for.\n * @returns Whether the permission has the specified caveat.\n */\n hasCaveat<\n TargetName extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n CaveatType extends\n ExtractAllowedCaveatTypes,\n >(origin: OriginString, target: TargetName, caveatType: CaveatType): boolean {\n return Boolean(this.getCaveat(origin, target, caveatType));\n }\n\n /**\n * Gets the caveat of the specified type, if any, for the permission of\n * the subject corresponding to the given origin.\n *\n * Throws an error if the subject does not have a permission with the\n * specified target name.\n *\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to get.\n * @returns The caveat, or `undefined` if no such caveat exists.\n */\n getCaveat<\n TargetName extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n CaveatType extends\n ExtractAllowedCaveatTypes,\n >(\n origin: OriginString,\n target: TargetName,\n caveatType: CaveatType,\n ): ExtractCaveat | undefined {\n const permission = this.getPermission(origin, target);\n if (!permission) {\n throw new PermissionDoesNotExistError(origin, target);\n }\n\n return findCaveat(permission, caveatType) as\n | ExtractCaveat\n | undefined;\n }\n\n /**\n * Adds a caveat of the specified type, with the specified caveat value, to\n * the permission corresponding to the given subject origin and permission\n * target.\n *\n * For modifying existing caveats, use\n * {@link PermissionController.updateCaveat}.\n *\n * Throws an error if no such permission exists, or if the caveat already\n * exists.\n *\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to add.\n * @param caveatValue - The value of the caveat to add.\n */\n addCaveat<\n TargetName extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n CaveatType extends\n ExtractAllowedCaveatTypes,\n >(\n origin: OriginString,\n target: TargetName,\n caveatType: CaveatType,\n caveatValue: ExtractCaveatValue,\n ): void {\n if (this.hasCaveat(origin, target, caveatType)) {\n throw new CaveatAlreadyExistsError(origin, target, caveatType);\n }\n\n this.setCaveat(origin, target, caveatType, caveatValue);\n }\n\n /**\n * Updates the value of the caveat of the specified type belonging to the\n * permission corresponding to the given subject origin and permission\n * target.\n *\n * For adding new caveats, use\n * {@link PermissionController.addCaveat}.\n *\n * Throws an error if no such permission or caveat exists.\n *\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to update.\n * @param caveatValue - The new value of the caveat.\n */\n updateCaveat<\n TargetName extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n CaveatType extends\n ExtractAllowedCaveatTypes,\n CaveatValue extends ExtractCaveatValue<\n ControllerCaveatSpecification,\n CaveatType\n >,\n >(\n origin: OriginString,\n target: TargetName,\n caveatType: CaveatType,\n caveatValue: CaveatValue,\n ): void {\n if (!this.hasCaveat(origin, target, caveatType)) {\n throw new CaveatDoesNotExistError(origin, target, caveatType);\n }\n\n this.setCaveat(origin, target, caveatType, caveatValue);\n }\n\n /**\n * Sets the specified caveat on the specified permission. Overwrites existing\n * caveats of the same type in-place (preserving array order), and adds the\n * caveat to the end of the array otherwise.\n *\n * Throws an error if the permission does not exist or fails to validate after\n * its caveats have been modified.\n *\n * @see {@link PermissionController.addCaveat}\n * @see {@link PermissionController.updateCaveat}\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to set.\n * @param caveatValue - The value of the caveat to set.\n */\n private setCaveat<\n TargetName extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n CaveatType extends\n ExtractAllowedCaveatTypes,\n >(\n origin: OriginString,\n target: TargetName,\n caveatType: CaveatType,\n caveatValue: ExtractCaveatValue,\n ): void {\n this.update((draftState) => {\n const subject = draftState.subjects[origin];\n\n // Unreachable because `hasCaveat` is always called before this, and it\n // throws if permissions are missing. TypeScript needs this, however.\n /* istanbul ignore if */\n if (!subject) {\n throw new UnrecognizedSubjectError(origin);\n }\n\n const permission = subject.permissions[target];\n\n /* istanbul ignore if: practically impossible, but TypeScript wants it */\n if (!permission) {\n throw new PermissionDoesNotExistError(origin, target);\n }\n\n const caveat = {\n type: caveatType,\n value: caveatValue,\n };\n this.validateCaveat(caveat, origin, target);\n\n let addedCaveat = false;\n if (permission.caveats) {\n const caveatIndex = permission.caveats.findIndex(\n (existingCaveat) => existingCaveat.type === caveat.type,\n );\n\n if (caveatIndex === -1) {\n permission.caveats.push(caveat);\n addedCaveat = true;\n } else {\n permission.caveats.splice(caveatIndex, 1, caveat);\n }\n } else {\n // At this point, we don't know if the specific permission is allowed\n // to have caveats, but it should be impossible to call this method\n // for a permission that may not have any caveats. If all else fails,\n // the permission validator is also called.\n // @ts-expect-error See above comment\n permission.caveats = [caveat];\n addedCaveat = true;\n }\n\n // Mutating a caveat does not warrant permission validation, but mutating\n // the caveat array does.\n if (addedCaveat) {\n this.validateModifiedPermission(permission, origin, {\n invokePermissionValidator: true,\n performCaveatValidation: false, // We just validated the caveat\n });\n }\n });\n }\n\n /**\n * Updates all caveats with the specified type for all subjects and\n * permissions by applying the specified mutator function to them.\n *\n * ATTN: Permissions can be revoked entirely by the action of this method,\n * read on for details.\n *\n * Caveat mutators are functions that receive a caveat value and return a\n * tuple consisting of a {@link CaveatMutatorOperation} and, optionally, a new\n * value to update the existing caveat with.\n *\n * For each caveat, depending on the mutator result, this method will:\n * - Do nothing ({@link CaveatMutatorOperation.Noop})\n * - Update the value of the caveat ({@link CaveatMutatorOperation.UpdateValue}). The caveat specification validator, if any, will be called after updating the value.\n * - Delete the caveat ({@link CaveatMutatorOperation.DeleteCaveat}). The permission specification validator, if any, will be called after deleting the caveat.\n * - Revoke the parent permission ({@link CaveatMutatorOperation.RevokePermission})\n *\n * This method throws if the validation of any caveat or permission fails.\n *\n * @param targetCaveatType - The type of the caveats to update.\n * @param mutator - The mutator function which will be applied to all caveat\n * values.\n */\n updatePermissionsByCaveat<\n CaveatType extends ExtractCaveats['type'],\n TargetCaveat extends ExtractCaveat<\n ControllerCaveatSpecification,\n CaveatType\n >,\n >(targetCaveatType: CaveatType, mutator: CaveatMutator): void {\n if (Object.keys(this.state.subjects).length === 0) {\n return;\n }\n\n this.update((draftState) => {\n Object.values(draftState.subjects).forEach((subject) => {\n Object.values(subject.permissions).forEach((permission) => {\n const { caveats } = permission;\n const targetCaveat = caveats?.find(\n ({ type }) => type === targetCaveatType,\n );\n if (!targetCaveat) {\n return;\n }\n\n // The mutator may modify the caveat value in place, and must always\n // return a valid mutation result.\n const mutatorResult = mutator(targetCaveat.value);\n const { operation } = mutatorResult;\n switch (operation) {\n case CaveatMutatorOperation.Noop:\n break;\n\n case CaveatMutatorOperation.UpdateValue:\n // Typecast: `Mutable` is used here to assign to a readonly\n // property. `targetConstraint` should already be mutable because\n // it's part of a draft, but for some reason it's not. We can't\n // use the more-correct `Draft` type here either because it\n // results in an error.\n (targetCaveat as Mutable).value =\n mutatorResult.value;\n\n this.validateCaveat(\n targetCaveat,\n subject.origin,\n permission.parentCapability,\n );\n break;\n\n case CaveatMutatorOperation.DeleteCaveat:\n this.deleteCaveat(permission, targetCaveatType, subject.origin);\n break;\n\n case CaveatMutatorOperation.RevokePermission:\n this.deletePermission(\n draftState.subjects,\n subject.origin,\n permission.parentCapability,\n );\n break;\n\n default: {\n // Overriding as `never` is the expected result of exhaustiveness checking,\n // and is intended to represent unchecked exception cases.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n throw new Error(`Unrecognized mutation result: \"${operation}\"`);\n }\n }\n });\n });\n });\n }\n\n /**\n * Removes the caveat of the specified type from the permission corresponding\n * to the given subject origin and target name.\n *\n * Throws an error if no such permission or caveat exists.\n *\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to remove.\n */\n removeCaveat<\n TargetName extends ControllerPermissionSpecification['targetName'],\n CaveatType extends\n ExtractAllowedCaveatTypes,\n >(origin: OriginString, target: TargetName, caveatType: CaveatType): void {\n this.update((draftState) => {\n const permission = draftState.subjects[origin]?.permissions[target];\n if (!permission) {\n throw new PermissionDoesNotExistError(origin, target);\n }\n\n if (!permission.caveats) {\n throw new CaveatDoesNotExistError(origin, target, caveatType);\n }\n\n this.deleteCaveat(permission, caveatType, origin);\n });\n }\n\n /**\n * Deletes the specified caveat from the specified permission. If no caveats\n * remain after deletion, the permission's caveat property is set to `null`.\n * The permission is validated after being modified.\n *\n * Throws an error if the permission does not have a caveat with the specified\n * type.\n *\n * @param permission - The permission whose caveat to delete.\n * @param caveatType - The type of the caveat to delete.\n * @param origin - The origin the permission subject.\n */\n private deleteCaveat<\n CaveatType extends ExtractCaveats['type'],\n >(\n permission: Draft,\n caveatType: CaveatType,\n origin: OriginString,\n ): void {\n /* istanbul ignore if: not possible in our usage */\n if (!permission.caveats) {\n throw new CaveatDoesNotExistError(\n origin,\n permission.parentCapability,\n caveatType,\n );\n }\n\n const caveatIndex = permission.caveats.findIndex(\n (existingCaveat) => existingCaveat.type === caveatType,\n );\n\n if (caveatIndex === -1) {\n throw new CaveatDoesNotExistError(\n origin,\n permission.parentCapability,\n caveatType,\n );\n }\n\n if (permission.caveats.length === 1) {\n permission.caveats = null;\n } else {\n permission.caveats.splice(caveatIndex, 1);\n }\n\n this.validateModifiedPermission(permission, origin, {\n invokePermissionValidator: true,\n performCaveatValidation: false, // No caveat object was mutated\n });\n }\n\n /**\n * Validates the specified modified permission. Should **always** be invoked\n * on a permission when its caveat array has been mutated.\n *\n * Just like {@link PermissionController.validatePermission}, except that the\n * corresponding target name and specification are retrieved first, and an\n * error is thrown if the target name does not exist.\n *\n * @param permission - The modified permission to validate.\n * @param origin - The origin associated with the permission.\n * @param validationFlags - Validation flags. See {@link PermissionController.validatePermission}.\n */\n private validateModifiedPermission(\n permission: Draft,\n origin: OriginString,\n validationFlags: PermissionValidationFlags,\n ): void {\n /* istanbul ignore if: this should be impossible */\n if (!this.targetExists(permission.parentCapability)) {\n throw new Error(\n `Fatal: Existing permission target \"${permission.parentCapability}\" has no specification.`,\n );\n }\n\n this.validatePermission(\n this.getPermissionSpecification(permission.parentCapability),\n permission as PermissionConstraint,\n origin,\n validationFlags,\n );\n }\n\n /**\n * Verifies the existence the specified permission target, i.e. whether it has\n * a specification.\n *\n * @param target - The requested permission target.\n * @returns Whether the permission target exists.\n */\n private targetExists(\n target: string,\n ): target is ControllerPermissionSpecification['targetName'] {\n return hasProperty(this._permissionSpecifications, target);\n }\n\n /**\n * Grants _approved_ permissions to the specified subject. Every permission and\n * caveat is stringently validated—including by calling their specification\n * validators—and an error is thrown if validation fails.\n *\n * ATTN: This method does **not** prompt the user for approval. User consent must\n * first be obtained through some other means.\n *\n * @see {@link PermissionController.requestPermissions} For initiating a\n * permissions request requiring user approval.\n * @param options - Options bag.\n * @param options.approvedPermissions - The requested permissions approved by\n * the user.\n * @param options.requestData - Permission request data. Passed to permission\n * factory functions.\n * @param options.preserveExistingPermissions - Whether to preserve the\n * subject's existing permissions.\n * @param options.subject - The subject to grant permissions to.\n * @returns The subject's new permission state. It may or may not have changed.\n */\n grantPermissions({\n approvedPermissions,\n requestData,\n preserveExistingPermissions = true,\n subject,\n }: {\n approvedPermissions: RequestedPermissions;\n subject: PermissionSubjectMetadata;\n preserveExistingPermissions?: boolean;\n requestData?: Record;\n }): Partial<\n SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n > {\n return this.#applyGrantedPermissions({\n approvedPermissions,\n subject,\n mergePermissions: false,\n preserveExistingPermissions,\n requestData,\n });\n }\n\n /**\n * Incrementally grants _approved_ permissions to the specified subject. Every\n * permission and caveat is stringently validated—including by calling their\n * specification validators—and an error is thrown if validation fails.\n *\n * ATTN: This method does **not** prompt the user for approval. User consent must\n * first be obtained through some other means.\n *\n * @see {@link PermissionController.requestPermissionsIncremental} For initiating\n * an incremental permissions request requiring user approval.\n * @param options - Options bag.\n * @param options.approvedPermissions - The requested permissions approved by\n * the user.\n * @param options.requestData - Permission request data. Passed to permission\n * factory functions.\n * @param options.subject - The subject to grant permissions to.\n * @returns The subject's new permission state. It may or may not have changed.\n */\n grantPermissionsIncremental({\n approvedPermissions,\n requestData,\n subject,\n }: {\n approvedPermissions: RequestedPermissions;\n subject: PermissionSubjectMetadata;\n requestData?: Record;\n }): Partial<\n SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n > {\n return this.#applyGrantedPermissions({\n approvedPermissions,\n subject,\n mergePermissions: true,\n preserveExistingPermissions: true,\n requestData,\n });\n }\n\n #applyGrantedPermissions({\n approvedPermissions,\n subject,\n mergePermissions,\n preserveExistingPermissions,\n requestData,\n }: {\n approvedPermissions: RequestedPermissions;\n subject: PermissionSubjectMetadata;\n mergePermissions: boolean;\n preserveExistingPermissions: boolean;\n requestData?: Record;\n }): Partial<\n SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n > {\n const { origin } = subject;\n\n if (!origin || typeof origin !== 'string') {\n throw new InvalidSubjectIdentifierError(origin);\n }\n\n const permissions = (\n preserveExistingPermissions\n ? {\n ...this.getPermissions(origin),\n }\n : {}\n ) as SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >;\n\n for (const [requestedTarget, approvedPermission] of Object.entries(\n approvedPermissions,\n )) {\n if (!this.targetExists(requestedTarget)) {\n throw methodNotFound(requestedTarget);\n }\n\n if (\n approvedPermission.parentCapability !== undefined &&\n requestedTarget !== approvedPermission.parentCapability\n ) {\n throw new InvalidApprovedPermissionError(\n origin,\n requestedTarget,\n approvedPermission,\n );\n }\n\n // We have verified that the target exists, and reassign it to change its\n // type.\n const targetName = requestedTarget as ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'];\n const specification = this.getPermissionSpecification(targetName);\n\n // The requested caveats are validated here.\n const caveats = this.constructCaveats(\n origin,\n targetName,\n approvedPermission.caveats,\n );\n\n const permissionOptions = {\n caveats,\n invoker: origin,\n target: targetName,\n };\n\n let permission: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >;\n if (specification.factory) {\n permission = specification.factory(permissionOptions, requestData);\n } else {\n permission = constructPermission(permissionOptions);\n }\n\n if (mergePermissions) {\n permission = this.#mergePermission(\n permissions[targetName],\n permission,\n )[0];\n }\n\n this.validatePermission(specification, permission, origin, {\n invokePermissionValidator: true,\n performCaveatValidation: true,\n });\n permissions[targetName] = permission;\n }\n\n this.setValidatedPermissions(origin, permissions);\n return permissions;\n }\n\n /**\n * Validates the specified permission by:\n * - Ensuring that if `subjectTypes` is specified, the subject requesting the permission is of a type in the list.\n * - Ensuring that its `caveats` property is either `null` or a non-empty array.\n * - Ensuring that it only includes caveats allowed by its specification.\n * - Ensuring that it includes no duplicate caveats (by caveat type).\n * - Validating each caveat object, if `performCaveatValidation` is `true`.\n * - Calling the validator of its specification, if one exists and `invokePermissionValidator` is `true`.\n *\n * An error is thrown if validation fails.\n *\n * @param specification - The specification of the permission.\n * @param permission - The permission to validate.\n * @param origin - The origin associated with the permission.\n * @param validationOptions - Validation options.\n * @param validationOptions.invokePermissionValidator - Whether to invoke the\n * permission's consumer-specified validator function, if any.\n * @param validationOptions.performCaveatValidation - Whether to invoke\n * {@link PermissionController.validateCaveat} on each of the permission's\n * caveats.\n */\n private validatePermission(\n specification: PermissionSpecificationConstraint,\n permission: PermissionConstraint,\n origin: OriginString,\n {\n invokePermissionValidator,\n performCaveatValidation,\n }: PermissionValidationFlags,\n ): void {\n const { allowedCaveats, validator, targetName } = specification;\n\n if (\n specification.subjectTypes?.length &&\n specification.subjectTypes.length > 0\n ) {\n const metadata = this.messenger.call(\n 'SubjectMetadataController:getSubjectMetadata',\n origin,\n );\n\n if (\n !metadata ||\n metadata.subjectType === null ||\n !specification.subjectTypes.includes(metadata.subjectType)\n ) {\n throw specification.permissionType === PermissionType.RestrictedMethod\n ? methodNotFound(targetName, { origin })\n : new EndowmentPermissionDoesNotExistError(targetName, origin);\n }\n }\n\n if (hasProperty(permission, 'caveats')) {\n const { caveats } = permission;\n\n if (caveats !== null && !(Array.isArray(caveats) && caveats.length > 0)) {\n throw new InvalidCaveatsPropertyError(origin, targetName, caveats);\n }\n\n const seenCaveatTypes = new Set();\n caveats?.forEach((caveat) => {\n if (performCaveatValidation) {\n this.validateCaveat(caveat, origin, targetName);\n }\n\n if (!allowedCaveats?.includes(caveat.type)) {\n throw new ForbiddenCaveatError(caveat.type, origin, targetName);\n }\n\n if (seenCaveatTypes.has(caveat.type)) {\n throw new DuplicateCaveatError(caveat.type, origin, targetName);\n }\n seenCaveatTypes.add(caveat.type);\n });\n }\n\n if (invokePermissionValidator && validator) {\n validator(permission, origin, targetName);\n }\n }\n\n /**\n * Assigns the specified permissions to the subject with the given origin.\n * Overwrites all existing permissions, and creates a subject entry if it\n * doesn't already exist.\n *\n * ATTN: Assumes that the new permissions have been validated.\n *\n * @param origin - The origin of the grantee subject.\n * @param permissions - The new permissions for the grantee subject.\n */\n private setValidatedPermissions(\n origin: OriginString,\n permissions: Record<\n string,\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >,\n ): void {\n this.update((draftState) => {\n if (!draftState.subjects[origin]) {\n draftState.subjects[origin] = { origin, permissions: {} };\n }\n\n draftState.subjects[origin].permissions = castDraft(permissions);\n });\n }\n\n /**\n * Validates the requested caveats for the permission of the specified\n * subject origin and target name and returns the validated caveat array.\n *\n * Throws an error if validation fails.\n *\n * @param origin - The origin of the permission subject.\n * @param target - The permission target name.\n * @param requestedCaveats - The requested caveats to construct.\n * @returns The constructed caveats.\n */\n private constructCaveats(\n origin: OriginString,\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n requestedCaveats?: unknown[] | null,\n ): NonEmptyArray> | undefined {\n const caveatArray = requestedCaveats?.map((requestedCaveat) => {\n this.validateCaveat(requestedCaveat, origin, target);\n\n // Reassign so that we have a fresh object.\n const { type, value } = requestedCaveat as CaveatConstraint;\n return { type, value } as ExtractCaveats;\n });\n\n return caveatArray && isNonEmptyArray(caveatArray)\n ? caveatArray\n : undefined;\n }\n\n /**\n * This methods validates that the specified caveat is an object with the\n * expected properties and types. It also ensures that a caveat specification\n * exists for the requested caveat type, and calls the specification\n * validator, if it exists, on the caveat object.\n *\n * Throws an error if validation fails.\n *\n * @param caveat - The caveat object to validate.\n * @param origin - The origin associated with the subject of the parent\n * permission.\n * @param target - The target name associated with the parent permission.\n */\n private validateCaveat(\n caveat: unknown,\n origin: OriginString,\n target: string,\n ): void {\n if (!isPlainObject(caveat)) {\n throw new InvalidCaveatError(caveat, origin, target);\n }\n\n if (Object.keys(caveat).length !== 2) {\n throw new InvalidCaveatFieldsError(caveat, origin, target);\n }\n\n if (typeof caveat.type !== 'string') {\n throw new InvalidCaveatTypeError(caveat, origin, target);\n }\n\n const specification = this.getCaveatSpecification(caveat.type);\n if (!specification) {\n throw new UnrecognizedCaveatTypeError(caveat.type, origin, target);\n }\n\n if (!hasProperty(caveat, 'value') || caveat.value === undefined) {\n throw new CaveatMissingValueError(caveat, origin, target);\n }\n\n if (!isValidJson(caveat.value)) {\n throw new CaveatInvalidJsonError(caveat, origin, target);\n }\n\n // Typecast: TypeScript still believes that the caveat is a PlainObject.\n specification.validator?.(caveat as CaveatConstraint, origin, target);\n }\n\n /**\n * Initiates a permission request that requires user approval.\n *\n * Either this or {@link PermissionController.requestPermissionsIncremental}\n * should always be used to grant additional permissions to a subject,\n * unless user approval has been obtained through some other means.\n *\n * Permissions are validated at every step of the approval process, and this\n * method will reject if validation fails.\n *\n * @see {@link ApprovalController} For the user approval logic.\n * @see {@link PermissionController.acceptPermissionsRequest} For the method\n * that _accepts_ the request and resolves the user approval promise.\n * @see {@link PermissionController.rejectPermissionsRequest} For the method\n * that _rejects_ the request and the user approval promise.\n * @param subject - The grantee subject.\n * @param requestedPermissions - The requested permissions.\n * @param options - Additional options.\n * @param options.id - The id of the permissions request. Defaults to a unique\n * id.\n * @param options.preserveExistingPermissions - Whether to preserve the\n * subject's existing permissions. Defaults to `true`.\n * @param options.metadata - Additional metadata about the permission request.\n * @returns The granted permissions and request metadata.\n */\n async requestPermissions(\n subject: PermissionSubjectMetadata,\n requestedPermissions: RequestedPermissions,\n options: {\n id?: string;\n preserveExistingPermissions?: boolean;\n metadata?: Record;\n } = {},\n ): Promise<\n [\n Partial<\n SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n >,\n ApprovedPermissionsMetadata,\n ]\n > {\n const { origin } = subject;\n const { id = nanoid(), preserveExistingPermissions = true } = options;\n this.validateRequestedPermissions(origin, requestedPermissions);\n\n const metadata = {\n ...options.metadata,\n id,\n origin,\n };\n\n const permissionsRequest: PermissionsRequest = {\n metadata,\n permissions: requestedPermissions,\n };\n\n const approvedRequest = await this.requestUserApproval(permissionsRequest);\n return await this.#handleApprovedPermissions({\n subject,\n metadata,\n preserveExistingPermissions,\n approvedRequest,\n });\n }\n\n /**\n * Initiates an incremental permission request that prompts for user approval.\n * Incremental permission requests allow the caller to replace existing and/or\n * add brand new permissions and caveats for the specified subject.\n *\n * Incremental permission request are merged with the subject's existing permissions\n * through a right-biased union, where the incremental permission are the right-hand\n * side of the merger. If both sides of the merger specify the same caveats for a\n * given permission, the caveats are merged using their specification's caveat value\n * merger property.\n *\n * Either this or {@link PermissionController.requestPermissions} should\n * always be used to grant additional permissions to a subject, unless user\n * approval has been obtained through some other means.\n *\n * Permissions are validated at every step of the approval process, and this\n * method will reject if validation fails.\n *\n * @see {@link ApprovalController} For the user approval logic.\n * @see {@link PermissionController.acceptPermissionsRequest} For the method\n * that _accepts_ the request and resolves the user approval promise.\n * @see {@link PermissionController.rejectPermissionsRequest} For the method\n * that _rejects_ the request and the user approval promise.\n * @param subject - The grantee subject.\n * @param requestedPermissions - The requested permissions.\n * @param options - Additional options.\n * @param options.id - The id of the permissions request. Defaults to a unique\n * id.\n * @param options.metadata - Additional metadata about the permission request.\n * @returns The granted permissions and request metadata.\n */\n async requestPermissionsIncremental(\n subject: PermissionSubjectMetadata,\n requestedPermissions: RequestedPermissions,\n options: {\n id?: string;\n metadata?: Record;\n } = {},\n ): Promise<\n | [\n Partial<\n SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n >,\n ApprovedPermissionsMetadata,\n ]\n | []\n > {\n const { origin } = subject;\n const { id = nanoid() } = options;\n this.validateRequestedPermissions(origin, requestedPermissions);\n\n const currentPermissions = this.getPermissions(origin) ?? {};\n const [newPermissions, permissionDiffMap] =\n this.#mergeIncrementalPermissions(\n currentPermissions,\n requestedPermissions,\n );\n\n // The second undefined check is just for type narrowing purposes. These values\n // will always be jointly defined or undefined.\n if (newPermissions === undefined || permissionDiffMap === undefined) {\n return [];\n }\n\n try {\n // It does not spark joy to run this validation again after the merger operation.\n // But, optimizing this procedure is probably not worth it, especially considering\n // that the worst-case scenario for validation degrades to the below function call.\n this.validateRequestedPermissions(origin, newPermissions);\n } catch (error) {\n if (error instanceof Error) {\n throw new InvalidMergedPermissionsError(\n origin,\n error,\n permissionDiffMap,\n );\n }\n /* istanbul ignore next: This should be impossible */\n throw internalError('Unrecognized error type', { error });\n }\n\n const metadata = {\n ...options.metadata,\n id,\n origin,\n };\n\n const permissionsRequest: PermissionsRequest = {\n metadata,\n permissions: newPermissions,\n diff: {\n currentPermissions,\n permissionDiffMap,\n },\n };\n\n const approvedRequest = await this.requestUserApproval(permissionsRequest);\n return await this.#handleApprovedPermissions({\n subject,\n metadata,\n preserveExistingPermissions: false,\n approvedRequest,\n });\n }\n\n /**\n * Validates requested permissions. Throws if validation fails.\n *\n * This method ensures that the requested permissions are a properly\n * formatted {@link RequestedPermissions} object, and performs the same\n * validation as {@link PermissionController.grantPermissions}, except that\n * consumer-specified permission validator functions are not called, since\n * they are only called on fully constructed, approved permissions that are\n * otherwise completely valid.\n *\n * Unrecognzied properties on requested permissions are ignored.\n *\n * @param origin - The origin of the grantee subject.\n * @param requestedPermissions - The requested permissions.\n */\n private validateRequestedPermissions(\n origin: OriginString,\n requestedPermissions: unknown,\n ): void {\n if (!isPlainObject(requestedPermissions)) {\n throw invalidParams({\n message: `Requested permissions for origin \"${origin}\" is not a plain object.`,\n data: { origin, requestedPermissions },\n });\n }\n\n if (Object.keys(requestedPermissions).length === 0) {\n throw invalidParams({\n message: `Permissions request for origin \"${origin}\" contains no permissions.`,\n data: { requestedPermissions },\n });\n }\n\n for (const targetName of Object.keys(requestedPermissions)) {\n const permission = requestedPermissions[targetName];\n\n if (!this.targetExists(targetName)) {\n throw methodNotFound(targetName, { origin, requestedPermissions });\n }\n\n if (\n !isPlainObject(permission) ||\n (permission.parentCapability !== undefined &&\n targetName !== permission.parentCapability)\n ) {\n throw invalidParams({\n message: `Permissions request for origin \"${origin}\" contains invalid requested permission(s).`,\n data: { origin, requestedPermissions },\n });\n }\n\n // Here we validate the permission without invoking its validator, if any.\n // The validator will be invoked after the permission has been approved.\n this.validatePermission(\n this.getPermissionSpecification(targetName),\n // Typecast: The permission is still a \"PlainObject\" here.\n permission as PermissionConstraint,\n origin,\n { invokePermissionValidator: false, performCaveatValidation: true },\n );\n }\n }\n\n /**\n * Merges a set of incrementally requested permissions into the existing permissions of\n * the requesting subject. The merge is a right-biased union, where the existing\n * permissions are the left-hand side, and the incrementally requested permissions are\n * the right-hand side.\n *\n * @param existingPermissions - The subject's existing permissions.\n * @param incrementalRequestedPermissions - The requested permissions to merge.\n * @returns The merged permissions and the resulting diff.\n */\n #mergeIncrementalPermissions(\n existingPermissions: Exclude<\n ReturnType,\n undefined\n >,\n incrementalRequestedPermissions: RequestedPermissions,\n ):\n | [\n SubjectPermissions<\n ValidPermission>\n >,\n PermissionDiffMap,\n ]\n | [] {\n const permissionDiffMap: PermissionDiffMap = {};\n\n // Use immer's produce as a convenience for calculating the new permissions\n // without mutating the existing permissions or committing the results to state.\n const newPermissions = immerProduce(\n existingPermissions,\n (draftExistingPermissions) => {\n const leftPermissions =\n draftExistingPermissions as RequestedPermissions;\n\n Object.entries(incrementalRequestedPermissions).forEach(\n ([targetName, rightPermission]) => {\n const leftPermission: Partial | undefined =\n leftPermissions[targetName];\n\n const [newPermission, caveatsDiff] = this.#mergePermission(\n leftPermission ?? {},\n rightPermission,\n );\n\n if (\n leftPermission === undefined ||\n Object.keys(caveatsDiff).length > 0\n ) {\n leftPermissions[targetName] = newPermission;\n permissionDiffMap[targetName] = caveatsDiff;\n }\n // Otherwise, leave the left permission as-is; its authority has\n // not changed.\n },\n );\n },\n );\n\n if (Object.keys(permissionDiffMap).length === 0) {\n return [];\n }\n return [newPermissions, permissionDiffMap];\n }\n\n /**\n * Performs a right-biased union between two permissions. The task of merging caveats\n * of the same type between the two permissions is delegated to the corresponding\n * caveat type's merger implementation.\n *\n * Throws if the left-hand and right-hand permissions both have a caveat whose\n * specification does not provide a caveat value merger function.\n *\n * @param leftPermission - The left-hand permission to merge.\n * @param rightPermission - The right-hand permission to merge.\n * @returns The merged permission.\n */\n #mergePermission<\n PermissionType extends Partial | PermissionConstraint,\n >(\n leftPermission: PermissionType | undefined,\n rightPermission: PermissionType,\n ): [PermissionType, CaveatDiffMap] {\n const { caveatPairs, leftUniqueCaveats, rightUniqueCaveats } =\n collectUniqueAndPairedCaveats(leftPermission, rightPermission);\n\n const [mergedCaveats, caveatDiffMap] = caveatPairs.reduce(\n ([caveats, diffMap], [leftCaveat, rightCaveat]) => {\n const [newCaveat, diff] = this.#mergeCaveat(leftCaveat, rightCaveat);\n\n if (newCaveat !== undefined && diff !== undefined) {\n caveats.push(newCaveat);\n diffMap[newCaveat.type] = diff;\n } else {\n caveats.push(leftCaveat);\n }\n\n return [caveats, diffMap];\n },\n [[], {}] as [CaveatConstraint[], CaveatDiffMap],\n );\n\n const mergedRightUniqueCaveats = rightUniqueCaveats.map((caveat) => {\n const [newCaveat, diff] = this.#mergeCaveat(undefined, caveat);\n\n caveatDiffMap[newCaveat.type] = diff;\n return newCaveat;\n });\n\n const allCaveats = [\n ...mergedCaveats,\n ...leftUniqueCaveats,\n ...mergedRightUniqueCaveats,\n ];\n\n const newPermission = {\n ...leftPermission,\n ...rightPermission,\n ...(allCaveats.length > 0\n ? { caveats: allCaveats as NonEmptyArray }\n : {}),\n };\n\n return [newPermission, caveatDiffMap];\n }\n\n /**\n * Merges two caveats of the same type. The task of merging the values of the\n * two caveats is delegated to the corresponding caveat type's merger implementation.\n *\n * @param leftCaveat - The left-hand caveat to merge.\n * @param rightCaveat - The right-hand caveat to merge.\n * @returns The merged caveat and the diff between the two caveats.\n */\n #mergeCaveat<\n RightCaveat extends CaveatConstraint,\n LeftCaveat extends RightCaveat | undefined,\n >(\n leftCaveat: LeftCaveat,\n rightCaveat: RightCaveat,\n ): MergeCaveatResult {\n /* istanbul ignore if: This should be impossible */\n if (leftCaveat !== undefined && leftCaveat.type !== rightCaveat.type) {\n throw new CaveatMergeTypeMismatchError(leftCaveat.type, rightCaveat.type);\n }\n\n const merger = this.#expectGetCaveatMerger(rightCaveat.type);\n\n if (leftCaveat === undefined) {\n return [\n {\n ...rightCaveat,\n },\n rightCaveat.value,\n ];\n }\n\n const [newValue, diff] = merger(leftCaveat.value, rightCaveat.value);\n\n return newValue !== undefined && diff !== undefined\n ? [\n {\n type: rightCaveat.type,\n value: newValue,\n },\n diff,\n ]\n : ([] as MergeCaveatResult);\n }\n\n /**\n * Adds a request to the {@link ApprovalController} using the\n * {@link AddApprovalRequest} action. Also validates the resulting approved\n * permissions request, and throws an error if validation fails.\n *\n * @param permissionsRequest - The permissions request object.\n * @returns The approved permissions request object.\n */\n private async requestUserApproval(permissionsRequest: PermissionsRequest) {\n const { origin, id } = permissionsRequest.metadata;\n const approvedRequest = await this.messenger.call(\n 'ApprovalController:addRequest',\n {\n id,\n origin,\n requestData: permissionsRequest,\n type: MethodNames.RequestPermissions,\n },\n true,\n );\n\n this.validateApprovedPermissions(approvedRequest, { id, origin });\n return approvedRequest as PermissionsRequest;\n }\n\n /**\n * Accepts a permissions request that has been approved by the user. This\n * method should be called after the user has approved the request and the\n * {@link ApprovalController} has resolved the user approval promise.\n *\n * @param options - Options bag.\n * @param options.subject - The subject to grant permissions to.\n * @param options.metadata - The metadata of the approved permissions request.\n * @param options.preserveExistingPermissions - Whether to preserve the\n * subject's existing permissions.\n * @param options.approvedRequest - The approved permissions request to handle.\n * @returns The granted permissions and request metadata.\n */\n async #handleApprovedPermissions({\n subject,\n metadata,\n preserveExistingPermissions,\n approvedRequest,\n }: {\n subject: PermissionSubjectMetadata;\n metadata: PermissionsRequest['metadata'];\n preserveExistingPermissions: boolean;\n approvedRequest: PermissionsRequest;\n }): Promise<\n [ReturnType, ApprovedPermissionsMetadata]\n > {\n const { permissions: approvedPermissions, ...requestData } =\n approvedRequest;\n const approvedMetadata: ApprovedPermissionsMetadata = { ...metadata };\n\n const sideEffects = this.getSideEffects(approvedPermissions);\n if (Object.values(sideEffects.permittedHandlers).length > 0) {\n const sideEffectsData = await this.executeSideEffects(\n sideEffects,\n approvedRequest,\n );\n\n approvedMetadata.data = Object.keys(sideEffects.permittedHandlers).reduce(\n (acc, permission, i) => ({ [permission]: sideEffectsData[i], ...acc }),\n {},\n );\n }\n\n return [\n this.grantPermissions({\n subject,\n approvedPermissions,\n preserveExistingPermissions,\n requestData,\n }),\n approvedMetadata,\n ];\n }\n\n /**\n * Reunites all the side-effects (onPermitted and onFailure) of the requested permissions inside a record of arrays.\n *\n * @param permissions - The approved permissions.\n * @returns The {@link SideEffects} object containing the handlers arrays.\n */\n private getSideEffects(permissions: RequestedPermissions) {\n return Object.keys(permissions).reduce(\n (sideEffectList, targetName) => {\n if (this.targetExists(targetName)) {\n const specification = this.getPermissionSpecification(targetName);\n\n if (specification.sideEffect) {\n sideEffectList.permittedHandlers[targetName] =\n specification.sideEffect.onPermitted;\n\n if (specification.sideEffect.onFailure) {\n sideEffectList.failureHandlers[targetName] =\n specification.sideEffect.onFailure;\n }\n }\n }\n return sideEffectList;\n },\n { permittedHandlers: {}, failureHandlers: {} },\n );\n }\n\n /**\n * Executes the side-effects of the approved permissions while handling the errors if any.\n * It will pass an instance of the {@link messenger} and the request data associated with the permission request to the handlers through its params.\n *\n * @param sideEffects - the side-effect record created by {@link getSideEffects}\n * @param requestData - the permissions requestData.\n * @returns the value returned by all the `onPermitted` handlers in an array.\n */\n private async executeSideEffects(\n sideEffects: SideEffects,\n requestData: PermissionsRequest,\n ) {\n const { permittedHandlers, failureHandlers } = sideEffects;\n const params = {\n requestData,\n messenger: this.messenger,\n };\n\n const promiseResults = await Promise.allSettled(\n Object.values(permittedHandlers).map((permittedHandler) =>\n permittedHandler(params),\n ),\n );\n\n // lib.es2020.promise.d.ts does not export its types so we're using a simple type.\n const rejectedHandlers = promiseResults.filter(\n (promise) => promise.status === 'rejected',\n ) as { status: 'rejected'; reason: Error }[];\n\n if (rejectedHandlers.length > 0) {\n const failureHandlersList = Object.values(failureHandlers);\n if (failureHandlersList.length > 0) {\n try {\n await Promise.all(\n failureHandlersList.map((failureHandler) => failureHandler(params)),\n );\n } catch (error) {\n throw internalError('Unexpected error in side-effects', { error });\n }\n }\n const reasons = rejectedHandlers.map((handler) => handler.reason);\n\n reasons.forEach((reason) => {\n console.error(reason);\n });\n\n throw reasons.length > 1\n ? internalError(\n 'Multiple errors occurred during side-effects execution',\n { errors: reasons },\n )\n : reasons[0];\n }\n\n // lib.es2020.promise.d.ts does not export its types so we're using a simple type.\n return (promiseResults as { status: 'fulfilled'; value: unknown }[]).map(\n ({ value }) => value,\n );\n }\n\n /**\n * Validates an approved {@link PermissionsRequest} object. The approved\n * request must have the required `metadata` and `permissions` properties,\n * the `id` and `origin` of the `metadata` must match the original request\n * metadata, and the requested permissions must be valid per\n * {@link PermissionController.validateRequestedPermissions}. Any extra\n * metadata properties are ignored.\n *\n * An error is thrown if validation fails.\n *\n * @param approvedRequest - The approved permissions request object.\n * @param originalMetadata - The original request metadata.\n */\n private validateApprovedPermissions(\n approvedRequest: unknown,\n originalMetadata: PermissionsRequestMetadata,\n ) {\n const { id, origin } = originalMetadata;\n\n if (\n !isPlainObject(approvedRequest) ||\n !isPlainObject(approvedRequest.metadata)\n ) {\n throw internalError(\n `Approved permissions request for subject \"${origin}\" is invalid.`,\n { data: { approvedRequest } },\n );\n }\n\n const {\n metadata: { id: newId, origin: newOrigin },\n permissions,\n } = approvedRequest;\n\n if (newId !== id) {\n throw internalError(\n `Approved permissions request for subject \"${origin}\" mutated its id.`,\n { originalId: id, mutatedId: newId },\n );\n }\n\n if (newOrigin !== origin) {\n throw internalError(\n `Approved permissions request for subject \"${origin}\" mutated its origin.`,\n { originalOrigin: origin, mutatedOrigin: newOrigin },\n );\n }\n\n try {\n this.validateRequestedPermissions(origin, permissions);\n } catch (error) {\n if (error instanceof Error) {\n // Re-throw as an internal error; we should never receive invalid approved\n // permissions.\n throw internalError(\n `Invalid approved permissions request: ${error.message}`,\n error instanceof JsonRpcError ? error.data : undefined,\n );\n }\n /* istanbul ignore next: This should be impossible */\n throw internalError('Unrecognized error type', { error });\n }\n }\n\n /**\n * Accepts a permissions request created by\n * {@link PermissionController.requestPermissions}.\n *\n * @param request - The permissions request.\n */\n async acceptPermissionsRequest(request: PermissionsRequest): Promise {\n const { id } = request.metadata;\n\n if (!this.hasApprovalRequest({ id })) {\n throw new PermissionsRequestNotFoundError(id);\n }\n\n if (Object.keys(request.permissions).length === 0) {\n this._rejectPermissionsRequest(\n id,\n invalidParams({\n message: 'Must request at least one permission.',\n }),\n );\n return;\n }\n\n try {\n await this.messenger.call(\n 'ApprovalController:acceptRequest',\n id,\n request,\n );\n } catch (error) {\n // If accepting unexpectedly fails, reject the request and re-throw the\n // error\n this._rejectPermissionsRequest(id, error);\n throw error;\n }\n }\n\n /**\n * Rejects a permissions request created by\n * {@link PermissionController.requestPermissions}.\n *\n * @param id - The id of the request to be rejected.\n */\n async rejectPermissionsRequest(id: string): Promise {\n if (!this.hasApprovalRequest({ id })) {\n throw new PermissionsRequestNotFoundError(id);\n }\n\n this._rejectPermissionsRequest(id, userRejectedRequest());\n }\n\n /**\n * Checks whether the {@link ApprovalController} has a particular permissions\n * request.\n *\n * @see {@link PermissionController.acceptPermissionsRequest} and\n * {@link PermissionController.rejectPermissionsRequest} for usage.\n * @param options - The {@link HasApprovalRequest} options.\n * @param options.id - The id of the approval request to check for.\n * @returns Whether the specified request exists.\n */\n private hasApprovalRequest(options: { id: string }): boolean {\n return this.messenger.call('ApprovalController:hasRequest', options);\n }\n\n /**\n * Rejects the permissions request with the specified id, with the specified\n * error as the reason. This method is effectively a wrapper around a\n * messenger call for the `ApprovalController:rejectRequest` action.\n *\n * @see {@link PermissionController.acceptPermissionsRequest} and\n * {@link PermissionController.rejectPermissionsRequest} for usage.\n * @param id - The id of the request to reject.\n * @param error - The error associated with the rejection.\n * @returns Nothing\n */\n private _rejectPermissionsRequest(id: string, error: unknown): void {\n return this.messenger.call('ApprovalController:rejectRequest', id, error);\n }\n\n /**\n * Gets the subject's endowments per the specified endowment permission.\n * Throws if the subject does not have the required permission or if the\n * permission is not an endowment permission.\n *\n * @param origin - The origin of the subject whose endowments to retrieve.\n * @param targetName - The name of the endowment permission. This must be a\n * valid permission target name.\n * @param requestData - Additional data associated with the request, if any.\n * Forwarded to the endowment getter function for the permission.\n * @returns The endowments, if any.\n */\n async getEndowments(\n origin: string,\n targetName: ExtractEndowmentPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n requestData?: unknown,\n ): Promise {\n if (!this.hasPermission(origin, targetName)) {\n throw unauthorized({ data: { origin, targetName } });\n }\n\n return this.getTypedPermissionSpecification(\n PermissionType.Endowment,\n targetName,\n origin,\n ).endowmentGetter({ origin, requestData });\n }\n\n /**\n * Executes a restricted method as the subject with the given origin.\n * The specified params, if any, will be passed to the method implementation.\n *\n * ATTN: Great caution should be exercised in the use of this method.\n * Methods that cause side effects or affect application state should\n * be avoided.\n *\n * This method will first attempt to retrieve the requested restricted method\n * implementation, throwing if it does not exist. The method will then be\n * invoked as though the subject with the specified origin had invoked it with\n * the specified parameters. This means that any existing caveats will be\n * applied to the restricted method, and this method will throw if the\n * restricted method or its caveat decorators throw.\n *\n * In addition, this method will throw if the subject does not have a\n * permission for the specified restricted method.\n *\n * @param origin - The origin of the subject to execute the method on behalf\n * of.\n * @param targetName - The name of the method to execute. This must be a valid\n * permission target name.\n * @param params - The parameters to pass to the method implementation.\n * @returns The result of the executed method.\n */\n async executeRestrictedMethod(\n origin: OriginString,\n targetName: ExtractRestrictedMethodPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n params?: RestrictedMethodParameters,\n ): Promise {\n // Throws if the method does not exist\n const methodImplementation = this.getRestrictedMethod(targetName, origin);\n\n const result = await this._executeRestrictedMethod(\n methodImplementation,\n { origin },\n targetName,\n params,\n );\n\n if (result === undefined) {\n throw new Error(\n `Internal request for method \"${targetName}\" as origin \"${origin}\" returned no result.`,\n );\n }\n\n return result;\n }\n\n /**\n * An internal method used in the controller's `json-rpc-engine` middleware\n * and {@link PermissionController.executeRestrictedMethod}. Calls the\n * specified restricted method implementation after decorating it with the\n * caveats of its permission. Throws if the subject does not have the\n * requisite permission.\n *\n * ATTN: Parameter validation is the responsibility of the caller, or\n * the restricted method implementation in the case of `params`.\n *\n * @see {@link PermissionController.executeRestrictedMethod} and\n * {@link PermissionController.createPermissionMiddleware} for usage.\n * @param methodImplementation - The implementation of the method to call.\n * @param subject - Metadata about the subject that made the request.\n * @param method - The method name\n * @param params - Params needed for executing the restricted method\n * @returns The result of the restricted method implementation\n */\n private _executeRestrictedMethod(\n methodImplementation: RestrictedMethod,\n subject: PermissionSubjectMetadata,\n method: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n params: RestrictedMethodParameters = [],\n ): ReturnType> {\n const { origin } = subject;\n\n const permission = this.getPermission(origin, method);\n if (!permission) {\n throw unauthorized({ data: { origin, method } });\n }\n\n return decorateWithCaveats(\n methodImplementation,\n permission,\n this._caveatSpecifications,\n )({ method, params, context: { origin } });\n }\n}\n"]} +\ No newline at end of file +diff --git a/dist/PermissionController.d.cts b/dist/PermissionController.d.cts +index 06debfabcb6122c6a06f02a88135ddf4fee8a35e..ae01aa62250ab9d416d896547eb5da8daffa3c4d 100644 +--- a/dist/PermissionController.d.cts ++++ b/dist/PermissionController.d.cts +@@ -1,7 +1,8 @@ + import type { AcceptRequest as AcceptApprovalRequest, AddApprovalRequest, HasApprovalRequest, RejectRequest as RejectApprovalRequest } from "@metamask/approval-controller"; +-import type { RestrictedMessenger, ActionConstraint, EventConstraint, ControllerGetStateAction, ControllerStateChangeEvent } from "@metamask/base-controller"; +-import { BaseController } from "@metamask/base-controller"; ++import type { ControllerGetStateAction, ControllerStateChangeEvent } from "@metamask/base-controller/next"; ++import { BaseController } from "@metamask/base-controller/next"; + import type { NonEmptyArray } from "@metamask/controller-utils"; ++import type { Messenger, ActionConstraint, EventConstraint } from "@metamask/messenger"; + import type { Json } from "@metamask/utils"; + import type { CaveatConstraint, CaveatDiffMap, CaveatSpecificationConstraint, CaveatSpecificationMap, ExtractCaveat, ExtractCaveats, ExtractCaveatValue } from "./Caveat.cjs"; + import type { EndowmentSpecificationConstraint, ExtractAllowedCaveatTypes, OriginString, PermissionConstraint, PermissionSpecificationConstraint, PermissionSpecificationMap, RequestedPermissions, RestrictedMethod, RestrictedMethodParameters, RestrictedMethodSpecificationConstraint, SideEffectHandler, ValidPermission, ValidPermissionSpecification } from "./Permission.cjs"; +@@ -118,14 +119,14 @@ export type HasPermission = { + handler: GenericPermissionController['hasPermission']; + }; + /** +- * Directly grants given permissions for a specificed origin without requesting user approval ++ * Directly grants given permissions for a specified origin without requesting user approval + */ + export type GrantPermissions = { + type: `${typeof controllerName}:grantPermissions`; + handler: GenericPermissionController['grantPermissions']; + }; + /** +- * Directly grants given permissions for a specificed origin without requesting user approval ++ * Directly grants given permissions for a specified origin without requesting user approval + */ + export type GrantPermissionsIncremental = { + type: `${typeof controllerName}:grantPermissionsIncremental`; +@@ -212,8 +213,8 @@ type AllowedActions = AddApprovalRequest | HasApprovalRequest | AcceptApprovalRe + /** + * The messenger of the {@link PermissionController}. + */ +-export type PermissionControllerMessenger = RestrictedMessenger; +-export type SideEffectMessenger = RestrictedMessenger; ++export type PermissionControllerMessenger = Messenger; ++export type SideEffectMessenger = Messenger; + /** + * A generic {@link PermissionController}. + */ +@@ -370,8 +371,7 @@ export declare class PermissionController; +-export type SideEffectMessenger = RestrictedMessenger; ++export type PermissionControllerMessenger = Messenger; ++export type SideEffectMessenger = Messenger; + /** + * A generic {@link PermissionController}. + */ +@@ -370,8 +371,7 @@ export declare class PermissionController this.clearState()); +- this.messagingSystem.registerActionHandler(`${controllerName}:getEndowments`, (origin, targetName, requestData) => this.getEndowments(origin, targetName, requestData)); +- this.messagingSystem.registerActionHandler(`${controllerName}:getSubjectNames`, () => this.getSubjectNames()); +- this.messagingSystem.registerActionHandler(`${controllerName}:getPermissions`, (origin) => this.getPermissions(origin)); +- this.messagingSystem.registerActionHandler(`${controllerName}:hasPermission`, (origin, targetName) => this.hasPermission(origin, targetName)); +- this.messagingSystem.registerActionHandler(`${controllerName}:hasPermissions`, (origin) => this.hasPermissions(origin)); +- this.messagingSystem.registerActionHandler(`${controllerName}:grantPermissions`, this.grantPermissions.bind(this)); +- this.messagingSystem.registerActionHandler(`${controllerName}:grantPermissionsIncremental`, this.grantPermissionsIncremental.bind(this)); +- this.messagingSystem.registerActionHandler(`${controllerName}:requestPermissions`, (subject, permissions) => this.requestPermissions(subject, permissions)); +- this.messagingSystem.registerActionHandler(`${controllerName}:requestPermissionsIncremental`, (subject, permissions) => this.requestPermissionsIncremental(subject, permissions)); +- this.messagingSystem.registerActionHandler(`${controllerName}:revokeAllPermissions`, (origin) => this.revokeAllPermissions(origin)); +- this.messagingSystem.registerActionHandler(`${controllerName}:revokePermissionForAllSubjects`, (target) => this.revokePermissionForAllSubjects(target)); +- this.messagingSystem.registerActionHandler(`${controllerName}:revokePermissions`, this.revokePermissions.bind(this)); +- this.messagingSystem.registerActionHandler(`${controllerName}:updateCaveat`, (origin, target, caveatType, caveatValue) => { ++ this.messenger.registerActionHandler(`${controllerName}:clearPermissions`, () => this.clearState()); ++ this.messenger.registerActionHandler(`${controllerName}:getEndowments`, (origin, targetName, requestData) => this.getEndowments(origin, targetName, requestData)); ++ this.messenger.registerActionHandler(`${controllerName}:getSubjectNames`, () => this.getSubjectNames()); ++ this.messenger.registerActionHandler(`${controllerName}:getPermissions`, (origin) => this.getPermissions(origin)); ++ this.messenger.registerActionHandler(`${controllerName}:hasPermission`, (origin, targetName) => this.hasPermission(origin, targetName)); ++ this.messenger.registerActionHandler(`${controllerName}:hasPermissions`, (origin) => this.hasPermissions(origin)); ++ this.messenger.registerActionHandler(`${controllerName}:grantPermissions`, this.grantPermissions.bind(this)); ++ this.messenger.registerActionHandler(`${controllerName}:grantPermissionsIncremental`, this.grantPermissionsIncremental.bind(this)); ++ this.messenger.registerActionHandler(`${controllerName}:requestPermissions`, (subject, permissions) => this.requestPermissions(subject, permissions)); ++ this.messenger.registerActionHandler(`${controllerName}:requestPermissionsIncremental`, (subject, permissions) => this.requestPermissionsIncremental(subject, permissions)); ++ this.messenger.registerActionHandler(`${controllerName}:revokeAllPermissions`, (origin) => this.revokeAllPermissions(origin)); ++ this.messenger.registerActionHandler(`${controllerName}:revokePermissionForAllSubjects`, (target) => this.revokePermissionForAllSubjects(target)); ++ this.messenger.registerActionHandler(`${controllerName}:revokePermissions`, this.revokePermissions.bind(this)); ++ this.messenger.registerActionHandler(`${controllerName}:updateCaveat`, (origin, target, caveatType, caveatValue) => { + this.updateCaveat(origin, target, caveatType, caveatValue); + }); + } +@@ -780,7 +786,7 @@ export class PermissionController extends BaseController { + const { allowedCaveats, validator, targetName } = specification; + if (specification.subjectTypes?.length && + specification.subjectTypes.length > 0) { +- const metadata = this.messagingSystem.call('SubjectMetadataController:getSubjectMetadata', origin); ++ const metadata = this.messenger.call('SubjectMetadataController:getSubjectMetadata', origin); + if (!metadata || + metadata.subjectType === null || + !specification.subjectTypes.includes(metadata.subjectType)) { +@@ -1068,7 +1074,7 @@ export class PermissionController extends BaseController { + */ + async requestUserApproval(permissionsRequest) { + const { origin, id } = permissionsRequest.metadata; +- const approvedRequest = await this.messagingSystem.call('ApprovalController:addRequest', { ++ const approvedRequest = await this.messenger.call('ApprovalController:addRequest', { + id, + origin, + requestData: permissionsRequest, +@@ -1101,7 +1107,7 @@ export class PermissionController extends BaseController { + } + /** + * Executes the side-effects of the approved permissions while handling the errors if any. +- * It will pass an instance of the {@link messagingSystem} and the request data associated with the permission request to the handlers through its params. ++ * It will pass an instance of the {@link messenger} and the request data associated with the permission request to the handlers through its params. + * + * @param sideEffects - the side-effect record created by {@link getSideEffects} + * @param requestData - the permissions requestData. +@@ -1111,7 +1117,7 @@ export class PermissionController extends BaseController { + const { permittedHandlers, failureHandlers } = sideEffects; + const params = { + requestData, +- messagingSystem: this.messagingSystem, ++ messenger: this.messenger, + }; + const promiseResults = await Promise.allSettled(Object.values(permittedHandlers).map((permittedHandler) => permittedHandler(params))); + // lib.es2020.promise.d.ts does not export its types so we're using a simple type. +@@ -1194,7 +1200,7 @@ export class PermissionController extends BaseController { + return; + } + try { +- await this.messagingSystem.call('ApprovalController:acceptRequest', id, request); ++ await this.messenger.call('ApprovalController:acceptRequest', id, request); + } + catch (error) { + // If accepting unexpectedly fails, reject the request and re-throw the +@@ -1226,7 +1232,7 @@ export class PermissionController extends BaseController { + * @returns Whether the specified request exists. + */ + hasApprovalRequest(options) { +- return this.messagingSystem.call('ApprovalController:hasRequest', options); ++ return this.messenger.call('ApprovalController:hasRequest', options); + } + /** + * Rejects the permissions request with the specified id, with the specified +@@ -1240,7 +1246,7 @@ export class PermissionController extends BaseController { + * @returns Nothing + */ + _rejectPermissionsRequest(id, error) { +- return this.messagingSystem.call('ApprovalController:rejectRequest', id, error); ++ return this.messenger.call('ApprovalController:rejectRequest', id, error); + } + /** + * Gets the subject's endowments per the specified endowment permission. +diff --git a/dist/PermissionController.mjs.map b/dist/PermissionController.mjs.map +index 92536c31336df622cdd4020bcc3f271c085b66f3..d1e9aa0dd613d28b54a47261b7aaa9b3e2c6b516 100644 +--- a/dist/PermissionController.mjs.map ++++ b/dist/PermissionController.mjs.map +@@ -1 +1 @@ +-{"version":3,"file":"PermissionController.mjs","sourceRoot":"","sources":["../src/PermissionController.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-enable @typescript-eslint/no-unused-vars */\nimport type {\n AcceptRequest as AcceptApprovalRequest,\n AddApprovalRequest,\n HasApprovalRequest,\n RejectRequest as RejectApprovalRequest,\n} from '@metamask/approval-controller';\nimport type {\n StateMetadata,\n RestrictedMessenger,\n ActionConstraint,\n EventConstraint,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { NonEmptyArray } from '@metamask/controller-utils';\nimport {\n isNonEmptyArray,\n isPlainObject,\n isValidJson,\n} from '@metamask/controller-utils';\nimport { JsonRpcError } from '@metamask/rpc-errors';\nimport { hasProperty } from '@metamask/utils';\nimport type { Json, Mutable } from '@metamask/utils';\nimport deepFreeze from 'deep-freeze-strict';\nimport { castDraft, produce as immerProduce, type Draft } from 'immer';\nimport { nanoid } from 'nanoid';\n\nimport type {\n CaveatConstraint,\n CaveatDiffMap,\n CaveatSpecificationConstraint,\n CaveatSpecificationMap,\n CaveatValueMerger,\n ExtractCaveat,\n ExtractCaveats,\n ExtractCaveatValue,\n} from './Caveat';\nimport {\n decorateWithCaveats,\n isRestrictedMethodCaveatSpecification,\n} from './Caveat';\nimport {\n CaveatAlreadyExistsError,\n CaveatDoesNotExistError,\n CaveatInvalidJsonError,\n CaveatMergerDoesNotExistError,\n CaveatMergeTypeMismatchError,\n CaveatMissingValueError,\n CaveatSpecificationMismatchError,\n DuplicateCaveatError,\n EndowmentPermissionDoesNotExistError,\n ForbiddenCaveatError,\n internalError,\n InvalidApprovedPermissionError,\n InvalidCaveatError,\n InvalidCaveatFieldsError,\n InvalidCaveatsPropertyError,\n InvalidCaveatTypeError,\n InvalidMergedPermissionsError,\n invalidParams,\n InvalidSubjectIdentifierError,\n methodNotFound,\n PermissionDoesNotExistError,\n PermissionsRequestNotFoundError,\n unauthorized,\n UnrecognizedCaveatTypeError,\n UnrecognizedSubjectError,\n userRejectedRequest,\n} from './errors';\nimport type {\n EndowmentSpecificationConstraint,\n ExtractAllowedCaveatTypes,\n ExtractPermissionSpecification,\n OriginString,\n PermissionConstraint,\n PermissionSpecificationConstraint,\n PermissionSpecificationMap,\n RequestedPermissions,\n RestrictedMethod,\n RestrictedMethodParameters,\n RestrictedMethodSpecificationConstraint,\n SideEffectHandler,\n ValidPermission,\n ValidPermissionSpecification,\n} from './Permission';\nimport {\n constructPermission,\n findCaveat,\n hasSpecificationType,\n PermissionType,\n} from './Permission';\nimport { getPermissionMiddlewareFactory } from './permission-middleware';\nimport type { GetSubjectMetadata } from './SubjectMetadataController';\nimport { collectUniqueAndPairedCaveats, MethodNames } from './utils';\n\n/**\n * Flags for controlling the validation behavior of certain internal methods.\n */\ntype PermissionValidationFlags = {\n invokePermissionValidator: boolean;\n performCaveatValidation: boolean;\n};\n\n/**\n * Metadata associated with {@link PermissionController} subjects.\n */\nexport type PermissionSubjectMetadata = {\n origin: OriginString;\n};\n\n/**\n * Metadata associated with permission requests.\n */\nexport type PermissionsRequestMetadata = PermissionSubjectMetadata & {\n id: string;\n [key: string]: Json;\n};\n\n/**\n * A diff produced by an incremental permissions request.\n */\nexport type PermissionDiffMap<\n TargetName extends string,\n AllowedCaveats extends CaveatConstraint,\n> = Record>;\n\n/**\n * Used for prompting the user about a proposed new permission.\n * Includes information about the grantee subject, requested permissions, the\n * diff relative to the previously granted permissions (if relevant), and any\n * additional information added by the consumer.\n *\n * All properties except `diff` and `permissions` are passed to any factories\n * for the requested permissions.\n */\nexport type PermissionsRequest = {\n metadata: PermissionsRequestMetadata;\n permissions: RequestedPermissions;\n [key: string]: Json;\n} & {\n diff?: {\n currentPermissions: SubjectPermissions;\n permissionDiffMap: PermissionDiffMap;\n };\n};\n\n/**\n * Metadata associated with an approved permission request.\n */\ntype ApprovedPermissionsMetadata = {\n data?: Record;\n id: string;\n origin: OriginString;\n};\n\nexport type SideEffects = {\n permittedHandlers: Record<\n string,\n SideEffectHandler\n >;\n failureHandlers: Record<\n string,\n SideEffectHandler\n >;\n};\n\n/**\n * The name of the {@link PermissionController}.\n */\nconst controllerName = 'PermissionController';\n\n/**\n * Permissions associated with a {@link PermissionController} subject.\n */\nexport type SubjectPermissions =\n Record;\n\n/**\n * Permissions and metadata associated with a {@link PermissionController}\n * subject.\n */\nexport type PermissionSubjectEntry<\n SubjectPermission extends PermissionConstraint,\n> = {\n origin: SubjectPermission['invoker'];\n permissions: SubjectPermissions;\n};\n\n/**\n * All subjects of a {@link PermissionController}.\n *\n * @template SubjectPermission - The permissions of the subject.\n */\nexport type PermissionControllerSubjects<\n SubjectPermission extends PermissionConstraint,\n> = Record<\n SubjectPermission['invoker'],\n PermissionSubjectEntry\n>;\n\n/**\n * The state of a {@link PermissionController}.\n *\n * @template Permission - The controller's permission type union.\n */\nexport type PermissionControllerState =\n Permission extends PermissionConstraint\n ? {\n subjects: PermissionControllerSubjects;\n }\n : never;\n\n/**\n * Get the state metadata of the {@link PermissionController}.\n *\n * @template Permission - The controller's permission type union.\n * @returns The state metadata\n */\nfunction getStateMetadata() {\n return { subjects: { anonymous: true, persist: true } } as StateMetadata<\n PermissionControllerState\n >;\n}\n\n/**\n * Get the default state of the {@link PermissionController}.\n *\n * @template Permission - The controller's permission type union.\n * @returns The default state of the controller\n */\nfunction getDefaultState() {\n return { subjects: {} } as PermissionControllerState;\n}\n\n/**\n * Gets the state of the {@link PermissionController}.\n */\nexport type GetPermissionControllerState = ControllerGetStateAction<\n typeof controllerName,\n PermissionControllerState\n>;\n\n/**\n * Gets the names of all subjects from the {@link PermissionController}.\n */\nexport type GetSubjects = {\n type: `${typeof controllerName}:getSubjectNames`;\n handler: () => (keyof PermissionControllerSubjects)[];\n};\n\n/**\n * Gets the permissions for specified subject\n */\nexport type GetPermissions = {\n type: `${typeof controllerName}:getPermissions`;\n handler: GenericPermissionController['getPermissions'];\n};\n\n/**\n * Checks whether the specified subject has any permissions.\n */\nexport type HasPermissions = {\n type: `${typeof controllerName}:hasPermissions`;\n handler: GenericPermissionController['hasPermissions'];\n};\n\n/**\n * Checks whether the specified subject has a specific permission.\n */\nexport type HasPermission = {\n type: `${typeof controllerName}:hasPermission`;\n handler: GenericPermissionController['hasPermission'];\n};\n\n/**\n * Directly grants given permissions for a specificed origin without requesting user approval\n */\nexport type GrantPermissions = {\n type: `${typeof controllerName}:grantPermissions`;\n handler: GenericPermissionController['grantPermissions'];\n};\n\n/**\n * Directly grants given permissions for a specificed origin without requesting user approval\n */\nexport type GrantPermissionsIncremental = {\n type: `${typeof controllerName}:grantPermissionsIncremental`;\n handler: GenericPermissionController['grantPermissionsIncremental'];\n};\n\n/**\n * Requests given permissions for a specified origin\n */\nexport type RequestPermissions = {\n type: `${typeof controllerName}:requestPermissions`;\n handler: GenericPermissionController['requestPermissions'];\n};\n\n/**\n * Requests given permissions for a specified origin\n */\nexport type RequestPermissionsIncremental = {\n type: `${typeof controllerName}:requestPermissionsIncremental`;\n handler: GenericPermissionController['requestPermissionsIncremental'];\n};\n\n/**\n * Removes the specified permissions for each origin.\n */\nexport type RevokePermissions = {\n type: `${typeof controllerName}:revokePermissions`;\n handler: GenericPermissionController['revokePermissions'];\n};\n\n/**\n * Removes all permissions for a given origin\n */\nexport type RevokeAllPermissions = {\n type: `${typeof controllerName}:revokeAllPermissions`;\n handler: GenericPermissionController['revokeAllPermissions'];\n};\n\n/**\n * Revokes all permissions corresponding to the specified target for all subjects.\n * Does nothing if no subjects or no such permission exists.\n */\nexport type RevokePermissionForAllSubjects = {\n type: `${typeof controllerName}:revokePermissionForAllSubjects`;\n handler: GenericPermissionController['revokePermissionForAllSubjects'];\n};\n\n/**\n * Updates a caveat value for a specified caveat type belonging to a specific target and origin.\n */\nexport type UpdateCaveat = {\n type: `${typeof controllerName}:updateCaveat`;\n handler: GenericPermissionController['updateCaveat'];\n};\n\n/**\n * Clears all permissions from the {@link PermissionController}.\n */\nexport type ClearPermissions = {\n type: `${typeof controllerName}:clearPermissions`;\n handler: () => void;\n};\n\n/**\n * Gets the endowments for the given subject and permission.\n */\nexport type GetEndowments = {\n type: `${typeof controllerName}:getEndowments`;\n handler: GenericPermissionController['getEndowments'];\n};\n\n/**\n * The {@link Messenger} actions of the {@link PermissionController}.\n */\nexport type PermissionControllerActions =\n | ClearPermissions\n | GetEndowments\n | GetPermissionControllerState\n | GetSubjects\n | GetPermissions\n | HasPermission\n | HasPermissions\n | GrantPermissions\n | GrantPermissionsIncremental\n | RequestPermissions\n | RequestPermissionsIncremental\n | RevokeAllPermissions\n | RevokePermissionForAllSubjects\n | RevokePermissions\n | UpdateCaveat;\n\n/**\n * The generic state change event of the {@link PermissionController}.\n */\nexport type PermissionControllerStateChange = ControllerStateChangeEvent<\n typeof controllerName,\n PermissionControllerState\n>;\n\n/**\n * The {@link Messenger} events of the {@link PermissionController}.\n *\n * The permission controller only emits its generic state change events.\n * Consumers should use selector subscriptions to subscribe to relevant\n * substate.\n */\nexport type PermissionControllerEvents = PermissionControllerStateChange;\n\n/**\n * The external {@link Messenger} actions available to the\n * {@link PermissionController}.\n */\ntype AllowedActions =\n | AddApprovalRequest\n | HasApprovalRequest\n | AcceptApprovalRequest\n | RejectApprovalRequest\n | GetSubjectMetadata;\n\n/**\n * The messenger of the {@link PermissionController}.\n */\nexport type PermissionControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n PermissionControllerActions | AllowedActions,\n PermissionControllerEvents,\n AllowedActions['type'],\n never\n>;\n\nexport type SideEffectMessenger<\n Actions extends ActionConstraint,\n Events extends EventConstraint,\n> = RestrictedMessenger<\n typeof controllerName,\n Actions | AllowedActions,\n Events,\n AllowedActions['type'] | Actions['type'],\n Events['type']\n>;\n\n/**\n * A generic {@link PermissionController}.\n */\nexport type GenericPermissionController = PermissionController<\n PermissionSpecificationConstraint,\n CaveatSpecificationConstraint\n>;\n\n/**\n * Describes the possible results of a {@link CaveatMutator} function.\n */\nexport enum CaveatMutatorOperation {\n Noop,\n UpdateValue,\n DeleteCaveat,\n RevokePermission,\n}\n\n/**\n * Given a caveat value, returns a {@link CaveatMutatorOperation} and, optionally,\n * a new caveat value.\n *\n * @see {@link PermissionController.updatePermissionsByCaveat} for more details.\n * @template Caveat - The caveat type for which this mutator is intended.\n * @param caveatValue - The existing value of the caveat being mutated.\n * @returns A tuple of the mutation result and, optionally, the new caveat\n * value.\n */\nexport type CaveatMutator = (\n caveatValue: TargetCaveat['value'],\n) => CaveatMutatorResult;\n\ntype CaveatMutatorResult =\n | Readonly<{\n operation: CaveatMutatorOperation.UpdateValue;\n value: CaveatConstraint['value'];\n }>\n | Readonly<{\n operation: Exclude<\n CaveatMutatorOperation,\n CaveatMutatorOperation.UpdateValue\n >;\n }>;\n\ntype MergeCaveatResult =\n CaveatType extends undefined\n ? [CaveatConstraint, CaveatConstraint['value']]\n : [CaveatConstraint, CaveatConstraint['value']] | [];\n\n/**\n * Extracts the permission(s) specified by the given permission and caveat\n * specifications.\n *\n * @template ControllerPermissionSpecification - The permission specification(s)\n * to extract from.\n * @template ControllerCaveatSpecification - The caveat specification(s) to\n * extract from. Necessary because {@link Permission} has a generic parameter\n * that describes the allowed caveats for the permission.\n */\nexport type ExtractPermission<\n ControllerPermissionSpecification extends PermissionSpecificationConstraint,\n ControllerCaveatSpecification extends CaveatSpecificationConstraint,\n> = ControllerPermissionSpecification extends ValidPermissionSpecification\n ? ValidPermission<\n ControllerPermissionSpecification['targetName'],\n ExtractCaveats\n >\n : never;\n\n/**\n * Extracts the restricted method permission(s) specified by the given\n * permission and caveat specifications.\n *\n * @template ControllerPermissionSpecification - The permission specification(s)\n * to extract from.\n * @template ControllerCaveatSpecification - The caveat specification(s) to\n * extract from. Necessary because {@link Permission} has a generic parameter\n * that describes the allowed caveats for the permission.\n */\nexport type ExtractRestrictedMethodPermission<\n ControllerPermissionSpecification extends PermissionSpecificationConstraint,\n ControllerCaveatSpecification extends CaveatSpecificationConstraint,\n> = ExtractPermission<\n Extract<\n ControllerPermissionSpecification,\n RestrictedMethodSpecificationConstraint\n >,\n ControllerCaveatSpecification\n>;\n\n/**\n * Extracts the endowment permission(s) specified by the given permission and\n * caveat specifications.\n *\n * @template ControllerPermissionSpecification - The permission specification(s)\n * to extract from.\n * @template ControllerCaveatSpecification - The caveat specification(s) to\n * extract from. Necessary because {@link Permission} has a generic parameter\n * that describes the allowed caveats for the permission.\n */\nexport type ExtractEndowmentPermission<\n ControllerPermissionSpecification extends PermissionSpecificationConstraint,\n ControllerCaveatSpecification extends CaveatSpecificationConstraint,\n> = ExtractPermission<\n Extract,\n ControllerCaveatSpecification\n>;\n\n/**\n * Options for the {@link PermissionController} constructor.\n *\n * @template ControllerPermissionSpecification - A union of the types of all\n * permission specifications available to the controller. Any referenced caveats\n * must be included in the controller's caveat specifications.\n * @template ControllerCaveatSpecification - A union of the types of all\n * caveat specifications available to the controller.\n */\nexport type PermissionControllerOptions<\n ControllerPermissionSpecification extends PermissionSpecificationConstraint,\n ControllerCaveatSpecification extends CaveatSpecificationConstraint,\n> = {\n messenger: PermissionControllerMessenger;\n caveatSpecifications: CaveatSpecificationMap;\n permissionSpecifications: PermissionSpecificationMap;\n unrestrictedMethods: readonly string[];\n state?: Partial<\n PermissionControllerState<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n >;\n};\n\n/**\n * The permission controller. See the [Architecture](../ARCHITECTURE.md)\n * document for details.\n *\n * Assumes the existence of an {@link ApprovalController} reachable via the\n * {@link Messenger}.\n *\n * @template ControllerPermissionSpecification - A union of the types of all\n * permission specifications available to the controller. Any referenced caveats\n * must be included in the controller's caveat specifications.\n * @template ControllerCaveatSpecification - A union of the types of all\n * caveat specifications available to the controller.\n */\nexport class PermissionController<\n ControllerPermissionSpecification extends PermissionSpecificationConstraint,\n ControllerCaveatSpecification extends CaveatSpecificationConstraint,\n> extends BaseController<\n typeof controllerName,\n PermissionControllerState<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >,\n PermissionControllerMessenger\n> {\n private readonly _caveatSpecifications: Readonly<\n CaveatSpecificationMap\n >;\n\n private readonly _permissionSpecifications: Readonly<\n PermissionSpecificationMap\n >;\n\n private readonly _unrestrictedMethods: ReadonlySet;\n\n /**\n * The names of all JSON-RPC methods that will be ignored by the controller.\n *\n * @returns The names of all unrestricted JSON-RPC methods\n */\n public get unrestrictedMethods(): ReadonlySet {\n return this._unrestrictedMethods;\n }\n\n /**\n * Returns a `json-rpc-engine` middleware function factory, so that the rules\n * described by the state of this controller can be applied to incoming\n * JSON-RPC requests.\n *\n * The middleware **must** be added in the correct place in the middleware\n * stack in order for it to work. See the README for an example.\n */\n public createPermissionMiddleware: ReturnType<\n typeof getPermissionMiddlewareFactory\n >;\n\n /**\n * Constructs the PermissionController.\n *\n * @param options - Permission controller options.\n * @param options.caveatSpecifications - The specifications of all caveats\n * available to the controller. See {@link CaveatSpecificationMap} and the\n * documentation for more details.\n * @param options.permissionSpecifications - The specifications of all\n * permissions available to the controller. See\n * {@link PermissionSpecificationMap} and the README for more details.\n * @param options.unrestrictedMethods - The callable names of all JSON-RPC\n * methods ignored by the new controller.\n * @param options.messenger - The messenger. See\n * {@link BaseController} for more information.\n * @param options.state - Existing state to hydrate the controller with at\n * initialization.\n */\n constructor(\n options: PermissionControllerOptions<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >,\n ) {\n const {\n caveatSpecifications,\n permissionSpecifications,\n unrestrictedMethods,\n messenger,\n state = {},\n } = options;\n\n super({\n name: controllerName,\n metadata:\n getStateMetadata<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >(),\n messenger,\n state: {\n ...getDefaultState<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >(),\n ...state,\n },\n });\n\n this._unrestrictedMethods = new Set(unrestrictedMethods);\n this._caveatSpecifications = deepFreeze({ ...caveatSpecifications });\n\n this.validatePermissionSpecifications(\n permissionSpecifications,\n this._caveatSpecifications,\n );\n\n this._permissionSpecifications = deepFreeze({\n ...permissionSpecifications,\n });\n\n this.registerMessageHandlers();\n this.createPermissionMiddleware = getPermissionMiddlewareFactory({\n executeRestrictedMethod: this._executeRestrictedMethod.bind(this),\n getRestrictedMethod: this.getRestrictedMethod.bind(this),\n isUnrestrictedMethod: this.unrestrictedMethods.has.bind(\n this.unrestrictedMethods,\n ),\n });\n }\n\n /**\n * Gets a permission specification.\n *\n * @param targetName - The name of the permission specification to get.\n * @returns The permission specification with the specified target name.\n */\n private getPermissionSpecification<\n TargetName extends ControllerPermissionSpecification['targetName'],\n >(\n targetName: TargetName,\n ): ExtractPermissionSpecification<\n ControllerPermissionSpecification,\n TargetName\n > {\n return this._permissionSpecifications[targetName];\n }\n\n /**\n * Gets a caveat specification.\n *\n * @param caveatType - The type of the caveat specification to get.\n * @returns The caveat specification with the specified type.\n */\n private getCaveatSpecification<\n CaveatType extends ControllerCaveatSpecification['type'],\n >(caveatType: CaveatType) {\n return this._caveatSpecifications[caveatType];\n }\n\n /**\n * Gets the merger function for the specified caveat. Throws if no\n * merger exists.\n *\n * @param caveatType - The type of the caveat whose merger to get.\n * @returns The caveat value merger function for the specified caveat type.\n */\n #expectGetCaveatMerger<\n CaveatType extends ControllerCaveatSpecification['type'],\n >(caveatType: CaveatType): CaveatValueMerger {\n const { merger } = this.getCaveatSpecification(caveatType);\n\n if (merger === undefined) {\n throw new CaveatMergerDoesNotExistError(caveatType);\n }\n return merger;\n }\n\n /**\n * Constructor helper for validating permission specifications.\n *\n * Throws an error if validation fails.\n *\n * @param permissionSpecifications - The permission specifications passed to\n * this controller's constructor.\n * @param caveatSpecifications - The caveat specifications passed to this\n * controller.\n */\n private validatePermissionSpecifications(\n permissionSpecifications: PermissionSpecificationMap,\n caveatSpecifications: CaveatSpecificationMap,\n ) {\n Object.entries(\n permissionSpecifications,\n ).forEach(\n ([\n targetName,\n { permissionType, targetName: innerTargetName, allowedCaveats },\n ]) => {\n if (!permissionType || !hasProperty(PermissionType, permissionType)) {\n throw new Error(`Invalid permission type: \"${permissionType}\"`);\n }\n\n if (!targetName) {\n throw new Error(`Invalid permission target name: \"${targetName}\"`);\n }\n\n if (targetName !== innerTargetName) {\n throw new Error(\n `Invalid permission specification: target name \"${targetName}\" must match specification.targetName value \"${innerTargetName}\".`,\n );\n }\n\n if (allowedCaveats) {\n allowedCaveats.forEach((caveatType) => {\n if (!hasProperty(caveatSpecifications, caveatType)) {\n throw new UnrecognizedCaveatTypeError(caveatType);\n }\n\n const specification =\n caveatSpecifications[\n caveatType as ControllerCaveatSpecification['type']\n ];\n const isRestrictedMethodCaveat =\n isRestrictedMethodCaveatSpecification(specification);\n\n if (\n (permissionType === PermissionType.RestrictedMethod &&\n !isRestrictedMethodCaveat) ||\n (permissionType === PermissionType.Endowment &&\n isRestrictedMethodCaveat)\n ) {\n throw new CaveatSpecificationMismatchError(\n specification,\n permissionType,\n );\n }\n });\n }\n },\n );\n }\n\n /**\n * Constructor helper for registering the controller's messaging system\n * actions.\n */\n private registerMessageHandlers(): void {\n this.messagingSystem.registerActionHandler(\n `${controllerName}:clearPermissions` as const,\n () => this.clearState(),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getEndowments` as const,\n (origin: string, targetName: string, requestData?: unknown) =>\n this.getEndowments(origin, targetName, requestData),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getSubjectNames` as const,\n () => this.getSubjectNames(),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getPermissions` as const,\n (origin: OriginString) => this.getPermissions(origin),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:hasPermission` as const,\n (origin: OriginString, targetName: string) =>\n this.hasPermission(origin, targetName),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:hasPermissions` as const,\n (origin: OriginString) => this.hasPermissions(origin),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:grantPermissions` as const,\n this.grantPermissions.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:grantPermissionsIncremental` as const,\n this.grantPermissionsIncremental.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:requestPermissions` as const,\n (subject: PermissionSubjectMetadata, permissions: RequestedPermissions) =>\n this.requestPermissions(subject, permissions),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:requestPermissionsIncremental` as const,\n (subject: PermissionSubjectMetadata, permissions: RequestedPermissions) =>\n this.requestPermissionsIncremental(subject, permissions),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:revokeAllPermissions` as const,\n (origin: OriginString) => this.revokeAllPermissions(origin),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:revokePermissionForAllSubjects` as const,\n (\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n ) => this.revokePermissionForAllSubjects(target),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:revokePermissions` as const,\n this.revokePermissions.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateCaveat` as const,\n (origin, target, caveatType, caveatValue) => {\n this.updateCaveat(\n origin,\n target,\n caveatType as ExtractAllowedCaveatTypes,\n caveatValue,\n );\n },\n );\n }\n\n /**\n * Clears the state of the controller.\n */\n clearState(): void {\n this.update((_draftState) => {\n return {\n ...getDefaultState<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >(),\n };\n });\n }\n\n /**\n * Gets the permission specification corresponding to the given permission\n * type and target name. Throws an error if the target name does not\n * correspond to a permission, or if the specification is not of the\n * given permission type.\n *\n * @template Type - The type of the permission specification to get.\n * @param permissionType - The type of the permission specification to get.\n * @param targetName - The name of the permission whose specification to get.\n * @param requestingOrigin - The origin of the requesting subject, if any.\n * Will be added to any thrown errors.\n * @returns The specification object corresponding to the given type and\n * target name.\n */\n private getTypedPermissionSpecification(\n permissionType: Type,\n targetName: string,\n requestingOrigin?: string,\n ): ControllerPermissionSpecification & { permissionType: Type } {\n const failureError =\n permissionType === PermissionType.RestrictedMethod\n ? methodNotFound(\n targetName,\n requestingOrigin ? { origin: requestingOrigin } : undefined,\n )\n : new EndowmentPermissionDoesNotExistError(\n targetName,\n requestingOrigin,\n );\n\n if (!this.targetExists(targetName)) {\n throw failureError;\n }\n\n const specification = this.getPermissionSpecification(targetName);\n if (!hasSpecificationType(specification, permissionType)) {\n throw failureError;\n }\n\n return specification;\n }\n\n /**\n * Gets the implementation of the specified restricted method.\n *\n * A JSON-RPC error is thrown if the method does not exist.\n *\n * @see {@link PermissionController.executeRestrictedMethod} and\n * {@link PermissionController.createPermissionMiddleware} for internal usage.\n * @param method - The name of the restricted method.\n * @param origin - The origin associated with the request for the restricted\n * method, if any.\n * @returns The restricted method implementation.\n */\n getRestrictedMethod(\n method: string,\n origin?: string,\n ): RestrictedMethod {\n return this.getTypedPermissionSpecification(\n PermissionType.RestrictedMethod,\n method,\n origin,\n ).methodImplementation;\n }\n\n /**\n * Gets a list of all origins of subjects.\n *\n * @returns The origins (i.e. IDs) of all subjects.\n */\n getSubjectNames(): OriginString[] {\n return Object.keys(this.state.subjects);\n }\n\n /**\n * Gets the permission for the specified target of the subject corresponding\n * to the specified origin.\n *\n * @param origin - The origin of the subject.\n * @param targetName - The method name as invoked by a third party (i.e., not\n * a method key).\n * @returns The permission if it exists, or undefined otherwise.\n */\n getPermission<\n SubjectPermission extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >,\n >(\n origin: OriginString,\n targetName: SubjectPermission['parentCapability'],\n ): SubjectPermission | undefined {\n return this.state.subjects[origin]?.permissions[targetName] as\n | SubjectPermission\n | undefined;\n }\n\n /**\n * Gets all permissions for the specified subject, if any.\n *\n * @param origin - The origin of the subject.\n * @returns The permissions of the subject, if any.\n */\n getPermissions(\n origin: OriginString,\n ):\n | SubjectPermissions<\n ValidPermission>\n >\n | undefined {\n return this.state.subjects[origin]?.permissions;\n }\n\n /**\n * Checks whether the subject with the specified origin has the specified\n * permission.\n *\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @returns Whether the subject has the permission.\n */\n hasPermission(\n origin: OriginString,\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n ): boolean {\n return Boolean(this.getPermission(origin, target));\n }\n\n /**\n * Checks whether the subject with the specified origin has any permissions.\n * Use this if you want to know if a subject \"exists\".\n *\n * @param origin - The origin of the subject to check.\n * @returns Whether the subject has any permissions.\n */\n hasPermissions(origin: OriginString): boolean {\n return Boolean(this.state.subjects[origin]);\n }\n\n /**\n * Revokes all permissions from the specified origin.\n *\n * Throws an error of the origin has no permissions.\n *\n * @param origin - The origin whose permissions to revoke.\n */\n revokeAllPermissions(origin: OriginString): void {\n this.update((draftState) => {\n if (!draftState.subjects[origin]) {\n throw new UnrecognizedSubjectError(origin);\n }\n delete draftState.subjects[origin];\n });\n }\n\n /**\n * Revokes the specified permission from the subject with the specified\n * origin.\n *\n * Throws an error if the subject or the permission does not exist.\n *\n * @param origin - The origin of the subject whose permission to revoke.\n * @param target - The target name of the permission to revoke.\n */\n revokePermission(\n origin: OriginString,\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n ): void {\n this.revokePermissions({ [origin]: [target] });\n }\n\n /**\n * Revokes the specified permissions from the specified subjects.\n *\n * Throws an error if any of the subjects or permissions do not exist.\n *\n * @param subjectsAndPermissions - An object mapping subject origins\n * to arrays of permission target names to revoke.\n */\n revokePermissions(\n subjectsAndPermissions: Record<\n OriginString,\n NonEmptyArray<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability']\n >\n >,\n ): void {\n this.update((draftState) => {\n Object.keys(subjectsAndPermissions).forEach((origin) => {\n if (!hasProperty(draftState.subjects, origin)) {\n throw new UnrecognizedSubjectError(origin);\n }\n\n subjectsAndPermissions[origin].forEach((target) => {\n const { permissions } = draftState.subjects[origin];\n if (!hasProperty(permissions as Record, target)) {\n throw new PermissionDoesNotExistError(origin, target);\n }\n\n this.deletePermission(draftState.subjects, origin, target);\n });\n });\n });\n }\n\n /**\n * Revokes all permissions corresponding to the specified target for all subjects.\n * Does nothing if no subjects or no such permission exists.\n *\n * @param target - The name of the target to revoke all permissions for.\n */\n revokePermissionForAllSubjects(\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n ): void {\n if (this.getSubjectNames().length === 0) {\n return;\n }\n\n this.update((draftState) => {\n Object.entries(draftState.subjects).forEach(([origin, subject]) => {\n const { permissions } = subject;\n\n if (hasProperty(permissions as Record, target)) {\n this.deletePermission(draftState.subjects, origin, target);\n }\n });\n });\n }\n\n /**\n * Deletes the permission identified by the given origin and target. If the\n * permission is the single remaining permission of its subject, the subject\n * is also deleted.\n *\n * @param subjects - The draft permission controller subjects.\n * @param origin - The origin of the subject associated with the permission\n * to delete.\n * @param target - The target name of the permission to delete.\n */\n private deletePermission(\n subjects: Draft>,\n origin: OriginString,\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n ): void {\n const { permissions } = subjects[origin];\n if (Object.keys(permissions).length > 1) {\n delete permissions[target];\n } else {\n delete subjects[origin];\n }\n }\n\n /**\n * Checks whether the permission of the subject corresponding to the given\n * origin has a caveat of the specified type.\n *\n * Throws an error if the subject does not have a permission with the\n * specified target name.\n *\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to check for.\n * @returns Whether the permission has the specified caveat.\n */\n hasCaveat<\n TargetName extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n CaveatType extends ExtractAllowedCaveatTypes,\n >(origin: OriginString, target: TargetName, caveatType: CaveatType): boolean {\n return Boolean(this.getCaveat(origin, target, caveatType));\n }\n\n /**\n * Gets the caveat of the specified type, if any, for the permission of\n * the subject corresponding to the given origin.\n *\n * Throws an error if the subject does not have a permission with the\n * specified target name.\n *\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to get.\n * @returns The caveat, or `undefined` if no such caveat exists.\n */\n getCaveat<\n TargetName extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n CaveatType extends ExtractAllowedCaveatTypes,\n >(\n origin: OriginString,\n target: TargetName,\n caveatType: CaveatType,\n ): ExtractCaveat | undefined {\n const permission = this.getPermission(origin, target);\n if (!permission) {\n throw new PermissionDoesNotExistError(origin, target);\n }\n\n return findCaveat(permission, caveatType) as\n | ExtractCaveat\n | undefined;\n }\n\n /**\n * Adds a caveat of the specified type, with the specified caveat value, to\n * the permission corresponding to the given subject origin and permission\n * target.\n *\n * For modifying existing caveats, use\n * {@link PermissionController.updateCaveat}.\n *\n * Throws an error if no such permission exists, or if the caveat already\n * exists.\n *\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to add.\n * @param caveatValue - The value of the caveat to add.\n */\n addCaveat<\n TargetName extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n CaveatType extends ExtractAllowedCaveatTypes,\n >(\n origin: OriginString,\n target: TargetName,\n caveatType: CaveatType,\n caveatValue: ExtractCaveatValue,\n ): void {\n if (this.hasCaveat(origin, target, caveatType)) {\n throw new CaveatAlreadyExistsError(origin, target, caveatType);\n }\n\n this.setCaveat(origin, target, caveatType, caveatValue);\n }\n\n /**\n * Updates the value of the caveat of the specified type belonging to the\n * permission corresponding to the given subject origin and permission\n * target.\n *\n * For adding new caveats, use\n * {@link PermissionController.addCaveat}.\n *\n * Throws an error if no such permission or caveat exists.\n *\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to update.\n * @param caveatValue - The new value of the caveat.\n */\n updateCaveat<\n TargetName extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n CaveatType extends ExtractAllowedCaveatTypes,\n CaveatValue extends ExtractCaveatValue<\n ControllerCaveatSpecification,\n CaveatType\n >,\n >(\n origin: OriginString,\n target: TargetName,\n caveatType: CaveatType,\n caveatValue: CaveatValue,\n ): void {\n if (!this.hasCaveat(origin, target, caveatType)) {\n throw new CaveatDoesNotExistError(origin, target, caveatType);\n }\n\n this.setCaveat(origin, target, caveatType, caveatValue);\n }\n\n /**\n * Sets the specified caveat on the specified permission. Overwrites existing\n * caveats of the same type in-place (preserving array order), and adds the\n * caveat to the end of the array otherwise.\n *\n * Throws an error if the permission does not exist or fails to validate after\n * its caveats have been modified.\n *\n * @see {@link PermissionController.addCaveat}\n * @see {@link PermissionController.updateCaveat}\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to set.\n * @param caveatValue - The value of the caveat to set.\n */\n private setCaveat<\n TargetName extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n CaveatType extends ExtractAllowedCaveatTypes,\n >(\n origin: OriginString,\n target: TargetName,\n caveatType: CaveatType,\n caveatValue: ExtractCaveatValue,\n ): void {\n this.update((draftState) => {\n const subject = draftState.subjects[origin];\n\n // Unreachable because `hasCaveat` is always called before this, and it\n // throws if permissions are missing. TypeScript needs this, however.\n /* istanbul ignore if */\n if (!subject) {\n throw new UnrecognizedSubjectError(origin);\n }\n\n const permission = subject.permissions[target];\n\n /* istanbul ignore if: practically impossible, but TypeScript wants it */\n if (!permission) {\n throw new PermissionDoesNotExistError(origin, target);\n }\n\n const caveat = {\n type: caveatType,\n value: caveatValue,\n };\n this.validateCaveat(caveat, origin, target);\n\n let addedCaveat = false;\n if (permission.caveats) {\n const caveatIndex = permission.caveats.findIndex(\n (existingCaveat) => existingCaveat.type === caveat.type,\n );\n\n if (caveatIndex === -1) {\n permission.caveats.push(caveat);\n addedCaveat = true;\n } else {\n permission.caveats.splice(caveatIndex, 1, caveat);\n }\n } else {\n // At this point, we don't know if the specific permission is allowed\n // to have caveats, but it should be impossible to call this method\n // for a permission that may not have any caveats. If all else fails,\n // the permission validator is also called.\n // @ts-expect-error See above comment\n permission.caveats = [caveat];\n addedCaveat = true;\n }\n\n // Mutating a caveat does not warrant permission validation, but mutating\n // the caveat array does.\n if (addedCaveat) {\n this.validateModifiedPermission(permission, origin, {\n invokePermissionValidator: true,\n performCaveatValidation: false, // We just validated the caveat\n });\n }\n });\n }\n\n /**\n * Updates all caveats with the specified type for all subjects and\n * permissions by applying the specified mutator function to them.\n *\n * ATTN: Permissions can be revoked entirely by the action of this method,\n * read on for details.\n *\n * Caveat mutators are functions that receive a caveat value and return a\n * tuple consisting of a {@link CaveatMutatorOperation} and, optionally, a new\n * value to update the existing caveat with.\n *\n * For each caveat, depending on the mutator result, this method will:\n * - Do nothing ({@link CaveatMutatorOperation.Noop})\n * - Update the value of the caveat ({@link CaveatMutatorOperation.UpdateValue}). The caveat specification validator, if any, will be called after updating the value.\n * - Delete the caveat ({@link CaveatMutatorOperation.DeleteCaveat}). The permission specification validator, if any, will be called after deleting the caveat.\n * - Revoke the parent permission ({@link CaveatMutatorOperation.RevokePermission})\n *\n * This method throws if the validation of any caveat or permission fails.\n *\n * @param targetCaveatType - The type of the caveats to update.\n * @param mutator - The mutator function which will be applied to all caveat\n * values.\n */\n updatePermissionsByCaveat<\n CaveatType extends ExtractCaveats['type'],\n TargetCaveat extends ExtractCaveat<\n ControllerCaveatSpecification,\n CaveatType\n >,\n >(targetCaveatType: CaveatType, mutator: CaveatMutator): void {\n if (Object.keys(this.state.subjects).length === 0) {\n return;\n }\n\n this.update((draftState) => {\n Object.values(draftState.subjects).forEach((subject) => {\n Object.values(subject.permissions).forEach((permission) => {\n const { caveats } = permission;\n const targetCaveat = caveats?.find(\n ({ type }) => type === targetCaveatType,\n );\n if (!targetCaveat) {\n return;\n }\n\n // The mutator may modify the caveat value in place, and must always\n // return a valid mutation result.\n const mutatorResult = mutator(targetCaveat.value);\n const { operation } = mutatorResult;\n switch (operation) {\n case CaveatMutatorOperation.Noop:\n break;\n\n case CaveatMutatorOperation.UpdateValue:\n // Typecast: `Mutable` is used here to assign to a readonly\n // property. `targetConstraint` should already be mutable because\n // it's part of a draft, but for some reason it's not. We can't\n // use the more-correct `Draft` type here either because it\n // results in an error.\n (targetCaveat as Mutable).value =\n mutatorResult.value;\n\n this.validateCaveat(\n targetCaveat,\n subject.origin,\n permission.parentCapability,\n );\n break;\n\n case CaveatMutatorOperation.DeleteCaveat:\n this.deleteCaveat(permission, targetCaveatType, subject.origin);\n break;\n\n case CaveatMutatorOperation.RevokePermission:\n this.deletePermission(\n draftState.subjects,\n subject.origin,\n permission.parentCapability,\n );\n break;\n\n default: {\n // Overriding as `never` is the expected result of exhaustiveness checking,\n // and is intended to represent unchecked exception cases.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n throw new Error(`Unrecognized mutation result: \"${operation}\"`);\n }\n }\n });\n });\n });\n }\n\n /**\n * Removes the caveat of the specified type from the permission corresponding\n * to the given subject origin and target name.\n *\n * Throws an error if no such permission or caveat exists.\n *\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to remove.\n */\n removeCaveat<\n TargetName extends ControllerPermissionSpecification['targetName'],\n CaveatType extends ExtractAllowedCaveatTypes,\n >(origin: OriginString, target: TargetName, caveatType: CaveatType): void {\n this.update((draftState) => {\n const permission = draftState.subjects[origin]?.permissions[target];\n if (!permission) {\n throw new PermissionDoesNotExistError(origin, target);\n }\n\n if (!permission.caveats) {\n throw new CaveatDoesNotExistError(origin, target, caveatType);\n }\n\n this.deleteCaveat(permission, caveatType, origin);\n });\n }\n\n /**\n * Deletes the specified caveat from the specified permission. If no caveats\n * remain after deletion, the permission's caveat property is set to `null`.\n * The permission is validated after being modified.\n *\n * Throws an error if the permission does not have a caveat with the specified\n * type.\n *\n * @param permission - The permission whose caveat to delete.\n * @param caveatType - The type of the caveat to delete.\n * @param origin - The origin the permission subject.\n */\n private deleteCaveat<\n CaveatType extends ExtractCaveats['type'],\n >(\n permission: Draft,\n caveatType: CaveatType,\n origin: OriginString,\n ): void {\n /* istanbul ignore if: not possible in our usage */\n if (!permission.caveats) {\n throw new CaveatDoesNotExistError(\n origin,\n permission.parentCapability,\n caveatType,\n );\n }\n\n const caveatIndex = permission.caveats.findIndex(\n (existingCaveat) => existingCaveat.type === caveatType,\n );\n\n if (caveatIndex === -1) {\n throw new CaveatDoesNotExistError(\n origin,\n permission.parentCapability,\n caveatType,\n );\n }\n\n if (permission.caveats.length === 1) {\n permission.caveats = null;\n } else {\n permission.caveats.splice(caveatIndex, 1);\n }\n\n this.validateModifiedPermission(permission, origin, {\n invokePermissionValidator: true,\n performCaveatValidation: false, // No caveat object was mutated\n });\n }\n\n /**\n * Validates the specified modified permission. Should **always** be invoked\n * on a permission when its caveat array has been mutated.\n *\n * Just like {@link PermissionController.validatePermission}, except that the\n * corresponding target name and specification are retrieved first, and an\n * error is thrown if the target name does not exist.\n *\n * @param permission - The modified permission to validate.\n * @param origin - The origin associated with the permission.\n * @param validationFlags - Validation flags. See {@link PermissionController.validatePermission}.\n */\n private validateModifiedPermission(\n permission: Draft,\n origin: OriginString,\n validationFlags: PermissionValidationFlags,\n ): void {\n /* istanbul ignore if: this should be impossible */\n if (!this.targetExists(permission.parentCapability)) {\n throw new Error(\n `Fatal: Existing permission target \"${permission.parentCapability}\" has no specification.`,\n );\n }\n\n this.validatePermission(\n this.getPermissionSpecification(permission.parentCapability),\n permission as PermissionConstraint,\n origin,\n validationFlags,\n );\n }\n\n /**\n * Verifies the existence the specified permission target, i.e. whether it has\n * a specification.\n *\n * @param target - The requested permission target.\n * @returns Whether the permission target exists.\n */\n private targetExists(\n target: string,\n ): target is ControllerPermissionSpecification['targetName'] {\n return hasProperty(this._permissionSpecifications, target);\n }\n\n /**\n * Grants _approved_ permissions to the specified subject. Every permission and\n * caveat is stringently validated—including by calling their specification\n * validators—and an error is thrown if validation fails.\n *\n * ATTN: This method does **not** prompt the user for approval. User consent must\n * first be obtained through some other means.\n *\n * @see {@link PermissionController.requestPermissions} For initiating a\n * permissions request requiring user approval.\n * @param options - Options bag.\n * @param options.approvedPermissions - The requested permissions approved by\n * the user.\n * @param options.requestData - Permission request data. Passed to permission\n * factory functions.\n * @param options.preserveExistingPermissions - Whether to preserve the\n * subject's existing permissions.\n * @param options.subject - The subject to grant permissions to.\n * @returns The subject's new permission state. It may or may not have changed.\n */\n grantPermissions({\n approvedPermissions,\n requestData,\n preserveExistingPermissions = true,\n subject,\n }: {\n approvedPermissions: RequestedPermissions;\n subject: PermissionSubjectMetadata;\n preserveExistingPermissions?: boolean;\n requestData?: Record;\n }): Partial<\n SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n > {\n return this.#applyGrantedPermissions({\n approvedPermissions,\n subject,\n mergePermissions: false,\n preserveExistingPermissions,\n requestData,\n });\n }\n\n /**\n * Incrementally grants _approved_ permissions to the specified subject. Every\n * permission and caveat is stringently validated—including by calling their\n * specification validators—and an error is thrown if validation fails.\n *\n * ATTN: This method does **not** prompt the user for approval. User consent must\n * first be obtained through some other means.\n *\n * @see {@link PermissionController.requestPermissionsIncremental} For initiating\n * an incremental permissions request requiring user approval.\n * @param options - Options bag.\n * @param options.approvedPermissions - The requested permissions approved by\n * the user.\n * @param options.requestData - Permission request data. Passed to permission\n * factory functions.\n * @param options.subject - The subject to grant permissions to.\n * @returns The subject's new permission state. It may or may not have changed.\n */\n grantPermissionsIncremental({\n approvedPermissions,\n requestData,\n subject,\n }: {\n approvedPermissions: RequestedPermissions;\n subject: PermissionSubjectMetadata;\n requestData?: Record;\n }): Partial<\n SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n > {\n return this.#applyGrantedPermissions({\n approvedPermissions,\n subject,\n mergePermissions: true,\n preserveExistingPermissions: true,\n requestData,\n });\n }\n\n #applyGrantedPermissions({\n approvedPermissions,\n subject,\n mergePermissions,\n preserveExistingPermissions,\n requestData,\n }: {\n approvedPermissions: RequestedPermissions;\n subject: PermissionSubjectMetadata;\n mergePermissions: boolean;\n preserveExistingPermissions: boolean;\n requestData?: Record;\n }): Partial<\n SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n > {\n const { origin } = subject;\n\n if (!origin || typeof origin !== 'string') {\n throw new InvalidSubjectIdentifierError(origin);\n }\n\n const permissions = (\n preserveExistingPermissions\n ? {\n ...this.getPermissions(origin),\n }\n : {}\n ) as SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >;\n\n for (const [requestedTarget, approvedPermission] of Object.entries(\n approvedPermissions,\n )) {\n if (!this.targetExists(requestedTarget)) {\n throw methodNotFound(requestedTarget);\n }\n\n if (\n approvedPermission.parentCapability !== undefined &&\n requestedTarget !== approvedPermission.parentCapability\n ) {\n throw new InvalidApprovedPermissionError(\n origin,\n requestedTarget,\n approvedPermission,\n );\n }\n\n // We have verified that the target exists, and reassign it to change its\n // type.\n const targetName = requestedTarget as ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'];\n const specification = this.getPermissionSpecification(targetName);\n\n // The requested caveats are validated here.\n const caveats = this.constructCaveats(\n origin,\n targetName,\n approvedPermission.caveats,\n );\n\n const permissionOptions = {\n caveats,\n invoker: origin,\n target: targetName,\n };\n\n let permission: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >;\n if (specification.factory) {\n permission = specification.factory(permissionOptions, requestData);\n } else {\n permission = constructPermission(permissionOptions);\n }\n\n if (mergePermissions) {\n permission = this.#mergePermission(\n permissions[targetName],\n permission,\n )[0];\n }\n\n this.validatePermission(specification, permission, origin, {\n invokePermissionValidator: true,\n performCaveatValidation: true,\n });\n permissions[targetName] = permission;\n }\n\n this.setValidatedPermissions(origin, permissions);\n return permissions;\n }\n\n /**\n * Validates the specified permission by:\n * - Ensuring that if `subjectTypes` is specified, the subject requesting the permission is of a type in the list.\n * - Ensuring that its `caveats` property is either `null` or a non-empty array.\n * - Ensuring that it only includes caveats allowed by its specification.\n * - Ensuring that it includes no duplicate caveats (by caveat type).\n * - Validating each caveat object, if `performCaveatValidation` is `true`.\n * - Calling the validator of its specification, if one exists and `invokePermissionValidator` is `true`.\n *\n * An error is thrown if validation fails.\n *\n * @param specification - The specification of the permission.\n * @param permission - The permission to validate.\n * @param origin - The origin associated with the permission.\n * @param validationOptions - Validation options.\n * @param validationOptions.invokePermissionValidator - Whether to invoke the\n * permission's consumer-specified validator function, if any.\n * @param validationOptions.performCaveatValidation - Whether to invoke\n * {@link PermissionController.validateCaveat} on each of the permission's\n * caveats.\n */\n private validatePermission(\n specification: PermissionSpecificationConstraint,\n permission: PermissionConstraint,\n origin: OriginString,\n {\n invokePermissionValidator,\n performCaveatValidation,\n }: PermissionValidationFlags,\n ): void {\n const { allowedCaveats, validator, targetName } = specification;\n\n if (\n specification.subjectTypes?.length &&\n specification.subjectTypes.length > 0\n ) {\n const metadata = this.messagingSystem.call(\n 'SubjectMetadataController:getSubjectMetadata',\n origin,\n );\n\n if (\n !metadata ||\n metadata.subjectType === null ||\n !specification.subjectTypes.includes(metadata.subjectType)\n ) {\n throw specification.permissionType === PermissionType.RestrictedMethod\n ? methodNotFound(targetName, { origin })\n : new EndowmentPermissionDoesNotExistError(targetName, origin);\n }\n }\n\n if (hasProperty(permission, 'caveats')) {\n const { caveats } = permission;\n\n if (caveats !== null && !(Array.isArray(caveats) && caveats.length > 0)) {\n throw new InvalidCaveatsPropertyError(origin, targetName, caveats);\n }\n\n const seenCaveatTypes = new Set();\n caveats?.forEach((caveat) => {\n if (performCaveatValidation) {\n this.validateCaveat(caveat, origin, targetName);\n }\n\n if (!allowedCaveats?.includes(caveat.type)) {\n throw new ForbiddenCaveatError(caveat.type, origin, targetName);\n }\n\n if (seenCaveatTypes.has(caveat.type)) {\n throw new DuplicateCaveatError(caveat.type, origin, targetName);\n }\n seenCaveatTypes.add(caveat.type);\n });\n }\n\n if (invokePermissionValidator && validator) {\n validator(permission, origin, targetName);\n }\n }\n\n /**\n * Assigns the specified permissions to the subject with the given origin.\n * Overwrites all existing permissions, and creates a subject entry if it\n * doesn't already exist.\n *\n * ATTN: Assumes that the new permissions have been validated.\n *\n * @param origin - The origin of the grantee subject.\n * @param permissions - The new permissions for the grantee subject.\n */\n private setValidatedPermissions(\n origin: OriginString,\n permissions: Record<\n string,\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >,\n ): void {\n this.update((draftState) => {\n if (!draftState.subjects[origin]) {\n draftState.subjects[origin] = { origin, permissions: {} };\n }\n\n draftState.subjects[origin].permissions = castDraft(permissions);\n });\n }\n\n /**\n * Validates the requested caveats for the permission of the specified\n * subject origin and target name and returns the validated caveat array.\n *\n * Throws an error if validation fails.\n *\n * @param origin - The origin of the permission subject.\n * @param target - The permission target name.\n * @param requestedCaveats - The requested caveats to construct.\n * @returns The constructed caveats.\n */\n private constructCaveats(\n origin: OriginString,\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n requestedCaveats?: unknown[] | null,\n ): NonEmptyArray> | undefined {\n const caveatArray = requestedCaveats?.map((requestedCaveat) => {\n this.validateCaveat(requestedCaveat, origin, target);\n\n // Reassign so that we have a fresh object.\n const { type, value } = requestedCaveat as CaveatConstraint;\n return { type, value } as ExtractCaveats;\n });\n\n return caveatArray && isNonEmptyArray(caveatArray)\n ? caveatArray\n : undefined;\n }\n\n /**\n * This methods validates that the specified caveat is an object with the\n * expected properties and types. It also ensures that a caveat specification\n * exists for the requested caveat type, and calls the specification\n * validator, if it exists, on the caveat object.\n *\n * Throws an error if validation fails.\n *\n * @param caveat - The caveat object to validate.\n * @param origin - The origin associated with the subject of the parent\n * permission.\n * @param target - The target name associated with the parent permission.\n */\n private validateCaveat(\n caveat: unknown,\n origin: OriginString,\n target: string,\n ): void {\n if (!isPlainObject(caveat)) {\n throw new InvalidCaveatError(caveat, origin, target);\n }\n\n if (Object.keys(caveat).length !== 2) {\n throw new InvalidCaveatFieldsError(caveat, origin, target);\n }\n\n if (typeof caveat.type !== 'string') {\n throw new InvalidCaveatTypeError(caveat, origin, target);\n }\n\n const specification = this.getCaveatSpecification(caveat.type);\n if (!specification) {\n throw new UnrecognizedCaveatTypeError(caveat.type, origin, target);\n }\n\n if (!hasProperty(caveat, 'value') || caveat.value === undefined) {\n throw new CaveatMissingValueError(caveat, origin, target);\n }\n\n if (!isValidJson(caveat.value)) {\n throw new CaveatInvalidJsonError(caveat, origin, target);\n }\n\n // Typecast: TypeScript still believes that the caveat is a PlainObject.\n specification.validator?.(caveat as CaveatConstraint, origin, target);\n }\n\n /**\n * Initiates a permission request that requires user approval.\n *\n * Either this or {@link PermissionController.requestPermissionsIncremental}\n * should always be used to grant additional permissions to a subject,\n * unless user approval has been obtained through some other means.\n *\n * Permissions are validated at every step of the approval process, and this\n * method will reject if validation fails.\n *\n * @see {@link ApprovalController} For the user approval logic.\n * @see {@link PermissionController.acceptPermissionsRequest} For the method\n * that _accepts_ the request and resolves the user approval promise.\n * @see {@link PermissionController.rejectPermissionsRequest} For the method\n * that _rejects_ the request and the user approval promise.\n * @param subject - The grantee subject.\n * @param requestedPermissions - The requested permissions.\n * @param options - Additional options.\n * @param options.id - The id of the permissions request. Defaults to a unique\n * id.\n * @param options.preserveExistingPermissions - Whether to preserve the\n * subject's existing permissions. Defaults to `true`.\n * @param options.metadata - Additional metadata about the permission request.\n * @returns The granted permissions and request metadata.\n */\n async requestPermissions(\n subject: PermissionSubjectMetadata,\n requestedPermissions: RequestedPermissions,\n options: {\n id?: string;\n preserveExistingPermissions?: boolean;\n metadata?: Record;\n } = {},\n ): Promise<\n [\n Partial<\n SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n >,\n ApprovedPermissionsMetadata,\n ]\n > {\n const { origin } = subject;\n const { id = nanoid(), preserveExistingPermissions = true } = options;\n this.validateRequestedPermissions(origin, requestedPermissions);\n\n const metadata = {\n ...options.metadata,\n id,\n origin,\n };\n\n const permissionsRequest: PermissionsRequest = {\n metadata,\n permissions: requestedPermissions,\n };\n\n const approvedRequest = await this.requestUserApproval(permissionsRequest);\n return await this.#handleApprovedPermissions({\n subject,\n metadata,\n preserveExistingPermissions,\n approvedRequest,\n });\n }\n\n /**\n * Initiates an incremental permission request that prompts for user approval.\n * Incremental permission requests allow the caller to replace existing and/or\n * add brand new permissions and caveats for the specified subject.\n *\n * Incremental permission request are merged with the subject's existing permissions\n * through a right-biased union, where the incremental permission are the right-hand\n * side of the merger. If both sides of the merger specify the same caveats for a\n * given permission, the caveats are merged using their specification's caveat value\n * merger property.\n *\n * Either this or {@link PermissionController.requestPermissions} should\n * always be used to grant additional permissions to a subject, unless user\n * approval has been obtained through some other means.\n *\n * Permissions are validated at every step of the approval process, and this\n * method will reject if validation fails.\n *\n * @see {@link ApprovalController} For the user approval logic.\n * @see {@link PermissionController.acceptPermissionsRequest} For the method\n * that _accepts_ the request and resolves the user approval promise.\n * @see {@link PermissionController.rejectPermissionsRequest} For the method\n * that _rejects_ the request and the user approval promise.\n * @param subject - The grantee subject.\n * @param requestedPermissions - The requested permissions.\n * @param options - Additional options.\n * @param options.id - The id of the permissions request. Defaults to a unique\n * id.\n * @param options.metadata - Additional metadata about the permission request.\n * @returns The granted permissions and request metadata.\n */\n async requestPermissionsIncremental(\n subject: PermissionSubjectMetadata,\n requestedPermissions: RequestedPermissions,\n options: {\n id?: string;\n metadata?: Record;\n } = {},\n ): Promise<\n | [\n Partial<\n SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n >,\n ApprovedPermissionsMetadata,\n ]\n | []\n > {\n const { origin } = subject;\n const { id = nanoid() } = options;\n this.validateRequestedPermissions(origin, requestedPermissions);\n\n const currentPermissions = this.getPermissions(origin) ?? {};\n const [newPermissions, permissionDiffMap] =\n this.#mergeIncrementalPermissions(\n currentPermissions,\n requestedPermissions,\n );\n\n // The second undefined check is just for type narrowing purposes. These values\n // will always be jointly defined or undefined.\n if (newPermissions === undefined || permissionDiffMap === undefined) {\n return [];\n }\n\n try {\n // It does not spark joy to run this validation again after the merger operation.\n // But, optimizing this procedure is probably not worth it, especially considering\n // that the worst-case scenario for validation degrades to the below function call.\n this.validateRequestedPermissions(origin, newPermissions);\n } catch (error) {\n if (error instanceof Error) {\n throw new InvalidMergedPermissionsError(\n origin,\n error,\n permissionDiffMap,\n );\n }\n /* istanbul ignore next: This should be impossible */\n throw internalError('Unrecognized error type', { error });\n }\n\n const metadata = {\n ...options.metadata,\n id,\n origin,\n };\n\n const permissionsRequest: PermissionsRequest = {\n metadata,\n permissions: newPermissions,\n diff: {\n currentPermissions,\n permissionDiffMap,\n },\n };\n\n const approvedRequest = await this.requestUserApproval(permissionsRequest);\n return await this.#handleApprovedPermissions({\n subject,\n metadata,\n preserveExistingPermissions: false,\n approvedRequest,\n });\n }\n\n /**\n * Validates requested permissions. Throws if validation fails.\n *\n * This method ensures that the requested permissions are a properly\n * formatted {@link RequestedPermissions} object, and performs the same\n * validation as {@link PermissionController.grantPermissions}, except that\n * consumer-specified permission validator functions are not called, since\n * they are only called on fully constructed, approved permissions that are\n * otherwise completely valid.\n *\n * Unrecognzied properties on requested permissions are ignored.\n *\n * @param origin - The origin of the grantee subject.\n * @param requestedPermissions - The requested permissions.\n */\n private validateRequestedPermissions(\n origin: OriginString,\n requestedPermissions: unknown,\n ): void {\n if (!isPlainObject(requestedPermissions)) {\n throw invalidParams({\n message: `Requested permissions for origin \"${origin}\" is not a plain object.`,\n data: { origin, requestedPermissions },\n });\n }\n\n if (Object.keys(requestedPermissions).length === 0) {\n throw invalidParams({\n message: `Permissions request for origin \"${origin}\" contains no permissions.`,\n data: { requestedPermissions },\n });\n }\n\n for (const targetName of Object.keys(requestedPermissions)) {\n const permission = requestedPermissions[targetName];\n\n if (!this.targetExists(targetName)) {\n throw methodNotFound(targetName, { origin, requestedPermissions });\n }\n\n if (\n !isPlainObject(permission) ||\n (permission.parentCapability !== undefined &&\n targetName !== permission.parentCapability)\n ) {\n throw invalidParams({\n message: `Permissions request for origin \"${origin}\" contains invalid requested permission(s).`,\n data: { origin, requestedPermissions },\n });\n }\n\n // Here we validate the permission without invoking its validator, if any.\n // The validator will be invoked after the permission has been approved.\n this.validatePermission(\n this.getPermissionSpecification(targetName),\n // Typecast: The permission is still a \"PlainObject\" here.\n permission as PermissionConstraint,\n origin,\n { invokePermissionValidator: false, performCaveatValidation: true },\n );\n }\n }\n\n /**\n * Merges a set of incrementally requested permissions into the existing permissions of\n * the requesting subject. The merge is a right-biased union, where the existing\n * permissions are the left-hand side, and the incrementally requested permissions are\n * the right-hand side.\n *\n * @param existingPermissions - The subject's existing permissions.\n * @param incrementalRequestedPermissions - The requested permissions to merge.\n * @returns The merged permissions and the resulting diff.\n */\n #mergeIncrementalPermissions(\n existingPermissions: Exclude<\n ReturnType,\n undefined\n >,\n incrementalRequestedPermissions: RequestedPermissions,\n ):\n | [\n SubjectPermissions<\n ValidPermission>\n >,\n PermissionDiffMap,\n ]\n | [] {\n const permissionDiffMap: PermissionDiffMap = {};\n\n // Use immer's produce as a convenience for calculating the new permissions\n // without mutating the existing permissions or committing the results to state.\n const newPermissions = immerProduce(\n existingPermissions,\n (draftExistingPermissions) => {\n const leftPermissions =\n draftExistingPermissions as RequestedPermissions;\n\n Object.entries(incrementalRequestedPermissions).forEach(\n ([targetName, rightPermission]) => {\n const leftPermission: Partial | undefined =\n leftPermissions[targetName];\n\n const [newPermission, caveatsDiff] = this.#mergePermission(\n leftPermission ?? {},\n rightPermission,\n );\n\n if (\n leftPermission === undefined ||\n Object.keys(caveatsDiff).length > 0\n ) {\n leftPermissions[targetName] = newPermission;\n permissionDiffMap[targetName] = caveatsDiff;\n }\n // Otherwise, leave the left permission as-is; its authority has\n // not changed.\n },\n );\n },\n );\n\n if (Object.keys(permissionDiffMap).length === 0) {\n return [];\n }\n return [newPermissions, permissionDiffMap];\n }\n\n /**\n * Performs a right-biased union between two permissions. The task of merging caveats\n * of the same type between the two permissions is delegated to the corresponding\n * caveat type's merger implementation.\n *\n * Throws if the left-hand and right-hand permissions both have a caveat whose\n * specification does not provide a caveat value merger function.\n *\n * @param leftPermission - The left-hand permission to merge.\n * @param rightPermission - The right-hand permission to merge.\n * @returns The merged permission.\n */\n #mergePermission<\n PermissionType extends Partial | PermissionConstraint,\n >(\n leftPermission: PermissionType | undefined,\n rightPermission: PermissionType,\n ): [PermissionType, CaveatDiffMap] {\n const { caveatPairs, leftUniqueCaveats, rightUniqueCaveats } =\n collectUniqueAndPairedCaveats(leftPermission, rightPermission);\n\n const [mergedCaveats, caveatDiffMap] = caveatPairs.reduce(\n ([caveats, diffMap], [leftCaveat, rightCaveat]) => {\n const [newCaveat, diff] = this.#mergeCaveat(leftCaveat, rightCaveat);\n\n if (newCaveat !== undefined && diff !== undefined) {\n caveats.push(newCaveat);\n diffMap[newCaveat.type] = diff;\n } else {\n caveats.push(leftCaveat);\n }\n\n return [caveats, diffMap];\n },\n [[], {}] as [CaveatConstraint[], CaveatDiffMap],\n );\n\n const mergedRightUniqueCaveats = rightUniqueCaveats.map((caveat) => {\n const [newCaveat, diff] = this.#mergeCaveat(undefined, caveat);\n\n caveatDiffMap[newCaveat.type] = diff;\n return newCaveat;\n });\n\n const allCaveats = [\n ...mergedCaveats,\n ...leftUniqueCaveats,\n ...mergedRightUniqueCaveats,\n ];\n\n const newPermission = {\n ...leftPermission,\n ...rightPermission,\n ...(allCaveats.length > 0\n ? { caveats: allCaveats as NonEmptyArray }\n : {}),\n };\n\n return [newPermission, caveatDiffMap];\n }\n\n /**\n * Merges two caveats of the same type. The task of merging the values of the\n * two caveats is delegated to the corresponding caveat type's merger implementation.\n *\n * @param leftCaveat - The left-hand caveat to merge.\n * @param rightCaveat - The right-hand caveat to merge.\n * @returns The merged caveat and the diff between the two caveats.\n */\n #mergeCaveat<\n RightCaveat extends CaveatConstraint,\n LeftCaveat extends RightCaveat | undefined,\n >(\n leftCaveat: LeftCaveat,\n rightCaveat: RightCaveat,\n ): MergeCaveatResult {\n /* istanbul ignore if: This should be impossible */\n if (leftCaveat !== undefined && leftCaveat.type !== rightCaveat.type) {\n throw new CaveatMergeTypeMismatchError(leftCaveat.type, rightCaveat.type);\n }\n\n const merger = this.#expectGetCaveatMerger(rightCaveat.type);\n\n if (leftCaveat === undefined) {\n return [\n {\n ...rightCaveat,\n },\n rightCaveat.value,\n ];\n }\n\n const [newValue, diff] = merger(leftCaveat.value, rightCaveat.value);\n\n return newValue !== undefined && diff !== undefined\n ? [\n {\n type: rightCaveat.type,\n value: newValue,\n },\n diff,\n ]\n : ([] as MergeCaveatResult);\n }\n\n /**\n * Adds a request to the {@link ApprovalController} using the\n * {@link AddApprovalRequest} action. Also validates the resulting approved\n * permissions request, and throws an error if validation fails.\n *\n * @param permissionsRequest - The permissions request object.\n * @returns The approved permissions request object.\n */\n private async requestUserApproval(permissionsRequest: PermissionsRequest) {\n const { origin, id } = permissionsRequest.metadata;\n const approvedRequest = await this.messagingSystem.call(\n 'ApprovalController:addRequest',\n {\n id,\n origin,\n requestData: permissionsRequest,\n type: MethodNames.RequestPermissions,\n },\n true,\n );\n\n this.validateApprovedPermissions(approvedRequest, { id, origin });\n return approvedRequest as PermissionsRequest;\n }\n\n /**\n * Accepts a permissions request that has been approved by the user. This\n * method should be called after the user has approved the request and the\n * {@link ApprovalController} has resolved the user approval promise.\n *\n * @param options - Options bag.\n * @param options.subject - The subject to grant permissions to.\n * @param options.metadata - The metadata of the approved permissions request.\n * @param options.preserveExistingPermissions - Whether to preserve the\n * subject's existing permissions.\n * @param options.approvedRequest - The approved permissions request to handle.\n * @returns The granted permissions and request metadata.\n */\n async #handleApprovedPermissions({\n subject,\n metadata,\n preserveExistingPermissions,\n approvedRequest,\n }: {\n subject: PermissionSubjectMetadata;\n metadata: PermissionsRequest['metadata'];\n preserveExistingPermissions: boolean;\n approvedRequest: PermissionsRequest;\n }): Promise<\n [ReturnType, ApprovedPermissionsMetadata]\n > {\n const { permissions: approvedPermissions, ...requestData } =\n approvedRequest;\n const approvedMetadata: ApprovedPermissionsMetadata = { ...metadata };\n\n const sideEffects = this.getSideEffects(approvedPermissions);\n if (Object.values(sideEffects.permittedHandlers).length > 0) {\n const sideEffectsData = await this.executeSideEffects(\n sideEffects,\n approvedRequest,\n );\n\n approvedMetadata.data = Object.keys(sideEffects.permittedHandlers).reduce(\n (acc, permission, i) => ({ [permission]: sideEffectsData[i], ...acc }),\n {},\n );\n }\n\n return [\n this.grantPermissions({\n subject,\n approvedPermissions,\n preserveExistingPermissions,\n requestData,\n }),\n approvedMetadata,\n ];\n }\n\n /**\n * Reunites all the side-effects (onPermitted and onFailure) of the requested permissions inside a record of arrays.\n *\n * @param permissions - The approved permissions.\n * @returns The {@link SideEffects} object containing the handlers arrays.\n */\n private getSideEffects(permissions: RequestedPermissions) {\n return Object.keys(permissions).reduce(\n (sideEffectList, targetName) => {\n if (this.targetExists(targetName)) {\n const specification = this.getPermissionSpecification(targetName);\n\n if (specification.sideEffect) {\n sideEffectList.permittedHandlers[targetName] =\n specification.sideEffect.onPermitted;\n\n if (specification.sideEffect.onFailure) {\n sideEffectList.failureHandlers[targetName] =\n specification.sideEffect.onFailure;\n }\n }\n }\n return sideEffectList;\n },\n { permittedHandlers: {}, failureHandlers: {} },\n );\n }\n\n /**\n * Executes the side-effects of the approved permissions while handling the errors if any.\n * It will pass an instance of the {@link messagingSystem} and the request data associated with the permission request to the handlers through its params.\n *\n * @param sideEffects - the side-effect record created by {@link getSideEffects}\n * @param requestData - the permissions requestData.\n * @returns the value returned by all the `onPermitted` handlers in an array.\n */\n private async executeSideEffects(\n sideEffects: SideEffects,\n requestData: PermissionsRequest,\n ) {\n const { permittedHandlers, failureHandlers } = sideEffects;\n const params = {\n requestData,\n messagingSystem: this.messagingSystem,\n };\n\n const promiseResults = await Promise.allSettled(\n Object.values(permittedHandlers).map((permittedHandler) =>\n permittedHandler(params),\n ),\n );\n\n // lib.es2020.promise.d.ts does not export its types so we're using a simple type.\n const rejectedHandlers = promiseResults.filter(\n (promise) => promise.status === 'rejected',\n ) as { status: 'rejected'; reason: Error }[];\n\n if (rejectedHandlers.length > 0) {\n const failureHandlersList = Object.values(failureHandlers);\n if (failureHandlersList.length > 0) {\n try {\n await Promise.all(\n failureHandlersList.map((failureHandler) => failureHandler(params)),\n );\n } catch (error) {\n throw internalError('Unexpected error in side-effects', { error });\n }\n }\n const reasons = rejectedHandlers.map((handler) => handler.reason);\n\n reasons.forEach((reason) => {\n console.error(reason);\n });\n\n throw reasons.length > 1\n ? internalError(\n 'Multiple errors occurred during side-effects execution',\n { errors: reasons },\n )\n : reasons[0];\n }\n\n // lib.es2020.promise.d.ts does not export its types so we're using a simple type.\n return (promiseResults as { status: 'fulfilled'; value: unknown }[]).map(\n ({ value }) => value,\n );\n }\n\n /**\n * Validates an approved {@link PermissionsRequest} object. The approved\n * request must have the required `metadata` and `permissions` properties,\n * the `id` and `origin` of the `metadata` must match the original request\n * metadata, and the requested permissions must be valid per\n * {@link PermissionController.validateRequestedPermissions}. Any extra\n * metadata properties are ignored.\n *\n * An error is thrown if validation fails.\n *\n * @param approvedRequest - The approved permissions request object.\n * @param originalMetadata - The original request metadata.\n */\n private validateApprovedPermissions(\n approvedRequest: unknown,\n originalMetadata: PermissionsRequestMetadata,\n ) {\n const { id, origin } = originalMetadata;\n\n if (\n !isPlainObject(approvedRequest) ||\n !isPlainObject(approvedRequest.metadata)\n ) {\n throw internalError(\n `Approved permissions request for subject \"${origin}\" is invalid.`,\n { data: { approvedRequest } },\n );\n }\n\n const {\n metadata: { id: newId, origin: newOrigin },\n permissions,\n } = approvedRequest;\n\n if (newId !== id) {\n throw internalError(\n `Approved permissions request for subject \"${origin}\" mutated its id.`,\n { originalId: id, mutatedId: newId },\n );\n }\n\n if (newOrigin !== origin) {\n throw internalError(\n `Approved permissions request for subject \"${origin}\" mutated its origin.`,\n { originalOrigin: origin, mutatedOrigin: newOrigin },\n );\n }\n\n try {\n this.validateRequestedPermissions(origin, permissions);\n } catch (error) {\n if (error instanceof Error) {\n // Re-throw as an internal error; we should never receive invalid approved\n // permissions.\n throw internalError(\n `Invalid approved permissions request: ${error.message}`,\n error instanceof JsonRpcError ? error.data : undefined,\n );\n }\n /* istanbul ignore next: This should be impossible */\n throw internalError('Unrecognized error type', { error });\n }\n }\n\n /**\n * Accepts a permissions request created by\n * {@link PermissionController.requestPermissions}.\n *\n * @param request - The permissions request.\n */\n async acceptPermissionsRequest(request: PermissionsRequest): Promise {\n const { id } = request.metadata;\n\n if (!this.hasApprovalRequest({ id })) {\n throw new PermissionsRequestNotFoundError(id);\n }\n\n if (Object.keys(request.permissions).length === 0) {\n this._rejectPermissionsRequest(\n id,\n invalidParams({\n message: 'Must request at least one permission.',\n }),\n );\n return;\n }\n\n try {\n await this.messagingSystem.call(\n 'ApprovalController:acceptRequest',\n id,\n request,\n );\n } catch (error) {\n // If accepting unexpectedly fails, reject the request and re-throw the\n // error\n this._rejectPermissionsRequest(id, error);\n throw error;\n }\n }\n\n /**\n * Rejects a permissions request created by\n * {@link PermissionController.requestPermissions}.\n *\n * @param id - The id of the request to be rejected.\n */\n async rejectPermissionsRequest(id: string): Promise {\n if (!this.hasApprovalRequest({ id })) {\n throw new PermissionsRequestNotFoundError(id);\n }\n\n this._rejectPermissionsRequest(id, userRejectedRequest());\n }\n\n /**\n * Checks whether the {@link ApprovalController} has a particular permissions\n * request.\n *\n * @see {@link PermissionController.acceptPermissionsRequest} and\n * {@link PermissionController.rejectPermissionsRequest} for usage.\n * @param options - The {@link HasApprovalRequest} options.\n * @param options.id - The id of the approval request to check for.\n * @returns Whether the specified request exists.\n */\n private hasApprovalRequest(options: { id: string }): boolean {\n return this.messagingSystem.call('ApprovalController:hasRequest', options);\n }\n\n /**\n * Rejects the permissions request with the specified id, with the specified\n * error as the reason. This method is effectively a wrapper around a\n * messenger call for the `ApprovalController:rejectRequest` action.\n *\n * @see {@link PermissionController.acceptPermissionsRequest} and\n * {@link PermissionController.rejectPermissionsRequest} for usage.\n * @param id - The id of the request to reject.\n * @param error - The error associated with the rejection.\n * @returns Nothing\n */\n private _rejectPermissionsRequest(id: string, error: unknown): void {\n return this.messagingSystem.call(\n 'ApprovalController:rejectRequest',\n id,\n error,\n );\n }\n\n /**\n * Gets the subject's endowments per the specified endowment permission.\n * Throws if the subject does not have the required permission or if the\n * permission is not an endowment permission.\n *\n * @param origin - The origin of the subject whose endowments to retrieve.\n * @param targetName - The name of the endowment permission. This must be a\n * valid permission target name.\n * @param requestData - Additional data associated with the request, if any.\n * Forwarded to the endowment getter function for the permission.\n * @returns The endowments, if any.\n */\n async getEndowments(\n origin: string,\n targetName: ExtractEndowmentPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n requestData?: unknown,\n ): Promise {\n if (!this.hasPermission(origin, targetName)) {\n throw unauthorized({ data: { origin, targetName } });\n }\n\n return this.getTypedPermissionSpecification(\n PermissionType.Endowment,\n targetName,\n origin,\n ).endowmentGetter({ origin, requestData });\n }\n\n /**\n * Executes a restricted method as the subject with the given origin.\n * The specified params, if any, will be passed to the method implementation.\n *\n * ATTN: Great caution should be exercised in the use of this method.\n * Methods that cause side effects or affect application state should\n * be avoided.\n *\n * This method will first attempt to retrieve the requested restricted method\n * implementation, throwing if it does not exist. The method will then be\n * invoked as though the subject with the specified origin had invoked it with\n * the specified parameters. This means that any existing caveats will be\n * applied to the restricted method, and this method will throw if the\n * restricted method or its caveat decorators throw.\n *\n * In addition, this method will throw if the subject does not have a\n * permission for the specified restricted method.\n *\n * @param origin - The origin of the subject to execute the method on behalf\n * of.\n * @param targetName - The name of the method to execute. This must be a valid\n * permission target name.\n * @param params - The parameters to pass to the method implementation.\n * @returns The result of the executed method.\n */\n async executeRestrictedMethod(\n origin: OriginString,\n targetName: ExtractRestrictedMethodPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n params?: RestrictedMethodParameters,\n ): Promise {\n // Throws if the method does not exist\n const methodImplementation = this.getRestrictedMethod(targetName, origin);\n\n const result = await this._executeRestrictedMethod(\n methodImplementation,\n { origin },\n targetName,\n params,\n );\n\n if (result === undefined) {\n throw new Error(\n `Internal request for method \"${targetName}\" as origin \"${origin}\" returned no result.`,\n );\n }\n\n return result;\n }\n\n /**\n * An internal method used in the controller's `json-rpc-engine` middleware\n * and {@link PermissionController.executeRestrictedMethod}. Calls the\n * specified restricted method implementation after decorating it with the\n * caveats of its permission. Throws if the subject does not have the\n * requisite permission.\n *\n * ATTN: Parameter validation is the responsibility of the caller, or\n * the restricted method implementation in the case of `params`.\n *\n * @see {@link PermissionController.executeRestrictedMethod} and\n * {@link PermissionController.createPermissionMiddleware} for usage.\n * @param methodImplementation - The implementation of the method to call.\n * @param subject - Metadata about the subject that made the request.\n * @param method - The method name\n * @param params - Params needed for executing the restricted method\n * @returns The result of the restricted method implementation\n */\n private _executeRestrictedMethod(\n methodImplementation: RestrictedMethod,\n subject: PermissionSubjectMetadata,\n method: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n params: RestrictedMethodParameters = [],\n ): ReturnType> {\n const { origin } = subject;\n\n const permission = this.getPermission(origin, method);\n if (!permission) {\n throw unauthorized({ data: { origin, method } });\n }\n\n return decorateWithCaveats(\n methodImplementation,\n permission,\n this._caveatSpecifications,\n )({ method, params, context: { origin } });\n }\n}\n"]} +\ No newline at end of file ++{"version":3,"file":"PermissionController.mjs","sourceRoot":"","sources":["../src/PermissionController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AcceptRequest as AcceptApprovalRequest,\n AddApprovalRequest,\n HasApprovalRequest,\n RejectRequest as RejectApprovalRequest,\n} from '@metamask/approval-controller';\nimport type {\n StateMetadata,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller/next';\nimport { BaseController } from '@metamask/base-controller/next';\nimport type { NonEmptyArray } from '@metamask/controller-utils';\nimport {\n isNonEmptyArray,\n isPlainObject,\n isValidJson,\n} from '@metamask/controller-utils';\nimport type {\n Messenger,\n ActionConstraint,\n EventConstraint,\n} from '@metamask/messenger';\nimport { JsonRpcError } from '@metamask/rpc-errors';\nimport { hasProperty } from '@metamask/utils';\nimport type { Json, Mutable } from '@metamask/utils';\nimport deepFreeze from 'deep-freeze-strict';\nimport { castDraft, produce as immerProduce, type Draft } from 'immer';\nimport { nanoid } from 'nanoid';\n\nimport type {\n CaveatConstraint,\n CaveatDiffMap,\n CaveatSpecificationConstraint,\n CaveatSpecificationMap,\n CaveatValueMerger,\n ExtractCaveat,\n ExtractCaveats,\n ExtractCaveatValue,\n} from './Caveat';\nimport {\n decorateWithCaveats,\n isRestrictedMethodCaveatSpecification,\n} from './Caveat';\nimport {\n CaveatAlreadyExistsError,\n CaveatDoesNotExistError,\n CaveatInvalidJsonError,\n CaveatMergerDoesNotExistError,\n CaveatMergeTypeMismatchError,\n CaveatMissingValueError,\n CaveatSpecificationMismatchError,\n DuplicateCaveatError,\n EndowmentPermissionDoesNotExistError,\n ForbiddenCaveatError,\n internalError,\n InvalidApprovedPermissionError,\n InvalidCaveatError,\n InvalidCaveatFieldsError,\n InvalidCaveatsPropertyError,\n InvalidCaveatTypeError,\n InvalidMergedPermissionsError,\n invalidParams,\n InvalidSubjectIdentifierError,\n methodNotFound,\n PermissionDoesNotExistError,\n PermissionsRequestNotFoundError,\n unauthorized,\n UnrecognizedCaveatTypeError,\n UnrecognizedSubjectError,\n userRejectedRequest,\n} from './errors';\nimport type {\n EndowmentSpecificationConstraint,\n ExtractAllowedCaveatTypes,\n ExtractPermissionSpecification,\n OriginString,\n PermissionConstraint,\n PermissionSpecificationConstraint,\n PermissionSpecificationMap,\n RequestedPermissions,\n RestrictedMethod,\n RestrictedMethodParameters,\n RestrictedMethodSpecificationConstraint,\n SideEffectHandler,\n ValidPermission,\n ValidPermissionSpecification,\n} from './Permission';\nimport {\n constructPermission,\n findCaveat,\n hasSpecificationType,\n PermissionType,\n} from './Permission';\nimport { getPermissionMiddlewareFactory } from './permission-middleware';\nimport type { GetSubjectMetadata } from './SubjectMetadataController';\nimport { collectUniqueAndPairedCaveats, MethodNames } from './utils';\n\n/**\n * Flags for controlling the validation behavior of certain internal methods.\n */\ntype PermissionValidationFlags = {\n invokePermissionValidator: boolean;\n performCaveatValidation: boolean;\n};\n\n/**\n * Metadata associated with {@link PermissionController} subjects.\n */\nexport type PermissionSubjectMetadata = {\n origin: OriginString;\n};\n\n/**\n * Metadata associated with permission requests.\n */\nexport type PermissionsRequestMetadata = PermissionSubjectMetadata & {\n id: string;\n [key: string]: Json;\n};\n\n/**\n * A diff produced by an incremental permissions request.\n */\nexport type PermissionDiffMap<\n TargetName extends string,\n AllowedCaveats extends CaveatConstraint,\n> = Record>;\n\n/**\n * Used for prompting the user about a proposed new permission.\n * Includes information about the grantee subject, requested permissions, the\n * diff relative to the previously granted permissions (if relevant), and any\n * additional information added by the consumer.\n *\n * All properties except `diff` and `permissions` are passed to any factories\n * for the requested permissions.\n */\nexport type PermissionsRequest = {\n metadata: PermissionsRequestMetadata;\n permissions: RequestedPermissions;\n [key: string]: Json;\n} & {\n diff?: {\n currentPermissions: SubjectPermissions;\n permissionDiffMap: PermissionDiffMap;\n };\n};\n\n/**\n * Metadata associated with an approved permission request.\n */\ntype ApprovedPermissionsMetadata = {\n data?: Record;\n id: string;\n origin: OriginString;\n};\n\nexport type SideEffects = {\n permittedHandlers: Record<\n string,\n SideEffectHandler\n >;\n failureHandlers: Record<\n string,\n SideEffectHandler\n >;\n};\n\n/**\n * The name of the {@link PermissionController}.\n */\nconst controllerName = 'PermissionController';\n\n/**\n * Permissions associated with a {@link PermissionController} subject.\n */\nexport type SubjectPermissions =\n Record;\n\n/**\n * Permissions and metadata associated with a {@link PermissionController}\n * subject.\n */\nexport type PermissionSubjectEntry<\n SubjectPermission extends PermissionConstraint,\n> = {\n origin: SubjectPermission['invoker'];\n permissions: SubjectPermissions;\n};\n\n/**\n * All subjects of a {@link PermissionController}.\n *\n * @template SubjectPermission - The permissions of the subject.\n */\nexport type PermissionControllerSubjects<\n SubjectPermission extends PermissionConstraint,\n> = Record<\n SubjectPermission['invoker'],\n PermissionSubjectEntry\n>;\n\n/**\n * The state of a {@link PermissionController}.\n *\n * @template Permission - The controller's permission type union.\n */\nexport type PermissionControllerState =\n Permission extends PermissionConstraint\n ? {\n subjects: PermissionControllerSubjects;\n }\n : never;\n\n/**\n * Get the state metadata of the {@link PermissionController}.\n *\n * @template Permission - The controller's permission type union.\n * @returns The state metadata\n */\nfunction getStateMetadata() {\n return {\n subjects: {\n includeInStateLogs: true,\n includeInDebugSnapshot: true,\n persist: true,\n usedInUi: true,\n },\n } as StateMetadata>;\n}\n\n/**\n * Get the default state of the {@link PermissionController}.\n *\n * @template Permission - The controller's permission type union.\n * @returns The default state of the controller\n */\nfunction getDefaultState() {\n return { subjects: {} } as PermissionControllerState;\n}\n\n/**\n * Gets the state of the {@link PermissionController}.\n */\nexport type GetPermissionControllerState = ControllerGetStateAction<\n typeof controllerName,\n PermissionControllerState\n>;\n\n/**\n * Gets the names of all subjects from the {@link PermissionController}.\n */\nexport type GetSubjects = {\n type: `${typeof controllerName}:getSubjectNames`;\n handler: () => (keyof PermissionControllerSubjects)[];\n};\n\n/**\n * Gets the permissions for specified subject\n */\nexport type GetPermissions = {\n type: `${typeof controllerName}:getPermissions`;\n handler: GenericPermissionController['getPermissions'];\n};\n\n/**\n * Checks whether the specified subject has any permissions.\n */\nexport type HasPermissions = {\n type: `${typeof controllerName}:hasPermissions`;\n handler: GenericPermissionController['hasPermissions'];\n};\n\n/**\n * Checks whether the specified subject has a specific permission.\n */\nexport type HasPermission = {\n type: `${typeof controllerName}:hasPermission`;\n handler: GenericPermissionController['hasPermission'];\n};\n\n/**\n * Directly grants given permissions for a specified origin without requesting user approval\n */\nexport type GrantPermissions = {\n type: `${typeof controllerName}:grantPermissions`;\n handler: GenericPermissionController['grantPermissions'];\n};\n\n/**\n * Directly grants given permissions for a specified origin without requesting user approval\n */\nexport type GrantPermissionsIncremental = {\n type: `${typeof controllerName}:grantPermissionsIncremental`;\n handler: GenericPermissionController['grantPermissionsIncremental'];\n};\n\n/**\n * Requests given permissions for a specified origin\n */\nexport type RequestPermissions = {\n type: `${typeof controllerName}:requestPermissions`;\n handler: GenericPermissionController['requestPermissions'];\n};\n\n/**\n * Requests given permissions for a specified origin\n */\nexport type RequestPermissionsIncremental = {\n type: `${typeof controllerName}:requestPermissionsIncremental`;\n handler: GenericPermissionController['requestPermissionsIncremental'];\n};\n\n/**\n * Removes the specified permissions for each origin.\n */\nexport type RevokePermissions = {\n type: `${typeof controllerName}:revokePermissions`;\n handler: GenericPermissionController['revokePermissions'];\n};\n\n/**\n * Removes all permissions for a given origin\n */\nexport type RevokeAllPermissions = {\n type: `${typeof controllerName}:revokeAllPermissions`;\n handler: GenericPermissionController['revokeAllPermissions'];\n};\n\n/**\n * Revokes all permissions corresponding to the specified target for all subjects.\n * Does nothing if no subjects or no such permission exists.\n */\nexport type RevokePermissionForAllSubjects = {\n type: `${typeof controllerName}:revokePermissionForAllSubjects`;\n handler: GenericPermissionController['revokePermissionForAllSubjects'];\n};\n\n/**\n * Updates a caveat value for a specified caveat type belonging to a specific target and origin.\n */\nexport type UpdateCaveat = {\n type: `${typeof controllerName}:updateCaveat`;\n handler: GenericPermissionController['updateCaveat'];\n};\n\n/**\n * Clears all permissions from the {@link PermissionController}.\n */\nexport type ClearPermissions = {\n type: `${typeof controllerName}:clearPermissions`;\n handler: () => void;\n};\n\n/**\n * Gets the endowments for the given subject and permission.\n */\nexport type GetEndowments = {\n type: `${typeof controllerName}:getEndowments`;\n handler: GenericPermissionController['getEndowments'];\n};\n\n/**\n * The {@link Messenger} actions of the {@link PermissionController}.\n */\nexport type PermissionControllerActions =\n | ClearPermissions\n | GetEndowments\n | GetPermissionControllerState\n | GetSubjects\n | GetPermissions\n | HasPermission\n | HasPermissions\n | GrantPermissions\n | GrantPermissionsIncremental\n | RequestPermissions\n | RequestPermissionsIncremental\n | RevokeAllPermissions\n | RevokePermissionForAllSubjects\n | RevokePermissions\n | UpdateCaveat;\n\n/**\n * The generic state change event of the {@link PermissionController}.\n */\nexport type PermissionControllerStateChange = ControllerStateChangeEvent<\n typeof controllerName,\n PermissionControllerState\n>;\n\n/**\n * The {@link Messenger} events of the {@link PermissionController}.\n *\n * The permission controller only emits its generic state change events.\n * Consumers should use selector subscriptions to subscribe to relevant\n * substate.\n */\nexport type PermissionControllerEvents = PermissionControllerStateChange;\n\n/**\n * The external {@link Messenger} actions available to the\n * {@link PermissionController}.\n */\ntype AllowedActions =\n | AddApprovalRequest\n | HasApprovalRequest\n | AcceptApprovalRequest\n | RejectApprovalRequest\n | GetSubjectMetadata;\n\n/**\n * The messenger of the {@link PermissionController}.\n */\nexport type PermissionControllerMessenger = Messenger<\n typeof controllerName,\n PermissionControllerActions | AllowedActions,\n PermissionControllerEvents\n>;\n\nexport type SideEffectMessenger<\n Actions extends ActionConstraint,\n Events extends EventConstraint,\n> = Messenger;\n\n/**\n * A generic {@link PermissionController}.\n */\nexport type GenericPermissionController = PermissionController<\n PermissionSpecificationConstraint,\n CaveatSpecificationConstraint\n>;\n\n/**\n * Describes the possible results of a {@link CaveatMutator} function.\n */\nexport enum CaveatMutatorOperation {\n Noop,\n UpdateValue,\n DeleteCaveat,\n RevokePermission,\n}\n\n/**\n * Given a caveat value, returns a {@link CaveatMutatorOperation} and, optionally,\n * a new caveat value.\n *\n * @see {@link PermissionController.updatePermissionsByCaveat} for more details.\n * @template Caveat - The caveat type for which this mutator is intended.\n * @param caveatValue - The existing value of the caveat being mutated.\n * @returns A tuple of the mutation result and, optionally, the new caveat\n * value.\n */\nexport type CaveatMutator = (\n caveatValue: TargetCaveat['value'],\n) => CaveatMutatorResult;\n\ntype CaveatMutatorResult =\n | Readonly<{\n operation: CaveatMutatorOperation.UpdateValue;\n value: CaveatConstraint['value'];\n }>\n | Readonly<{\n operation: Exclude<\n CaveatMutatorOperation,\n CaveatMutatorOperation.UpdateValue\n >;\n }>;\n\ntype MergeCaveatResult =\n CaveatType extends undefined\n ? [CaveatConstraint, CaveatConstraint['value']]\n : [CaveatConstraint, CaveatConstraint['value']] | [];\n\n/**\n * Extracts the permission(s) specified by the given permission and caveat\n * specifications.\n *\n * @template ControllerPermissionSpecification - The permission specification(s)\n * to extract from.\n * @template ControllerCaveatSpecification - The caveat specification(s) to\n * extract from. Necessary because {@link Permission} has a generic parameter\n * that describes the allowed caveats for the permission.\n */\nexport type ExtractPermission<\n ControllerPermissionSpecification extends PermissionSpecificationConstraint,\n ControllerCaveatSpecification extends CaveatSpecificationConstraint,\n> =\n ControllerPermissionSpecification extends ValidPermissionSpecification\n ? ValidPermission<\n ControllerPermissionSpecification['targetName'],\n ExtractCaveats\n >\n : never;\n\n/**\n * Extracts the restricted method permission(s) specified by the given\n * permission and caveat specifications.\n *\n * @template ControllerPermissionSpecification - The permission specification(s)\n * to extract from.\n * @template ControllerCaveatSpecification - The caveat specification(s) to\n * extract from. Necessary because {@link Permission} has a generic parameter\n * that describes the allowed caveats for the permission.\n */\nexport type ExtractRestrictedMethodPermission<\n ControllerPermissionSpecification extends PermissionSpecificationConstraint,\n ControllerCaveatSpecification extends CaveatSpecificationConstraint,\n> = ExtractPermission<\n Extract<\n ControllerPermissionSpecification,\n RestrictedMethodSpecificationConstraint\n >,\n ControllerCaveatSpecification\n>;\n\n/**\n * Extracts the endowment permission(s) specified by the given permission and\n * caveat specifications.\n *\n * @template ControllerPermissionSpecification - The permission specification(s)\n * to extract from.\n * @template ControllerCaveatSpecification - The caveat specification(s) to\n * extract from. Necessary because {@link Permission} has a generic parameter\n * that describes the allowed caveats for the permission.\n */\nexport type ExtractEndowmentPermission<\n ControllerPermissionSpecification extends PermissionSpecificationConstraint,\n ControllerCaveatSpecification extends CaveatSpecificationConstraint,\n> = ExtractPermission<\n Extract,\n ControllerCaveatSpecification\n>;\n\n/**\n * Options for the {@link PermissionController} constructor.\n *\n * @template ControllerPermissionSpecification - A union of the types of all\n * permission specifications available to the controller. Any referenced caveats\n * must be included in the controller's caveat specifications.\n * @template ControllerCaveatSpecification - A union of the types of all\n * caveat specifications available to the controller.\n */\nexport type PermissionControllerOptions<\n ControllerPermissionSpecification extends PermissionSpecificationConstraint,\n ControllerCaveatSpecification extends CaveatSpecificationConstraint,\n> = {\n messenger: PermissionControllerMessenger;\n caveatSpecifications: CaveatSpecificationMap;\n permissionSpecifications: PermissionSpecificationMap;\n unrestrictedMethods: readonly string[];\n state?: Partial<\n PermissionControllerState<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n >;\n};\n\n/**\n * The permission controller. See the [Architecture](../ARCHITECTURE.md)\n * document for details.\n *\n * Assumes the existence of an {@link ApprovalController} reachable via the\n * {@link Messenger}.\n *\n * @template ControllerPermissionSpecification - A union of the types of all\n * permission specifications available to the controller. Any referenced caveats\n * must be included in the controller's caveat specifications.\n * @template ControllerCaveatSpecification - A union of the types of all\n * caveat specifications available to the controller.\n */\nexport class PermissionController<\n ControllerPermissionSpecification extends PermissionSpecificationConstraint,\n ControllerCaveatSpecification extends CaveatSpecificationConstraint,\n> extends BaseController<\n typeof controllerName,\n PermissionControllerState<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >,\n PermissionControllerMessenger\n> {\n private readonly _caveatSpecifications: Readonly<\n CaveatSpecificationMap\n >;\n\n private readonly _permissionSpecifications: Readonly<\n PermissionSpecificationMap\n >;\n\n private readonly _unrestrictedMethods: ReadonlySet;\n\n /**\n * The names of all JSON-RPC methods that will be ignored by the controller.\n *\n * @returns The names of all unrestricted JSON-RPC methods\n */\n public get unrestrictedMethods(): ReadonlySet {\n return this._unrestrictedMethods;\n }\n\n /**\n * Returns a `json-rpc-engine` middleware function factory, so that the rules\n * described by the state of this controller can be applied to incoming\n * JSON-RPC requests.\n *\n * The middleware **must** be added in the correct place in the middleware\n * stack in order for it to work. See the README for an example.\n */\n public createPermissionMiddleware: ReturnType<\n typeof getPermissionMiddlewareFactory\n >;\n\n /**\n * Constructs the PermissionController.\n *\n * @param options - Permission controller options.\n * @param options.caveatSpecifications - The specifications of all caveats\n * available to the controller. See {@link CaveatSpecificationMap} and the\n * documentation for more details.\n * @param options.permissionSpecifications - The specifications of all\n * permissions available to the controller. See\n * {@link PermissionSpecificationMap} and the README for more details.\n * @param options.unrestrictedMethods - The callable names of all JSON-RPC\n * methods ignored by the new controller.\n * @param options.messenger - The messenger. See\n * {@link BaseController} for more information.\n * @param options.state - Existing state to hydrate the controller with at\n * initialization.\n */\n constructor(\n options: PermissionControllerOptions<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >,\n ) {\n const {\n caveatSpecifications,\n permissionSpecifications,\n unrestrictedMethods,\n messenger,\n state = {},\n } = options;\n\n super({\n name: controllerName,\n metadata:\n getStateMetadata<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >(),\n messenger,\n state: {\n ...getDefaultState<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >(),\n ...state,\n },\n });\n\n this._unrestrictedMethods = new Set(unrestrictedMethods);\n this._caveatSpecifications = deepFreeze({ ...caveatSpecifications });\n\n this.validatePermissionSpecifications(\n permissionSpecifications,\n this._caveatSpecifications,\n );\n\n this._permissionSpecifications = deepFreeze({\n ...permissionSpecifications,\n });\n\n this.registerMessageHandlers();\n this.createPermissionMiddleware = getPermissionMiddlewareFactory({\n executeRestrictedMethod: this._executeRestrictedMethod.bind(this),\n getRestrictedMethod: this.getRestrictedMethod.bind(this),\n isUnrestrictedMethod: this.unrestrictedMethods.has.bind(\n this.unrestrictedMethods,\n ),\n });\n }\n\n /**\n * Gets a permission specification.\n *\n * @param targetName - The name of the permission specification to get.\n * @returns The permission specification with the specified target name.\n */\n private getPermissionSpecification<\n TargetName extends ControllerPermissionSpecification['targetName'],\n >(\n targetName: TargetName,\n ): ExtractPermissionSpecification<\n ControllerPermissionSpecification,\n TargetName\n > {\n return this._permissionSpecifications[targetName];\n }\n\n /**\n * Gets a caveat specification.\n *\n * @param caveatType - The type of the caveat specification to get.\n * @returns The caveat specification with the specified type.\n */\n private getCaveatSpecification<\n CaveatType extends ControllerCaveatSpecification['type'],\n >(caveatType: CaveatType) {\n return this._caveatSpecifications[caveatType];\n }\n\n /**\n * Gets the merger function for the specified caveat. Throws if no\n * merger exists.\n *\n * @param caveatType - The type of the caveat whose merger to get.\n * @returns The caveat value merger function for the specified caveat type.\n */\n #expectGetCaveatMerger<\n CaveatType extends ControllerCaveatSpecification['type'],\n >(caveatType: CaveatType): CaveatValueMerger {\n const { merger } = this.getCaveatSpecification(caveatType);\n\n if (merger === undefined) {\n throw new CaveatMergerDoesNotExistError(caveatType);\n }\n return merger;\n }\n\n /**\n * Constructor helper for validating permission specifications.\n *\n * Throws an error if validation fails.\n *\n * @param permissionSpecifications - The permission specifications passed to\n * this controller's constructor.\n * @param caveatSpecifications - The caveat specifications passed to this\n * controller.\n */\n private validatePermissionSpecifications(\n permissionSpecifications: PermissionSpecificationMap,\n caveatSpecifications: CaveatSpecificationMap,\n ) {\n Object.entries(\n permissionSpecifications,\n ).forEach(\n ([\n targetName,\n { permissionType, targetName: innerTargetName, allowedCaveats },\n ]) => {\n if (!permissionType || !hasProperty(PermissionType, permissionType)) {\n throw new Error(`Invalid permission type: \"${permissionType}\"`);\n }\n\n if (!targetName) {\n throw new Error(`Invalid permission target name: \"${targetName}\"`);\n }\n\n if (targetName !== innerTargetName) {\n throw new Error(\n `Invalid permission specification: target name \"${targetName}\" must match specification.targetName value \"${innerTargetName}\".`,\n );\n }\n\n if (allowedCaveats) {\n allowedCaveats.forEach((caveatType) => {\n if (!hasProperty(caveatSpecifications, caveatType)) {\n throw new UnrecognizedCaveatTypeError(caveatType);\n }\n\n const specification =\n caveatSpecifications[\n caveatType as ControllerCaveatSpecification['type']\n ];\n const isRestrictedMethodCaveat =\n isRestrictedMethodCaveatSpecification(specification);\n\n if (\n (permissionType === PermissionType.RestrictedMethod &&\n !isRestrictedMethodCaveat) ||\n (permissionType === PermissionType.Endowment &&\n isRestrictedMethodCaveat)\n ) {\n throw new CaveatSpecificationMismatchError(\n specification,\n permissionType,\n );\n }\n });\n }\n },\n );\n }\n\n /**\n * Constructor helper for registering the controller's messenger actions.\n */\n private registerMessageHandlers(): void {\n this.messenger.registerActionHandler(\n `${controllerName}:clearPermissions` as const,\n () => this.clearState(),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:getEndowments` as const,\n (origin: string, targetName: string, requestData?: unknown) =>\n this.getEndowments(origin, targetName, requestData),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:getSubjectNames` as const,\n () => this.getSubjectNames(),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:getPermissions` as const,\n (origin: OriginString) => this.getPermissions(origin),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:hasPermission` as const,\n (origin: OriginString, targetName: string) =>\n this.hasPermission(origin, targetName),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:hasPermissions` as const,\n (origin: OriginString) => this.hasPermissions(origin),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:grantPermissions` as const,\n this.grantPermissions.bind(this),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:grantPermissionsIncremental` as const,\n this.grantPermissionsIncremental.bind(this),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:requestPermissions` as const,\n (subject: PermissionSubjectMetadata, permissions: RequestedPermissions) =>\n this.requestPermissions(subject, permissions),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:requestPermissionsIncremental` as const,\n (subject: PermissionSubjectMetadata, permissions: RequestedPermissions) =>\n this.requestPermissionsIncremental(subject, permissions),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:revokeAllPermissions` as const,\n (origin: OriginString) => this.revokeAllPermissions(origin),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:revokePermissionForAllSubjects` as const,\n (\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n ) => this.revokePermissionForAllSubjects(target),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:revokePermissions` as const,\n this.revokePermissions.bind(this),\n );\n\n this.messenger.registerActionHandler(\n `${controllerName}:updateCaveat` as const,\n (origin, target, caveatType, caveatValue) => {\n this.updateCaveat(\n origin,\n target,\n caveatType as ExtractAllowedCaveatTypes,\n caveatValue,\n );\n },\n );\n }\n\n /**\n * Clears the state of the controller.\n */\n clearState(): void {\n this.update((_draftState) => {\n return {\n ...getDefaultState<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >(),\n };\n });\n }\n\n /**\n * Gets the permission specification corresponding to the given permission\n * type and target name. Throws an error if the target name does not\n * correspond to a permission, or if the specification is not of the\n * given permission type.\n *\n * @template Type - The type of the permission specification to get.\n * @param permissionType - The type of the permission specification to get.\n * @param targetName - The name of the permission whose specification to get.\n * @param requestingOrigin - The origin of the requesting subject, if any.\n * Will be added to any thrown errors.\n * @returns The specification object corresponding to the given type and\n * target name.\n */\n private getTypedPermissionSpecification(\n permissionType: Type,\n targetName: string,\n requestingOrigin?: string,\n ): ControllerPermissionSpecification & { permissionType: Type } {\n const failureError =\n permissionType === PermissionType.RestrictedMethod\n ? methodNotFound(\n targetName,\n requestingOrigin ? { origin: requestingOrigin } : undefined,\n )\n : new EndowmentPermissionDoesNotExistError(\n targetName,\n requestingOrigin,\n );\n\n if (!this.targetExists(targetName)) {\n throw failureError;\n }\n\n const specification = this.getPermissionSpecification(targetName);\n if (!hasSpecificationType(specification, permissionType)) {\n throw failureError;\n }\n\n return specification;\n }\n\n /**\n * Gets the implementation of the specified restricted method.\n *\n * A JSON-RPC error is thrown if the method does not exist.\n *\n * @see {@link PermissionController.executeRestrictedMethod} and\n * {@link PermissionController.createPermissionMiddleware} for internal usage.\n * @param method - The name of the restricted method.\n * @param origin - The origin associated with the request for the restricted\n * method, if any.\n * @returns The restricted method implementation.\n */\n getRestrictedMethod(\n method: string,\n origin?: string,\n ): RestrictedMethod {\n return this.getTypedPermissionSpecification(\n PermissionType.RestrictedMethod,\n method,\n origin,\n ).methodImplementation;\n }\n\n /**\n * Gets a list of all origins of subjects.\n *\n * @returns The origins (i.e. IDs) of all subjects.\n */\n getSubjectNames(): OriginString[] {\n return Object.keys(this.state.subjects);\n }\n\n /**\n * Gets the permission for the specified target of the subject corresponding\n * to the specified origin.\n *\n * @param origin - The origin of the subject.\n * @param targetName - The method name as invoked by a third party (i.e., not\n * a method key).\n * @returns The permission if it exists, or undefined otherwise.\n */\n getPermission<\n SubjectPermission extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >,\n >(\n origin: OriginString,\n targetName: SubjectPermission['parentCapability'],\n ): SubjectPermission | undefined {\n return this.state.subjects[origin]?.permissions[targetName] as\n | SubjectPermission\n | undefined;\n }\n\n /**\n * Gets all permissions for the specified subject, if any.\n *\n * @param origin - The origin of the subject.\n * @returns The permissions of the subject, if any.\n */\n getPermissions(\n origin: OriginString,\n ):\n | SubjectPermissions<\n ValidPermission>\n >\n | undefined {\n return this.state.subjects[origin]?.permissions;\n }\n\n /**\n * Checks whether the subject with the specified origin has the specified\n * permission.\n *\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @returns Whether the subject has the permission.\n */\n hasPermission(\n origin: OriginString,\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n ): boolean {\n return Boolean(this.getPermission(origin, target));\n }\n\n /**\n * Checks whether the subject with the specified origin has any permissions.\n * Use this if you want to know if a subject \"exists\".\n *\n * @param origin - The origin of the subject to check.\n * @returns Whether the subject has any permissions.\n */\n hasPermissions(origin: OriginString): boolean {\n return Boolean(this.state.subjects[origin]);\n }\n\n /**\n * Revokes all permissions from the specified origin.\n *\n * Throws an error of the origin has no permissions.\n *\n * @param origin - The origin whose permissions to revoke.\n */\n revokeAllPermissions(origin: OriginString): void {\n this.update((draftState) => {\n if (!draftState.subjects[origin]) {\n throw new UnrecognizedSubjectError(origin);\n }\n delete draftState.subjects[origin];\n });\n }\n\n /**\n * Revokes the specified permission from the subject with the specified\n * origin.\n *\n * Throws an error if the subject or the permission does not exist.\n *\n * @param origin - The origin of the subject whose permission to revoke.\n * @param target - The target name of the permission to revoke.\n */\n revokePermission(\n origin: OriginString,\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n ): void {\n this.revokePermissions({ [origin]: [target] });\n }\n\n /**\n * Revokes the specified permissions from the specified subjects.\n *\n * Throws an error if any of the subjects or permissions do not exist.\n *\n * @param subjectsAndPermissions - An object mapping subject origins\n * to arrays of permission target names to revoke.\n */\n revokePermissions(\n subjectsAndPermissions: Record<\n OriginString,\n NonEmptyArray<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability']\n >\n >,\n ): void {\n this.update((draftState) => {\n Object.keys(subjectsAndPermissions).forEach((origin) => {\n if (!hasProperty(draftState.subjects, origin)) {\n throw new UnrecognizedSubjectError(origin);\n }\n\n subjectsAndPermissions[origin].forEach((target) => {\n const { permissions } = draftState.subjects[origin];\n if (!hasProperty(permissions as Record, target)) {\n throw new PermissionDoesNotExistError(origin, target);\n }\n\n this.deletePermission(draftState.subjects, origin, target);\n });\n });\n });\n }\n\n /**\n * Revokes all permissions corresponding to the specified target for all subjects.\n * Does nothing if no subjects or no such permission exists.\n *\n * @param target - The name of the target to revoke all permissions for.\n */\n revokePermissionForAllSubjects(\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n ): void {\n if (this.getSubjectNames().length === 0) {\n return;\n }\n\n this.update((draftState) => {\n Object.entries(draftState.subjects).forEach(([origin, subject]) => {\n const { permissions } = subject;\n\n if (hasProperty(permissions as Record, target)) {\n this.deletePermission(draftState.subjects, origin, target);\n }\n });\n });\n }\n\n /**\n * Deletes the permission identified by the given origin and target. If the\n * permission is the single remaining permission of its subject, the subject\n * is also deleted.\n *\n * @param subjects - The draft permission controller subjects.\n * @param origin - The origin of the subject associated with the permission\n * to delete.\n * @param target - The target name of the permission to delete.\n */\n private deletePermission(\n subjects: Draft>,\n origin: OriginString,\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n ): void {\n const { permissions } = subjects[origin];\n if (Object.keys(permissions).length > 1) {\n delete permissions[target];\n } else {\n delete subjects[origin];\n }\n }\n\n /**\n * Checks whether the permission of the subject corresponding to the given\n * origin has a caveat of the specified type.\n *\n * Throws an error if the subject does not have a permission with the\n * specified target name.\n *\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to check for.\n * @returns Whether the permission has the specified caveat.\n */\n hasCaveat<\n TargetName extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n CaveatType extends\n ExtractAllowedCaveatTypes,\n >(origin: OriginString, target: TargetName, caveatType: CaveatType): boolean {\n return Boolean(this.getCaveat(origin, target, caveatType));\n }\n\n /**\n * Gets the caveat of the specified type, if any, for the permission of\n * the subject corresponding to the given origin.\n *\n * Throws an error if the subject does not have a permission with the\n * specified target name.\n *\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to get.\n * @returns The caveat, or `undefined` if no such caveat exists.\n */\n getCaveat<\n TargetName extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n CaveatType extends\n ExtractAllowedCaveatTypes,\n >(\n origin: OriginString,\n target: TargetName,\n caveatType: CaveatType,\n ): ExtractCaveat | undefined {\n const permission = this.getPermission(origin, target);\n if (!permission) {\n throw new PermissionDoesNotExistError(origin, target);\n }\n\n return findCaveat(permission, caveatType) as\n | ExtractCaveat\n | undefined;\n }\n\n /**\n * Adds a caveat of the specified type, with the specified caveat value, to\n * the permission corresponding to the given subject origin and permission\n * target.\n *\n * For modifying existing caveats, use\n * {@link PermissionController.updateCaveat}.\n *\n * Throws an error if no such permission exists, or if the caveat already\n * exists.\n *\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to add.\n * @param caveatValue - The value of the caveat to add.\n */\n addCaveat<\n TargetName extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n CaveatType extends\n ExtractAllowedCaveatTypes,\n >(\n origin: OriginString,\n target: TargetName,\n caveatType: CaveatType,\n caveatValue: ExtractCaveatValue,\n ): void {\n if (this.hasCaveat(origin, target, caveatType)) {\n throw new CaveatAlreadyExistsError(origin, target, caveatType);\n }\n\n this.setCaveat(origin, target, caveatType, caveatValue);\n }\n\n /**\n * Updates the value of the caveat of the specified type belonging to the\n * permission corresponding to the given subject origin and permission\n * target.\n *\n * For adding new caveats, use\n * {@link PermissionController.addCaveat}.\n *\n * Throws an error if no such permission or caveat exists.\n *\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to update.\n * @param caveatValue - The new value of the caveat.\n */\n updateCaveat<\n TargetName extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n CaveatType extends\n ExtractAllowedCaveatTypes,\n CaveatValue extends ExtractCaveatValue<\n ControllerCaveatSpecification,\n CaveatType\n >,\n >(\n origin: OriginString,\n target: TargetName,\n caveatType: CaveatType,\n caveatValue: CaveatValue,\n ): void {\n if (!this.hasCaveat(origin, target, caveatType)) {\n throw new CaveatDoesNotExistError(origin, target, caveatType);\n }\n\n this.setCaveat(origin, target, caveatType, caveatValue);\n }\n\n /**\n * Sets the specified caveat on the specified permission. Overwrites existing\n * caveats of the same type in-place (preserving array order), and adds the\n * caveat to the end of the array otherwise.\n *\n * Throws an error if the permission does not exist or fails to validate after\n * its caveats have been modified.\n *\n * @see {@link PermissionController.addCaveat}\n * @see {@link PermissionController.updateCaveat}\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to set.\n * @param caveatValue - The value of the caveat to set.\n */\n private setCaveat<\n TargetName extends ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n CaveatType extends\n ExtractAllowedCaveatTypes,\n >(\n origin: OriginString,\n target: TargetName,\n caveatType: CaveatType,\n caveatValue: ExtractCaveatValue,\n ): void {\n this.update((draftState) => {\n const subject = draftState.subjects[origin];\n\n // Unreachable because `hasCaveat` is always called before this, and it\n // throws if permissions are missing. TypeScript needs this, however.\n /* istanbul ignore if */\n if (!subject) {\n throw new UnrecognizedSubjectError(origin);\n }\n\n const permission = subject.permissions[target];\n\n /* istanbul ignore if: practically impossible, but TypeScript wants it */\n if (!permission) {\n throw new PermissionDoesNotExistError(origin, target);\n }\n\n const caveat = {\n type: caveatType,\n value: caveatValue,\n };\n this.validateCaveat(caveat, origin, target);\n\n let addedCaveat = false;\n if (permission.caveats) {\n const caveatIndex = permission.caveats.findIndex(\n (existingCaveat) => existingCaveat.type === caveat.type,\n );\n\n if (caveatIndex === -1) {\n permission.caveats.push(caveat);\n addedCaveat = true;\n } else {\n permission.caveats.splice(caveatIndex, 1, caveat);\n }\n } else {\n // At this point, we don't know if the specific permission is allowed\n // to have caveats, but it should be impossible to call this method\n // for a permission that may not have any caveats. If all else fails,\n // the permission validator is also called.\n // @ts-expect-error See above comment\n permission.caveats = [caveat];\n addedCaveat = true;\n }\n\n // Mutating a caveat does not warrant permission validation, but mutating\n // the caveat array does.\n if (addedCaveat) {\n this.validateModifiedPermission(permission, origin, {\n invokePermissionValidator: true,\n performCaveatValidation: false, // We just validated the caveat\n });\n }\n });\n }\n\n /**\n * Updates all caveats with the specified type for all subjects and\n * permissions by applying the specified mutator function to them.\n *\n * ATTN: Permissions can be revoked entirely by the action of this method,\n * read on for details.\n *\n * Caveat mutators are functions that receive a caveat value and return a\n * tuple consisting of a {@link CaveatMutatorOperation} and, optionally, a new\n * value to update the existing caveat with.\n *\n * For each caveat, depending on the mutator result, this method will:\n * - Do nothing ({@link CaveatMutatorOperation.Noop})\n * - Update the value of the caveat ({@link CaveatMutatorOperation.UpdateValue}). The caveat specification validator, if any, will be called after updating the value.\n * - Delete the caveat ({@link CaveatMutatorOperation.DeleteCaveat}). The permission specification validator, if any, will be called after deleting the caveat.\n * - Revoke the parent permission ({@link CaveatMutatorOperation.RevokePermission})\n *\n * This method throws if the validation of any caveat or permission fails.\n *\n * @param targetCaveatType - The type of the caveats to update.\n * @param mutator - The mutator function which will be applied to all caveat\n * values.\n */\n updatePermissionsByCaveat<\n CaveatType extends ExtractCaveats['type'],\n TargetCaveat extends ExtractCaveat<\n ControllerCaveatSpecification,\n CaveatType\n >,\n >(targetCaveatType: CaveatType, mutator: CaveatMutator): void {\n if (Object.keys(this.state.subjects).length === 0) {\n return;\n }\n\n this.update((draftState) => {\n Object.values(draftState.subjects).forEach((subject) => {\n Object.values(subject.permissions).forEach((permission) => {\n const { caveats } = permission;\n const targetCaveat = caveats?.find(\n ({ type }) => type === targetCaveatType,\n );\n if (!targetCaveat) {\n return;\n }\n\n // The mutator may modify the caveat value in place, and must always\n // return a valid mutation result.\n const mutatorResult = mutator(targetCaveat.value);\n const { operation } = mutatorResult;\n switch (operation) {\n case CaveatMutatorOperation.Noop:\n break;\n\n case CaveatMutatorOperation.UpdateValue:\n // Typecast: `Mutable` is used here to assign to a readonly\n // property. `targetConstraint` should already be mutable because\n // it's part of a draft, but for some reason it's not. We can't\n // use the more-correct `Draft` type here either because it\n // results in an error.\n (targetCaveat as Mutable).value =\n mutatorResult.value;\n\n this.validateCaveat(\n targetCaveat,\n subject.origin,\n permission.parentCapability,\n );\n break;\n\n case CaveatMutatorOperation.DeleteCaveat:\n this.deleteCaveat(permission, targetCaveatType, subject.origin);\n break;\n\n case CaveatMutatorOperation.RevokePermission:\n this.deletePermission(\n draftState.subjects,\n subject.origin,\n permission.parentCapability,\n );\n break;\n\n default: {\n // Overriding as `never` is the expected result of exhaustiveness checking,\n // and is intended to represent unchecked exception cases.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n throw new Error(`Unrecognized mutation result: \"${operation}\"`);\n }\n }\n });\n });\n });\n }\n\n /**\n * Removes the caveat of the specified type from the permission corresponding\n * to the given subject origin and target name.\n *\n * Throws an error if no such permission or caveat exists.\n *\n * @template TargetName - The permission target name. Should be inferred.\n * @template CaveatType - The valid caveat types for the permission. Should\n * be inferred.\n * @param origin - The origin of the subject.\n * @param target - The target name of the permission.\n * @param caveatType - The type of the caveat to remove.\n */\n removeCaveat<\n TargetName extends ControllerPermissionSpecification['targetName'],\n CaveatType extends\n ExtractAllowedCaveatTypes,\n >(origin: OriginString, target: TargetName, caveatType: CaveatType): void {\n this.update((draftState) => {\n const permission = draftState.subjects[origin]?.permissions[target];\n if (!permission) {\n throw new PermissionDoesNotExistError(origin, target);\n }\n\n if (!permission.caveats) {\n throw new CaveatDoesNotExistError(origin, target, caveatType);\n }\n\n this.deleteCaveat(permission, caveatType, origin);\n });\n }\n\n /**\n * Deletes the specified caveat from the specified permission. If no caveats\n * remain after deletion, the permission's caveat property is set to `null`.\n * The permission is validated after being modified.\n *\n * Throws an error if the permission does not have a caveat with the specified\n * type.\n *\n * @param permission - The permission whose caveat to delete.\n * @param caveatType - The type of the caveat to delete.\n * @param origin - The origin the permission subject.\n */\n private deleteCaveat<\n CaveatType extends ExtractCaveats['type'],\n >(\n permission: Draft,\n caveatType: CaveatType,\n origin: OriginString,\n ): void {\n /* istanbul ignore if: not possible in our usage */\n if (!permission.caveats) {\n throw new CaveatDoesNotExistError(\n origin,\n permission.parentCapability,\n caveatType,\n );\n }\n\n const caveatIndex = permission.caveats.findIndex(\n (existingCaveat) => existingCaveat.type === caveatType,\n );\n\n if (caveatIndex === -1) {\n throw new CaveatDoesNotExistError(\n origin,\n permission.parentCapability,\n caveatType,\n );\n }\n\n if (permission.caveats.length === 1) {\n permission.caveats = null;\n } else {\n permission.caveats.splice(caveatIndex, 1);\n }\n\n this.validateModifiedPermission(permission, origin, {\n invokePermissionValidator: true,\n performCaveatValidation: false, // No caveat object was mutated\n });\n }\n\n /**\n * Validates the specified modified permission. Should **always** be invoked\n * on a permission when its caveat array has been mutated.\n *\n * Just like {@link PermissionController.validatePermission}, except that the\n * corresponding target name and specification are retrieved first, and an\n * error is thrown if the target name does not exist.\n *\n * @param permission - The modified permission to validate.\n * @param origin - The origin associated with the permission.\n * @param validationFlags - Validation flags. See {@link PermissionController.validatePermission}.\n */\n private validateModifiedPermission(\n permission: Draft,\n origin: OriginString,\n validationFlags: PermissionValidationFlags,\n ): void {\n /* istanbul ignore if: this should be impossible */\n if (!this.targetExists(permission.parentCapability)) {\n throw new Error(\n `Fatal: Existing permission target \"${permission.parentCapability}\" has no specification.`,\n );\n }\n\n this.validatePermission(\n this.getPermissionSpecification(permission.parentCapability),\n permission as PermissionConstraint,\n origin,\n validationFlags,\n );\n }\n\n /**\n * Verifies the existence the specified permission target, i.e. whether it has\n * a specification.\n *\n * @param target - The requested permission target.\n * @returns Whether the permission target exists.\n */\n private targetExists(\n target: string,\n ): target is ControllerPermissionSpecification['targetName'] {\n return hasProperty(this._permissionSpecifications, target);\n }\n\n /**\n * Grants _approved_ permissions to the specified subject. Every permission and\n * caveat is stringently validated—including by calling their specification\n * validators—and an error is thrown if validation fails.\n *\n * ATTN: This method does **not** prompt the user for approval. User consent must\n * first be obtained through some other means.\n *\n * @see {@link PermissionController.requestPermissions} For initiating a\n * permissions request requiring user approval.\n * @param options - Options bag.\n * @param options.approvedPermissions - The requested permissions approved by\n * the user.\n * @param options.requestData - Permission request data. Passed to permission\n * factory functions.\n * @param options.preserveExistingPermissions - Whether to preserve the\n * subject's existing permissions.\n * @param options.subject - The subject to grant permissions to.\n * @returns The subject's new permission state. It may or may not have changed.\n */\n grantPermissions({\n approvedPermissions,\n requestData,\n preserveExistingPermissions = true,\n subject,\n }: {\n approvedPermissions: RequestedPermissions;\n subject: PermissionSubjectMetadata;\n preserveExistingPermissions?: boolean;\n requestData?: Record;\n }): Partial<\n SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n > {\n return this.#applyGrantedPermissions({\n approvedPermissions,\n subject,\n mergePermissions: false,\n preserveExistingPermissions,\n requestData,\n });\n }\n\n /**\n * Incrementally grants _approved_ permissions to the specified subject. Every\n * permission and caveat is stringently validated—including by calling their\n * specification validators—and an error is thrown if validation fails.\n *\n * ATTN: This method does **not** prompt the user for approval. User consent must\n * first be obtained through some other means.\n *\n * @see {@link PermissionController.requestPermissionsIncremental} For initiating\n * an incremental permissions request requiring user approval.\n * @param options - Options bag.\n * @param options.approvedPermissions - The requested permissions approved by\n * the user.\n * @param options.requestData - Permission request data. Passed to permission\n * factory functions.\n * @param options.subject - The subject to grant permissions to.\n * @returns The subject's new permission state. It may or may not have changed.\n */\n grantPermissionsIncremental({\n approvedPermissions,\n requestData,\n subject,\n }: {\n approvedPermissions: RequestedPermissions;\n subject: PermissionSubjectMetadata;\n requestData?: Record;\n }): Partial<\n SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n > {\n return this.#applyGrantedPermissions({\n approvedPermissions,\n subject,\n mergePermissions: true,\n preserveExistingPermissions: true,\n requestData,\n });\n }\n\n #applyGrantedPermissions({\n approvedPermissions,\n subject,\n mergePermissions,\n preserveExistingPermissions,\n requestData,\n }: {\n approvedPermissions: RequestedPermissions;\n subject: PermissionSubjectMetadata;\n mergePermissions: boolean;\n preserveExistingPermissions: boolean;\n requestData?: Record;\n }): Partial<\n SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n > {\n const { origin } = subject;\n\n if (!origin || typeof origin !== 'string') {\n throw new InvalidSubjectIdentifierError(origin);\n }\n\n const permissions = (\n preserveExistingPermissions\n ? {\n ...this.getPermissions(origin),\n }\n : {}\n ) as SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >;\n\n for (const [requestedTarget, approvedPermission] of Object.entries(\n approvedPermissions,\n )) {\n if (!this.targetExists(requestedTarget)) {\n throw methodNotFound(requestedTarget);\n }\n\n if (\n approvedPermission.parentCapability !== undefined &&\n requestedTarget !== approvedPermission.parentCapability\n ) {\n throw new InvalidApprovedPermissionError(\n origin,\n requestedTarget,\n approvedPermission,\n );\n }\n\n // We have verified that the target exists, and reassign it to change its\n // type.\n const targetName = requestedTarget as ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'];\n const specification = this.getPermissionSpecification(targetName);\n\n // The requested caveats are validated here.\n const caveats = this.constructCaveats(\n origin,\n targetName,\n approvedPermission.caveats,\n );\n\n const permissionOptions = {\n caveats,\n invoker: origin,\n target: targetName,\n };\n\n let permission: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >;\n if (specification.factory) {\n permission = specification.factory(permissionOptions, requestData);\n } else {\n permission = constructPermission(permissionOptions);\n }\n\n if (mergePermissions) {\n permission = this.#mergePermission(\n permissions[targetName],\n permission,\n )[0];\n }\n\n this.validatePermission(specification, permission, origin, {\n invokePermissionValidator: true,\n performCaveatValidation: true,\n });\n permissions[targetName] = permission;\n }\n\n this.setValidatedPermissions(origin, permissions);\n return permissions;\n }\n\n /**\n * Validates the specified permission by:\n * - Ensuring that if `subjectTypes` is specified, the subject requesting the permission is of a type in the list.\n * - Ensuring that its `caveats` property is either `null` or a non-empty array.\n * - Ensuring that it only includes caveats allowed by its specification.\n * - Ensuring that it includes no duplicate caveats (by caveat type).\n * - Validating each caveat object, if `performCaveatValidation` is `true`.\n * - Calling the validator of its specification, if one exists and `invokePermissionValidator` is `true`.\n *\n * An error is thrown if validation fails.\n *\n * @param specification - The specification of the permission.\n * @param permission - The permission to validate.\n * @param origin - The origin associated with the permission.\n * @param validationOptions - Validation options.\n * @param validationOptions.invokePermissionValidator - Whether to invoke the\n * permission's consumer-specified validator function, if any.\n * @param validationOptions.performCaveatValidation - Whether to invoke\n * {@link PermissionController.validateCaveat} on each of the permission's\n * caveats.\n */\n private validatePermission(\n specification: PermissionSpecificationConstraint,\n permission: PermissionConstraint,\n origin: OriginString,\n {\n invokePermissionValidator,\n performCaveatValidation,\n }: PermissionValidationFlags,\n ): void {\n const { allowedCaveats, validator, targetName } = specification;\n\n if (\n specification.subjectTypes?.length &&\n specification.subjectTypes.length > 0\n ) {\n const metadata = this.messenger.call(\n 'SubjectMetadataController:getSubjectMetadata',\n origin,\n );\n\n if (\n !metadata ||\n metadata.subjectType === null ||\n !specification.subjectTypes.includes(metadata.subjectType)\n ) {\n throw specification.permissionType === PermissionType.RestrictedMethod\n ? methodNotFound(targetName, { origin })\n : new EndowmentPermissionDoesNotExistError(targetName, origin);\n }\n }\n\n if (hasProperty(permission, 'caveats')) {\n const { caveats } = permission;\n\n if (caveats !== null && !(Array.isArray(caveats) && caveats.length > 0)) {\n throw new InvalidCaveatsPropertyError(origin, targetName, caveats);\n }\n\n const seenCaveatTypes = new Set();\n caveats?.forEach((caveat) => {\n if (performCaveatValidation) {\n this.validateCaveat(caveat, origin, targetName);\n }\n\n if (!allowedCaveats?.includes(caveat.type)) {\n throw new ForbiddenCaveatError(caveat.type, origin, targetName);\n }\n\n if (seenCaveatTypes.has(caveat.type)) {\n throw new DuplicateCaveatError(caveat.type, origin, targetName);\n }\n seenCaveatTypes.add(caveat.type);\n });\n }\n\n if (invokePermissionValidator && validator) {\n validator(permission, origin, targetName);\n }\n }\n\n /**\n * Assigns the specified permissions to the subject with the given origin.\n * Overwrites all existing permissions, and creates a subject entry if it\n * doesn't already exist.\n *\n * ATTN: Assumes that the new permissions have been validated.\n *\n * @param origin - The origin of the grantee subject.\n * @param permissions - The new permissions for the grantee subject.\n */\n private setValidatedPermissions(\n origin: OriginString,\n permissions: Record<\n string,\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >,\n ): void {\n this.update((draftState) => {\n if (!draftState.subjects[origin]) {\n draftState.subjects[origin] = { origin, permissions: {} };\n }\n\n draftState.subjects[origin].permissions = castDraft(permissions);\n });\n }\n\n /**\n * Validates the requested caveats for the permission of the specified\n * subject origin and target name and returns the validated caveat array.\n *\n * Throws an error if validation fails.\n *\n * @param origin - The origin of the permission subject.\n * @param target - The permission target name.\n * @param requestedCaveats - The requested caveats to construct.\n * @returns The constructed caveats.\n */\n private constructCaveats(\n origin: OriginString,\n target: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n requestedCaveats?: unknown[] | null,\n ): NonEmptyArray> | undefined {\n const caveatArray = requestedCaveats?.map((requestedCaveat) => {\n this.validateCaveat(requestedCaveat, origin, target);\n\n // Reassign so that we have a fresh object.\n const { type, value } = requestedCaveat as CaveatConstraint;\n return { type, value } as ExtractCaveats;\n });\n\n return caveatArray && isNonEmptyArray(caveatArray)\n ? caveatArray\n : undefined;\n }\n\n /**\n * This methods validates that the specified caveat is an object with the\n * expected properties and types. It also ensures that a caveat specification\n * exists for the requested caveat type, and calls the specification\n * validator, if it exists, on the caveat object.\n *\n * Throws an error if validation fails.\n *\n * @param caveat - The caveat object to validate.\n * @param origin - The origin associated with the subject of the parent\n * permission.\n * @param target - The target name associated with the parent permission.\n */\n private validateCaveat(\n caveat: unknown,\n origin: OriginString,\n target: string,\n ): void {\n if (!isPlainObject(caveat)) {\n throw new InvalidCaveatError(caveat, origin, target);\n }\n\n if (Object.keys(caveat).length !== 2) {\n throw new InvalidCaveatFieldsError(caveat, origin, target);\n }\n\n if (typeof caveat.type !== 'string') {\n throw new InvalidCaveatTypeError(caveat, origin, target);\n }\n\n const specification = this.getCaveatSpecification(caveat.type);\n if (!specification) {\n throw new UnrecognizedCaveatTypeError(caveat.type, origin, target);\n }\n\n if (!hasProperty(caveat, 'value') || caveat.value === undefined) {\n throw new CaveatMissingValueError(caveat, origin, target);\n }\n\n if (!isValidJson(caveat.value)) {\n throw new CaveatInvalidJsonError(caveat, origin, target);\n }\n\n // Typecast: TypeScript still believes that the caveat is a PlainObject.\n specification.validator?.(caveat as CaveatConstraint, origin, target);\n }\n\n /**\n * Initiates a permission request that requires user approval.\n *\n * Either this or {@link PermissionController.requestPermissionsIncremental}\n * should always be used to grant additional permissions to a subject,\n * unless user approval has been obtained through some other means.\n *\n * Permissions are validated at every step of the approval process, and this\n * method will reject if validation fails.\n *\n * @see {@link ApprovalController} For the user approval logic.\n * @see {@link PermissionController.acceptPermissionsRequest} For the method\n * that _accepts_ the request and resolves the user approval promise.\n * @see {@link PermissionController.rejectPermissionsRequest} For the method\n * that _rejects_ the request and the user approval promise.\n * @param subject - The grantee subject.\n * @param requestedPermissions - The requested permissions.\n * @param options - Additional options.\n * @param options.id - The id of the permissions request. Defaults to a unique\n * id.\n * @param options.preserveExistingPermissions - Whether to preserve the\n * subject's existing permissions. Defaults to `true`.\n * @param options.metadata - Additional metadata about the permission request.\n * @returns The granted permissions and request metadata.\n */\n async requestPermissions(\n subject: PermissionSubjectMetadata,\n requestedPermissions: RequestedPermissions,\n options: {\n id?: string;\n preserveExistingPermissions?: boolean;\n metadata?: Record;\n } = {},\n ): Promise<\n [\n Partial<\n SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n >,\n ApprovedPermissionsMetadata,\n ]\n > {\n const { origin } = subject;\n const { id = nanoid(), preserveExistingPermissions = true } = options;\n this.validateRequestedPermissions(origin, requestedPermissions);\n\n const metadata = {\n ...options.metadata,\n id,\n origin,\n };\n\n const permissionsRequest: PermissionsRequest = {\n metadata,\n permissions: requestedPermissions,\n };\n\n const approvedRequest = await this.requestUserApproval(permissionsRequest);\n return await this.#handleApprovedPermissions({\n subject,\n metadata,\n preserveExistingPermissions,\n approvedRequest,\n });\n }\n\n /**\n * Initiates an incremental permission request that prompts for user approval.\n * Incremental permission requests allow the caller to replace existing and/or\n * add brand new permissions and caveats for the specified subject.\n *\n * Incremental permission request are merged with the subject's existing permissions\n * through a right-biased union, where the incremental permission are the right-hand\n * side of the merger. If both sides of the merger specify the same caveats for a\n * given permission, the caveats are merged using their specification's caveat value\n * merger property.\n *\n * Either this or {@link PermissionController.requestPermissions} should\n * always be used to grant additional permissions to a subject, unless user\n * approval has been obtained through some other means.\n *\n * Permissions are validated at every step of the approval process, and this\n * method will reject if validation fails.\n *\n * @see {@link ApprovalController} For the user approval logic.\n * @see {@link PermissionController.acceptPermissionsRequest} For the method\n * that _accepts_ the request and resolves the user approval promise.\n * @see {@link PermissionController.rejectPermissionsRequest} For the method\n * that _rejects_ the request and the user approval promise.\n * @param subject - The grantee subject.\n * @param requestedPermissions - The requested permissions.\n * @param options - Additional options.\n * @param options.id - The id of the permissions request. Defaults to a unique\n * id.\n * @param options.metadata - Additional metadata about the permission request.\n * @returns The granted permissions and request metadata.\n */\n async requestPermissionsIncremental(\n subject: PermissionSubjectMetadata,\n requestedPermissions: RequestedPermissions,\n options: {\n id?: string;\n metadata?: Record;\n } = {},\n ): Promise<\n | [\n Partial<\n SubjectPermissions<\n ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >\n >\n >,\n ApprovedPermissionsMetadata,\n ]\n | []\n > {\n const { origin } = subject;\n const { id = nanoid() } = options;\n this.validateRequestedPermissions(origin, requestedPermissions);\n\n const currentPermissions = this.getPermissions(origin) ?? {};\n const [newPermissions, permissionDiffMap] =\n this.#mergeIncrementalPermissions(\n currentPermissions,\n requestedPermissions,\n );\n\n // The second undefined check is just for type narrowing purposes. These values\n // will always be jointly defined or undefined.\n if (newPermissions === undefined || permissionDiffMap === undefined) {\n return [];\n }\n\n try {\n // It does not spark joy to run this validation again after the merger operation.\n // But, optimizing this procedure is probably not worth it, especially considering\n // that the worst-case scenario for validation degrades to the below function call.\n this.validateRequestedPermissions(origin, newPermissions);\n } catch (error) {\n if (error instanceof Error) {\n throw new InvalidMergedPermissionsError(\n origin,\n error,\n permissionDiffMap,\n );\n }\n /* istanbul ignore next: This should be impossible */\n throw internalError('Unrecognized error type', { error });\n }\n\n const metadata = {\n ...options.metadata,\n id,\n origin,\n };\n\n const permissionsRequest: PermissionsRequest = {\n metadata,\n permissions: newPermissions,\n diff: {\n currentPermissions,\n permissionDiffMap,\n },\n };\n\n const approvedRequest = await this.requestUserApproval(permissionsRequest);\n return await this.#handleApprovedPermissions({\n subject,\n metadata,\n preserveExistingPermissions: false,\n approvedRequest,\n });\n }\n\n /**\n * Validates requested permissions. Throws if validation fails.\n *\n * This method ensures that the requested permissions are a properly\n * formatted {@link RequestedPermissions} object, and performs the same\n * validation as {@link PermissionController.grantPermissions}, except that\n * consumer-specified permission validator functions are not called, since\n * they are only called on fully constructed, approved permissions that are\n * otherwise completely valid.\n *\n * Unrecognzied properties on requested permissions are ignored.\n *\n * @param origin - The origin of the grantee subject.\n * @param requestedPermissions - The requested permissions.\n */\n private validateRequestedPermissions(\n origin: OriginString,\n requestedPermissions: unknown,\n ): void {\n if (!isPlainObject(requestedPermissions)) {\n throw invalidParams({\n message: `Requested permissions for origin \"${origin}\" is not a plain object.`,\n data: { origin, requestedPermissions },\n });\n }\n\n if (Object.keys(requestedPermissions).length === 0) {\n throw invalidParams({\n message: `Permissions request for origin \"${origin}\" contains no permissions.`,\n data: { requestedPermissions },\n });\n }\n\n for (const targetName of Object.keys(requestedPermissions)) {\n const permission = requestedPermissions[targetName];\n\n if (!this.targetExists(targetName)) {\n throw methodNotFound(targetName, { origin, requestedPermissions });\n }\n\n if (\n !isPlainObject(permission) ||\n (permission.parentCapability !== undefined &&\n targetName !== permission.parentCapability)\n ) {\n throw invalidParams({\n message: `Permissions request for origin \"${origin}\" contains invalid requested permission(s).`,\n data: { origin, requestedPermissions },\n });\n }\n\n // Here we validate the permission without invoking its validator, if any.\n // The validator will be invoked after the permission has been approved.\n this.validatePermission(\n this.getPermissionSpecification(targetName),\n // Typecast: The permission is still a \"PlainObject\" here.\n permission as PermissionConstraint,\n origin,\n { invokePermissionValidator: false, performCaveatValidation: true },\n );\n }\n }\n\n /**\n * Merges a set of incrementally requested permissions into the existing permissions of\n * the requesting subject. The merge is a right-biased union, where the existing\n * permissions are the left-hand side, and the incrementally requested permissions are\n * the right-hand side.\n *\n * @param existingPermissions - The subject's existing permissions.\n * @param incrementalRequestedPermissions - The requested permissions to merge.\n * @returns The merged permissions and the resulting diff.\n */\n #mergeIncrementalPermissions(\n existingPermissions: Exclude<\n ReturnType,\n undefined\n >,\n incrementalRequestedPermissions: RequestedPermissions,\n ):\n | [\n SubjectPermissions<\n ValidPermission>\n >,\n PermissionDiffMap,\n ]\n | [] {\n const permissionDiffMap: PermissionDiffMap = {};\n\n // Use immer's produce as a convenience for calculating the new permissions\n // without mutating the existing permissions or committing the results to state.\n const newPermissions = immerProduce(\n existingPermissions,\n (draftExistingPermissions) => {\n const leftPermissions =\n draftExistingPermissions as RequestedPermissions;\n\n Object.entries(incrementalRequestedPermissions).forEach(\n ([targetName, rightPermission]) => {\n const leftPermission: Partial | undefined =\n leftPermissions[targetName];\n\n const [newPermission, caveatsDiff] = this.#mergePermission(\n leftPermission ?? {},\n rightPermission,\n );\n\n if (\n leftPermission === undefined ||\n Object.keys(caveatsDiff).length > 0\n ) {\n leftPermissions[targetName] = newPermission;\n permissionDiffMap[targetName] = caveatsDiff;\n }\n // Otherwise, leave the left permission as-is; its authority has\n // not changed.\n },\n );\n },\n );\n\n if (Object.keys(permissionDiffMap).length === 0) {\n return [];\n }\n return [newPermissions, permissionDiffMap];\n }\n\n /**\n * Performs a right-biased union between two permissions. The task of merging caveats\n * of the same type between the two permissions is delegated to the corresponding\n * caveat type's merger implementation.\n *\n * Throws if the left-hand and right-hand permissions both have a caveat whose\n * specification does not provide a caveat value merger function.\n *\n * @param leftPermission - The left-hand permission to merge.\n * @param rightPermission - The right-hand permission to merge.\n * @returns The merged permission.\n */\n #mergePermission<\n PermissionType extends Partial | PermissionConstraint,\n >(\n leftPermission: PermissionType | undefined,\n rightPermission: PermissionType,\n ): [PermissionType, CaveatDiffMap] {\n const { caveatPairs, leftUniqueCaveats, rightUniqueCaveats } =\n collectUniqueAndPairedCaveats(leftPermission, rightPermission);\n\n const [mergedCaveats, caveatDiffMap] = caveatPairs.reduce(\n ([caveats, diffMap], [leftCaveat, rightCaveat]) => {\n const [newCaveat, diff] = this.#mergeCaveat(leftCaveat, rightCaveat);\n\n if (newCaveat !== undefined && diff !== undefined) {\n caveats.push(newCaveat);\n diffMap[newCaveat.type] = diff;\n } else {\n caveats.push(leftCaveat);\n }\n\n return [caveats, diffMap];\n },\n [[], {}] as [CaveatConstraint[], CaveatDiffMap],\n );\n\n const mergedRightUniqueCaveats = rightUniqueCaveats.map((caveat) => {\n const [newCaveat, diff] = this.#mergeCaveat(undefined, caveat);\n\n caveatDiffMap[newCaveat.type] = diff;\n return newCaveat;\n });\n\n const allCaveats = [\n ...mergedCaveats,\n ...leftUniqueCaveats,\n ...mergedRightUniqueCaveats,\n ];\n\n const newPermission = {\n ...leftPermission,\n ...rightPermission,\n ...(allCaveats.length > 0\n ? { caveats: allCaveats as NonEmptyArray }\n : {}),\n };\n\n return [newPermission, caveatDiffMap];\n }\n\n /**\n * Merges two caveats of the same type. The task of merging the values of the\n * two caveats is delegated to the corresponding caveat type's merger implementation.\n *\n * @param leftCaveat - The left-hand caveat to merge.\n * @param rightCaveat - The right-hand caveat to merge.\n * @returns The merged caveat and the diff between the two caveats.\n */\n #mergeCaveat<\n RightCaveat extends CaveatConstraint,\n LeftCaveat extends RightCaveat | undefined,\n >(\n leftCaveat: LeftCaveat,\n rightCaveat: RightCaveat,\n ): MergeCaveatResult {\n /* istanbul ignore if: This should be impossible */\n if (leftCaveat !== undefined && leftCaveat.type !== rightCaveat.type) {\n throw new CaveatMergeTypeMismatchError(leftCaveat.type, rightCaveat.type);\n }\n\n const merger = this.#expectGetCaveatMerger(rightCaveat.type);\n\n if (leftCaveat === undefined) {\n return [\n {\n ...rightCaveat,\n },\n rightCaveat.value,\n ];\n }\n\n const [newValue, diff] = merger(leftCaveat.value, rightCaveat.value);\n\n return newValue !== undefined && diff !== undefined\n ? [\n {\n type: rightCaveat.type,\n value: newValue,\n },\n diff,\n ]\n : ([] as MergeCaveatResult);\n }\n\n /**\n * Adds a request to the {@link ApprovalController} using the\n * {@link AddApprovalRequest} action. Also validates the resulting approved\n * permissions request, and throws an error if validation fails.\n *\n * @param permissionsRequest - The permissions request object.\n * @returns The approved permissions request object.\n */\n private async requestUserApproval(permissionsRequest: PermissionsRequest) {\n const { origin, id } = permissionsRequest.metadata;\n const approvedRequest = await this.messenger.call(\n 'ApprovalController:addRequest',\n {\n id,\n origin,\n requestData: permissionsRequest,\n type: MethodNames.RequestPermissions,\n },\n true,\n );\n\n this.validateApprovedPermissions(approvedRequest, { id, origin });\n return approvedRequest as PermissionsRequest;\n }\n\n /**\n * Accepts a permissions request that has been approved by the user. This\n * method should be called after the user has approved the request and the\n * {@link ApprovalController} has resolved the user approval promise.\n *\n * @param options - Options bag.\n * @param options.subject - The subject to grant permissions to.\n * @param options.metadata - The metadata of the approved permissions request.\n * @param options.preserveExistingPermissions - Whether to preserve the\n * subject's existing permissions.\n * @param options.approvedRequest - The approved permissions request to handle.\n * @returns The granted permissions and request metadata.\n */\n async #handleApprovedPermissions({\n subject,\n metadata,\n preserveExistingPermissions,\n approvedRequest,\n }: {\n subject: PermissionSubjectMetadata;\n metadata: PermissionsRequest['metadata'];\n preserveExistingPermissions: boolean;\n approvedRequest: PermissionsRequest;\n }): Promise<\n [ReturnType, ApprovedPermissionsMetadata]\n > {\n const { permissions: approvedPermissions, ...requestData } =\n approvedRequest;\n const approvedMetadata: ApprovedPermissionsMetadata = { ...metadata };\n\n const sideEffects = this.getSideEffects(approvedPermissions);\n if (Object.values(sideEffects.permittedHandlers).length > 0) {\n const sideEffectsData = await this.executeSideEffects(\n sideEffects,\n approvedRequest,\n );\n\n approvedMetadata.data = Object.keys(sideEffects.permittedHandlers).reduce(\n (acc, permission, i) => ({ [permission]: sideEffectsData[i], ...acc }),\n {},\n );\n }\n\n return [\n this.grantPermissions({\n subject,\n approvedPermissions,\n preserveExistingPermissions,\n requestData,\n }),\n approvedMetadata,\n ];\n }\n\n /**\n * Reunites all the side-effects (onPermitted and onFailure) of the requested permissions inside a record of arrays.\n *\n * @param permissions - The approved permissions.\n * @returns The {@link SideEffects} object containing the handlers arrays.\n */\n private getSideEffects(permissions: RequestedPermissions) {\n return Object.keys(permissions).reduce(\n (sideEffectList, targetName) => {\n if (this.targetExists(targetName)) {\n const specification = this.getPermissionSpecification(targetName);\n\n if (specification.sideEffect) {\n sideEffectList.permittedHandlers[targetName] =\n specification.sideEffect.onPermitted;\n\n if (specification.sideEffect.onFailure) {\n sideEffectList.failureHandlers[targetName] =\n specification.sideEffect.onFailure;\n }\n }\n }\n return sideEffectList;\n },\n { permittedHandlers: {}, failureHandlers: {} },\n );\n }\n\n /**\n * Executes the side-effects of the approved permissions while handling the errors if any.\n * It will pass an instance of the {@link messenger} and the request data associated with the permission request to the handlers through its params.\n *\n * @param sideEffects - the side-effect record created by {@link getSideEffects}\n * @param requestData - the permissions requestData.\n * @returns the value returned by all the `onPermitted` handlers in an array.\n */\n private async executeSideEffects(\n sideEffects: SideEffects,\n requestData: PermissionsRequest,\n ) {\n const { permittedHandlers, failureHandlers } = sideEffects;\n const params = {\n requestData,\n messenger: this.messenger,\n };\n\n const promiseResults = await Promise.allSettled(\n Object.values(permittedHandlers).map((permittedHandler) =>\n permittedHandler(params),\n ),\n );\n\n // lib.es2020.promise.d.ts does not export its types so we're using a simple type.\n const rejectedHandlers = promiseResults.filter(\n (promise) => promise.status === 'rejected',\n ) as { status: 'rejected'; reason: Error }[];\n\n if (rejectedHandlers.length > 0) {\n const failureHandlersList = Object.values(failureHandlers);\n if (failureHandlersList.length > 0) {\n try {\n await Promise.all(\n failureHandlersList.map((failureHandler) => failureHandler(params)),\n );\n } catch (error) {\n throw internalError('Unexpected error in side-effects', { error });\n }\n }\n const reasons = rejectedHandlers.map((handler) => handler.reason);\n\n reasons.forEach((reason) => {\n console.error(reason);\n });\n\n throw reasons.length > 1\n ? internalError(\n 'Multiple errors occurred during side-effects execution',\n { errors: reasons },\n )\n : reasons[0];\n }\n\n // lib.es2020.promise.d.ts does not export its types so we're using a simple type.\n return (promiseResults as { status: 'fulfilled'; value: unknown }[]).map(\n ({ value }) => value,\n );\n }\n\n /**\n * Validates an approved {@link PermissionsRequest} object. The approved\n * request must have the required `metadata` and `permissions` properties,\n * the `id` and `origin` of the `metadata` must match the original request\n * metadata, and the requested permissions must be valid per\n * {@link PermissionController.validateRequestedPermissions}. Any extra\n * metadata properties are ignored.\n *\n * An error is thrown if validation fails.\n *\n * @param approvedRequest - The approved permissions request object.\n * @param originalMetadata - The original request metadata.\n */\n private validateApprovedPermissions(\n approvedRequest: unknown,\n originalMetadata: PermissionsRequestMetadata,\n ) {\n const { id, origin } = originalMetadata;\n\n if (\n !isPlainObject(approvedRequest) ||\n !isPlainObject(approvedRequest.metadata)\n ) {\n throw internalError(\n `Approved permissions request for subject \"${origin}\" is invalid.`,\n { data: { approvedRequest } },\n );\n }\n\n const {\n metadata: { id: newId, origin: newOrigin },\n permissions,\n } = approvedRequest;\n\n if (newId !== id) {\n throw internalError(\n `Approved permissions request for subject \"${origin}\" mutated its id.`,\n { originalId: id, mutatedId: newId },\n );\n }\n\n if (newOrigin !== origin) {\n throw internalError(\n `Approved permissions request for subject \"${origin}\" mutated its origin.`,\n { originalOrigin: origin, mutatedOrigin: newOrigin },\n );\n }\n\n try {\n this.validateRequestedPermissions(origin, permissions);\n } catch (error) {\n if (error instanceof Error) {\n // Re-throw as an internal error; we should never receive invalid approved\n // permissions.\n throw internalError(\n `Invalid approved permissions request: ${error.message}`,\n error instanceof JsonRpcError ? error.data : undefined,\n );\n }\n /* istanbul ignore next: This should be impossible */\n throw internalError('Unrecognized error type', { error });\n }\n }\n\n /**\n * Accepts a permissions request created by\n * {@link PermissionController.requestPermissions}.\n *\n * @param request - The permissions request.\n */\n async acceptPermissionsRequest(request: PermissionsRequest): Promise {\n const { id } = request.metadata;\n\n if (!this.hasApprovalRequest({ id })) {\n throw new PermissionsRequestNotFoundError(id);\n }\n\n if (Object.keys(request.permissions).length === 0) {\n this._rejectPermissionsRequest(\n id,\n invalidParams({\n message: 'Must request at least one permission.',\n }),\n );\n return;\n }\n\n try {\n await this.messenger.call(\n 'ApprovalController:acceptRequest',\n id,\n request,\n );\n } catch (error) {\n // If accepting unexpectedly fails, reject the request and re-throw the\n // error\n this._rejectPermissionsRequest(id, error);\n throw error;\n }\n }\n\n /**\n * Rejects a permissions request created by\n * {@link PermissionController.requestPermissions}.\n *\n * @param id - The id of the request to be rejected.\n */\n async rejectPermissionsRequest(id: string): Promise {\n if (!this.hasApprovalRequest({ id })) {\n throw new PermissionsRequestNotFoundError(id);\n }\n\n this._rejectPermissionsRequest(id, userRejectedRequest());\n }\n\n /**\n * Checks whether the {@link ApprovalController} has a particular permissions\n * request.\n *\n * @see {@link PermissionController.acceptPermissionsRequest} and\n * {@link PermissionController.rejectPermissionsRequest} for usage.\n * @param options - The {@link HasApprovalRequest} options.\n * @param options.id - The id of the approval request to check for.\n * @returns Whether the specified request exists.\n */\n private hasApprovalRequest(options: { id: string }): boolean {\n return this.messenger.call('ApprovalController:hasRequest', options);\n }\n\n /**\n * Rejects the permissions request with the specified id, with the specified\n * error as the reason. This method is effectively a wrapper around a\n * messenger call for the `ApprovalController:rejectRequest` action.\n *\n * @see {@link PermissionController.acceptPermissionsRequest} and\n * {@link PermissionController.rejectPermissionsRequest} for usage.\n * @param id - The id of the request to reject.\n * @param error - The error associated with the rejection.\n * @returns Nothing\n */\n private _rejectPermissionsRequest(id: string, error: unknown): void {\n return this.messenger.call('ApprovalController:rejectRequest', id, error);\n }\n\n /**\n * Gets the subject's endowments per the specified endowment permission.\n * Throws if the subject does not have the required permission or if the\n * permission is not an endowment permission.\n *\n * @param origin - The origin of the subject whose endowments to retrieve.\n * @param targetName - The name of the endowment permission. This must be a\n * valid permission target name.\n * @param requestData - Additional data associated with the request, if any.\n * Forwarded to the endowment getter function for the permission.\n * @returns The endowments, if any.\n */\n async getEndowments(\n origin: string,\n targetName: ExtractEndowmentPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n requestData?: unknown,\n ): Promise {\n if (!this.hasPermission(origin, targetName)) {\n throw unauthorized({ data: { origin, targetName } });\n }\n\n return this.getTypedPermissionSpecification(\n PermissionType.Endowment,\n targetName,\n origin,\n ).endowmentGetter({ origin, requestData });\n }\n\n /**\n * Executes a restricted method as the subject with the given origin.\n * The specified params, if any, will be passed to the method implementation.\n *\n * ATTN: Great caution should be exercised in the use of this method.\n * Methods that cause side effects or affect application state should\n * be avoided.\n *\n * This method will first attempt to retrieve the requested restricted method\n * implementation, throwing if it does not exist. The method will then be\n * invoked as though the subject with the specified origin had invoked it with\n * the specified parameters. This means that any existing caveats will be\n * applied to the restricted method, and this method will throw if the\n * restricted method or its caveat decorators throw.\n *\n * In addition, this method will throw if the subject does not have a\n * permission for the specified restricted method.\n *\n * @param origin - The origin of the subject to execute the method on behalf\n * of.\n * @param targetName - The name of the method to execute. This must be a valid\n * permission target name.\n * @param params - The parameters to pass to the method implementation.\n * @returns The result of the executed method.\n */\n async executeRestrictedMethod(\n origin: OriginString,\n targetName: ExtractRestrictedMethodPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n params?: RestrictedMethodParameters,\n ): Promise {\n // Throws if the method does not exist\n const methodImplementation = this.getRestrictedMethod(targetName, origin);\n\n const result = await this._executeRestrictedMethod(\n methodImplementation,\n { origin },\n targetName,\n params,\n );\n\n if (result === undefined) {\n throw new Error(\n `Internal request for method \"${targetName}\" as origin \"${origin}\" returned no result.`,\n );\n }\n\n return result;\n }\n\n /**\n * An internal method used in the controller's `json-rpc-engine` middleware\n * and {@link PermissionController.executeRestrictedMethod}. Calls the\n * specified restricted method implementation after decorating it with the\n * caveats of its permission. Throws if the subject does not have the\n * requisite permission.\n *\n * ATTN: Parameter validation is the responsibility of the caller, or\n * the restricted method implementation in the case of `params`.\n *\n * @see {@link PermissionController.executeRestrictedMethod} and\n * {@link PermissionController.createPermissionMiddleware} for usage.\n * @param methodImplementation - The implementation of the method to call.\n * @param subject - Metadata about the subject that made the request.\n * @param method - The method name\n * @param params - Params needed for executing the restricted method\n * @returns The result of the restricted method implementation\n */\n private _executeRestrictedMethod(\n methodImplementation: RestrictedMethod,\n subject: PermissionSubjectMetadata,\n method: ExtractPermission<\n ControllerPermissionSpecification,\n ControllerCaveatSpecification\n >['parentCapability'],\n params: RestrictedMethodParameters = [],\n ): ReturnType> {\n const { origin } = subject;\n\n const permission = this.getPermission(origin, method);\n if (!permission) {\n throw unauthorized({ data: { origin, method } });\n }\n\n return decorateWithCaveats(\n methodImplementation,\n permission,\n this._caveatSpecifications,\n )({ method, params, context: { origin } });\n }\n}\n"]} +\ No newline at end of file +diff --git a/dist/SubjectMetadataController.cjs b/dist/SubjectMetadataController.cjs +index a91f0733bdd4c2946355d7c7be36374e58753b84..4a3858700fe0e983e1a24d4d150b7d8ff1af12f0 100644 +--- a/dist/SubjectMetadataController.cjs ++++ b/dist/SubjectMetadataController.cjs +@@ -1,7 +1,7 @@ + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.SubjectMetadataController = exports.SubjectType = void 0; +-const base_controller_1 = require("@metamask/base-controller"); ++const next_1 = require("@metamask/base-controller/next"); + const controllerName = 'SubjectMetadataController'; + /** + * The different kinds of subjects that MetaMask may interact with, including +@@ -16,7 +16,12 @@ var SubjectType; + SubjectType["Snap"] = "snap"; + })(SubjectType || (exports.SubjectType = SubjectType = {})); + const stateMetadata = { +- subjectMetadata: { persist: true, anonymous: false }, ++ subjectMetadata: { ++ includeInStateLogs: true, ++ persist: true, ++ includeInDebugSnapshot: false, ++ usedInUi: true, ++ }, + }; + const defaultState = { + subjectMetadata: {}, +@@ -25,7 +30,7 @@ const defaultState = { + * A controller for storing metadata associated with permission subjects. More + * or less, a cache. + */ +-class SubjectMetadataController extends base_controller_1.BaseController { ++class SubjectMetadataController extends next_1.BaseController { + constructor({ messenger, subjectCacheLimit, state = {}, }) { + if (!Number.isInteger(subjectCacheLimit) || subjectCacheLimit < 1) { + throw new Error(`subjectCacheLimit must be a positive integer. Received: "${subjectCacheLimit}"`); +@@ -44,11 +49,11 @@ class SubjectMetadataController extends base_controller_1.BaseController { + this.subjectHasPermissions = hasPermissions; + this.subjectCacheLimit = subjectCacheLimit; + this.subjectsWithoutPermissionsEncounteredSinceStartup = new Set(); +- this.messagingSystem.registerActionHandler( ++ this.messenger.registerActionHandler( + // ESLint is confused by the string literal type. + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + `${this.name}:getSubjectMetadata`, this.getSubjectMetadata.bind(this)); +- this.messagingSystem.registerActionHandler( ++ this.messenger.registerActionHandler( + // ESLint is confused by the string literal type. + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + `${this.name}:addSubjectMetadata`, this.addSubjectMetadata.bind(this)); +diff --git a/dist/SubjectMetadataController.cjs.map b/dist/SubjectMetadataController.cjs.map +index 3f0c5aa098dd179148e7bc5f7de1f653d510a16d..7cb159e7b3fe6b5ec3368830497eaab59406a8f3 100644 +--- a/dist/SubjectMetadataController.cjs.map ++++ b/dist/SubjectMetadataController.cjs.map +@@ -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 RestrictedMessenger,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\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;\n\nexport type SubjectMetadataControllerState = {\n subjectMetadata: Record;\n};\n\nconst stateMetadata = {\n subjectMetadata: { persist: true, anonymous: false },\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 = RestrictedMessenger<\n typeof controllerName,\n SubjectMetadataControllerActions | AllowedActions,\n SubjectMetadataControllerEvents,\n AllowedActions['type'],\n never\n>;\n\ntype SubjectMetadataControllerOptions = {\n messenger: SubjectMetadataControllerMessenger;\n subjectCacheLimit: number;\n state?: Partial;\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;\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.messagingSystem.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.messagingSystem.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 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((draftState) => {\n // @ts-expect-error ts(2589)\n return SubjectMetadataController.getTrimmedState(\n draftState,\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,\n hasPermissions: SubjectMetadataController['subjectHasPermissions'],\n ): SubjectMetadataControllerState {\n const { subjectMetadata = {} } = state;\n\n return {\n subjectMetadata: Object.keys(subjectMetadata).reduce<\n Record\n >((newSubjectMetadata, origin) => {\n if (hasPermissions(origin)) {\n newSubjectMetadata[origin] = subjectMetadata[origin];\n }\n return newSubjectMetadata;\n }, {}),\n };\n }\n}\n"]} +\ No newline at end of file ++{"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/next';\nimport { BaseController } from '@metamask/base-controller/next';\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;\n\nexport type SubjectMetadataControllerState = {\n subjectMetadata: Record;\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;\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;\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 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((draftState) => {\n // @ts-expect-error ts(2589)\n return SubjectMetadataController.getTrimmedState(\n draftState,\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,\n hasPermissions: SubjectMetadataController['subjectHasPermissions'],\n ): SubjectMetadataControllerState {\n const { subjectMetadata = {} } = state;\n\n return {\n subjectMetadata: Object.keys(subjectMetadata).reduce<\n Record\n >((newSubjectMetadata, origin) => {\n if (hasPermissions(origin)) {\n newSubjectMetadata[origin] = subjectMetadata[origin];\n }\n return newSubjectMetadata;\n }, {}),\n };\n }\n}\n"]} +\ No newline at end of file +diff --git a/dist/SubjectMetadataController.d.cts b/dist/SubjectMetadataController.d.cts +index 10480b161a356a702c57acbcea9a752b048e0a0c..4d8f798b33f2a94454b32abe8ea113f71d8d15eb 100644 +--- a/dist/SubjectMetadataController.d.cts ++++ b/dist/SubjectMetadataController.d.cts +@@ -1,5 +1,6 @@ +-import type { ControllerGetStateAction, ControllerStateChangeEvent, RestrictedMessenger } from "@metamask/base-controller"; +-import { BaseController } from "@metamask/base-controller"; ++import type { ControllerGetStateAction, ControllerStateChangeEvent } from "@metamask/base-controller/next"; ++import { BaseController } from "@metamask/base-controller/next"; ++import type { Messenger } from "@metamask/messenger"; + import type { Json } from "@metamask/utils"; + import type { HasPermissions, PermissionSubjectMetadata } from "./PermissionController.cjs"; + declare const controllerName = "SubjectMetadataController"; +@@ -44,7 +45,7 @@ export type SubjectMetadataControllerActions = GetSubjectMetadataState | GetSubj + export type SubjectMetadataStateChange = ControllerStateChangeEvent; + export type SubjectMetadataControllerEvents = SubjectMetadataStateChange; + type AllowedActions = HasPermissions; +-export type SubjectMetadataControllerMessenger = RestrictedMessenger; ++export type SubjectMetadataControllerMessenger = Messenger; + type SubjectMetadataControllerOptions = { + messenger: SubjectMetadataControllerMessenger; + subjectCacheLimit: number; +diff --git a/dist/SubjectMetadataController.d.cts.map b/dist/SubjectMetadataController.d.cts.map +index 3ec7526cda66802315b222516be7041f47e42e4f..7ef1c7c7d1fe189f2986d1a779af94d01fb30c21 100644 +--- a/dist/SubjectMetadataController.d.cts.map ++++ b/dist/SubjectMetadataController.d.cts.map +@@ -1 +1 @@ +-{"version":3,"file":"SubjectMetadataController.d.cts","sourceRoot":"","sources":["../src/SubjectMetadataController.ts"],"names":[],"mappings":"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"} +\ No newline at end of file ++{"version":3,"file":"SubjectMetadataController.d.cts","sourceRoot":"","sources":["../src/SubjectMetadataController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC3B,uCAAuC;AACxC,OAAO,EAAE,cAAc,EAAE,uCAAuC;AAChE,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;IAuCnC;;;OAGG;IACH,UAAU,IAAI,IAAI;IAOlB;;;;;;;;;;;OAWG;IACH,kBAAkB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI;IAyCxD;;;;;OAKG;IACH,kBAAkB,CAAC,MAAM,EAAE,aAAa,GAAG,eAAe,GAAG,SAAS;IAItE;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAUzB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;CAiB/B"} +\ No newline at end of file +diff --git a/dist/SubjectMetadataController.d.mts b/dist/SubjectMetadataController.d.mts +index 5274bc34740d8322e64c8113aee8ac45ab1f8b79..88672d459702fa366691026a573a6630e5cdb097 100644 +--- a/dist/SubjectMetadataController.d.mts ++++ b/dist/SubjectMetadataController.d.mts +@@ -1,5 +1,6 @@ +-import type { ControllerGetStateAction, ControllerStateChangeEvent, RestrictedMessenger } from "@metamask/base-controller"; +-import { BaseController } from "@metamask/base-controller"; ++import type { ControllerGetStateAction, ControllerStateChangeEvent } from "@metamask/base-controller/next"; ++import { BaseController } from "@metamask/base-controller/next"; ++import type { Messenger } from "@metamask/messenger"; + import type { Json } from "@metamask/utils"; + import type { HasPermissions, PermissionSubjectMetadata } from "./PermissionController.mjs"; + declare const controllerName = "SubjectMetadataController"; +@@ -44,7 +45,7 @@ export type SubjectMetadataControllerActions = GetSubjectMetadataState | GetSubj + export type SubjectMetadataStateChange = ControllerStateChangeEvent; + export type SubjectMetadataControllerEvents = SubjectMetadataStateChange; + type AllowedActions = HasPermissions; +-export type SubjectMetadataControllerMessenger = RestrictedMessenger; ++export type SubjectMetadataControllerMessenger = Messenger; + type SubjectMetadataControllerOptions = { + messenger: SubjectMetadataControllerMessenger; + subjectCacheLimit: number; +diff --git a/dist/SubjectMetadataController.d.mts.map b/dist/SubjectMetadataController.d.mts.map +index 239338764d8365ba9ae1afbc9dc70ea856728b91..199272028bee3fae84c3bfe27e57fe75618ae4d0 100644 +--- a/dist/SubjectMetadataController.d.mts.map ++++ b/dist/SubjectMetadataController.d.mts.map +@@ -1 +1 @@ +-{"version":3,"file":"SubjectMetadataController.d.mts","sourceRoot":"","sources":["../src/SubjectMetadataController.ts"],"names":[],"mappings":"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"} +\ No newline at end of file ++{"version":3,"file":"SubjectMetadataController.d.mts","sourceRoot":"","sources":["../src/SubjectMetadataController.ts"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/dist/SubjectMetadataController.mjs b/dist/SubjectMetadataController.mjs +index 95af1a1bb69666beb592326c05f78d5527be8b19..62ba28ecddeff952c5d786b5930ea5c7ce4a6669 100644 +--- a/dist/SubjectMetadataController.mjs ++++ b/dist/SubjectMetadataController.mjs +@@ -1,4 +1,4 @@ +-import { BaseController } from "@metamask/base-controller"; ++import { BaseController } from "@metamask/base-controller/next"; + const controllerName = 'SubjectMetadataController'; + /** + * The different kinds of subjects that MetaMask may interact with, including +@@ -13,7 +13,12 @@ export var SubjectType; + SubjectType["Snap"] = "snap"; + })(SubjectType || (SubjectType = {})); + const stateMetadata = { +- subjectMetadata: { persist: true, anonymous: false }, ++ subjectMetadata: { ++ includeInStateLogs: true, ++ persist: true, ++ includeInDebugSnapshot: false, ++ usedInUi: true, ++ }, + }; + const defaultState = { + subjectMetadata: {}, +@@ -41,11 +46,11 @@ export class SubjectMetadataController extends BaseController { + this.subjectHasPermissions = hasPermissions; + this.subjectCacheLimit = subjectCacheLimit; + this.subjectsWithoutPermissionsEncounteredSinceStartup = new Set(); +- this.messagingSystem.registerActionHandler( ++ this.messenger.registerActionHandler( + // ESLint is confused by the string literal type. + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + `${this.name}:getSubjectMetadata`, this.getSubjectMetadata.bind(this)); +- this.messagingSystem.registerActionHandler( ++ this.messenger.registerActionHandler( + // ESLint is confused by the string literal type. + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + `${this.name}:addSubjectMetadata`, this.addSubjectMetadata.bind(this)); +diff --git a/dist/SubjectMetadataController.mjs.map b/dist/SubjectMetadataController.mjs.map +index 3d3b34fb3cb75e493167a57f1fd2665f0ad85202..1d68c727c105e3bb6aaa721c50ff0067acf245bf 100644 +--- a/dist/SubjectMetadataController.mjs.map ++++ b/dist/SubjectMetadataController.mjs.map +@@ -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 RestrictedMessenger,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\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;\n\nexport type SubjectMetadataControllerState = {\n subjectMetadata: Record;\n};\n\nconst stateMetadata = {\n subjectMetadata: { persist: true, anonymous: false },\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 = RestrictedMessenger<\n typeof controllerName,\n SubjectMetadataControllerActions | AllowedActions,\n SubjectMetadataControllerEvents,\n AllowedActions['type'],\n never\n>;\n\ntype SubjectMetadataControllerOptions = {\n messenger: SubjectMetadataControllerMessenger;\n subjectCacheLimit: number;\n state?: Partial;\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;\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.messagingSystem.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.messagingSystem.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 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((draftState) => {\n // @ts-expect-error ts(2589)\n return SubjectMetadataController.getTrimmedState(\n draftState,\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,\n hasPermissions: SubjectMetadataController['subjectHasPermissions'],\n ): SubjectMetadataControllerState {\n const { subjectMetadata = {} } = state;\n\n return {\n subjectMetadata: Object.keys(subjectMetadata).reduce<\n Record\n >((newSubjectMetadata, origin) => {\n if (hasPermissions(origin)) {\n newSubjectMetadata[origin] = subjectMetadata[origin];\n }\n return newSubjectMetadata;\n }, {}),\n };\n }\n}\n"]} +\ No newline at end of file ++{"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/next';\nimport { BaseController } from '@metamask/base-controller/next';\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;\n\nexport type SubjectMetadataControllerState = {\n subjectMetadata: Record;\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;\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;\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 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((draftState) => {\n // @ts-expect-error ts(2589)\n return SubjectMetadataController.getTrimmedState(\n draftState,\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,\n hasPermissions: SubjectMetadataController['subjectHasPermissions'],\n ): SubjectMetadataControllerState {\n const { subjectMetadata = {} } = state;\n\n return {\n subjectMetadata: Object.keys(subjectMetadata).reduce<\n Record\n >((newSubjectMetadata, origin) => {\n if (hasPermissions(origin)) {\n newSubjectMetadata[origin] = subjectMetadata[origin];\n }\n return newSubjectMetadata;\n }, {}),\n };\n }\n}\n"]} +\ No newline at end of file +diff --git a/dist/permission-middleware.cjs.map b/dist/permission-middleware.cjs.map +index 1d62e90d31c556e430ad7579c14df27d8dc699bf..d77790078e26587e0fec78481be7f7abbfd3b6ba 100644 +--- a/dist/permission-middleware.cjs.map ++++ b/dist/permission-middleware.cjs.map +@@ -1 +1 @@ +-{"version":3,"file":"permission-middleware.cjs","sourceRoot":"","sources":["../src/permission-middleware.ts"],"names":[],"mappings":";;;AAAA,+DAAkE;AAkBlE,yCAAyC;AAUzC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAgB,8BAA8B,CAAC,EAC7C,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,GACe;IACnC,OAAO,SAAS,0BAA0B,CACxC,OAAkC;QAElC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAC3B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,EAAE;YACzC,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;SACrE;QAED,MAAM,qBAAqB,GAAG,KAAK,EACjC,GAA+C,EAC/C,GAAiC,EACjC,IAAoC,EACrB,EAAE;YACjB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;YAE/B,wCAAwC;YACxC,IAAI,oBAAoB,CAAC,MAAM,CAAC,EAAE;gBAChC,OAAO,IAAI,EAAE,CAAC;aACf;YAED,mEAAmE;YACnE,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAEjE,oDAAoD;YACpD,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAC1C,oBAAoB,EACpB,OAAO,EACP,MAAM,EACN,MAAM,CACP,CAAC;YAEF,IAAI,MAAM,KAAK,SAAS,EAAE;gBACxB,GAAG,CAAC,KAAK,GAAG,IAAA,sBAAa,EACvB,uBAAuB,GAAG,CAAC,MAAM,8BAA8B,EAC/D,EAAE,OAAO,EAAE,GAAG,EAAE,CACjB,CAAC;gBACF,OAAO,SAAS,CAAC;aAClB;YAED,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;YACpB,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC;QAEF,OAAO,IAAA,uCAAqB,EAAC,qBAAqB,CAAC,CAAC;IACtD,CAAC,CAAC;AACJ,CAAC;AAlDD,wEAkDC","sourcesContent":["import { createAsyncMiddleware } from '@metamask/json-rpc-engine';\nimport type {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n JsonRpcEngine,\n JsonRpcMiddleware,\n AsyncJsonRpcEngineNextCallback,\n} from '@metamask/json-rpc-engine';\nimport type {\n Json,\n PendingJsonRpcResponse,\n JsonRpcRequest,\n} from '@metamask/utils';\n\nimport type {\n GenericPermissionController,\n PermissionSubjectMetadata,\n RestrictedMethodParameters,\n} from '.';\nimport { internalError } from './errors';\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport type { PermissionController } from './PermissionController';\n\ntype PermissionMiddlewareFactoryOptions = {\n executeRestrictedMethod: GenericPermissionController['_executeRestrictedMethod'];\n getRestrictedMethod: GenericPermissionController['getRestrictedMethod'];\n isUnrestrictedMethod: (method: string) => boolean;\n};\n\n/**\n * Creates a permission middleware function factory. Intended for internal use\n * in the {@link PermissionController}. Like any {@link JsonRpcEngine}\n * middleware, each middleware will only receive requests from a particular\n * subject / origin. However, each middleware also requires access to some\n * `PermissionController` internals, which is why this \"factory factory\" exists.\n *\n * The middlewares returned by the factory will pass through requests for\n * unrestricted methods, and attempt to execute restricted methods. If a method\n * is neither restricted nor unrestricted, a \"method not found\" error will be\n * returned.\n * If a method is restricted, the middleware will first attempt to retrieve the\n * subject's permission for that method. If the permission is found, the method\n * will be executed. Otherwise, an \"unauthorized\" error will be returned.\n *\n * @param options - Options bag.\n * @param options.executeRestrictedMethod - {@link PermissionController._executeRestrictedMethod}.\n * @param options.getRestrictedMethod - {@link PermissionController.getRestrictedMethod}.\n * @param options.isUnrestrictedMethod - A function that checks whether a\n * particular method is unrestricted.\n * @returns A permission middleware factory function.\n */\nexport function getPermissionMiddlewareFactory({\n executeRestrictedMethod,\n getRestrictedMethod,\n isUnrestrictedMethod,\n}: PermissionMiddlewareFactoryOptions) {\n return function createPermissionMiddleware(\n subject: PermissionSubjectMetadata,\n ): JsonRpcMiddleware {\n const { origin } = subject;\n if (typeof origin !== 'string' || !origin) {\n throw new Error('The subject \"origin\" must be a non-empty string.');\n }\n\n const permissionsMiddleware = async (\n req: JsonRpcRequest,\n res: PendingJsonRpcResponse,\n next: AsyncJsonRpcEngineNextCallback,\n ): Promise => {\n const { method, params } = req;\n\n // Skip registered unrestricted methods.\n if (isUnrestrictedMethod(method)) {\n return next();\n }\n\n // This will throw if no restricted method implementation is found.\n const methodImplementation = getRestrictedMethod(method, origin);\n\n // This will throw if the permission does not exist.\n const result = await executeRestrictedMethod(\n methodImplementation,\n subject,\n method,\n params,\n );\n\n if (result === undefined) {\n res.error = internalError(\n `Request for method \"${req.method}\" returned undefined result.`,\n { request: req },\n );\n return undefined;\n }\n\n res.result = result;\n return undefined;\n };\n\n return createAsyncMiddleware(permissionsMiddleware);\n };\n}\n"]} +\ No newline at end of file ++{"version":3,"file":"permission-middleware.cjs","sourceRoot":"","sources":["../src/permission-middleware.ts"],"names":[],"mappings":";;;AAAA,+DAAkE;AAgBlE,yCAAyC;AAQzC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAgB,8BAA8B,CAAC,EAC7C,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,GACe;IACnC,OAAO,SAAS,0BAA0B,CACxC,OAAkC;QAElC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAC3B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,EAAE;YACzC,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;SACrE;QAED,MAAM,qBAAqB,GAAG,KAAK,EACjC,GAA+C,EAC/C,GAA2B,EAC3B,IAAoC,EACrB,EAAE;YACjB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;YAE/B,wCAAwC;YACxC,IAAI,oBAAoB,CAAC,MAAM,CAAC,EAAE;gBAChC,OAAO,IAAI,EAAE,CAAC;aACf;YAED,mEAAmE;YACnE,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAEjE,oDAAoD;YACpD,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAC1C,oBAAoB,EACpB,OAAO,EACP,MAAM,EACN,MAAM,CACP,CAAC;YAEF,IAAI,MAAM,KAAK,SAAS,EAAE;gBACxB,GAAG,CAAC,KAAK,GAAG,IAAA,sBAAa,EACvB,uBAAuB,GAAG,CAAC,MAAM,8BAA8B,EAC/D,EAAE,OAAO,EAAE,GAAG,EAAE,CACjB,CAAC;gBACF,OAAO,SAAS,CAAC;aAClB;YAED,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;YACpB,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC;QAEF,OAAO,IAAA,uCAAqB,EAAC,qBAAqB,CAAC,CAAC;IACtD,CAAC,CAAC;AACJ,CAAC;AAlDD,wEAkDC","sourcesContent":["import { createAsyncMiddleware } from '@metamask/json-rpc-engine';\nimport type {\n JsonRpcMiddleware,\n AsyncJsonRpcEngineNextCallback,\n} from '@metamask/json-rpc-engine';\nimport type {\n Json,\n PendingJsonRpcResponse,\n JsonRpcRequest,\n} from '@metamask/utils';\n\nimport type {\n GenericPermissionController,\n PermissionSubjectMetadata,\n RestrictedMethodParameters,\n} from '.';\nimport { internalError } from './errors';\n\ntype PermissionMiddlewareFactoryOptions = {\n executeRestrictedMethod: GenericPermissionController['_executeRestrictedMethod'];\n getRestrictedMethod: GenericPermissionController['getRestrictedMethod'];\n isUnrestrictedMethod: (method: string) => boolean;\n};\n\n/**\n * Creates a permission middleware function factory. Intended for internal use\n * in the {@link PermissionController}. Like any {@link JsonRpcEngine}\n * middleware, each middleware will only receive requests from a particular\n * subject / origin. However, each middleware also requires access to some\n * `PermissionController` internals, which is why this \"factory factory\" exists.\n *\n * The middlewares returned by the factory will pass through requests for\n * unrestricted methods, and attempt to execute restricted methods. If a method\n * is neither restricted nor unrestricted, a \"method not found\" error will be\n * returned.\n * If a method is restricted, the middleware will first attempt to retrieve the\n * subject's permission for that method. If the permission is found, the method\n * will be executed. Otherwise, an \"unauthorized\" error will be returned.\n *\n * @param options - Options bag.\n * @param options.executeRestrictedMethod - {@link PermissionController._executeRestrictedMethod}.\n * @param options.getRestrictedMethod - {@link PermissionController.getRestrictedMethod}.\n * @param options.isUnrestrictedMethod - A function that checks whether a\n * particular method is unrestricted.\n * @returns A permission middleware factory function.\n */\nexport function getPermissionMiddlewareFactory({\n executeRestrictedMethod,\n getRestrictedMethod,\n isUnrestrictedMethod,\n}: PermissionMiddlewareFactoryOptions) {\n return function createPermissionMiddleware(\n subject: PermissionSubjectMetadata,\n ): JsonRpcMiddleware {\n const { origin } = subject;\n if (typeof origin !== 'string' || !origin) {\n throw new Error('The subject \"origin\" must be a non-empty string.');\n }\n\n const permissionsMiddleware = async (\n req: JsonRpcRequest,\n res: PendingJsonRpcResponse,\n next: AsyncJsonRpcEngineNextCallback,\n ): Promise => {\n const { method, params } = req;\n\n // Skip registered unrestricted methods.\n if (isUnrestrictedMethod(method)) {\n return next();\n }\n\n // This will throw if no restricted method implementation is found.\n const methodImplementation = getRestrictedMethod(method, origin);\n\n // This will throw if the permission does not exist.\n const result = await executeRestrictedMethod(\n methodImplementation,\n subject,\n method,\n params,\n );\n\n if (result === undefined) {\n res.error = internalError(\n `Request for method \"${req.method}\" returned undefined result.`,\n { request: req },\n );\n return undefined;\n }\n\n res.result = result;\n return undefined;\n };\n\n return createAsyncMiddleware(permissionsMiddleware);\n };\n}\n"]} +\ No newline at end of file +diff --git a/dist/permission-middleware.d.cts.map b/dist/permission-middleware.d.cts.map +index 51ec017b82b1d5bb0c778a3ffacd4f37b2f14037..732b8386e8a8cce428dc3e8a344fb1635f24f91d 100644 +--- a/dist/permission-middleware.d.cts.map ++++ b/dist/permission-middleware.d.cts.map +@@ -1 +1 @@ +-{"version":3,"file":"permission-middleware.d.cts","sourceRoot":"","sources":["../src/permission-middleware.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,iBAAiB,EAElB,kCAAkC;AACnC,OAAO,KAAK,EACV,IAAI,EAGL,wBAAwB;AAEzB,OAAO,KAAK,EACV,2BAA2B,EAC3B,yBAAyB,EACzB,0BAA0B,EAC3B,oBAAU;AAKX,KAAK,kCAAkC,GAAG;IACxC,uBAAuB,EAAE,2BAA2B,CAAC,0BAA0B,CAAC,CAAC;IACjF,mBAAmB,EAAE,2BAA2B,CAAC,qBAAqB,CAAC,CAAC;IACxE,oBAAoB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;CACnD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,8BAA8B,CAAC,EAC7C,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,GACrB,EAAE,kCAAkC,aAExB,yBAAyB,KACjC,kBAAkB,0BAA0B,EAAE,IAAI,CAAC,CA2CvD"} +\ No newline at end of file ++{"version":3,"file":"permission-middleware.d.cts","sourceRoot":"","sources":["../src/permission-middleware.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,iBAAiB,EAElB,kCAAkC;AACnC,OAAO,KAAK,EACV,IAAI,EAGL,wBAAwB;AAEzB,OAAO,KAAK,EACV,2BAA2B,EAC3B,yBAAyB,EACzB,0BAA0B,EAC3B,oBAAU;AAGX,KAAK,kCAAkC,GAAG;IACxC,uBAAuB,EAAE,2BAA2B,CAAC,0BAA0B,CAAC,CAAC;IACjF,mBAAmB,EAAE,2BAA2B,CAAC,qBAAqB,CAAC,CAAC;IACxE,oBAAoB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;CACnD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,8BAA8B,CAAC,EAC7C,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,GACrB,EAAE,kCAAkC,aAExB,yBAAyB,KACjC,kBAAkB,0BAA0B,EAAE,IAAI,CAAC,CA2CvD"} +\ No newline at end of file +diff --git a/dist/permission-middleware.d.mts.map b/dist/permission-middleware.d.mts.map +index 5ff3c0cf1fb510bb51dec5ecf54b0cc4d552b48e..999ae42b65794495e9869fcae03b52a2c94a5409 100644 +--- a/dist/permission-middleware.d.mts.map ++++ b/dist/permission-middleware.d.mts.map +@@ -1 +1 @@ +-{"version":3,"file":"permission-middleware.d.mts","sourceRoot":"","sources":["../src/permission-middleware.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,iBAAiB,EAElB,kCAAkC;AACnC,OAAO,KAAK,EACV,IAAI,EAGL,wBAAwB;AAEzB,OAAO,KAAK,EACV,2BAA2B,EAC3B,yBAAyB,EACzB,0BAA0B,EAC3B,oBAAU;AAKX,KAAK,kCAAkC,GAAG;IACxC,uBAAuB,EAAE,2BAA2B,CAAC,0BAA0B,CAAC,CAAC;IACjF,mBAAmB,EAAE,2BAA2B,CAAC,qBAAqB,CAAC,CAAC;IACxE,oBAAoB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;CACnD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,8BAA8B,CAAC,EAC7C,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,GACrB,EAAE,kCAAkC,aAExB,yBAAyB,KACjC,kBAAkB,0BAA0B,EAAE,IAAI,CAAC,CA2CvD"} +\ No newline at end of file ++{"version":3,"file":"permission-middleware.d.mts","sourceRoot":"","sources":["../src/permission-middleware.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,iBAAiB,EAElB,kCAAkC;AACnC,OAAO,KAAK,EACV,IAAI,EAGL,wBAAwB;AAEzB,OAAO,KAAK,EACV,2BAA2B,EAC3B,yBAAyB,EACzB,0BAA0B,EAC3B,oBAAU;AAGX,KAAK,kCAAkC,GAAG;IACxC,uBAAuB,EAAE,2BAA2B,CAAC,0BAA0B,CAAC,CAAC;IACjF,mBAAmB,EAAE,2BAA2B,CAAC,qBAAqB,CAAC,CAAC;IACxE,oBAAoB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;CACnD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,8BAA8B,CAAC,EAC7C,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,GACrB,EAAE,kCAAkC,aAExB,yBAAyB,KACjC,kBAAkB,0BAA0B,EAAE,IAAI,CAAC,CA2CvD"} +\ No newline at end of file +diff --git a/dist/permission-middleware.mjs.map b/dist/permission-middleware.mjs.map +index 54f87181b5230033a8aead311589f4690c5b39eb..4e869a74469028bbe55f9e5e7857c1a4def4b911 100644 +--- a/dist/permission-middleware.mjs.map ++++ b/dist/permission-middleware.mjs.map +@@ -1 +1 @@ +-{"version":3,"file":"permission-middleware.mjs","sourceRoot":"","sources":["../src/permission-middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,kCAAkC;AAkBlE,OAAO,EAAE,aAAa,EAAE,qBAAiB;AAUzC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,8BAA8B,CAAC,EAC7C,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,GACe;IACnC,OAAO,SAAS,0BAA0B,CACxC,OAAkC;QAElC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAC3B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,EAAE;YACzC,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;SACrE;QAED,MAAM,qBAAqB,GAAG,KAAK,EACjC,GAA+C,EAC/C,GAAiC,EACjC,IAAoC,EACrB,EAAE;YACjB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;YAE/B,wCAAwC;YACxC,IAAI,oBAAoB,CAAC,MAAM,CAAC,EAAE;gBAChC,OAAO,IAAI,EAAE,CAAC;aACf;YAED,mEAAmE;YACnE,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAEjE,oDAAoD;YACpD,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAC1C,oBAAoB,EACpB,OAAO,EACP,MAAM,EACN,MAAM,CACP,CAAC;YAEF,IAAI,MAAM,KAAK,SAAS,EAAE;gBACxB,GAAG,CAAC,KAAK,GAAG,aAAa,CACvB,uBAAuB,GAAG,CAAC,MAAM,8BAA8B,EAC/D,EAAE,OAAO,EAAE,GAAG,EAAE,CACjB,CAAC;gBACF,OAAO,SAAS,CAAC;aAClB;YAED,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;YACpB,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC;QAEF,OAAO,qBAAqB,CAAC,qBAAqB,CAAC,CAAC;IACtD,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { createAsyncMiddleware } from '@metamask/json-rpc-engine';\nimport type {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n JsonRpcEngine,\n JsonRpcMiddleware,\n AsyncJsonRpcEngineNextCallback,\n} from '@metamask/json-rpc-engine';\nimport type {\n Json,\n PendingJsonRpcResponse,\n JsonRpcRequest,\n} from '@metamask/utils';\n\nimport type {\n GenericPermissionController,\n PermissionSubjectMetadata,\n RestrictedMethodParameters,\n} from '.';\nimport { internalError } from './errors';\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport type { PermissionController } from './PermissionController';\n\ntype PermissionMiddlewareFactoryOptions = {\n executeRestrictedMethod: GenericPermissionController['_executeRestrictedMethod'];\n getRestrictedMethod: GenericPermissionController['getRestrictedMethod'];\n isUnrestrictedMethod: (method: string) => boolean;\n};\n\n/**\n * Creates a permission middleware function factory. Intended for internal use\n * in the {@link PermissionController}. Like any {@link JsonRpcEngine}\n * middleware, each middleware will only receive requests from a particular\n * subject / origin. However, each middleware also requires access to some\n * `PermissionController` internals, which is why this \"factory factory\" exists.\n *\n * The middlewares returned by the factory will pass through requests for\n * unrestricted methods, and attempt to execute restricted methods. If a method\n * is neither restricted nor unrestricted, a \"method not found\" error will be\n * returned.\n * If a method is restricted, the middleware will first attempt to retrieve the\n * subject's permission for that method. If the permission is found, the method\n * will be executed. Otherwise, an \"unauthorized\" error will be returned.\n *\n * @param options - Options bag.\n * @param options.executeRestrictedMethod - {@link PermissionController._executeRestrictedMethod}.\n * @param options.getRestrictedMethod - {@link PermissionController.getRestrictedMethod}.\n * @param options.isUnrestrictedMethod - A function that checks whether a\n * particular method is unrestricted.\n * @returns A permission middleware factory function.\n */\nexport function getPermissionMiddlewareFactory({\n executeRestrictedMethod,\n getRestrictedMethod,\n isUnrestrictedMethod,\n}: PermissionMiddlewareFactoryOptions) {\n return function createPermissionMiddleware(\n subject: PermissionSubjectMetadata,\n ): JsonRpcMiddleware {\n const { origin } = subject;\n if (typeof origin !== 'string' || !origin) {\n throw new Error('The subject \"origin\" must be a non-empty string.');\n }\n\n const permissionsMiddleware = async (\n req: JsonRpcRequest,\n res: PendingJsonRpcResponse,\n next: AsyncJsonRpcEngineNextCallback,\n ): Promise => {\n const { method, params } = req;\n\n // Skip registered unrestricted methods.\n if (isUnrestrictedMethod(method)) {\n return next();\n }\n\n // This will throw if no restricted method implementation is found.\n const methodImplementation = getRestrictedMethod(method, origin);\n\n // This will throw if the permission does not exist.\n const result = await executeRestrictedMethod(\n methodImplementation,\n subject,\n method,\n params,\n );\n\n if (result === undefined) {\n res.error = internalError(\n `Request for method \"${req.method}\" returned undefined result.`,\n { request: req },\n );\n return undefined;\n }\n\n res.result = result;\n return undefined;\n };\n\n return createAsyncMiddleware(permissionsMiddleware);\n };\n}\n"]} +\ No newline at end of file ++{"version":3,"file":"permission-middleware.mjs","sourceRoot":"","sources":["../src/permission-middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,kCAAkC;AAgBlE,OAAO,EAAE,aAAa,EAAE,qBAAiB;AAQzC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,8BAA8B,CAAC,EAC7C,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,GACe;IACnC,OAAO,SAAS,0BAA0B,CACxC,OAAkC;QAElC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAC3B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,EAAE;YACzC,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;SACrE;QAED,MAAM,qBAAqB,GAAG,KAAK,EACjC,GAA+C,EAC/C,GAA2B,EAC3B,IAAoC,EACrB,EAAE;YACjB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;YAE/B,wCAAwC;YACxC,IAAI,oBAAoB,CAAC,MAAM,CAAC,EAAE;gBAChC,OAAO,IAAI,EAAE,CAAC;aACf;YAED,mEAAmE;YACnE,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAEjE,oDAAoD;YACpD,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAC1C,oBAAoB,EACpB,OAAO,EACP,MAAM,EACN,MAAM,CACP,CAAC;YAEF,IAAI,MAAM,KAAK,SAAS,EAAE;gBACxB,GAAG,CAAC,KAAK,GAAG,aAAa,CACvB,uBAAuB,GAAG,CAAC,MAAM,8BAA8B,EAC/D,EAAE,OAAO,EAAE,GAAG,EAAE,CACjB,CAAC;gBACF,OAAO,SAAS,CAAC;aAClB;YAED,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;YACpB,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC;QAEF,OAAO,qBAAqB,CAAC,qBAAqB,CAAC,CAAC;IACtD,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { createAsyncMiddleware } from '@metamask/json-rpc-engine';\nimport type {\n JsonRpcMiddleware,\n AsyncJsonRpcEngineNextCallback,\n} from '@metamask/json-rpc-engine';\nimport type {\n Json,\n PendingJsonRpcResponse,\n JsonRpcRequest,\n} from '@metamask/utils';\n\nimport type {\n GenericPermissionController,\n PermissionSubjectMetadata,\n RestrictedMethodParameters,\n} from '.';\nimport { internalError } from './errors';\n\ntype PermissionMiddlewareFactoryOptions = {\n executeRestrictedMethod: GenericPermissionController['_executeRestrictedMethod'];\n getRestrictedMethod: GenericPermissionController['getRestrictedMethod'];\n isUnrestrictedMethod: (method: string) => boolean;\n};\n\n/**\n * Creates a permission middleware function factory. Intended for internal use\n * in the {@link PermissionController}. Like any {@link JsonRpcEngine}\n * middleware, each middleware will only receive requests from a particular\n * subject / origin. However, each middleware also requires access to some\n * `PermissionController` internals, which is why this \"factory factory\" exists.\n *\n * The middlewares returned by the factory will pass through requests for\n * unrestricted methods, and attempt to execute restricted methods. If a method\n * is neither restricted nor unrestricted, a \"method not found\" error will be\n * returned.\n * If a method is restricted, the middleware will first attempt to retrieve the\n * subject's permission for that method. If the permission is found, the method\n * will be executed. Otherwise, an \"unauthorized\" error will be returned.\n *\n * @param options - Options bag.\n * @param options.executeRestrictedMethod - {@link PermissionController._executeRestrictedMethod}.\n * @param options.getRestrictedMethod - {@link PermissionController.getRestrictedMethod}.\n * @param options.isUnrestrictedMethod - A function that checks whether a\n * particular method is unrestricted.\n * @returns A permission middleware factory function.\n */\nexport function getPermissionMiddlewareFactory({\n executeRestrictedMethod,\n getRestrictedMethod,\n isUnrestrictedMethod,\n}: PermissionMiddlewareFactoryOptions) {\n return function createPermissionMiddleware(\n subject: PermissionSubjectMetadata,\n ): JsonRpcMiddleware {\n const { origin } = subject;\n if (typeof origin !== 'string' || !origin) {\n throw new Error('The subject \"origin\" must be a non-empty string.');\n }\n\n const permissionsMiddleware = async (\n req: JsonRpcRequest,\n res: PendingJsonRpcResponse,\n next: AsyncJsonRpcEngineNextCallback,\n ): Promise => {\n const { method, params } = req;\n\n // Skip registered unrestricted methods.\n if (isUnrestrictedMethod(method)) {\n return next();\n }\n\n // This will throw if no restricted method implementation is found.\n const methodImplementation = getRestrictedMethod(method, origin);\n\n // This will throw if the permission does not exist.\n const result = await executeRestrictedMethod(\n methodImplementation,\n subject,\n method,\n params,\n );\n\n if (result === undefined) {\n res.error = internalError(\n `Request for method \"${req.method}\" returned undefined result.`,\n { request: req },\n );\n return undefined;\n }\n\n res.result = result;\n return undefined;\n };\n\n return createAsyncMiddleware(permissionsMiddleware);\n };\n}\n"]} +\ No newline at end of file diff --git a/packages/snaps-controllers/package.json b/packages/snaps-controllers/package.json index cf800f8531..294e79fcec 100644 --- a/packages/snaps-controllers/package.json +++ b/packages/snaps-controllers/package.json @@ -86,7 +86,7 @@ "@metamask/key-tree": "^10.1.1", "@metamask/messenger": "^0.3.0", "@metamask/object-multiplex": "^2.1.0", - "@metamask/permission-controller": "^11.0.6", + "@metamask/permission-controller": "patch:@metamask/permission-controller@npm%3A11.0.6#~/.yarn/patches/@metamask-permission-controller-npm-11.0.6-5b7ce789d2.patch", "@metamask/phishing-controller": "^13.1.0", "@metamask/post-message-stream": "^10.0.0", "@metamask/rpc-errors": "^7.0.3", diff --git a/packages/snaps-rpc-methods/package.json b/packages/snaps-rpc-methods/package.json index f4e0f1fe9e..f9d6a66d30 100644 --- a/packages/snaps-rpc-methods/package.json +++ b/packages/snaps-rpc-methods/package.json @@ -56,7 +56,7 @@ }, "dependencies": { "@metamask/key-tree": "^10.1.1", - "@metamask/permission-controller": "^11.0.6", + "@metamask/permission-controller": "patch:@metamask/permission-controller@npm%3A11.0.6#~/.yarn/patches/@metamask-permission-controller-npm-11.0.6-5b7ce789d2.patch", "@metamask/rpc-errors": "^7.0.3", "@metamask/snaps-sdk": "workspace:^", "@metamask/snaps-utils": "workspace:^", diff --git a/packages/snaps-rpc-methods/src/restricted/invokeSnap.test.ts b/packages/snaps-rpc-methods/src/restricted/invokeSnap.test.ts index 51480f13f3..e36ebf07d5 100644 --- a/packages/snaps-rpc-methods/src/restricted/invokeSnap.test.ts +++ b/packages/snaps-rpc-methods/src/restricted/invokeSnap.test.ts @@ -119,7 +119,9 @@ describe('handleSnapInstall', () => { const sideEffectMessenger = new Messenger< 'PermissionController', - InstallSnaps | GetPermittedSnaps + InstallSnaps | GetPermittedSnaps, + never, + any >({ namespace: 'PermissionController', parent: messenger }); messenger.delegate({ @@ -160,7 +162,7 @@ describe('handleSnapInstall', () => { const result = await handleSnapInstall({ requestData, - messagingSystem: sideEffectMessenger, + messenger: sideEffectMessenger, }); expect(sideEffectMessenger.call).toHaveBeenCalledWith( @@ -180,7 +182,9 @@ describe('handleSnapInstall', () => { const sideEffectMessenger = new Messenger< 'PermissionController', - InstallSnaps | GetPermittedSnaps + InstallSnaps | GetPermittedSnaps, + never, + any >({ namespace: 'PermissionController', parent: messenger }); messenger.delegate({ @@ -224,7 +228,7 @@ describe('handleSnapInstall', () => { const result = await handleSnapInstall({ requestData, - messagingSystem: sideEffectMessenger, + messenger: sideEffectMessenger, }); expect(sideEffectMessenger.call).toHaveBeenCalledWith( diff --git a/packages/snaps-rpc-methods/src/restricted/invokeSnap.ts b/packages/snaps-rpc-methods/src/restricted/invokeSnap.ts index bffc491cd9..e69eb1926d 100644 --- a/packages/snaps-rpc-methods/src/restricted/invokeSnap.ts +++ b/packages/snaps-rpc-methods/src/restricted/invokeSnap.ts @@ -71,17 +71,17 @@ export type InvokeSnapParams = { * * @param params - The side-effect params. * @param params.requestData - The request data associated to the requested permission. - * @param params.messagingSystem - The messenger to call an action. + * @param params.messenger - The messenger to call an action. * @returns The result of the Snap installation. */ export const handleSnapInstall: PermissionSideEffect< AllowedActions, never ->['onPermitted'] = async ({ requestData, messagingSystem }) => { +>['onPermitted'] = async ({ requestData, messenger }) => { const snaps = requestData.permissions[WALLET_SNAP_PERMISSION_KEY].caveats?.[0] .value as RequestSnapsParams; - const permittedSnaps = messagingSystem.call( + const permittedSnaps = messenger.call( `SnapController:getPermitted`, requestData.metadata.origin, ); @@ -96,7 +96,7 @@ export const handleSnapInstall: PermissionSideEffect< {}, ); - return messagingSystem.call( + return messenger.call( `SnapController:install`, requestData.metadata.origin, dedupedSnaps, diff --git a/packages/snaps-simulation/package.json b/packages/snaps-simulation/package.json index 67e68e0bb5..1bdd7f24dd 100644 --- a/packages/snaps-simulation/package.json +++ b/packages/snaps-simulation/package.json @@ -60,7 +60,7 @@ "@metamask/json-rpc-middleware-stream": "^8.0.8", "@metamask/key-tree": "^10.1.1", "@metamask/messenger": "^0.3.0", - "@metamask/permission-controller": "^11.0.6", + "@metamask/permission-controller": "patch:@metamask/permission-controller@npm%3A11.0.6#~/.yarn/patches/@metamask-permission-controller-npm-11.0.6-5b7ce789d2.patch", "@metamask/phishing-controller": "^13.1.0", "@metamask/snaps-controllers": "workspace:^", "@metamask/snaps-execution-environments": "workspace:^", diff --git a/packages/snaps-simulation/src/controllers.ts b/packages/snaps-simulation/src/controllers.ts index a542b047e7..9d841beae0 100644 --- a/packages/snaps-simulation/src/controllers.ts +++ b/packages/snaps-simulation/src/controllers.ts @@ -73,7 +73,6 @@ export type Controllers = { export function getControllers(options: GetControllersOptions): Controllers { const { controllerMessenger } = options; const subjectMetadataController = new SubjectMetadataController({ - // @ts-expect-error Incompatible messenger types until migrated. messenger: new Messenger({ namespace: 'SubjectMetadataController', parent: controllerMessenger, @@ -143,7 +142,6 @@ function getPermissionController(options: GetControllersOptions) { }); return new PermissionController({ - // @ts-expect-error Incompatible messenger types until migrated. messenger, caveatSpecifications: { ...snapsCaveatsSpecifications, diff --git a/packages/snaps-utils/package.json b/packages/snaps-utils/package.json index d6f2a60775..249d459295 100644 --- a/packages/snaps-utils/package.json +++ b/packages/snaps-utils/package.json @@ -82,7 +82,7 @@ "@babel/types": "^7.23.0", "@metamask/key-tree": "^10.1.1", "@metamask/messenger": "^0.3.0", - "@metamask/permission-controller": "^11.0.6", + "@metamask/permission-controller": "patch:@metamask/permission-controller@npm%3A11.0.6#~/.yarn/patches/@metamask-permission-controller-npm-11.0.6-5b7ce789d2.patch", "@metamask/rpc-errors": "^7.0.3", "@metamask/slip44": "^4.3.0", "@metamask/snaps-registry": "^3.2.3", diff --git a/yarn.lock b/yarn.lock index 91aaecc697..11aebb8c0a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3905,7 +3905,7 @@ __metadata: languageName: node linkType: hard -"@metamask/permission-controller@npm:^11.0.6": +"@metamask/permission-controller@npm:11.0.6": version: 11.0.6 resolution: "@metamask/permission-controller@npm:11.0.6" dependencies: @@ -3924,6 +3924,25 @@ __metadata: languageName: node linkType: hard +"@metamask/permission-controller@patch:@metamask/permission-controller@npm%3A11.0.6#~/.yarn/patches/@metamask-permission-controller-npm-11.0.6-5b7ce789d2.patch": + version: 11.0.6 + resolution: "@metamask/permission-controller@patch:@metamask/permission-controller@npm%3A11.0.6#~/.yarn/patches/@metamask-permission-controller-npm-11.0.6-5b7ce789d2.patch::version=11.0.6&hash=89cdfc" + dependencies: + "@metamask/base-controller": "npm:^8.0.0" + "@metamask/controller-utils": "npm:^11.5.0" + "@metamask/json-rpc-engine": "npm:^10.0.3" + "@metamask/rpc-errors": "npm:^7.0.2" + "@metamask/utils": "npm:^11.1.0" + "@types/deep-freeze-strict": "npm:^1.1.0" + deep-freeze-strict: "npm:^1.1.1" + immer: "npm:^9.0.6" + nanoid: "npm:^3.3.8" + peerDependencies: + "@metamask/approval-controller": ^7.0.0 + checksum: 10/5cfa060c6583f3f3a5b135892c92364d1502873c11a392d9cc72c5009ff0f7d1919dd4fbf815e168189eda8ff263e184d7dff252d6eed98faeec9717326a5b44 + languageName: node + linkType: hard + "@metamask/phishing-controller@npm:^13.1.0": version: 13.1.0 resolution: "@metamask/phishing-controller@npm:13.1.0" @@ -4252,7 +4271,7 @@ __metadata: "@metamask/key-tree": "npm:^10.1.1" "@metamask/messenger": "npm:^0.3.0" "@metamask/object-multiplex": "npm:^2.1.0" - "@metamask/permission-controller": "npm:^11.0.6" + "@metamask/permission-controller": "patch:@metamask/permission-controller@npm%3A11.0.6#~/.yarn/patches/@metamask-permission-controller-npm-11.0.6-5b7ce789d2.patch" "@metamask/phishing-controller": "npm:^13.1.0" "@metamask/post-message-stream": "npm:^10.0.0" "@metamask/rpc-errors": "npm:^7.0.3" @@ -4453,7 +4472,7 @@ __metadata: "@metamask/json-rpc-engine": "npm:^10.1.0" "@metamask/key-tree": "npm:^10.1.1" "@metamask/messenger": "npm:^0.3.0" - "@metamask/permission-controller": "npm:^11.0.6" + "@metamask/permission-controller": "patch:@metamask/permission-controller@npm%3A11.0.6#~/.yarn/patches/@metamask-permission-controller-npm-11.0.6-5b7ce789d2.patch" "@metamask/rpc-errors": "npm:^7.0.3" "@metamask/snaps-sdk": "workspace:^" "@metamask/snaps-utils": "workspace:^" @@ -4546,7 +4565,7 @@ __metadata: "@metamask/json-rpc-middleware-stream": "npm:^8.0.8" "@metamask/key-tree": "npm:^10.1.1" "@metamask/messenger": "npm:^0.3.0" - "@metamask/permission-controller": "npm:^11.0.6" + "@metamask/permission-controller": "patch:@metamask/permission-controller@npm%3A11.0.6#~/.yarn/patches/@metamask-permission-controller-npm-11.0.6-5b7ce789d2.patch" "@metamask/phishing-controller": "npm:^13.1.0" "@metamask/snaps-controllers": "workspace:^" "@metamask/snaps-execution-environments": "workspace:^" @@ -4589,7 +4608,7 @@ __metadata: "@metamask/auto-changelog": "npm:^5.0.2" "@metamask/key-tree": "npm:^10.1.1" "@metamask/messenger": "npm:^0.3.0" - "@metamask/permission-controller": "npm:^11.0.6" + "@metamask/permission-controller": "patch:@metamask/permission-controller@npm%3A11.0.6#~/.yarn/patches/@metamask-permission-controller-npm-11.0.6-5b7ce789d2.patch" "@metamask/post-message-stream": "npm:^10.0.0" "@metamask/rpc-errors": "npm:^7.0.3" "@metamask/slip44": "npm:^4.3.0"