{"version":3,"file":"GatorPermissionsController.mjs","sourceRoot":"","sources":["../src/GatorPermissionsController.ts"],"names":[],"mappings":"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","sourcesContent":["import 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 PermissionTypes,\n  type SignerParam,\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<StoredGatorPermission<SignerParam, PermissionTypes>[] | null> {\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<SignerParam, PermissionTypes>[] | 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<SignerParam, PermissionTypes>,\n  ): StoredGatorPermissionSanitized<SignerParam, PermissionTypes> {\n    const { permissionResponse } = storedGatorPermission;\n    const { isAdjustmentAllowed, accountMeta, signer, ...rest } =\n      permissionResponse;\n    return {\n      ...storedGatorPermission,\n      permissionResponse: { ...rest },\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<SignerParam, PermissionTypes>[]\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                SignerParam,\n                PermissionTypes\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                SignerParam,\n                PermissionTypes\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"]}