{"version":3,"file":"SubscriptionController.cjs","sourceRoot":"","sources":["../src/SubscriptionController.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,+DAMmC;AAGnC,+CAGqB;AAgErB;;;;GAIG;AACH,SAAgB,qCAAqC;IACnD,OAAO;QACL,aAAa,EAAE,EAAE;KAClB,CAAC;AACJ,CAAC;AAJD,sFAIC;AAED;;;;;;GAMG;AACH,MAAM,8BAA8B,GAClC;IACE,aAAa,EAAE;QACb,OAAO,EAAE,IAAI;QACb,SAAS,EAAE,KAAK;KACjB;CACF,CAAC;AAEJ,MAAa,sBAAuB,SAAQ,gCAI3C;IAGC;;;;;;;OAOG;IACH,YAAY,EACV,SAAS,EACT,KAAK,EACL,mBAAmB,GACW;QAC9B,KAAK,CAAC;YACJ,IAAI,EAAE,0BAAc;YACpB,QAAQ,EAAE,8BAA8B;YACxC,KAAK,EAAE;gBACL,GAAG,qCAAqC,EAAE;gBAC1C,GAAG,KAAK;aACT;YACD,SAAS;SACV,CAAC,CAAC;;QAvBI,8DAA2C;QAyBlD,uBAAA,IAAI,+CAAwB,mBAAmB,MAAA,CAAC;QAEhD,uBAAA,IAAI,0FAAyB,MAA7B,IAAI,CAA2B,CAAC;IAClC,CAAC;IAkBD,KAAK,CAAC,gBAAgB;QACpB,MAAM,EAAE,aAAa,EAAE,GACrB,MAAM,uBAAA,IAAI,mDAAqB,CAAC,gBAAgB,EAAE,CAAC;QAErD,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,aAAa,GAAG,aAAa,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,OAAmC;QAC1D,uBAAA,IAAI,yFAAwB,MAA5B,IAAI,EAAyB,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;QAEzE,MAAM,uBAAA,IAAI,mDAAqB,CAAC,kBAAkB,CAAC;YACjD,cAAc,EAAE,OAAO,CAAC,cAAc;SACvC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAC7D,YAAY,CAAC,EAAE,KAAK,OAAO,CAAC,cAAc;gBACxC,CAAC,CAAC,EAAE,GAAG,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE;gBAC1C,CAAC,CAAC,YAAY,CACjB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;CAWF;AAvFD,wDAuFC;;IA/CG,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,yCAAyC,EACzC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CACjC,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,2CAA2C,EAC3C,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CACnC,CAAC;AACJ,CAAC,2GA6BuB,OAAmC;IACzD,IACE,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAC5B,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,EAAE,KAAK,OAAO,CAAC,cAAc,CAC7D,EACD;QACA,MAAM,IAAI,KAAK,CAAC,8CAAkC,CAAC,iBAAiB,CAAC,CAAC;KACvE;AACH,CAAC","sourcesContent":["import {\n  BaseController,\n  type StateMetadata,\n  type ControllerStateChangeEvent,\n  type ControllerGetStateAction,\n  type RestrictedMessenger,\n} from '@metamask/base-controller';\nimport type { AuthenticationController } from '@metamask/profile-sync-controller';\n\nimport {\n  controllerName,\n  SubscriptionControllerErrorMessage,\n} from './constants';\nimport type { ISubscriptionService, Subscription } from './types';\n\nexport type SubscriptionControllerState = {\n  subscriptions: Subscription[];\n};\n\n// Messenger Actions\ntype CreateActionsObj<Controller extends keyof SubscriptionController> = {\n  [K in Controller]: {\n    type: `${typeof controllerName}:${K}`;\n    handler: SubscriptionController[K];\n  };\n};\ntype ActionsObj = CreateActionsObj<'getSubscriptions' | 'cancelSubscription'>;\n\nexport type SubscriptionControllerGetStateAction = ControllerGetStateAction<\n  typeof controllerName,\n  SubscriptionControllerState\n>;\nexport type SubscriptionControllerActions =\n  | ActionsObj[keyof ActionsObj]\n  | SubscriptionControllerGetStateAction;\n\nexport type AllowedActions =\n  AuthenticationController.AuthenticationControllerGetBearerToken;\n\n// Events\nexport type SubscriptionControllerStateChangeEvent = ControllerStateChangeEvent<\n  typeof controllerName,\n  SubscriptionControllerState\n>;\nexport type SubscriptionControllerEvents =\n  SubscriptionControllerStateChangeEvent;\n\nexport type AllowedEvents =\n  AuthenticationController.AuthenticationControllerStateChangeEvent;\n\n// Messenger\nexport type SubscriptionControllerMessenger = RestrictedMessenger<\n  typeof controllerName,\n  SubscriptionControllerActions | AllowedActions,\n  SubscriptionControllerEvents | AllowedEvents,\n  AllowedActions['type'],\n  AllowedEvents['type']\n>;\n\n/**\n * Subscription Controller Options.\n */\nexport type SubscriptionControllerOptions = {\n  messenger: SubscriptionControllerMessenger;\n\n  /**\n   * Initial state to set on this controller.\n   */\n  state?: Partial<SubscriptionControllerState>;\n\n  /**\n   * Subscription service to use for the subscription controller.\n   */\n  subscriptionService: ISubscriptionService;\n};\n\n/**\n * Get the default state for the Subscription Controller.\n *\n * @returns The default state for the Subscription Controller.\n */\nexport function getDefaultSubscriptionControllerState(): SubscriptionControllerState {\n  return {\n    subscriptions: [],\n  };\n}\n\n/**\n * Seedless Onboarding Controller State Metadata.\n *\n * This allows us to choose if fields of the state should be persisted or not\n * using the `persist` flag; and if they can be sent to Sentry or not, using\n * the `anonymous` flag.\n */\nconst subscriptionControllerMetadata: StateMetadata<SubscriptionControllerState> =\n  {\n    subscriptions: {\n      persist: true,\n      anonymous: false,\n    },\n  };\n\nexport class SubscriptionController extends BaseController<\n  typeof controllerName,\n  SubscriptionControllerState,\n  SubscriptionControllerMessenger\n> {\n  readonly #subscriptionService: ISubscriptionService;\n\n  /**\n   * Creates a new SubscriptionController instance.\n   *\n   * @param options - The options for the SubscriptionController.\n   * @param options.messenger - A restricted messenger.\n   * @param options.state - Initial state to set on this controller.\n   * @param options.subscriptionService - The subscription service for communicating with subscription server.\n   */\n  constructor({\n    messenger,\n    state,\n    subscriptionService,\n  }: SubscriptionControllerOptions) {\n    super({\n      name: controllerName,\n      metadata: subscriptionControllerMetadata,\n      state: {\n        ...getDefaultSubscriptionControllerState(),\n        ...state,\n      },\n      messenger,\n    });\n\n    this.#subscriptionService = subscriptionService;\n\n    this.#registerMessageHandlers();\n  }\n\n  /**\n   * Constructor helper for registering this controller's messaging system\n   * actions.\n   */\n  #registerMessageHandlers(): void {\n    this.messagingSystem.registerActionHandler(\n      'SubscriptionController:getSubscriptions',\n      this.getSubscriptions.bind(this),\n    );\n\n    this.messagingSystem.registerActionHandler(\n      'SubscriptionController:cancelSubscription',\n      this.cancelSubscription.bind(this),\n    );\n  }\n\n  async getSubscriptions() {\n    const { subscriptions } =\n      await this.#subscriptionService.getSubscriptions();\n\n    this.update((state) => {\n      state.subscriptions = subscriptions;\n    });\n\n    return subscriptions;\n  }\n\n  async cancelSubscription(request: { subscriptionId: string }) {\n    this.#assertIsUserSubscribed({ subscriptionId: request.subscriptionId });\n\n    await this.#subscriptionService.cancelSubscription({\n      subscriptionId: request.subscriptionId,\n    });\n\n    this.update((state) => {\n      state.subscriptions = state.subscriptions.map((subscription) =>\n        subscription.id === request.subscriptionId\n          ? { ...subscription, status: 'cancelled' }\n          : subscription,\n      );\n    });\n  }\n\n  #assertIsUserSubscribed(request: { subscriptionId: string }) {\n    if (\n      !this.state.subscriptions.find(\n        (subscription) => subscription.id === request.subscriptionId,\n      )\n    ) {\n      throw new Error(SubscriptionControllerErrorMessage.UserNotSubscribed);\n    }\n  }\n}\n"]}