import { Json } from '@metamask/types'; import { NonEmptyArray } from '../util'; import { CaveatConstraint } from './Caveat'; /** * The origin of a subject. * Effectively the GUID of an entity that can have permissions. */ export declare type OriginString = string; /** * The name of a permission target. */ declare type TargetName = string; /** * A `ZCAP-LD`-like permission object. A permission is associated with a * particular `invoker`, which is the holder of the permission. Possessing the * permission grants access to a particular restricted resource, identified by * the `parentCapability`. The use of the restricted resource may be further * restricted by any `caveats` associated with the permission. * * See the README for details. */ export declare type PermissionConstraint = { /** * The context(s) in which this capability is meaningful. * * It is required by the standard, but we make it optional since there is only * one context in our usage (i.e. the user's MetaMask instance). */ readonly '@context'?: NonEmptyArray; /** * The caveats of the permission. * * @see {@link Caveat} For more information. */ readonly caveats: null | NonEmptyArray; /** * The creation date of the permission, in UNIX epoch time. */ readonly date: number; /** * The GUID of the permission object. */ readonly id: string; /** * The origin string of the subject that has the permission. */ readonly invoker: OriginString; /** * A pointer to the resource that possession of the capability grants * access to, for example a JSON-RPC method or endowment. */ readonly parentCapability: string; }; /** * A `ZCAP-LD`-like permission object. A permission is associated with a * particular `invoker`, which is the holder of the permission. Possessing the * permission grants access to a particular restricted resource, identified by * the `parentCapability`. The use of the restricted resource may be further * restricted by any `caveats` associated with the permission. * * See the README for details. * * @template TargetKey - They key of the permission target that the permission * corresponds to. * @template AllowedCaveat - A union of the allowed {@link Caveat} types * for the permission. */ export declare type ValidPermission = PermissionConstraint & { /** * The caveats of the permission. * * @see {@link Caveat} For more information. */ readonly caveats: AllowedCaveat extends never ? null : NonEmptyArray | null; /** * A pointer to the resource that possession of the capability grants * access to, for example a JSON-RPC method or endowment. */ readonly parentCapability: ExtractPermissionTargetNames; }; /** * A utility type for ensuring that the given permission target name conforms to * our naming conventions. * * See the README for the distinction between target names and keys. */ declare type ValidTargetName = Name extends `${string}*` ? never : Name extends `${string}_` ? never : Name; /** * A utility type for extracting permission target names from a union of target * keys. * * See the README for the distinction between target names and keys. * * @template Key - The target key type to extract target names from. */ export declare type ExtractPermissionTargetNames = ValidTargetName; /** * Extracts the permission key of a particular name from a union of keys. * An internal utility type used in {@link ExtractPermissionTargetKey}. * * @template Key - The target key type to extract from. * @template Name - The name whose key to extract. */ declare type KeyOfTargetName = Name extends ExtractPermissionTargetNames ? Key : never; /** * A utility type for finding the permission target key corresponding to a * target name. In a way, the inverse of {@link ExtractPermissionTargetNames}. * * See the README for the distinction between target names and keys. * * @template Key - The target key type to extract from. * @template Name - The name whose key to extract. */ export declare type ExtractPermissionTargetKey = Key extends Name ? Key : Extract>; /** * Internal utility for extracting the members types of an array. The type * evalutes to `never` if the specified type is the empty tuple or neither * an array nor a tuple. * * @template ArrayType - The array type whose members to extract. */ declare type ExtractArrayMembers = ArrayType extends [] ? never : ArrayType extends any[] | readonly any[] ? ArrayType[number] : never; /** * A utility type for extracting the allowed caveat types for a particular * permission from a permission specification type. * * @template PermissionSpecification - The permission specification type to * extract valid caveat types from. */ export declare type ExtractAllowedCaveatTypes = ExtractArrayMembers; /** * The options object of {@link constructPermission}. * * @template TargetPermission - The {@link Permission} that will be constructed. */ export declare type PermissionOptions = { target: TargetPermission['parentCapability']; /** * The origin string of the subject that has the permission. */ invoker: OriginString; /** * The caveats of the permission. * See {@link Caveat}. */ caveats?: NonEmptyArray; }; /** * The default permission factory function. Naively constructs a permission from * the inputs. Sets a default, random `id` if none is provided. * * @see {@link Permission} For more details. * @template TargetPermission- - The {@link Permission} that will be constructed. * @param options - The options for the permission. * @returns The new permission object. */ export declare function constructPermission(options: PermissionOptions): TargetPermission; /** * Gets the caveat of the specified type belonging to the specified permission. * * @param permission - The permission whose caveat to retrieve. * @param caveatType - The type of the caveat to retrieve. * @returns The caveat, or undefined if no such caveat exists. */ export declare function findCaveat(permission: PermissionConstraint, caveatType: string): CaveatConstraint | undefined; /** * A requested permission object. Just an object with any of the properties * of a {@link PermissionConstraint} object. */ declare type RequestedPermission = Partial; /** * A record of target names and their {@link RequestedPermission} objects. */ export declare type RequestedPermissions = Record; /** * The restricted method context object. Essentially a way to pass internal * arguments to restricted methods and caveat functions, most importantly the * requesting origin. */ declare type RestrictedMethodContext = Readonly<{ origin: OriginString; [key: string]: any; }>; export declare type RestrictedMethodParameters = Json[] | Record | void; /** * The arguments passed to a restricted method implementation. * * @template Params - The JSON-RPC parameters of the restricted method. */ export declare type RestrictedMethodOptions = { method: TargetName; params?: Params; context: RestrictedMethodContext; }; /** * A synchronous restricted method implementation. * * @template Params - The JSON-RPC parameters of the restricted method. * @template Result - The JSON-RPC result of the restricted method. */ export declare type SyncRestrictedMethod = (args: RestrictedMethodOptions) => Result; /** * An asynchronous restricted method implementation. * * @template Params - The JSON-RPC parameters of the restricted method. * @template Result - The JSON-RPC result of the restricted method. */ export declare type AsyncRestrictedMethod = (args: RestrictedMethodOptions) => Promise; /** * A synchronous or asynchronous restricted method implementation. * * @template Params - The JSON-RPC parameters of the restricted method. * @template Result - The JSON-RPC result of the restricted method. */ export declare type RestrictedMethod = SyncRestrictedMethod | AsyncRestrictedMethod; export declare type ValidRestrictedMethod> = MethodImplementation extends (args: infer Options) => Json | Promise ? Options extends RestrictedMethodOptions ? MethodImplementation : never : never; /** * {@link EndowmentGetter} parameter object. */ export declare type EndowmentGetterParams = { /** * The origin of the requesting subject. */ origin: string; /** * Any additional data associated with the request. */ requestData?: unknown; [key: string]: unknown; }; /** * A synchronous or asynchronous function that gets the endowments for a * particular endowment permission. The getter receives the origin of the * requesting subject and, optionally, additional request metadata. */ export declare type EndowmentGetter = (options: EndowmentGetterParams) => Endowments | Promise; export declare type PermissionFactory> = (options: PermissionOptions, requestData?: RequestData) => TargetPermission; export declare type PermissionValidatorConstraint = (permission: PermissionConstraint, origin?: OriginString, target?: string) => void; /** * A utility type for ensuring that the given permission target key conforms to * our naming conventions. * * See the README for the distinction between target names and keys. * * @template Key - The target key string to apply the constraint to. */ declare type ValidTargetKey = Key extends `${string}_*` ? Key : Key extends `${string}_` ? never : Key extends `${string}*` ? never : Key; /** * The different possible types of permissions. */ export declare enum PermissionType { /** * A restricted JSON-RPC method. A subject must have the requisite permission * to call a restricted JSON-RPC method. */ RestrictedMethod = "RestrictedMethod", /** * An "endowment" granted to subjects that possess the requisite permission, * such as a global environment variable exposing a restricted API, etc. */ Endowment = "Endowment" } /** * The base constraint for permission specification objects. Every * {@link Permission} supported by a {@link PermissionController} must have an * associated specification, which is the source of truth for all permission- * related types. A permission specification includes the list of permitted * caveats, and any factory and validation functions specified by the consumer. * A concrete permission specification may specify further fields as necessary. * * See the README for more details. */ declare type PermissionSpecificationBase = { /** * The type of the specified permission. */ permissionType: Type; /** * The target resource of the permission. The shape of this string depends on * the permission type. For example, a restricted method target key will * consist of either a complete method name or the prefix of a namespaced * method, e.g. `wallet_snap_*`. */ targetKey: string; /** * An array of the caveat types that may be added to instances of this * permission. */ allowedCaveats: Readonly> | null; /** * The factory function used to get permission objects. Permissions returned * by this function are presumed to valid, and they will not be passed to the * validator function associated with this specification (if any). In other * words, the factory function should validate the permissions it creates. * * If no factory is specified, the {@link Permission} constructor will be * used, and the validator function (if specified) will be called on newly * constructed permissions. */ factory?: PermissionFactory>; /** * The validator function used to validate permissions of the associated type * whenever they are mutated. The only way a permission can be legally mutated * is when its caveats are modified by the permission controller. * * The validator should throw an appropriate JSON-RPC error if validation fails. */ validator?: PermissionValidatorConstraint; }; /** * The constraint for restricted method permission specification objects. * Permissions that correspond to JSON-RPC methods are specified using objects * that conform to this type. * * See the README for more details. */ export declare type RestrictedMethodSpecificationConstraint = PermissionSpecificationBase & { /** * The implementation of the restricted method that the permission * corresponds to. */ methodImplementation: RestrictedMethod; }; /** * The constraint for endowment permission specification objects. Permissions * that endow callers with some restricted resource are specified using objects * that conform to this type. * * See the README for more details. */ export declare type EndowmentSpecificationConstraint = PermissionSpecificationBase & { /** * The {@link EndowmentGetter} function for the permission. This function * will be called by the {@link PermissionController} whenever the * permission is invoked, after which the host can apply the endowments to * the requesting subject in the intended manner. */ endowmentGetter: EndowmentGetter; }; /** * The constraint for permission specification objects. Every {@link Permission} * supported by a {@link PermissionController} must have an associated * specification, which is the source of truth for all permission-related types. * All specifications must adhere to the {@link PermissionSpecificationBase} * interface, but specifications may have different fields depending on the * {@link PermissionType}. * * See the README for more details. */ export declare type PermissionSpecificationConstraint = EndowmentSpecificationConstraint | RestrictedMethodSpecificationConstraint; /** * Options for {@link PermissionSpecificationBuilder} functions. */ declare type PermissionSpecificationBuilderOptions, MethodHooks extends Record, ValidatorHooks extends Record> = { targetKey?: string; allowedCaveats?: Readonly> | null; factoryHooks?: FactoryHooks; methodHooks?: MethodHooks; validatorHooks?: ValidatorHooks; }; /** * A function that builds a permission specification. Modules that specify * permissions for external consumption should make this their primary / * default export so that host applications can use them to generate concrete * specifications tailored to their requirements. */ export declare type PermissionSpecificationBuilder, Specification extends PermissionSpecificationConstraint & { permissionType: Type; }> = (options: Options) => Specification; /** * A restricted method permission export object, containing the * {@link PermissionSpecificationBuilder} function and "hook name" objects. */ export declare type PermissionSpecificationBuilderExportConstraint = { targetKey: string; specificationBuilder: PermissionSpecificationBuilder, PermissionSpecificationConstraint>; factoryHookNames?: Record; methodHookNames?: Record; validatorHookNames?: Record; }; declare type ValidRestrictedMethodSpecification = Specification['methodImplementation'] extends ValidRestrictedMethod ? Specification : never; /** * Constraint for {@link PermissionSpecificationConstraint} objects that * evaluates to `never` if the specification contains any invalid fields. * * @template Specification - The permission specification to validate. */ export declare type ValidPermissionSpecification = Specification['targetKey'] extends ValidTargetKey ? Specification['permissionType'] extends PermissionType.Endowment ? Specification : Specification['permissionType'] extends PermissionType.RestrictedMethod ? ValidRestrictedMethodSpecification> : never : never; /** * Checks that the specification has the expected permission type. * * @param specification - The specification to check. * @param expectedType - The expected permission type. * @template Specification - The specification to check. * @template Type - The expected permission type. * @returns Whether or not the specification is of the expected type. */ export declare function hasSpecificationType(specification: Specification, expectedType: Type): specification is Specification & { permissionType: Type; }; /** * The specifications for all permissions supported by a particular * {@link PermissionController}. * * @template Specifications - The union of all {@link PermissionSpecificationConstraint} types. */ export declare type PermissionSpecificationMap = { [TargetKey in Specification['targetKey']]: Specification extends { targetKey: TargetKey; } ? Specification : never; }; /** * Extracts a specific {@link PermissionSpecificationConstraint} from a union of * permission specifications. * * @template Specification - The specification union type to extract from. * @template TargetKey - The `targetKey` of the specification to extract. */ export declare type ExtractPermissionSpecification = Specification extends { targetKey: TargetKey; } ? Specification : never; export {};