@metamask/gator-permissions-controller 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -1
- package/dist/GatorPermissionsController.cjs +77 -2
- package/dist/GatorPermissionsController.cjs.map +1 -1
- package/dist/GatorPermissionsController.d.cts +41 -2
- package/dist/GatorPermissionsController.d.cts.map +1 -1
- package/dist/GatorPermissionsController.d.mts +41 -2
- package/dist/GatorPermissionsController.d.mts.map +1 -1
- package/dist/GatorPermissionsController.mjs +77 -2
- package/dist/GatorPermissionsController.mjs.map +1 -1
- package/dist/decodePermission/decodePermission.cjs +196 -0
- package/dist/decodePermission/decodePermission.cjs.map +1 -0
- package/dist/decodePermission/decodePermission.d.cts +87 -0
- package/dist/decodePermission/decodePermission.d.cts.map +1 -0
- package/dist/decodePermission/decodePermission.d.mts +87 -0
- package/dist/decodePermission/decodePermission.d.mts.map +1 -0
- package/dist/decodePermission/decodePermission.mjs +190 -0
- package/dist/decodePermission/decodePermission.mjs.map +1 -0
- package/dist/decodePermission/index.cjs +8 -0
- package/dist/decodePermission/index.cjs.map +1 -0
- package/dist/decodePermission/index.d.cts +3 -0
- package/dist/decodePermission/index.d.cts.map +1 -0
- package/dist/decodePermission/index.d.mts +3 -0
- package/dist/decodePermission/index.d.mts.map +1 -0
- package/dist/decodePermission/index.mjs +2 -0
- package/dist/decodePermission/index.mjs.map +1 -0
- package/dist/decodePermission/types.cjs +3 -0
- package/dist/decodePermission/types.cjs.map +1 -0
- package/dist/decodePermission/types.d.cts +23 -0
- package/dist/decodePermission/types.d.cts.map +1 -0
- package/dist/decodePermission/types.d.mts +23 -0
- package/dist/decodePermission/types.d.mts.map +1 -0
- package/dist/decodePermission/types.mjs +2 -0
- package/dist/decodePermission/types.mjs.map +1 -0
- package/dist/decodePermission/utils.cjs +181 -0
- package/dist/decodePermission/utils.cjs.map +1 -0
- package/dist/decodePermission/utils.d.cts +83 -0
- package/dist/decodePermission/utils.d.cts.map +1 -0
- package/dist/decodePermission/utils.d.mts +83 -0
- package/dist/decodePermission/utils.d.mts.map +1 -0
- package/dist/decodePermission/utils.mjs +173 -0
- package/dist/decodePermission/utils.mjs.map +1 -0
- package/dist/errors.cjs +22 -1
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.cts +10 -0
- package/dist/errors.d.cts.map +1 -1
- package/dist/errors.d.mts +10 -0
- package/dist/errors.d.mts.map +1 -1
- package/dist/errors.mjs +19 -0
- package/dist/errors.mjs.map +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +3 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/types.cjs +2 -0
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +8 -1
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +8 -1
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +2 -0
- package/dist/types.mjs.map +1 -1
- package/package.json +5 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GatorPermissionsController.mjs","sourceRoot":"","sources":["../src/GatorPermissionsController.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Signer } from '@metamask/7715-permission-types';\nimport type {\n RestrictedMessenger,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { HandleSnapRequest, HasSnap } from '@metamask/snaps-controllers';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\n\nimport {\n GatorPermissionsFetchError,\n GatorPermissionsNotEnabledError,\n GatorPermissionsProviderError,\n} from './errors';\nimport { controllerLog } from './logger';\nimport type { StoredGatorPermissionSanitized } from './types';\nimport {\n GatorPermissionsSnapRpcMethod,\n type GatorPermissionsMap,\n type PermissionTypesWithCustom,\n type StoredGatorPermission,\n} from './types';\nimport {\n deserializeGatorPermissionsMap,\n serializeGatorPermissionsMap,\n} from './utils';\n\n// === GENERAL ===\n\n// Unique name for the controller\nconst controllerName = 'GatorPermissionsController';\n\n// Default value for the gator permissions provider snap id\nconst defaultGatorPermissionsProviderSnapId =\n '@metamask/gator-permissions-snap' as SnapId;\n\nconst defaultGatorPermissionsMap: GatorPermissionsMap = {\n 'native-token-stream': {},\n 'native-token-periodic': {},\n 'erc20-token-stream': {},\n 'erc20-token-periodic': {},\n other: {},\n};\n\n// === STATE ===\n\n/**\n * State shape for GatorPermissionsController\n */\nexport type GatorPermissionsControllerState = {\n /**\n * Flag that indicates if the gator permissions feature is enabled\n */\n isGatorPermissionsEnabled: boolean;\n\n /**\n * JSON serialized object containing gator permissions fetched from profile sync\n */\n gatorPermissionsMapSerialized: string;\n\n /**\n * Flag that indicates that fetching permissions is in progress\n * This is used to show a loading spinner in the UI\n */\n isFetchingGatorPermissions: boolean;\n\n /**\n * The ID of the Snap of the gator permissions provider snap\n * Default value is `@metamask/gator-permissions-snap`\n */\n gatorPermissionsProviderSnapId: SnapId;\n};\n\nconst gatorPermissionsControllerMetadata = {\n isGatorPermissionsEnabled: {\n persist: true,\n anonymous: false,\n },\n gatorPermissionsMapSerialized: {\n persist: true,\n anonymous: false,\n },\n isFetchingGatorPermissions: {\n persist: false,\n anonymous: false,\n },\n gatorPermissionsProviderSnapId: {\n persist: false,\n anonymous: false,\n },\n} satisfies StateMetadata<GatorPermissionsControllerState>;\n\n/**\n * Constructs the default {@link GatorPermissionsController} state. This allows\n * consumers to provide a partial state object when initializing the controller\n * and also helps in constructing complete state objects for this controller in\n * tests.\n *\n * @returns The default {@link GatorPermissionsController} state.\n */\nexport function getDefaultGatorPermissionsControllerState(): GatorPermissionsControllerState {\n return {\n isGatorPermissionsEnabled: false,\n gatorPermissionsMapSerialized: serializeGatorPermissionsMap(\n defaultGatorPermissionsMap,\n ),\n isFetchingGatorPermissions: false,\n gatorPermissionsProviderSnapId: defaultGatorPermissionsProviderSnapId,\n };\n}\n\n// === MESSENGER ===\n\n/**\n * The action which can be used to retrieve the state of the\n * {@link GatorPermissionsController}.\n */\nexport type GatorPermissionsControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n GatorPermissionsControllerState\n>;\n\n/**\n * The action which can be used to fetch and update gator permissions.\n */\nexport type GatorPermissionsControllerFetchAndUpdateGatorPermissionsAction = {\n type: `${typeof controllerName}:fetchAndUpdateGatorPermissions`;\n handler: GatorPermissionsController['fetchAndUpdateGatorPermissions'];\n};\n\n/**\n * The action which can be used to enable gator permissions.\n */\nexport type GatorPermissionsControllerEnableGatorPermissionsAction = {\n type: `${typeof controllerName}:enableGatorPermissions`;\n handler: GatorPermissionsController['enableGatorPermissions'];\n};\n\n/**\n * The action which can be used to disable gator permissions.\n */\nexport type GatorPermissionsControllerDisableGatorPermissionsAction = {\n type: `${typeof controllerName}:disableGatorPermissions`;\n handler: GatorPermissionsController['disableGatorPermissions'];\n};\n\n/**\n * All actions that {@link GatorPermissionsController} registers, to be called\n * externally.\n */\nexport type GatorPermissionsControllerActions =\n | GatorPermissionsControllerGetStateAction\n | GatorPermissionsControllerFetchAndUpdateGatorPermissionsAction\n | GatorPermissionsControllerEnableGatorPermissionsAction\n | GatorPermissionsControllerDisableGatorPermissionsAction;\n\n/**\n * All actions that {@link GatorPermissionsController} calls internally.\n *\n * SnapsController:handleRequest and SnapsController:has are allowed to be called\n * internally because they are used to fetch gator permissions from the Snap.\n */\ntype AllowedActions = HandleSnapRequest | HasSnap;\n\n/**\n * The event that {@link GatorPermissionsController} publishes when updating state.\n */\nexport type GatorPermissionsControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n GatorPermissionsControllerState\n >;\n\n/**\n * All events that {@link GatorPermissionsController} publishes, to be subscribed to\n * externally.\n */\nexport type GatorPermissionsControllerEvents =\n GatorPermissionsControllerStateChangeEvent;\n\n/**\n * Events that {@link GatorPermissionsController} is allowed to subscribe to internally.\n */\ntype AllowedEvents = GatorPermissionsControllerStateChangeEvent;\n\n/**\n * Messenger type for the GatorPermissionsController.\n */\nexport type GatorPermissionsControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n GatorPermissionsControllerActions | AllowedActions,\n GatorPermissionsControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/**\n * Controller that manages gator permissions by reading from profile sync\n */\nexport default class GatorPermissionsController extends BaseController<\n typeof controllerName,\n GatorPermissionsControllerState,\n GatorPermissionsControllerMessenger\n> {\n /**\n * Creates a GatorPermissionsController instance.\n *\n * @param args - The arguments to this function.\n * @param args.messenger - Messenger used to communicate with BaseV2 controller.\n * @param args.state - Initial state to set on this controller.\n */\n constructor({\n messenger,\n state,\n }: {\n messenger: GatorPermissionsControllerMessenger;\n state?: Partial<GatorPermissionsControllerState>;\n }) {\n super({\n name: controllerName,\n metadata: gatorPermissionsControllerMetadata,\n messenger,\n state: {\n ...getDefaultGatorPermissionsControllerState(),\n ...state,\n isFetchingGatorPermissions: false,\n },\n });\n\n this.#registerMessageHandlers();\n }\n\n #setIsFetchingGatorPermissions(isFetchingGatorPermissions: boolean) {\n this.update((state) => {\n state.isFetchingGatorPermissions = isFetchingGatorPermissions;\n });\n }\n\n #setIsGatorPermissionsEnabled(isGatorPermissionsEnabled: boolean) {\n this.update((state) => {\n state.isGatorPermissionsEnabled = isGatorPermissionsEnabled;\n });\n }\n\n #registerMessageHandlers(): void {\n this.messagingSystem.registerActionHandler(\n `${controllerName}:fetchAndUpdateGatorPermissions`,\n this.fetchAndUpdateGatorPermissions.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:enableGatorPermissions`,\n this.enableGatorPermissions.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:disableGatorPermissions`,\n this.disableGatorPermissions.bind(this),\n );\n }\n\n /**\n * Asserts that the gator permissions are enabled.\n *\n * @throws {GatorPermissionsNotEnabledError} If the gator permissions are not enabled.\n */\n #assertGatorPermissionsEnabled() {\n if (!this.state.isGatorPermissionsEnabled) {\n throw new GatorPermissionsNotEnabledError();\n }\n }\n\n /**\n * Forwards a Snap request to the SnapController.\n *\n * @param args - The request parameters.\n * @param args.snapId - The ID of the Snap of the gator permissions provider snap.\n * @returns A promise that resolves with the gator permissions.\n */\n async #handleSnapRequestToGatorPermissionsProvider({\n snapId,\n }: {\n snapId: SnapId;\n }): Promise<\n StoredGatorPermission<Signer, PermissionTypesWithCustom>[] | null\n > {\n try {\n const response = (await this.messagingSystem.call(\n 'SnapController:handleRequest',\n {\n snapId,\n origin: 'metamask',\n handler: HandlerType.OnRpcRequest,\n request: {\n jsonrpc: '2.0',\n method:\n GatorPermissionsSnapRpcMethod.PermissionProviderGetGrantedPermissions,\n },\n },\n )) as StoredGatorPermission<Signer, PermissionTypesWithCustom>[] | null;\n\n return response;\n } catch (error) {\n controllerLog(\n 'Failed to handle snap request to gator permissions provider',\n error,\n );\n throw new GatorPermissionsProviderError({\n method:\n GatorPermissionsSnapRpcMethod.PermissionProviderGetGrantedPermissions,\n cause: error as Error,\n });\n }\n }\n\n /**\n * Sanitizes a stored gator permission by removing the fields that are not expose to MetaMask client.\n *\n * @param storedGatorPermission - The stored gator permission to sanitize.\n * @returns The sanitized stored gator permission.\n */\n #sanitizeStoredGatorPermission(\n storedGatorPermission: StoredGatorPermission<\n Signer,\n PermissionTypesWithCustom\n >,\n ): StoredGatorPermissionSanitized<Signer, PermissionTypesWithCustom> {\n const { permissionResponse } = storedGatorPermission;\n const { rules, dependencyInfo, signer, ...rest } = permissionResponse;\n return {\n ...storedGatorPermission,\n permissionResponse: {\n ...rest,\n },\n };\n }\n\n /**\n * Categorizes stored gator permissions by type and chainId.\n *\n * @param storedGatorPermissions - An array of stored gator permissions.\n * @returns The gator permissions map.\n */\n #categorizePermissionsDataByTypeAndChainId(\n storedGatorPermissions:\n | StoredGatorPermission<Signer, PermissionTypesWithCustom>[]\n | null,\n ): GatorPermissionsMap {\n if (!storedGatorPermissions) {\n return defaultGatorPermissionsMap;\n }\n\n return storedGatorPermissions.reduce(\n (gatorPermissionsMap, storedGatorPermission) => {\n const { permissionResponse } = storedGatorPermission;\n const permissionType = permissionResponse.permission.type;\n const { chainId } = permissionResponse;\n\n const sanitizedStoredGatorPermission =\n this.#sanitizeStoredGatorPermission(storedGatorPermission);\n\n switch (permissionType) {\n case 'native-token-stream':\n case 'native-token-periodic':\n case 'erc20-token-stream':\n case 'erc20-token-periodic':\n if (!gatorPermissionsMap[permissionType][chainId]) {\n gatorPermissionsMap[permissionType][chainId] = [];\n }\n\n (\n gatorPermissionsMap[permissionType][\n chainId\n ] as StoredGatorPermissionSanitized<\n Signer,\n PermissionTypesWithCustom\n >[]\n ).push(sanitizedStoredGatorPermission);\n break;\n default:\n if (!gatorPermissionsMap.other[chainId]) {\n gatorPermissionsMap.other[chainId] = [];\n }\n\n (\n gatorPermissionsMap.other[\n chainId\n ] as StoredGatorPermissionSanitized<\n Signer,\n PermissionTypesWithCustom\n >[]\n ).push(sanitizedStoredGatorPermission);\n break;\n }\n\n return gatorPermissionsMap;\n },\n {\n 'native-token-stream': {},\n 'native-token-periodic': {},\n 'erc20-token-stream': {},\n 'erc20-token-periodic': {},\n other: {},\n } as GatorPermissionsMap,\n );\n }\n\n /**\n * Gets the gator permissions map from the state.\n *\n * @returns The gator permissions map.\n */\n get gatorPermissionsMap(): GatorPermissionsMap {\n return deserializeGatorPermissionsMap(\n this.state.gatorPermissionsMapSerialized,\n );\n }\n\n /**\n * Gets the gator permissions provider snap id that is used to fetch gator permissions.\n *\n * @returns The gator permissions provider snap id.\n */\n get permissionsProviderSnapId(): SnapId {\n return this.state.gatorPermissionsProviderSnapId;\n }\n\n /**\n * Enables gator permissions for the user.\n */\n public async enableGatorPermissions() {\n this.#setIsGatorPermissionsEnabled(true);\n }\n\n /**\n * Clears the gator permissions map and disables the feature.\n */\n public async disableGatorPermissions() {\n this.update((state) => {\n state.isGatorPermissionsEnabled = false;\n state.gatorPermissionsMapSerialized = serializeGatorPermissionsMap(\n defaultGatorPermissionsMap,\n );\n });\n }\n\n /**\n * Fetches the gator permissions from profile sync and updates the state.\n *\n * @returns A promise that resolves to the gator permissions map.\n * @throws {GatorPermissionsFetchError} If the gator permissions fetch fails.\n */\n public async fetchAndUpdateGatorPermissions(): Promise<GatorPermissionsMap> {\n try {\n this.#setIsFetchingGatorPermissions(true);\n this.#assertGatorPermissionsEnabled();\n\n const permissionsData =\n await this.#handleSnapRequestToGatorPermissionsProvider({\n snapId: this.state.gatorPermissionsProviderSnapId,\n });\n\n const gatorPermissionsMap =\n this.#categorizePermissionsDataByTypeAndChainId(permissionsData);\n\n this.update((state) => {\n state.gatorPermissionsMapSerialized =\n serializeGatorPermissionsMap(gatorPermissionsMap);\n });\n\n return gatorPermissionsMap;\n } catch (error) {\n controllerLog('Failed to fetch gator permissions', error);\n throw new GatorPermissionsFetchError({\n message: 'Failed to fetch gator permissions',\n cause: error as Error,\n });\n } finally {\n this.#setIsFetchingGatorPermissions(false);\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"GatorPermissionsController.mjs","sourceRoot":"","sources":["../src/GatorPermissionsController.ts"],"names":[],"mappings":";;;;;;AAOA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,yCAAyC;AAGvE,OAAO,EAAE,WAAW,EAAE,8BAA8B;AAGpD,OAAO,EACL,0BAA0B,EAC1B,6BAA6B,EAC7B,4BAA4B,EAC7B,qCAA2B;AAC5B,OAAO,EACL,0BAA0B,EAC1B,+BAA+B,EAC/B,6BAA6B,EAC7B,qBAAqB,EACrB,uBAAuB,EACxB,qBAAiB;AAClB,OAAO,EAAE,aAAa,EAAE,qBAAiB;AAEzC,OAAO,EACL,6BAA6B,EAK9B,oBAAgB;AACjB,OAAO,EACL,8BAA8B,EAC9B,4BAA4B,EAC7B,oBAAgB;AAEjB,kBAAkB;AAElB,iCAAiC;AACjC,MAAM,cAAc,GAAG,4BAA4B,CAAC;AAEpD,2DAA2D;AAC3D,MAAM,qCAAqC,GACzC,sCAAgD,CAAC;AAEnD,MAAM,0BAA0B,GAAwB;IACtD,qBAAqB,EAAE,EAAE;IACzB,uBAAuB,EAAE,EAAE;IAC3B,oBAAoB,EAAE,EAAE;IACxB,sBAAsB,EAAE,EAAE;IAC1B,KAAK,EAAE,EAAE;CACV,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,OAAO,CAAC;AAEpD,MAAM,kBAAkB,GAAG,mBAAmB,CAAC,4BAA4B,CAAC,CAAC;AA+B7E,MAAM,kCAAkC,GAAG;IACzC,yBAAyB,EAAE;QACzB,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,SAAS,EAAE,KAAK;QAChB,QAAQ,EAAE,KAAK;KAChB;IACD,6BAA6B,EAAE;QAC7B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,SAAS,EAAE,KAAK;QAChB,QAAQ,EAAE,IAAI;KACf;IACD,0BAA0B,EAAE;QAC1B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,KAAK;QACd,SAAS,EAAE,KAAK;QAChB,QAAQ,EAAE,KAAK;KAChB;IACD,8BAA8B,EAAE;QAC9B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,KAAK;QACd,SAAS,EAAE,KAAK;QAChB,QAAQ,EAAE,KAAK;KAChB;CACuD,CAAC;AAE3D;;;;;;;GAOG;AACH,MAAM,UAAU,yCAAyC;IACvD,OAAO;QACL,yBAAyB,EAAE,KAAK;QAChC,6BAA6B,EAAE,4BAA4B,CACzD,0BAA0B,CAC3B;QACD,0BAA0B,EAAE,KAAK;QACjC,8BAA8B,EAAE,qCAAqC;KACtE,CAAC;AACJ,CAAC;AA8FD;;GAEG;AACH,MAAqB,0BAA2B,SAAQ,cAIvD;IACC;;;;;;OAMG;IACH,YAAY,EACV,SAAS,EACT,KAAK,GAIN;QACC,KAAK,CAAC;YACJ,IAAI,EAAE,cAAc;YACpB,QAAQ,EAAE,kCAAkC;YAC5C,SAAS;YACT,KAAK,EAAE;gBACL,GAAG,yCAAyC,EAAE;gBAC9C,GAAG,KAAK;gBACR,0BAA0B,EAAE,KAAK;aAClC;SACF,CAAC,CAAC;;QAEH,uBAAA,IAAI,kGAAyB,MAA7B,IAAI,CAA2B,CAAC;IAClC,CAAC;IAsLD;;;;OAIG;IACH,IAAI,mBAAmB;QACrB,OAAO,8BAA8B,CACnC,IAAI,CAAC,KAAK,CAAC,6BAA6B,CACzC,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,IAAI,yBAAyB;QAC3B,OAAO,IAAI,CAAC,KAAK,CAAC,8BAA8B,CAAC;IACnD,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,sBAAsB;QACjC,uBAAA,IAAI,uGAA8B,MAAlC,IAAI,EAA+B,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,uBAAuB;QAClC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,yBAAyB,GAAG,KAAK,CAAC;YACxC,KAAK,CAAC,6BAA6B,GAAG,4BAA4B,CAChE,0BAA0B,CAC3B,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,8BAA8B;QACzC,IAAI;YACF,uBAAA,IAAI,wGAA+B,MAAnC,IAAI,EAAgC,IAAI,CAAC,CAAC;YAC1C,uBAAA,IAAI,wGAA+B,MAAnC,IAAI,CAAiC,CAAC;YAEtC,MAAM,eAAe,GACnB,MAAM,uBAAA,IAAI,sHAA6C,MAAjD,IAAI,EAA8C;gBACtD,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,8BAA8B;aAClD,CAAC,CAAC;YAEL,MAAM,mBAAmB,GACvB,uBAAA,IAAI,oHAA2C,MAA/C,IAAI,EAA4C,eAAe,CAAC,CAAC;YAEnE,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;gBACpB,KAAK,CAAC,6BAA6B;oBACjC,4BAA4B,CAAC,mBAAmB,CAAC,CAAC;YACtD,CAAC,CAAC,CAAC;YAEH,OAAO,mBAAmB,CAAC;SAC5B;QAAC,OAAO,KAAK,EAAE;YACd,aAAa,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;YAC1D,MAAM,IAAI,0BAA0B,CAAC;gBACnC,OAAO,EAAE,mCAAmC;gBAC5C,KAAK,EAAE,KAAc;aACtB,CAAC,CAAC;SACJ;gBAAS;YACR,uBAAA,IAAI,wGAA+B,MAAnC,IAAI,EAAgC,KAAK,CAAC,CAAC;SAC5C;IACH,CAAC;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACI,8CAA8C,CAAC,EACpD,MAAM,EACN,OAAO,EACP,UAAU,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,EACvD,QAAQ,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,eAAe,EAAE,GASrD;QACC,IAAI,MAAM,KAAK,IAAI,CAAC,yBAAyB,EAAE;YAC7C,MAAM,IAAI,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;SAC7C;QAED,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAE9C,IAAI,CAAC,SAAS,EAAE;YACd,MAAM,IAAI,KAAK,CAAC,oCAAoC,OAAO,EAAE,CAAC,CAAC;SAChE;QAED,IAAI;YACF,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAE3D,MAAM,cAAc,GAAG,6BAA6B,CAAC;gBACnD,SAAS;gBACT,SAAS;aACV,CAAC,CAAC;YAEH,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,0BAA0B,CAAC;gBAClD,SAAS;gBACT,OAAO;gBACP,cAAc;aACf,CAAC,CAAC;YAEH,MAAM,UAAU,GAAG,4BAA4B,CAAC;gBAC9C,OAAO;gBACP,cAAc;gBACd,SAAS;gBACT,QAAQ;gBACR,SAAS;gBACT,MAAM;gBACN,IAAI;gBACJ,aAAa;gBACb,eAAe;aAChB,CAAC,CAAC;YAEH,OAAO,UAAU,CAAC;SACnB;QAAC,OAAO,KAAK,EAAE;YACd,MAAM,IAAI,uBAAuB,CAAC;gBAChC,KAAK,EAAE,KAAc;aACtB,CAAC,CAAC;SACJ;IACH,CAAC;CACF;sLA5UgC,0BAAmC;IAChE,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QACpB,KAAK,CAAC,0BAA0B,GAAG,0BAA0B,CAAC;IAChE,CAAC,CAAC,CAAC;AACL,CAAC,+HAE6B,yBAAkC;IAC9D,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QACpB,KAAK,CAAC,yBAAyB,GAAG,yBAAyB,CAAC;IAC9D,CAAC,CAAC,CAAC;AACL,CAAC;IAGC,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,iCAAiC,EAClD,IAAI,CAAC,8BAA8B,CAAC,IAAI,CAAC,IAAI,CAAC,CAC/C,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,yBAAyB,EAC1C,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,CACvC,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,0BAA0B,EAC3C,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,CACxC,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,iDAAiD,EAClE,IAAI,CAAC,8CAA8C,CAAC,IAAI,CAAC,IAAI,CAAC,CAC/D,CAAC;AACJ,CAAC;IAQC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,yBAAyB,EAAE;QACzC,MAAM,IAAI,+BAA+B,EAAE,CAAC;KAC7C;AACH,CAAC;AAED;;;;;;GAMG;AACH,KAAK,kFAA8C,EACjD,MAAM,GAGP;IAGC,IAAI;QACF,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAC/C,8BAA8B,EAC9B;YACE,MAAM;YACN,MAAM,EAAE,UAAU;YAClB,OAAO,EAAE,WAAW,CAAC,YAAY;YACjC,OAAO,EAAE;gBACP,OAAO,EAAE,KAAK;gBACd,MAAM,EACJ,6BAA6B,CAAC,uCAAuC;aACxE;SACF,CACF,CAAsE,CAAC;QAExE,OAAO,QAAQ,CAAC;KACjB;IAAC,OAAO,KAAK,EAAE;QACd,aAAa,CACX,6DAA6D,EAC7D,KAAK,CACN,CAAC;QACF,MAAM,IAAI,6BAA6B,CAAC;YACtC,MAAM,EACJ,6BAA6B,CAAC,uCAAuC;YACvE,KAAK,EAAE,KAAc;SACtB,CAAC,CAAC;KACJ;AACH,CAAC,iIASC,qBAGC;IAED,MAAM,EAAE,kBAAkB,EAAE,GAAG,qBAAqB,CAAC;IACrD,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,kBAAkB,CAAC;IACtE,OAAO;QACL,GAAG,qBAAqB;QACxB,kBAAkB,EAAE;YAClB,GAAG,IAAI;SACR;KACF,CAAC;AACJ,CAAC,yJASC,sBAEQ;IAER,IAAI,CAAC,sBAAsB,EAAE;QAC3B,OAAO,0BAA0B,CAAC;KACnC;IAED,OAAO,sBAAsB,CAAC,MAAM,CAClC,CAAC,mBAAmB,EAAE,qBAAqB,EAAE,EAAE;QAC7C,MAAM,EAAE,kBAAkB,EAAE,GAAG,qBAAqB,CAAC;QACrD,MAAM,cAAc,GAAG,kBAAkB,CAAC,UAAU,CAAC,IAAI,CAAC;QAC1D,MAAM,EAAE,OAAO,EAAE,GAAG,kBAAkB,CAAC;QAEvC,MAAM,8BAA8B,GAClC,uBAAA,IAAI,wGAA+B,MAAnC,IAAI,EAAgC,qBAAqB,CAAC,CAAC;QAE7D,QAAQ,cAAc,EAAE;YACtB,KAAK,qBAAqB,CAAC;YAC3B,KAAK,uBAAuB,CAAC;YAC7B,KAAK,oBAAoB,CAAC;YAC1B,KAAK,sBAAsB;gBACzB,IAAI,CAAC,mBAAmB,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,EAAE;oBACjD,mBAAmB,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;iBACnD;gBAGC,mBAAmB,CAAC,cAAc,CAAC,CACjC,OAAO,CAKV,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;gBACvC,MAAM;YACR;gBACE,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;oBACvC,mBAAmB,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;iBACzC;gBAGC,mBAAmB,CAAC,KAAK,CACvB,OAAO,CAKV,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;gBACvC,MAAM;SACT;QAED,OAAO,mBAAmB,CAAC;IAC7B,CAAC,EACD;QACE,qBAAqB,EAAE,EAAE;QACzB,uBAAuB,EAAE,EAAE;QAC3B,oBAAoB,EAAE,EAAE;QACxB,sBAAsB,EAAE,EAAE;QAC1B,KAAK,EAAE,EAAE;KACa,CACzB,CAAC;AACJ,CAAC;eAnNkB,0BAA0B","sourcesContent":["import type { Signer } from '@metamask/7715-permission-types';\nimport type {\n RestrictedMessenger,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport { DELEGATOR_CONTRACTS } from '@metamask/delegation-deployments';\nimport type { HandleSnapRequest, HasSnap } from '@metamask/snaps-controllers';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { HandlerType } from '@metamask/snaps-utils';\n\nimport type { DecodedPermission } from './decodePermission';\nimport {\n getPermissionDataAndExpiry,\n identifyPermissionByEnforcers,\n reconstructDecodedPermission,\n} from './decodePermission';\nimport {\n GatorPermissionsFetchError,\n GatorPermissionsNotEnabledError,\n GatorPermissionsProviderError,\n OriginNotAllowedError,\n PermissionDecodingError,\n} from './errors';\nimport { controllerLog } from './logger';\nimport type { StoredGatorPermissionSanitized } from './types';\nimport {\n GatorPermissionsSnapRpcMethod,\n type GatorPermissionsMap,\n type PermissionTypesWithCustom,\n type StoredGatorPermission,\n type DelegationDetails,\n} from './types';\nimport {\n deserializeGatorPermissionsMap,\n serializeGatorPermissionsMap,\n} from './utils';\n\n// === GENERAL ===\n\n// Unique name for the controller\nconst controllerName = 'GatorPermissionsController';\n\n// Default value for the gator permissions provider snap id\nconst defaultGatorPermissionsProviderSnapId =\n 'npm:@metamask/gator-permissions-snap' as SnapId;\n\nconst defaultGatorPermissionsMap: GatorPermissionsMap = {\n 'native-token-stream': {},\n 'native-token-periodic': {},\n 'erc20-token-stream': {},\n 'erc20-token-periodic': {},\n other: {},\n};\n\n/**\n * Delegation framework version used to select the correct deployed enforcer\n * contract addresses from `@metamask/delegation-deployments`.\n */\nexport const DELEGATION_FRAMEWORK_VERSION = '1.3.0';\n\nconst contractsByChainId = DELEGATOR_CONTRACTS[DELEGATION_FRAMEWORK_VERSION];\n\n// === STATE ===\n\n/**\n * State shape for GatorPermissionsController\n */\nexport type GatorPermissionsControllerState = {\n /**\n * Flag that indicates if the gator permissions feature is enabled\n */\n isGatorPermissionsEnabled: boolean;\n\n /**\n * JSON serialized object containing gator permissions fetched from profile sync\n */\n gatorPermissionsMapSerialized: string;\n\n /**\n * Flag that indicates that fetching permissions is in progress\n * This is used to show a loading spinner in the UI\n */\n isFetchingGatorPermissions: boolean;\n\n /**\n * The ID of the Snap of the gator permissions provider snap\n * Default value is `@metamask/gator-permissions-snap`\n */\n gatorPermissionsProviderSnapId: SnapId;\n};\n\nconst gatorPermissionsControllerMetadata = {\n isGatorPermissionsEnabled: {\n includeInStateLogs: true,\n persist: true,\n anonymous: false,\n usedInUi: false,\n },\n gatorPermissionsMapSerialized: {\n includeInStateLogs: true,\n persist: true,\n anonymous: false,\n usedInUi: true,\n },\n isFetchingGatorPermissions: {\n includeInStateLogs: true,\n persist: false,\n anonymous: false,\n usedInUi: false,\n },\n gatorPermissionsProviderSnapId: {\n includeInStateLogs: true,\n persist: false,\n anonymous: false,\n usedInUi: false,\n },\n} satisfies StateMetadata<GatorPermissionsControllerState>;\n\n/**\n * Constructs the default {@link GatorPermissionsController} state. This allows\n * consumers to provide a partial state object when initializing the controller\n * and also helps in constructing complete state objects for this controller in\n * tests.\n *\n * @returns The default {@link GatorPermissionsController} state.\n */\nexport function getDefaultGatorPermissionsControllerState(): GatorPermissionsControllerState {\n return {\n isGatorPermissionsEnabled: false,\n gatorPermissionsMapSerialized: serializeGatorPermissionsMap(\n defaultGatorPermissionsMap,\n ),\n isFetchingGatorPermissions: false,\n gatorPermissionsProviderSnapId: defaultGatorPermissionsProviderSnapId,\n };\n}\n\n// === MESSENGER ===\n\n/**\n * The action which can be used to retrieve the state of the\n * {@link GatorPermissionsController}.\n */\nexport type GatorPermissionsControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n GatorPermissionsControllerState\n>;\n\n/**\n * The action which can be used to fetch and update gator permissions.\n */\nexport type GatorPermissionsControllerFetchAndUpdateGatorPermissionsAction = {\n type: `${typeof controllerName}:fetchAndUpdateGatorPermissions`;\n handler: GatorPermissionsController['fetchAndUpdateGatorPermissions'];\n};\n\n/**\n * The action which can be used to enable gator permissions.\n */\nexport type GatorPermissionsControllerEnableGatorPermissionsAction = {\n type: `${typeof controllerName}:enableGatorPermissions`;\n handler: GatorPermissionsController['enableGatorPermissions'];\n};\n\n/**\n * The action which can be used to disable gator permissions.\n */\nexport type GatorPermissionsControllerDisableGatorPermissionsAction = {\n type: `${typeof controllerName}:disableGatorPermissions`;\n handler: GatorPermissionsController['disableGatorPermissions'];\n};\n\nexport type GatorPermissionsControllerDecodePermissionFromPermissionContextForOriginAction =\n {\n type: `${typeof controllerName}:decodePermissionFromPermissionContextForOrigin`;\n handler: GatorPermissionsController['decodePermissionFromPermissionContextForOrigin'];\n };\n\n/**\n * All actions that {@link GatorPermissionsController} registers, to be called\n * externally.\n */\nexport type GatorPermissionsControllerActions =\n | GatorPermissionsControllerGetStateAction\n | GatorPermissionsControllerFetchAndUpdateGatorPermissionsAction\n | GatorPermissionsControllerEnableGatorPermissionsAction\n | GatorPermissionsControllerDisableGatorPermissionsAction\n | GatorPermissionsControllerDecodePermissionFromPermissionContextForOriginAction;\n\n/**\n * All actions that {@link GatorPermissionsController} calls internally.\n *\n * SnapsController:handleRequest and SnapsController:has are allowed to be called\n * internally because they are used to fetch gator permissions from the Snap.\n */\ntype AllowedActions = HandleSnapRequest | HasSnap;\n\n/**\n * The event that {@link GatorPermissionsController} publishes when updating state.\n */\nexport type GatorPermissionsControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n GatorPermissionsControllerState\n >;\n\n/**\n * All events that {@link GatorPermissionsController} publishes, to be subscribed to\n * externally.\n */\nexport type GatorPermissionsControllerEvents =\n GatorPermissionsControllerStateChangeEvent;\n\n/**\n * Events that {@link GatorPermissionsController} is allowed to subscribe to internally.\n */\ntype AllowedEvents = GatorPermissionsControllerStateChangeEvent;\n\n/**\n * Messenger type for the GatorPermissionsController.\n */\nexport type GatorPermissionsControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n GatorPermissionsControllerActions | AllowedActions,\n GatorPermissionsControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/**\n * Controller that manages gator permissions by reading from profile sync\n */\nexport default class GatorPermissionsController extends BaseController<\n typeof controllerName,\n GatorPermissionsControllerState,\n GatorPermissionsControllerMessenger\n> {\n /**\n * Creates a GatorPermissionsController instance.\n *\n * @param args - The arguments to this function.\n * @param args.messenger - Messenger used to communicate with BaseV2 controller.\n * @param args.state - Initial state to set on this controller.\n */\n constructor({\n messenger,\n state,\n }: {\n messenger: GatorPermissionsControllerMessenger;\n state?: Partial<GatorPermissionsControllerState>;\n }) {\n super({\n name: controllerName,\n metadata: gatorPermissionsControllerMetadata,\n messenger,\n state: {\n ...getDefaultGatorPermissionsControllerState(),\n ...state,\n isFetchingGatorPermissions: false,\n },\n });\n\n this.#registerMessageHandlers();\n }\n\n #setIsFetchingGatorPermissions(isFetchingGatorPermissions: boolean) {\n this.update((state) => {\n state.isFetchingGatorPermissions = isFetchingGatorPermissions;\n });\n }\n\n #setIsGatorPermissionsEnabled(isGatorPermissionsEnabled: boolean) {\n this.update((state) => {\n state.isGatorPermissionsEnabled = isGatorPermissionsEnabled;\n });\n }\n\n #registerMessageHandlers(): void {\n this.messagingSystem.registerActionHandler(\n `${controllerName}:fetchAndUpdateGatorPermissions`,\n this.fetchAndUpdateGatorPermissions.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:enableGatorPermissions`,\n this.enableGatorPermissions.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:disableGatorPermissions`,\n this.disableGatorPermissions.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:decodePermissionFromPermissionContextForOrigin`,\n this.decodePermissionFromPermissionContextForOrigin.bind(this),\n );\n }\n\n /**\n * Asserts that the gator permissions are enabled.\n *\n * @throws {GatorPermissionsNotEnabledError} If the gator permissions are not enabled.\n */\n #assertGatorPermissionsEnabled() {\n if (!this.state.isGatorPermissionsEnabled) {\n throw new GatorPermissionsNotEnabledError();\n }\n }\n\n /**\n * Forwards a Snap request to the SnapController.\n *\n * @param args - The request parameters.\n * @param args.snapId - The ID of the Snap of the gator permissions provider snap.\n * @returns A promise that resolves with the gator permissions.\n */\n async #handleSnapRequestToGatorPermissionsProvider({\n snapId,\n }: {\n snapId: SnapId;\n }): Promise<\n StoredGatorPermission<Signer, PermissionTypesWithCustom>[] | null\n > {\n try {\n const response = (await this.messagingSystem.call(\n 'SnapController:handleRequest',\n {\n snapId,\n origin: 'metamask',\n handler: HandlerType.OnRpcRequest,\n request: {\n jsonrpc: '2.0',\n method:\n GatorPermissionsSnapRpcMethod.PermissionProviderGetGrantedPermissions,\n },\n },\n )) as StoredGatorPermission<Signer, PermissionTypesWithCustom>[] | null;\n\n return response;\n } catch (error) {\n controllerLog(\n 'Failed to handle snap request to gator permissions provider',\n error,\n );\n throw new GatorPermissionsProviderError({\n method:\n GatorPermissionsSnapRpcMethod.PermissionProviderGetGrantedPermissions,\n cause: error as Error,\n });\n }\n }\n\n /**\n * Sanitizes a stored gator permission by removing the fields that are not expose to MetaMask client.\n *\n * @param storedGatorPermission - The stored gator permission to sanitize.\n * @returns The sanitized stored gator permission.\n */\n #sanitizeStoredGatorPermission(\n storedGatorPermission: StoredGatorPermission<\n Signer,\n PermissionTypesWithCustom\n >,\n ): StoredGatorPermissionSanitized<Signer, PermissionTypesWithCustom> {\n const { permissionResponse } = storedGatorPermission;\n const { rules, dependencyInfo, signer, ...rest } = permissionResponse;\n return {\n ...storedGatorPermission,\n permissionResponse: {\n ...rest,\n },\n };\n }\n\n /**\n * Categorizes stored gator permissions by type and chainId.\n *\n * @param storedGatorPermissions - An array of stored gator permissions.\n * @returns The gator permissions map.\n */\n #categorizePermissionsDataByTypeAndChainId(\n storedGatorPermissions:\n | StoredGatorPermission<Signer, PermissionTypesWithCustom>[]\n | null,\n ): GatorPermissionsMap {\n if (!storedGatorPermissions) {\n return defaultGatorPermissionsMap;\n }\n\n return storedGatorPermissions.reduce(\n (gatorPermissionsMap, storedGatorPermission) => {\n const { permissionResponse } = storedGatorPermission;\n const permissionType = permissionResponse.permission.type;\n const { chainId } = permissionResponse;\n\n const sanitizedStoredGatorPermission =\n this.#sanitizeStoredGatorPermission(storedGatorPermission);\n\n switch (permissionType) {\n case 'native-token-stream':\n case 'native-token-periodic':\n case 'erc20-token-stream':\n case 'erc20-token-periodic':\n if (!gatorPermissionsMap[permissionType][chainId]) {\n gatorPermissionsMap[permissionType][chainId] = [];\n }\n\n (\n gatorPermissionsMap[permissionType][\n chainId\n ] as StoredGatorPermissionSanitized<\n Signer,\n PermissionTypesWithCustom\n >[]\n ).push(sanitizedStoredGatorPermission);\n break;\n default:\n if (!gatorPermissionsMap.other[chainId]) {\n gatorPermissionsMap.other[chainId] = [];\n }\n\n (\n gatorPermissionsMap.other[\n chainId\n ] as StoredGatorPermissionSanitized<\n Signer,\n PermissionTypesWithCustom\n >[]\n ).push(sanitizedStoredGatorPermission);\n break;\n }\n\n return gatorPermissionsMap;\n },\n {\n 'native-token-stream': {},\n 'native-token-periodic': {},\n 'erc20-token-stream': {},\n 'erc20-token-periodic': {},\n other: {},\n } as GatorPermissionsMap,\n );\n }\n\n /**\n * Gets the gator permissions map from the state.\n *\n * @returns The gator permissions map.\n */\n get gatorPermissionsMap(): GatorPermissionsMap {\n return deserializeGatorPermissionsMap(\n this.state.gatorPermissionsMapSerialized,\n );\n }\n\n /**\n * Gets the gator permissions provider snap id that is used to fetch gator permissions.\n *\n * @returns The gator permissions provider snap id.\n */\n get permissionsProviderSnapId(): SnapId {\n return this.state.gatorPermissionsProviderSnapId;\n }\n\n /**\n * Enables gator permissions for the user.\n */\n public async enableGatorPermissions() {\n this.#setIsGatorPermissionsEnabled(true);\n }\n\n /**\n * Clears the gator permissions map and disables the feature.\n */\n public async disableGatorPermissions() {\n this.update((state) => {\n state.isGatorPermissionsEnabled = false;\n state.gatorPermissionsMapSerialized = serializeGatorPermissionsMap(\n defaultGatorPermissionsMap,\n );\n });\n }\n\n /**\n * Fetches the gator permissions from profile sync and updates the state.\n *\n * @returns A promise that resolves to the gator permissions map.\n * @throws {GatorPermissionsFetchError} If the gator permissions fetch fails.\n */\n public async fetchAndUpdateGatorPermissions(): Promise<GatorPermissionsMap> {\n try {\n this.#setIsFetchingGatorPermissions(true);\n this.#assertGatorPermissionsEnabled();\n\n const permissionsData =\n await this.#handleSnapRequestToGatorPermissionsProvider({\n snapId: this.state.gatorPermissionsProviderSnapId,\n });\n\n const gatorPermissionsMap =\n this.#categorizePermissionsDataByTypeAndChainId(permissionsData);\n\n this.update((state) => {\n state.gatorPermissionsMapSerialized =\n serializeGatorPermissionsMap(gatorPermissionsMap);\n });\n\n return gatorPermissionsMap;\n } catch (error) {\n controllerLog('Failed to fetch gator permissions', error);\n throw new GatorPermissionsFetchError({\n message: 'Failed to fetch gator permissions',\n cause: error as Error,\n });\n } finally {\n this.#setIsFetchingGatorPermissions(false);\n }\n }\n\n /**\n * Decodes a permission context into a structured permission for a specific origin.\n *\n * This method validates the caller origin, decodes the provided `permissionContext`\n * into delegations, identifies the permission type from the caveat enforcers,\n * extracts the permission-specific data and expiry, and reconstructs a\n * {@link DecodedPermission} containing chainId, account addresses, signer, type and data.\n *\n * @param args - The arguments to this function.\n * @param args.origin - The caller's origin; must match the configured permissions provider Snap id.\n * @param args.chainId - Numeric EIP-155 chain id used for resolving enforcer contracts and encoding.\n * @param args.delegation - delegation representing the permission.\n * @param args.metadata - metadata included in the request.\n * @param args.metadata.justification - the justification as specified in the request metadata.\n * @param args.metadata.origin - the origin as specified in the request metadata.\n *\n * @returns A decoded permission object suitable for UI consumption and follow-up actions.\n * @throws If the origin is not allowed, the context cannot be decoded into exactly one delegation,\n * or the enforcers/terms do not match a supported permission type.\n */\n public decodePermissionFromPermissionContextForOrigin({\n origin,\n chainId,\n delegation: { caveats, delegator, delegate, authority },\n metadata: { justification, origin: specifiedOrigin },\n }: {\n origin: string;\n chainId: number;\n metadata: {\n justification: string;\n origin: string;\n };\n delegation: DelegationDetails;\n }): DecodedPermission {\n if (origin !== this.permissionsProviderSnapId) {\n throw new OriginNotAllowedError({ origin });\n }\n\n const contracts = contractsByChainId[chainId];\n\n if (!contracts) {\n throw new Error(`Contracts not found for chainId: ${chainId}`);\n }\n\n try {\n const enforcers = caveats.map((caveat) => caveat.enforcer);\n\n const permissionType = identifyPermissionByEnforcers({\n enforcers,\n contracts,\n });\n\n const { expiry, data } = getPermissionDataAndExpiry({\n contracts,\n caveats,\n permissionType,\n });\n\n const permission = reconstructDecodedPermission({\n chainId,\n permissionType,\n delegator,\n delegate,\n authority,\n expiry,\n data,\n justification,\n specifiedOrigin,\n });\n\n return permission;\n } catch (error) {\n throw new PermissionDecodingError({\n cause: error as Error,\n });\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.reconstructDecodedPermission = exports.getPermissionDataAndExpiry = exports.identifyPermissionByEnforcers = void 0;
|
|
4
|
+
const delegation_core_1 = require("@metamask/delegation-core");
|
|
5
|
+
const utils_1 = require("@metamask/utils");
|
|
6
|
+
const utils_2 = require("./utils.cjs");
|
|
7
|
+
/**
|
|
8
|
+
* Identifies the unique permission type that matches a given set of enforcer
|
|
9
|
+
* contract addresses for a specific chain.
|
|
10
|
+
*
|
|
11
|
+
* A permission type matches when:
|
|
12
|
+
* - All of its required enforcers are present in the provided list; and
|
|
13
|
+
* - No provided enforcer falls outside the union of the type's required and
|
|
14
|
+
* allowed enforcers (currently only `TimestampEnforcer` is allowed extra).
|
|
15
|
+
*
|
|
16
|
+
* If exactly one permission type matches, its identifier is returned.
|
|
17
|
+
*
|
|
18
|
+
* @param args - The arguments to this function.
|
|
19
|
+
* @param args.enforcers - List of enforcer contract addresses (hex strings).
|
|
20
|
+
*
|
|
21
|
+
* @param args.contracts - The deployed contracts for the chain.
|
|
22
|
+
* @returns The identifier of the matching permission type.
|
|
23
|
+
* @throws If no permission type matches, or if more than one permission type matches.
|
|
24
|
+
*/
|
|
25
|
+
const identifyPermissionByEnforcers = ({ enforcers, contracts, }) => {
|
|
26
|
+
const enforcersSet = new Set(enforcers.map(utils_1.getChecksumAddress));
|
|
27
|
+
const permissionRules = (0, utils_2.createPermissionRulesForChainId)(contracts);
|
|
28
|
+
let matchingPermissionType = null;
|
|
29
|
+
for (const { allowedEnforcers, requiredEnforcers, permissionType, } of permissionRules) {
|
|
30
|
+
const hasAllRequiredEnforcers = (0, utils_2.isSubset)(requiredEnforcers, enforcersSet);
|
|
31
|
+
let hasForbiddenEnforcers = false;
|
|
32
|
+
for (const caveat of enforcersSet) {
|
|
33
|
+
if (!allowedEnforcers.has(caveat) && !requiredEnforcers.has(caveat)) {
|
|
34
|
+
hasForbiddenEnforcers = true;
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (hasAllRequiredEnforcers && !hasForbiddenEnforcers) {
|
|
39
|
+
if (matchingPermissionType) {
|
|
40
|
+
throw new Error('Multiple permission types match');
|
|
41
|
+
}
|
|
42
|
+
matchingPermissionType = permissionType;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (!matchingPermissionType) {
|
|
46
|
+
throw new Error('Unable to identify permission type');
|
|
47
|
+
}
|
|
48
|
+
return matchingPermissionType;
|
|
49
|
+
};
|
|
50
|
+
exports.identifyPermissionByEnforcers = identifyPermissionByEnforcers;
|
|
51
|
+
/**
|
|
52
|
+
* Extracts the permission-specific data payload and the expiry timestamp from
|
|
53
|
+
* the provided caveats for a given permission type.
|
|
54
|
+
*
|
|
55
|
+
* This function locates the relevant caveat enforcer for the `permissionType`,
|
|
56
|
+
* interprets its `terms` by splitting the hex string into byte-sized segments,
|
|
57
|
+
* and converts each segment into the appropriate numeric or address shape.
|
|
58
|
+
*
|
|
59
|
+
* The expiry timestamp is derived from the `TimestampEnforcer` terms and must
|
|
60
|
+
* have a zero `timestampAfterThreshold` and a positive `timestampBeforeThreshold`.
|
|
61
|
+
*
|
|
62
|
+
* @param args - The arguments to this function.
|
|
63
|
+
* @param args.contracts - The deployed contracts for the chain.
|
|
64
|
+
* @param args.caveats - Caveats decoded from the permission context.
|
|
65
|
+
* @param args.permissionType - The previously identified permission type.
|
|
66
|
+
*
|
|
67
|
+
* @returns An object containing the `expiry` timestamp and the decoded `data` payload.
|
|
68
|
+
* @throws If the caveats are malformed, missing, or the terms fail to decode.
|
|
69
|
+
*/
|
|
70
|
+
const getPermissionDataAndExpiry = ({ contracts, caveats, permissionType, }) => {
|
|
71
|
+
const checksumCaveats = caveats.map((caveat) => ({
|
|
72
|
+
...caveat,
|
|
73
|
+
enforcer: (0, utils_1.getChecksumAddress)(caveat.enforcer),
|
|
74
|
+
}));
|
|
75
|
+
const { erc20StreamingEnforcer, erc20PeriodicEnforcer, nativeTokenStreamingEnforcer, nativeTokenPeriodicEnforcer, timestampEnforcer, } = (0, utils_2.getChecksumEnforcersByChainId)(contracts);
|
|
76
|
+
const expiryTerms = (0, utils_2.getTermsByEnforcer)({
|
|
77
|
+
caveats: checksumCaveats,
|
|
78
|
+
enforcer: timestampEnforcer,
|
|
79
|
+
throwIfNotFound: false,
|
|
80
|
+
});
|
|
81
|
+
let expiry = null;
|
|
82
|
+
if (expiryTerms) {
|
|
83
|
+
const [after, before] = (0, utils_2.splitHex)(expiryTerms, [16, 16]);
|
|
84
|
+
if ((0, utils_1.hexToNumber)(after) !== 0) {
|
|
85
|
+
throw new Error('Invalid expiry');
|
|
86
|
+
}
|
|
87
|
+
expiry = (0, utils_1.hexToNumber)(before);
|
|
88
|
+
}
|
|
89
|
+
let data;
|
|
90
|
+
switch (permissionType) {
|
|
91
|
+
case 'erc20-token-stream': {
|
|
92
|
+
const erc20StreamingTerms = (0, utils_2.getTermsByEnforcer)({
|
|
93
|
+
caveats: checksumCaveats,
|
|
94
|
+
enforcer: erc20StreamingEnforcer,
|
|
95
|
+
});
|
|
96
|
+
const [tokenAddress, initialAmount, maxAmount, amountPerSecond, startTimeRaw,] = (0, utils_2.splitHex)(erc20StreamingTerms, [20, 32, 32, 32, 32]);
|
|
97
|
+
data = {
|
|
98
|
+
tokenAddress,
|
|
99
|
+
initialAmount,
|
|
100
|
+
maxAmount,
|
|
101
|
+
amountPerSecond,
|
|
102
|
+
startTime: (0, utils_1.hexToNumber)(startTimeRaw),
|
|
103
|
+
};
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
case 'erc20-token-periodic': {
|
|
107
|
+
const erc20PeriodicTerms = (0, utils_2.getTermsByEnforcer)({
|
|
108
|
+
caveats: checksumCaveats,
|
|
109
|
+
enforcer: erc20PeriodicEnforcer,
|
|
110
|
+
});
|
|
111
|
+
const [tokenAddress, periodAmount, periodDurationRaw, startTimeRaw] = (0, utils_2.splitHex)(erc20PeriodicTerms, [20, 32, 32, 32]);
|
|
112
|
+
data = {
|
|
113
|
+
tokenAddress,
|
|
114
|
+
periodAmount,
|
|
115
|
+
periodDuration: (0, utils_1.hexToNumber)(periodDurationRaw),
|
|
116
|
+
startTime: (0, utils_1.hexToNumber)(startTimeRaw),
|
|
117
|
+
};
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
case 'native-token-stream': {
|
|
121
|
+
const nativeTokenStreamingTerms = (0, utils_2.getTermsByEnforcer)({
|
|
122
|
+
caveats: checksumCaveats,
|
|
123
|
+
enforcer: nativeTokenStreamingEnforcer,
|
|
124
|
+
});
|
|
125
|
+
const [initialAmount, maxAmount, amountPerSecond, startTimeRaw] = (0, utils_2.splitHex)(nativeTokenStreamingTerms, [32, 32, 32, 32]);
|
|
126
|
+
data = {
|
|
127
|
+
initialAmount,
|
|
128
|
+
maxAmount,
|
|
129
|
+
amountPerSecond,
|
|
130
|
+
startTime: (0, utils_1.hexToNumber)(startTimeRaw),
|
|
131
|
+
};
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
case 'native-token-periodic': {
|
|
135
|
+
const nativeTokenPeriodicTerms = (0, utils_2.getTermsByEnforcer)({
|
|
136
|
+
caveats: checksumCaveats,
|
|
137
|
+
enforcer: nativeTokenPeriodicEnforcer,
|
|
138
|
+
});
|
|
139
|
+
const [periodAmount, periodDurationRaw, startTimeRaw] = (0, utils_2.splitHex)(nativeTokenPeriodicTerms, [32, 32, 32]);
|
|
140
|
+
data = {
|
|
141
|
+
periodAmount,
|
|
142
|
+
periodDuration: (0, utils_1.hexToNumber)(periodDurationRaw),
|
|
143
|
+
startTime: (0, utils_1.hexToNumber)(startTimeRaw),
|
|
144
|
+
};
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
default:
|
|
148
|
+
throw new Error('Invalid permission type');
|
|
149
|
+
}
|
|
150
|
+
return { expiry, data };
|
|
151
|
+
};
|
|
152
|
+
exports.getPermissionDataAndExpiry = getPermissionDataAndExpiry;
|
|
153
|
+
/**
|
|
154
|
+
* Reconstructs a {@link DecodedPermission} object from primitive values
|
|
155
|
+
* obtained while decoding a permission context.
|
|
156
|
+
*
|
|
157
|
+
* The resulting object contains:
|
|
158
|
+
* - `chainId` encoded as hex (`0x…`)
|
|
159
|
+
* - `address` set to the delegator (user account)
|
|
160
|
+
* - `signer` set to an account signer with the delegate address
|
|
161
|
+
* - `permission` with the identified type and decoded data
|
|
162
|
+
* - `expiry` timestamp (or null)
|
|
163
|
+
*
|
|
164
|
+
* @param args - The arguments to this function.
|
|
165
|
+
* @param args.chainId - Chain ID.
|
|
166
|
+
* @param args.permissionType - Identified permission type.
|
|
167
|
+
* @param args.delegator - Address of the account delegating permission.
|
|
168
|
+
* @param args.delegate - Address that will act under the granted permission.
|
|
169
|
+
* @param args.authority - Authority identifier; must be ROOT_AUTHORITY.
|
|
170
|
+
* @param args.expiry - Expiry timestamp (unix seconds) or null if unbounded.
|
|
171
|
+
* @param args.data - Permission-specific decoded data payload.
|
|
172
|
+
* @param args.justification - Human-readable justification for the permission.
|
|
173
|
+
* @param args.specifiedOrigin - The origin reported in the request metadata.
|
|
174
|
+
*
|
|
175
|
+
* @returns The reconstructed {@link DecodedPermission}.
|
|
176
|
+
*/
|
|
177
|
+
const reconstructDecodedPermission = ({ chainId, permissionType, delegator, delegate, authority, expiry, data, justification, specifiedOrigin, }) => {
|
|
178
|
+
if (authority !== delegation_core_1.ROOT_AUTHORITY) {
|
|
179
|
+
throw new Error('Invalid authority');
|
|
180
|
+
}
|
|
181
|
+
const permission = {
|
|
182
|
+
chainId: (0, utils_1.numberToHex)(chainId),
|
|
183
|
+
address: delegator,
|
|
184
|
+
signer: { type: 'account', data: { address: delegate } },
|
|
185
|
+
permission: {
|
|
186
|
+
type: permissionType,
|
|
187
|
+
data,
|
|
188
|
+
justification,
|
|
189
|
+
},
|
|
190
|
+
expiry,
|
|
191
|
+
origin: specifiedOrigin,
|
|
192
|
+
};
|
|
193
|
+
return permission;
|
|
194
|
+
};
|
|
195
|
+
exports.reconstructDecodedPermission = reconstructDecodedPermission;
|
|
196
|
+
//# sourceMappingURL=decodePermission.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decodePermission.cjs","sourceRoot":"","sources":["../../src/decodePermission/decodePermission.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Caveat, Hex } from '@metamask/delegation-core';\nimport { ROOT_AUTHORITY } from '@metamask/delegation-core';\nimport { getChecksumAddress, hexToNumber, numberToHex } from '@metamask/utils';\n\nimport type {\n DecodedPermission,\n DeployedContractsByName,\n PermissionType,\n} from './types';\nimport {\n createPermissionRulesForChainId,\n getChecksumEnforcersByChainId,\n getTermsByEnforcer,\n isSubset,\n splitHex,\n} from './utils';\n\n/**\n * Identifies the unique permission type that matches a given set of enforcer\n * contract addresses for a specific chain.\n *\n * A permission type matches when:\n * - All of its required enforcers are present in the provided list; and\n * - No provided enforcer falls outside the union of the type's required and\n * allowed enforcers (currently only `TimestampEnforcer` is allowed extra).\n *\n * If exactly one permission type matches, its identifier is returned.\n *\n * @param args - The arguments to this function.\n * @param args.enforcers - List of enforcer contract addresses (hex strings).\n *\n * @param args.contracts - The deployed contracts for the chain.\n * @returns The identifier of the matching permission type.\n * @throws If no permission type matches, or if more than one permission type matches.\n */\nexport const identifyPermissionByEnforcers = ({\n enforcers,\n contracts,\n}: {\n enforcers: Hex[];\n contracts: DeployedContractsByName;\n}): PermissionType => {\n const enforcersSet = new Set(enforcers.map(getChecksumAddress));\n\n const permissionRules = createPermissionRulesForChainId(contracts);\n\n let matchingPermissionType: PermissionType | null = null;\n\n for (const {\n allowedEnforcers,\n requiredEnforcers,\n permissionType,\n } of permissionRules) {\n const hasAllRequiredEnforcers = isSubset(requiredEnforcers, enforcersSet);\n\n let hasForbiddenEnforcers = false;\n\n for (const caveat of enforcersSet) {\n if (!allowedEnforcers.has(caveat) && !requiredEnforcers.has(caveat)) {\n hasForbiddenEnforcers = true;\n break;\n }\n }\n\n if (hasAllRequiredEnforcers && !hasForbiddenEnforcers) {\n if (matchingPermissionType) {\n throw new Error('Multiple permission types match');\n }\n matchingPermissionType = permissionType;\n }\n }\n\n if (!matchingPermissionType) {\n throw new Error('Unable to identify permission type');\n }\n\n return matchingPermissionType;\n};\n\n/**\n * Extracts the permission-specific data payload and the expiry timestamp from\n * the provided caveats for a given permission type.\n *\n * This function locates the relevant caveat enforcer for the `permissionType`,\n * interprets its `terms` by splitting the hex string into byte-sized segments,\n * and converts each segment into the appropriate numeric or address shape.\n *\n * The expiry timestamp is derived from the `TimestampEnforcer` terms and must\n * have a zero `timestampAfterThreshold` and a positive `timestampBeforeThreshold`.\n *\n * @param args - The arguments to this function.\n * @param args.contracts - The deployed contracts for the chain.\n * @param args.caveats - Caveats decoded from the permission context.\n * @param args.permissionType - The previously identified permission type.\n *\n * @returns An object containing the `expiry` timestamp and the decoded `data` payload.\n * @throws If the caveats are malformed, missing, or the terms fail to decode.\n */\nexport const getPermissionDataAndExpiry = ({\n contracts,\n caveats,\n permissionType,\n}: {\n contracts: DeployedContractsByName;\n caveats: Caveat<Hex>[];\n permissionType: PermissionType;\n}): {\n expiry: number | null;\n data: DecodedPermission['permission']['data'];\n} => {\n const checksumCaveats = caveats.map((caveat) => ({\n ...caveat,\n enforcer: getChecksumAddress(caveat.enforcer),\n }));\n\n const {\n erc20StreamingEnforcer,\n erc20PeriodicEnforcer,\n nativeTokenStreamingEnforcer,\n nativeTokenPeriodicEnforcer,\n timestampEnforcer,\n } = getChecksumEnforcersByChainId(contracts);\n\n const expiryTerms = getTermsByEnforcer({\n caveats: checksumCaveats,\n enforcer: timestampEnforcer,\n throwIfNotFound: false,\n });\n\n let expiry: number | null = null;\n if (expiryTerms) {\n const [after, before] = splitHex(expiryTerms, [16, 16]);\n\n if (hexToNumber(after) !== 0) {\n throw new Error('Invalid expiry');\n }\n expiry = hexToNumber(before);\n }\n\n let data: DecodedPermission['permission']['data'];\n\n switch (permissionType) {\n case 'erc20-token-stream': {\n const erc20StreamingTerms = getTermsByEnforcer({\n caveats: checksumCaveats,\n enforcer: erc20StreamingEnforcer,\n });\n\n const [\n tokenAddress,\n initialAmount,\n maxAmount,\n amountPerSecond,\n startTimeRaw,\n ] = splitHex(erc20StreamingTerms, [20, 32, 32, 32, 32]);\n\n data = {\n tokenAddress,\n initialAmount,\n maxAmount,\n amountPerSecond,\n startTime: hexToNumber(startTimeRaw),\n };\n break;\n }\n case 'erc20-token-periodic': {\n const erc20PeriodicTerms = getTermsByEnforcer({\n caveats: checksumCaveats,\n enforcer: erc20PeriodicEnforcer,\n });\n\n const [tokenAddress, periodAmount, periodDurationRaw, startTimeRaw] =\n splitHex(erc20PeriodicTerms, [20, 32, 32, 32]);\n\n data = {\n tokenAddress,\n periodAmount,\n periodDuration: hexToNumber(periodDurationRaw),\n startTime: hexToNumber(startTimeRaw),\n };\n break;\n }\n\n case 'native-token-stream': {\n const nativeTokenStreamingTerms = getTermsByEnforcer({\n caveats: checksumCaveats,\n enforcer: nativeTokenStreamingEnforcer,\n });\n\n const [initialAmount, maxAmount, amountPerSecond, startTimeRaw] =\n splitHex(nativeTokenStreamingTerms, [32, 32, 32, 32]);\n\n data = {\n initialAmount,\n maxAmount,\n amountPerSecond,\n startTime: hexToNumber(startTimeRaw),\n };\n break;\n }\n case 'native-token-periodic': {\n const nativeTokenPeriodicTerms = getTermsByEnforcer({\n caveats: checksumCaveats,\n enforcer: nativeTokenPeriodicEnforcer,\n });\n\n const [periodAmount, periodDurationRaw, startTimeRaw] = splitHex(\n nativeTokenPeriodicTerms,\n [32, 32, 32],\n );\n\n data = {\n periodAmount,\n periodDuration: hexToNumber(periodDurationRaw),\n startTime: hexToNumber(startTimeRaw),\n };\n break;\n }\n default:\n throw new Error('Invalid permission type');\n }\n\n return { expiry, data };\n};\n\n/**\n * Reconstructs a {@link DecodedPermission} object from primitive values\n * obtained while decoding a permission context.\n *\n * The resulting object contains:\n * - `chainId` encoded as hex (`0x…`)\n * - `address` set to the delegator (user account)\n * - `signer` set to an account signer with the delegate address\n * - `permission` with the identified type and decoded data\n * - `expiry` timestamp (or null)\n *\n * @param args - The arguments to this function.\n * @param args.chainId - Chain ID.\n * @param args.permissionType - Identified permission type.\n * @param args.delegator - Address of the account delegating permission.\n * @param args.delegate - Address that will act under the granted permission.\n * @param args.authority - Authority identifier; must be ROOT_AUTHORITY.\n * @param args.expiry - Expiry timestamp (unix seconds) or null if unbounded.\n * @param args.data - Permission-specific decoded data payload.\n * @param args.justification - Human-readable justification for the permission.\n * @param args.specifiedOrigin - The origin reported in the request metadata.\n *\n * @returns The reconstructed {@link DecodedPermission}.\n */\nexport const reconstructDecodedPermission = ({\n chainId,\n permissionType,\n delegator,\n delegate,\n authority,\n expiry,\n data,\n justification,\n specifiedOrigin,\n}: {\n chainId: number;\n permissionType: PermissionType;\n delegator: Hex;\n delegate: Hex;\n authority: Hex;\n expiry: number | null;\n data: DecodedPermission['permission']['data'];\n justification: string;\n specifiedOrigin: string;\n}) => {\n if (authority !== ROOT_AUTHORITY) {\n throw new Error('Invalid authority');\n }\n\n const permission: DecodedPermission = {\n chainId: numberToHex(chainId),\n address: delegator,\n signer: { type: 'account', data: { address: delegate } },\n permission: {\n type: permissionType,\n data,\n justification,\n },\n expiry,\n origin: specifiedOrigin,\n };\n\n return permission;\n};\n"]}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { Caveat, Hex } from "@metamask/delegation-core";
|
|
2
|
+
import type { DecodedPermission, DeployedContractsByName, PermissionType } from "./types.cjs";
|
|
3
|
+
/**
|
|
4
|
+
* Identifies the unique permission type that matches a given set of enforcer
|
|
5
|
+
* contract addresses for a specific chain.
|
|
6
|
+
*
|
|
7
|
+
* A permission type matches when:
|
|
8
|
+
* - All of its required enforcers are present in the provided list; and
|
|
9
|
+
* - No provided enforcer falls outside the union of the type's required and
|
|
10
|
+
* allowed enforcers (currently only `TimestampEnforcer` is allowed extra).
|
|
11
|
+
*
|
|
12
|
+
* If exactly one permission type matches, its identifier is returned.
|
|
13
|
+
*
|
|
14
|
+
* @param args - The arguments to this function.
|
|
15
|
+
* @param args.enforcers - List of enforcer contract addresses (hex strings).
|
|
16
|
+
*
|
|
17
|
+
* @param args.contracts - The deployed contracts for the chain.
|
|
18
|
+
* @returns The identifier of the matching permission type.
|
|
19
|
+
* @throws If no permission type matches, or if more than one permission type matches.
|
|
20
|
+
*/
|
|
21
|
+
export declare const identifyPermissionByEnforcers: ({ enforcers, contracts, }: {
|
|
22
|
+
enforcers: Hex[];
|
|
23
|
+
contracts: DeployedContractsByName;
|
|
24
|
+
}) => PermissionType;
|
|
25
|
+
/**
|
|
26
|
+
* Extracts the permission-specific data payload and the expiry timestamp from
|
|
27
|
+
* the provided caveats for a given permission type.
|
|
28
|
+
*
|
|
29
|
+
* This function locates the relevant caveat enforcer for the `permissionType`,
|
|
30
|
+
* interprets its `terms` by splitting the hex string into byte-sized segments,
|
|
31
|
+
* and converts each segment into the appropriate numeric or address shape.
|
|
32
|
+
*
|
|
33
|
+
* The expiry timestamp is derived from the `TimestampEnforcer` terms and must
|
|
34
|
+
* have a zero `timestampAfterThreshold` and a positive `timestampBeforeThreshold`.
|
|
35
|
+
*
|
|
36
|
+
* @param args - The arguments to this function.
|
|
37
|
+
* @param args.contracts - The deployed contracts for the chain.
|
|
38
|
+
* @param args.caveats - Caveats decoded from the permission context.
|
|
39
|
+
* @param args.permissionType - The previously identified permission type.
|
|
40
|
+
*
|
|
41
|
+
* @returns An object containing the `expiry` timestamp and the decoded `data` payload.
|
|
42
|
+
* @throws If the caveats are malformed, missing, or the terms fail to decode.
|
|
43
|
+
*/
|
|
44
|
+
export declare const getPermissionDataAndExpiry: ({ contracts, caveats, permissionType, }: {
|
|
45
|
+
contracts: DeployedContractsByName;
|
|
46
|
+
caveats: Caveat<Hex>[];
|
|
47
|
+
permissionType: PermissionType;
|
|
48
|
+
}) => {
|
|
49
|
+
expiry: number | null;
|
|
50
|
+
data: DecodedPermission['permission']['data'];
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Reconstructs a {@link DecodedPermission} object from primitive values
|
|
54
|
+
* obtained while decoding a permission context.
|
|
55
|
+
*
|
|
56
|
+
* The resulting object contains:
|
|
57
|
+
* - `chainId` encoded as hex (`0x…`)
|
|
58
|
+
* - `address` set to the delegator (user account)
|
|
59
|
+
* - `signer` set to an account signer with the delegate address
|
|
60
|
+
* - `permission` with the identified type and decoded data
|
|
61
|
+
* - `expiry` timestamp (or null)
|
|
62
|
+
*
|
|
63
|
+
* @param args - The arguments to this function.
|
|
64
|
+
* @param args.chainId - Chain ID.
|
|
65
|
+
* @param args.permissionType - Identified permission type.
|
|
66
|
+
* @param args.delegator - Address of the account delegating permission.
|
|
67
|
+
* @param args.delegate - Address that will act under the granted permission.
|
|
68
|
+
* @param args.authority - Authority identifier; must be ROOT_AUTHORITY.
|
|
69
|
+
* @param args.expiry - Expiry timestamp (unix seconds) or null if unbounded.
|
|
70
|
+
* @param args.data - Permission-specific decoded data payload.
|
|
71
|
+
* @param args.justification - Human-readable justification for the permission.
|
|
72
|
+
* @param args.specifiedOrigin - The origin reported in the request metadata.
|
|
73
|
+
*
|
|
74
|
+
* @returns The reconstructed {@link DecodedPermission}.
|
|
75
|
+
*/
|
|
76
|
+
export declare const reconstructDecodedPermission: ({ chainId, permissionType, delegator, delegate, authority, expiry, data, justification, specifiedOrigin, }: {
|
|
77
|
+
chainId: number;
|
|
78
|
+
permissionType: PermissionType;
|
|
79
|
+
delegator: Hex;
|
|
80
|
+
delegate: Hex;
|
|
81
|
+
authority: Hex;
|
|
82
|
+
expiry: number | null;
|
|
83
|
+
data: DecodedPermission['permission']['data'];
|
|
84
|
+
justification: string;
|
|
85
|
+
specifiedOrigin: string;
|
|
86
|
+
}) => DecodedPermission;
|
|
87
|
+
//# sourceMappingURL=decodePermission.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decodePermission.d.cts","sourceRoot":"","sources":["../../src/decodePermission/decodePermission.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,kCAAkC;AAI7D,OAAO,KAAK,EACV,iBAAiB,EACjB,uBAAuB,EACvB,cAAc,EACf,oBAAgB;AASjB;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,6BAA6B;eAI7B,GAAG,EAAE;eACL,uBAAuB;MAChC,cAoCH,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,0BAA0B;eAK1B,uBAAuB;aACzB,OAAO,GAAG,CAAC,EAAE;oBACN,cAAc;;YAEtB,MAAM,GAAG,IAAI;UACf,iBAAiB,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC;CAmH9C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,4BAA4B;aAW9B,MAAM;oBACC,cAAc;eACnB,GAAG;cACJ,GAAG;eACF,GAAG;YACN,MAAM,GAAG,IAAI;UACf,iBAAiB,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC;mBAC9B,MAAM;qBACJ,MAAM;uBAoBxB,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { Caveat, Hex } from "@metamask/delegation-core";
|
|
2
|
+
import type { DecodedPermission, DeployedContractsByName, PermissionType } from "./types.mjs";
|
|
3
|
+
/**
|
|
4
|
+
* Identifies the unique permission type that matches a given set of enforcer
|
|
5
|
+
* contract addresses for a specific chain.
|
|
6
|
+
*
|
|
7
|
+
* A permission type matches when:
|
|
8
|
+
* - All of its required enforcers are present in the provided list; and
|
|
9
|
+
* - No provided enforcer falls outside the union of the type's required and
|
|
10
|
+
* allowed enforcers (currently only `TimestampEnforcer` is allowed extra).
|
|
11
|
+
*
|
|
12
|
+
* If exactly one permission type matches, its identifier is returned.
|
|
13
|
+
*
|
|
14
|
+
* @param args - The arguments to this function.
|
|
15
|
+
* @param args.enforcers - List of enforcer contract addresses (hex strings).
|
|
16
|
+
*
|
|
17
|
+
* @param args.contracts - The deployed contracts for the chain.
|
|
18
|
+
* @returns The identifier of the matching permission type.
|
|
19
|
+
* @throws If no permission type matches, or if more than one permission type matches.
|
|
20
|
+
*/
|
|
21
|
+
export declare const identifyPermissionByEnforcers: ({ enforcers, contracts, }: {
|
|
22
|
+
enforcers: Hex[];
|
|
23
|
+
contracts: DeployedContractsByName;
|
|
24
|
+
}) => PermissionType;
|
|
25
|
+
/**
|
|
26
|
+
* Extracts the permission-specific data payload and the expiry timestamp from
|
|
27
|
+
* the provided caveats for a given permission type.
|
|
28
|
+
*
|
|
29
|
+
* This function locates the relevant caveat enforcer for the `permissionType`,
|
|
30
|
+
* interprets its `terms` by splitting the hex string into byte-sized segments,
|
|
31
|
+
* and converts each segment into the appropriate numeric or address shape.
|
|
32
|
+
*
|
|
33
|
+
* The expiry timestamp is derived from the `TimestampEnforcer` terms and must
|
|
34
|
+
* have a zero `timestampAfterThreshold` and a positive `timestampBeforeThreshold`.
|
|
35
|
+
*
|
|
36
|
+
* @param args - The arguments to this function.
|
|
37
|
+
* @param args.contracts - The deployed contracts for the chain.
|
|
38
|
+
* @param args.caveats - Caveats decoded from the permission context.
|
|
39
|
+
* @param args.permissionType - The previously identified permission type.
|
|
40
|
+
*
|
|
41
|
+
* @returns An object containing the `expiry` timestamp and the decoded `data` payload.
|
|
42
|
+
* @throws If the caveats are malformed, missing, or the terms fail to decode.
|
|
43
|
+
*/
|
|
44
|
+
export declare const getPermissionDataAndExpiry: ({ contracts, caveats, permissionType, }: {
|
|
45
|
+
contracts: DeployedContractsByName;
|
|
46
|
+
caveats: Caveat<Hex>[];
|
|
47
|
+
permissionType: PermissionType;
|
|
48
|
+
}) => {
|
|
49
|
+
expiry: number | null;
|
|
50
|
+
data: DecodedPermission['permission']['data'];
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Reconstructs a {@link DecodedPermission} object from primitive values
|
|
54
|
+
* obtained while decoding a permission context.
|
|
55
|
+
*
|
|
56
|
+
* The resulting object contains:
|
|
57
|
+
* - `chainId` encoded as hex (`0x…`)
|
|
58
|
+
* - `address` set to the delegator (user account)
|
|
59
|
+
* - `signer` set to an account signer with the delegate address
|
|
60
|
+
* - `permission` with the identified type and decoded data
|
|
61
|
+
* - `expiry` timestamp (or null)
|
|
62
|
+
*
|
|
63
|
+
* @param args - The arguments to this function.
|
|
64
|
+
* @param args.chainId - Chain ID.
|
|
65
|
+
* @param args.permissionType - Identified permission type.
|
|
66
|
+
* @param args.delegator - Address of the account delegating permission.
|
|
67
|
+
* @param args.delegate - Address that will act under the granted permission.
|
|
68
|
+
* @param args.authority - Authority identifier; must be ROOT_AUTHORITY.
|
|
69
|
+
* @param args.expiry - Expiry timestamp (unix seconds) or null if unbounded.
|
|
70
|
+
* @param args.data - Permission-specific decoded data payload.
|
|
71
|
+
* @param args.justification - Human-readable justification for the permission.
|
|
72
|
+
* @param args.specifiedOrigin - The origin reported in the request metadata.
|
|
73
|
+
*
|
|
74
|
+
* @returns The reconstructed {@link DecodedPermission}.
|
|
75
|
+
*/
|
|
76
|
+
export declare const reconstructDecodedPermission: ({ chainId, permissionType, delegator, delegate, authority, expiry, data, justification, specifiedOrigin, }: {
|
|
77
|
+
chainId: number;
|
|
78
|
+
permissionType: PermissionType;
|
|
79
|
+
delegator: Hex;
|
|
80
|
+
delegate: Hex;
|
|
81
|
+
authority: Hex;
|
|
82
|
+
expiry: number | null;
|
|
83
|
+
data: DecodedPermission['permission']['data'];
|
|
84
|
+
justification: string;
|
|
85
|
+
specifiedOrigin: string;
|
|
86
|
+
}) => DecodedPermission;
|
|
87
|
+
//# sourceMappingURL=decodePermission.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decodePermission.d.mts","sourceRoot":"","sources":["../../src/decodePermission/decodePermission.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,kCAAkC;AAI7D,OAAO,KAAK,EACV,iBAAiB,EACjB,uBAAuB,EACvB,cAAc,EACf,oBAAgB;AASjB;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,6BAA6B;eAI7B,GAAG,EAAE;eACL,uBAAuB;MAChC,cAoCH,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,0BAA0B;eAK1B,uBAAuB;aACzB,OAAO,GAAG,CAAC,EAAE;oBACN,cAAc;;YAEtB,MAAM,GAAG,IAAI;UACf,iBAAiB,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC;CAmH9C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,4BAA4B;aAW9B,MAAM;oBACC,cAAc;eACnB,GAAG;cACJ,GAAG;eACF,GAAG;YACN,MAAM,GAAG,IAAI;UACf,iBAAiB,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC;mBAC9B,MAAM;qBACJ,MAAM;uBAoBxB,CAAC"}
|