@metamask-previews/subscription-controller 9.0.1-preview-e8a256c39 → 9.0.1-preview-6228714d1

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.
Files changed (43) hide show
  1. package/CHANGELOG.md +2 -11
  2. package/dist/SubscriptionController.d.ts.map +1 -1
  3. package/dist/SubscriptionController.js +9 -1
  4. package/dist/SubscriptionController.js.map +1 -1
  5. package/dist/SubscriptionService.d.ts.map +1 -1
  6. package/dist/SubscriptionService.js +7 -1
  7. package/dist/SubscriptionService.js.map +1 -1
  8. package/dist/constants.d.ts +11 -16
  9. package/dist/constants.d.ts.map +1 -1
  10. package/dist/constants.js +17 -17
  11. package/dist/constants.js.map +1 -1
  12. package/dist/index.d.ts +3 -8
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +2 -3
  15. package/dist/index.js.map +1 -1
  16. package/dist/types.d.ts +6 -0
  17. package/dist/types.d.ts.map +1 -1
  18. package/dist/types.js.map +1 -1
  19. package/package.json +1 -10
  20. package/dist/subscription-delegation/SubscriptionDelegationService-method-action-types.d.ts +0 -44
  21. package/dist/subscription-delegation/SubscriptionDelegationService-method-action-types.d.ts.map +0 -1
  22. package/dist/subscription-delegation/SubscriptionDelegationService-method-action-types.js +0 -6
  23. package/dist/subscription-delegation/SubscriptionDelegationService-method-action-types.js.map +0 -1
  24. package/dist/subscription-delegation/SubscriptionDelegationService.d.ts +0 -93
  25. package/dist/subscription-delegation/SubscriptionDelegationService.d.ts.map +0 -1
  26. package/dist/subscription-delegation/SubscriptionDelegationService.js +0 -290
  27. package/dist/subscription-delegation/SubscriptionDelegationService.js.map +0 -1
  28. package/dist/subscription-delegation/amount.d.ts +0 -49
  29. package/dist/subscription-delegation/amount.d.ts.map +0 -1
  30. package/dist/subscription-delegation/amount.js +0 -84
  31. package/dist/subscription-delegation/amount.js.map +0 -1
  32. package/dist/subscription-delegation/caveats.d.ts +0 -41
  33. package/dist/subscription-delegation/caveats.d.ts.map +0 -1
  34. package/dist/subscription-delegation/caveats.js +0 -59
  35. package/dist/subscription-delegation/caveats.js.map +0 -1
  36. package/dist/subscription-delegation/fingerprint.d.ts +0 -42
  37. package/dist/subscription-delegation/fingerprint.d.ts.map +0 -1
  38. package/dist/subscription-delegation/fingerprint.js +0 -80
  39. package/dist/subscription-delegation/fingerprint.js.map +0 -1
  40. package/dist/subscription-delegation/types.d.ts +0 -73
  41. package/dist/subscription-delegation/types.d.ts.map +0 -1
  42. package/dist/subscription-delegation/types.js +0 -10
  43. package/dist/subscription-delegation/types.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -9,20 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ### Added
11
11
 
12
- - Add `SubscriptionDelegationService` for Money Account Plus cash-subscription delegation setup. ([#10130](https://github.com/MetaMask/core/pull/10130))
13
- - New messenger action `SubscriptionDelegationService:prepareDelegation` orchestrates periodic caveat construction, signing, CHOMP verification, Authenticated User Storage persistence, and CHOMP intent registration.
14
- - Returns a verified `delegationHash` with `disposition: 'created' | 'reused'` for `SubscriptionController.startSubscriptionWithCrypto`; the controller does not depend on this service.
15
- - `prepareDelegation` accepts the product, recurring interval, payer address, trial selection, optional balance-check flag, and optional `skipChompInteractions` flag; it resolves plan, token, and delegate data through `SubscriptionController:getPricing`.
16
- - When `skipChompInteractions` is true, CHOMP verify and intent registration are skipped; the returned hash is computed locally and AUS persistence still occurs.
17
- - Resolves the chain from `moneyAccountVaultConfig` and Delegation Framework v1.3.0 enforcers from `@metamask/delegation-deployments`.
18
- - Uses pricing `delegateAddress` as both the delegation `delegate` and the RedeemerEnforcer redeemer.
19
- - Offsets the period-transfer `startDate` by pricing `trialPeriodDays` only when the trial is selected.
20
- - New messenger action `SubscriptionDelegationService:checkMoneyAccountBalance` compares Money Account convertible mUSD balance against pricing `unitAmount × minBillingCyclesForBalance`; `prepareDelegation` can gate on it via `checkBalance`.
21
- - Exports `CASH_SUBSCRIPTION_DELEGATION_TYPE` (`'cash-subscription'`) for AUS metadata (and for CHOMP intent metadata once chomp-api-service supports that type).
22
- - Only Money Account Plus is supported; Shield continues to use ERC-20 approval.
12
+ - Add stable cancellation reason codes and optional free-text feedback to the subscription cancellation request ([#10189](https://github.com/MetaMask/core/pull/10189))
23
13
 
24
14
  ### Changed
25
15
 
16
+ - Refresh subscriptions, product entitlements, and benefits after a successful subscription cancellation ([#10189](https://github.com/MetaMask/core/pull/10189))
26
17
  - Bump `@metamask/profile-sync-controller` from `^32.0.0` to `^32.1.0` ([#10184](https://github.com/MetaMask/core/pull/10184))
27
18
 
28
19
  ## [9.0.1]
@@ -1 +1 @@
1
- {"version":3,"file":"SubscriptionController.d.ts","sourceRoot":"","sources":["../src/SubscriptionController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SubscriptionController.d.ts","sourceRoot":"","sources":["../src/SubscriptionController.ts"],"names":[],"mappings":"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"}
@@ -258,7 +258,15 @@ export class SubscriptionController extends StaticIntervalPollingController() {
258
258
  ? { ...subscription, ...cancelledSubscription }
259
259
  : subscription);
260
260
  });
261
- await this.#refreshBenefitsIfActive();
261
+ try {
262
+ await this.#getSubscriptions();
263
+ }
264
+ catch (error) {
265
+ log('Failed to refresh subscriptions after cancellation', error);
266
+ // Preserve the existing best-effort benefits refresh behavior if the
267
+ // canonical subscription refresh is unavailable.
268
+ await this.#refreshBenefitsIfActive();
269
+ }
262
270
  this.triggerAccessTokenRefresh();
263
271
  }
264
272
  async unCancelSubscription(request) {
@@ -1 +1 @@
1
- {"version":3,"file":"SubscriptionController.js","sourceRoot":"","sources":["../src/SubscriptionController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n StateMetadata,\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { AuthenticationController } from '@metamask/profile-sync-controller';\nimport { TransactionType } from '@metamask/transaction-controller';\nimport type { CaipAccountId, Hex } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\nimport deepEqual from 'fast-deep-equal';\n\nimport {\n ACTIVE_SUBSCRIPTION_STATUSES,\n controllerName,\n DEFAULT_POLLING_INTERVAL,\n SubscriptionControllerErrorMessage,\n} from './constants.js';\nimport { createModuleLogger, projectLogger } from './logger.js';\nimport type { SubscriptionControllerMethodActions } from './SubscriptionController-method-action-types.js';\nimport type {\n SubscriptionServiceAssignUserToCohortAction,\n SubscriptionServiceCancelSubscriptionAction,\n SubscriptionServiceGetBillingPortalUrlAction,\n SubscriptionServiceGetBenefitsAction,\n SubscriptionServiceGetPricingAction,\n SubscriptionServiceGetSubscriptionsAction,\n SubscriptionServiceGetSubscriptionsEligibilitiesAction,\n SubscriptionServiceLinkRewardsAction,\n SubscriptionServiceStartSubscriptionWithCardAction,\n SubscriptionServiceStartSubscriptionWithCryptoAction,\n SubscriptionServiceSubmitSponsorshipIntentsAction,\n SubscriptionServiceSubmitUserEventAction,\n SubscriptionServiceUnCancelSubscriptionAction,\n SubscriptionServiceUpdatePaymentMethodCardAction,\n SubscriptionServiceUpdatePaymentMethodCryptoAction,\n} from './SubscriptionService-method-action-types.js';\nimport {\n CRYPTO_AUTH_METHODS,\n PAYMENT_TYPES,\n PRODUCT_TYPES,\n SUBSCRIPTION_STATUSES,\n} from './types.js';\nimport type {\n AssignCohortRequest,\n BillingPortalResponse,\n CryptoAuthMethod,\n GetCryptoApproveTransactionRequest,\n GetCryptoApproveTransactionResponse,\n GetSubscriptionsEligibilitiesRequest,\n GetSubscriptionsResponse,\n ProductPrice,\n SubscriptionEligibility,\n StartCryptoSubscriptionRequest,\n SubmitSubscriptionCryptoApprovalRequest,\n SubmitUserEventRequest,\n TokenPaymentInfo,\n UpdatePaymentMethodCardResponse,\n UpdatePaymentMethodOpts,\n CachedLastSelectedPaymentMethod,\n CacheLastSelectedPaymentMethodRequest,\n SubmitSponsorshipIntentsMethodParams,\n RecurringInterval,\n SubscriptionStatus,\n LinkRewardsRequest,\n StartCryptoSubscriptionResponse,\n StartSubscriptionResponse,\n CancelSubscriptionRequest,\n PricingCryptoPaymentMethod,\n SubscriptionBenefitsResponse,\n SubscriptionBenefitsState,\n} from './types.js';\nimport type {\n PricingResponse,\n ProductType,\n ProductEntitlements,\n StartSubscriptionRequest,\n Subscription,\n} from './types.js';\n\nconst log = createModuleLogger(projectLogger, controllerName);\n\nexport type SubscriptionControllerState = {\n customerId?: string;\n trialedProducts: ProductType[];\n subscriptions: Subscription[];\n productEntitlements?: ProductEntitlements;\n pricing?: PricingResponse;\n benefits?: SubscriptionBenefitsState;\n /** The last subscription that user has subscribed to if any. */\n lastSubscription?: Subscription;\n /** The reward account ID if user has linked rewards to the subscription. */\n rewardAccountId?: CaipAccountId;\n /**\n * The last selected payment method for the user.\n * This is used to display the last selected payment method in the UI.\n * This state is also meant to be used internally to track the last selected payment method for the user. (e.g. for crypto subscriptions)\n */\n lastSelectedPaymentMethod?: Partial<\n Record<ProductType, CachedLastSelectedPaymentMethod>\n >;\n};\n\nexport type SubscriptionControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n SubscriptionControllerState\n>;\nexport type SubscriptionControllerActions =\n | SubscriptionControllerGetStateAction\n | SubscriptionControllerMethodActions;\n\ntype AllowedActions =\n | SubscriptionServiceGetPricingAction\n | SubscriptionServiceGetSubscriptionsAction\n | SubscriptionServiceGetBenefitsAction\n | SubscriptionServiceGetSubscriptionsEligibilitiesAction\n | SubscriptionServiceCancelSubscriptionAction\n | SubscriptionServiceUnCancelSubscriptionAction\n | SubscriptionServiceStartSubscriptionWithCardAction\n | SubscriptionServiceStartSubscriptionWithCryptoAction\n | SubscriptionServiceUpdatePaymentMethodCardAction\n | SubscriptionServiceUpdatePaymentMethodCryptoAction\n | SubscriptionServiceGetBillingPortalUrlAction\n | SubscriptionServiceSubmitSponsorshipIntentsAction\n | SubscriptionServiceSubmitUserEventAction\n | SubscriptionServiceAssignUserToCohortAction\n | SubscriptionServiceLinkRewardsAction\n | AuthenticationController.AuthenticationControllerPerformSignOutAction;\n\n// Events\nexport type SubscriptionControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n SubscriptionControllerState\n>;\nexport type SubscriptionControllerEvents =\n SubscriptionControllerStateChangeEvent;\n\ntype AllowedEvents = never;\n\n// Messenger\nexport type SubscriptionControllerMessenger = Messenger<\n typeof controllerName,\n SubscriptionControllerActions | AllowedActions,\n SubscriptionControllerEvents | AllowedEvents\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 * Polling interval to use for the subscription controller.\n *\n * @default 5 minutes.\n */\n pollingInterval?: number;\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 trialedProducts: [],\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 includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n productEntitlements: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n lastSubscription: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n customerId: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n rewardAccountId: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n trialedProducts: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n pricing: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n benefits: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n lastSelectedPaymentMethod: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n };\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'getPricing',\n 'getSubscriptions',\n 'getBenefits',\n 'getSubscriptionByProduct',\n 'getSubscriptionsEligibilities',\n 'cancelSubscription',\n 'unCancelSubscription',\n 'startSubscriptionWithCard',\n 'startSubscriptionWithCrypto',\n 'stopAllPolling',\n 'submitSubscriptionCryptoApproval',\n 'getCryptoApproveTransactionParams',\n 'updatePaymentMethod',\n 'getBillingPortalUrl',\n 'cacheLastSelectedPaymentMethod',\n 'clearLastSelectedPaymentMethod',\n 'submitSponsorshipIntents',\n 'submitUserEvent',\n 'assignUserToCohort',\n 'linkRewards',\n 'getTokenApproveAmount',\n 'getTokenMinimumBalanceAmount',\n 'clearState',\n 'triggerAccessTokenRefresh',\n] as const;\n\nexport class SubscriptionController extends StaticIntervalPollingController()<\n typeof controllerName,\n SubscriptionControllerState,\n SubscriptionControllerMessenger\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.pollingInterval - The polling interval to use for the subscription controller.\n */\n constructor(options: SubscriptionControllerOptions) {\n const {\n messenger,\n state,\n pollingInterval = DEFAULT_POLLING_INTERVAL,\n } = options;\n super({\n name: controllerName,\n metadata: subscriptionControllerMetadata,\n state: {\n ...getDefaultSubscriptionControllerState(),\n ...state,\n },\n messenger,\n });\n\n this.setIntervalLength(pollingInterval);\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Gets the pricing information from the subscription service.\n *\n * @returns The pricing information.\n */\n async getPricing(): Promise<PricingResponse> {\n const pricing = await this.messenger.call('SubscriptionService:getPricing');\n this.update((state) => {\n state.pricing = pricing;\n });\n return pricing;\n }\n\n async getSubscriptions(): Promise<Subscription[]> {\n return await this.#getSubscriptions();\n }\n\n async #getSubscriptions({\n refreshBenefits = true,\n }: { refreshBenefits?: boolean } = {}): Promise<Subscription[]> {\n const currentSubscriptions = this.state.subscriptions;\n const currentTrialedProducts = this.state.trialedProducts;\n const currentCustomerId = this.state.customerId;\n const currentLastSubscription = this.state.lastSubscription;\n const currentRewardAccountId = this.state.rewardAccountId;\n const currentProductEntitlements = this.state.productEntitlements;\n const currentSubscriptionState: GetSubscriptionsResponse = {\n customerId: currentCustomerId,\n subscriptions: currentSubscriptions,\n trialedProducts: currentTrialedProducts,\n lastSubscription: currentLastSubscription,\n rewardAccountId: currentRewardAccountId,\n productEntitlements: currentProductEntitlements,\n };\n\n const newSubscriptionState = await this.messenger.call(\n 'SubscriptionService:getSubscriptions',\n );\n\n this.#updateSubscriptionStateIfChanged(\n currentSubscriptionState,\n newSubscriptionState,\n );\n\n await this.#refreshBenefitsIfActive(refreshBenefits);\n\n return newSubscriptionState.subscriptions;\n }\n\n /**\n * Updates the subscription state and refreshes the access token when the\n * fetched subscription state differs from the current state.\n *\n * @param currentState - The subscription state captured before the request.\n * @param newState - The subscription state returned by the service.\n */\n #updateSubscriptionStateIfChanged(\n currentState: GetSubscriptionsResponse,\n newState: GetSubscriptionsResponse,\n ): void {\n const {\n subscriptions: currentSubscriptions,\n trialedProducts: currentTrialedProducts,\n customerId: currentCustomerId,\n lastSubscription: currentLastSubscription,\n rewardAccountId: currentRewardAccountId,\n productEntitlements: currentProductEntitlements,\n } = currentState;\n const {\n customerId: newCustomerId,\n subscriptions: newSubscriptions,\n trialedProducts: newTrialedProducts,\n lastSubscription: newLastSubscription,\n rewardAccountId: newRewardAccountId,\n productEntitlements: newProductEntitlements,\n } = newState;\n\n const areSubscriptionsEqual = this.#areSubscriptionsEqual(\n currentSubscriptions,\n newSubscriptions,\n );\n const areTrialedProductsEqual = this.#areTrialedProductsEqual(\n currentTrialedProducts,\n newTrialedProducts,\n );\n const isLastSubscriptionEqual = this.#isSubscriptionEqual(\n currentLastSubscription,\n newLastSubscription,\n );\n const areCustomerIdsEqual = currentCustomerId === newCustomerId;\n const areRewardAccountIdsEqual =\n currentRewardAccountId === newRewardAccountId;\n const areProductEntitlementsEqual = this.#areProductEntitlementsEqual(\n currentProductEntitlements,\n newProductEntitlements,\n );\n // only update the state if the subscriptions or trialed products are different\n // this prevents unnecessary state updates events, easier for the clients to handle\n\n // Only update the state if any subscription-related field changed. This\n // prevents unnecessary state change events for clients to handle.\n if (\n !areSubscriptionsEqual ||\n !isLastSubscriptionEqual ||\n !areTrialedProductsEqual ||\n !areCustomerIdsEqual ||\n !areRewardAccountIdsEqual ||\n !areProductEntitlementsEqual\n ) {\n this.update((state) => {\n state.subscriptions = newSubscriptions;\n state.customerId = newCustomerId;\n state.trialedProducts = newTrialedProducts;\n state.lastSubscription = newLastSubscription;\n state.rewardAccountId = newRewardAccountId;\n // Omitted entitlements are an empty map so selectors fail closed\n // instead of keeping last-known paid-feature flags.\n state.productEntitlements = newProductEntitlements ?? {};\n });\n // Trigger an access token refresh to ensure the user has the latest\n // access token after a subscription state change.\n this.triggerAccessTokenRefresh();\n }\n }\n\n /**\n * Gets and stores the user's subscription benefits.\n *\n * @returns The benefits response.\n * @throws If the user is not an active Money Account Plus subscriber or is\n * not eligible for benefits.\n */\n async getBenefits(): Promise<SubscriptionBenefitsResponse> {\n this.#assertIsActiveMoneyAccountPlusSubscriber();\n\n const benefits = await this.messenger.call(\n 'SubscriptionService:getBenefits',\n );\n\n // The subscription may have become inactive while the benefits request\n // was in flight. Re-check before persisting the response so stale\n // benefits cannot be restored after entitlement ends.\n this.#assertIsActiveMoneyAccountPlusSubscriber();\n\n this.update((state) => {\n state.benefits = benefits.eligible\n ? {\n billingPeriodId: benefits.billingPeriodId,\n ...benefits.products,\n }\n : undefined;\n });\n\n if (!benefits.eligible) {\n throw new Error(SubscriptionControllerErrorMessage.UserNotSubscribed);\n }\n\n return benefits;\n }\n\n /**\n * Get the subscription by product.\n *\n * @param productType - The product type.\n * @returns The subscription.\n */\n getSubscriptionByProduct(productType: ProductType): Subscription | undefined {\n return this.state.subscriptions.find((subscription) =>\n subscription.products.some((product) => product.name === productType),\n );\n }\n\n /**\n * Get the subscriptions eligibilities.\n *\n * @param request - Optional request object containing user balance to check cohort eligibility.\n * @returns The subscriptions eligibilities.\n */\n async getSubscriptionsEligibilities(\n request?: GetSubscriptionsEligibilitiesRequest,\n ): Promise<SubscriptionEligibility[]> {\n return await this.messenger.call(\n 'SubscriptionService:getSubscriptionsEligibilities',\n request,\n );\n }\n\n async cancelSubscription(request: CancelSubscriptionRequest): Promise<void> {\n this.#assertIsUserSubscribed({ subscriptionId: request.subscriptionId });\n\n const cancelledSubscription = await this.messenger.call(\n 'SubscriptionService:cancelSubscription',\n request,\n );\n\n this.update((state) => {\n state.subscriptions = state.subscriptions.map((subscription) =>\n subscription.id === request.subscriptionId\n ? { ...subscription, ...cancelledSubscription }\n : subscription,\n );\n });\n\n await this.#refreshBenefitsIfActive();\n\n this.triggerAccessTokenRefresh();\n }\n\n async unCancelSubscription(request: {\n subscriptionId: string;\n }): Promise<void> {\n this.#assertIsUserSubscribed({ subscriptionId: request.subscriptionId });\n\n const uncancelledSubscription = await this.messenger.call(\n 'SubscriptionService:unCancelSubscription',\n {\n subscriptionId: request.subscriptionId,\n },\n );\n\n this.update((state) => {\n state.subscriptions = state.subscriptions.map((subscription) =>\n subscription.id === request.subscriptionId\n ? { ...subscription, ...uncancelledSubscription }\n : subscription,\n );\n });\n\n await this.#refreshBenefitsIfActive();\n\n this.triggerAccessTokenRefresh();\n }\n\n /**\n * Starts a card-paid subscription checkout session for the requested products\n * (e.g. Shield or Money Account Plus).\n *\n * `isTrialRequested` on the request is ignored and overwritten from pricing\n * (`trialPeriodDays > 0`) and `trialedProducts`.\n *\n * @param request - The start subscription request.\n * @returns The checkout session response.\n */\n async startSubscriptionWithCard(\n request: StartSubscriptionRequest,\n ): Promise<StartSubscriptionResponse> {\n // get the latest subscriptions state before computing trial eligibility\n await this.getSubscriptions();\n this.#assertIsUserNotSubscribed({ products: request.products });\n\n const response = await this.messenger.call(\n 'SubscriptionService:startSubscriptionWithCard',\n {\n ...request,\n isTrialRequested: this.#getIsTrialRequested(\n request.products,\n request.recurringInterval,\n ),\n },\n );\n // note: no need to trigger access token refresh after startSubscriptionWithCard request because this only return stripe checkout session url, subscription not created yet\n\n return response;\n }\n\n /**\n * Starts a crypto-paid subscription for the requested products\n * (e.g. Shield or Money Account Plus). Unlike card checkout, this\n * creates the subscription immediately, so local state is refreshed\n * afterwards.\n *\n * `isTrialRequested` on the request is ignored and overwritten from pricing\n * (`trialPeriodDays > 0`) and `trialedProducts`.\n *\n * @param request - The start crypto subscription request.\n * @returns The start crypto subscription response.\n * @throws If `products` is empty.\n */\n async startSubscriptionWithCrypto(\n request: StartCryptoSubscriptionRequest,\n ): Promise<StartCryptoSubscriptionResponse> {\n if (request.products.length === 0) {\n throw new Error(\n SubscriptionControllerErrorMessage.SubscriptionProductsEmpty,\n );\n }\n\n // get the latest subscriptions state before computing trial eligibility\n await this.#getSubscriptions({ refreshBenefits: false });\n this.#assertIsUserNotSubscribed({ products: request.products });\n const response = await this.messenger.call(\n 'SubscriptionService:startSubscriptionWithCrypto',\n {\n ...request,\n isTrialRequested: this.#getIsTrialRequested(\n request.products,\n request.recurringInterval,\n ),\n },\n );\n\n // Crypto start creates the subscription immediately (unlike card checkout).\n await this.getSubscriptions();\n\n return response;\n }\n\n /**\n * Submits a Shield ERC-20 crypto approval transaction to start or update a\n * crypto subscription.\n *\n * This handler is Shield / `TransactionType.shieldSubscriptionApprove` only.\n * Delegation-based products (e.g. Money Account) must call\n * `startSubscriptionWithCrypto` instead.\n *\n * @param request - The crypto approval request.\n * @param request.productType - The subscription product. Typed as\n * `typeof PRODUCT_TYPES.SHIELD` only at the moment (future might support more\n * product).\n * @param request.txMeta - The transaction metadata. Must have type\n * `TransactionType.shieldSubscriptionApprove`.\n * @param request.isSponsored - Whether the transaction is sponsored.\n * @param request.rewardAccountId - The account ID of the reward subscription\n * to link.\n * @throws If `productType` is not Shield or `txMeta.type` is not\n * `shieldSubscriptionApprove`.\n * @returns void\n */\n async submitSubscriptionCryptoApproval(\n request: SubmitSubscriptionCryptoApprovalRequest,\n ): Promise<void> {\n const { productType, txMeta, isSponsored, rewardAccountId } = request;\n if (\n // Widen for the runtime guard: JS / unsound callers may still pass a\n // non-Shield product.\n (productType as ProductType) !== PRODUCT_TYPES.SHIELD ||\n txMeta.type !== TransactionType.shieldSubscriptionApprove\n ) {\n throw new Error(\n SubscriptionControllerErrorMessage.CryptoApprovalRequiresShieldApprove,\n );\n }\n\n const { chainId, rawTx } = txMeta;\n if (!chainId || !rawTx) {\n throw new Error('Chain ID or raw transaction not found');\n }\n\n const { pricing, lastSelectedPaymentMethod } = this.state;\n if (!pricing) {\n throw new Error('Subscription pricing not found');\n }\n if (!lastSelectedPaymentMethod) {\n throw new Error('Last selected payment method not found');\n }\n const lastSelectedPaymentMethodForProduct =\n lastSelectedPaymentMethod[productType];\n this.#assertIsPaymentMethodCrypto(lastSelectedPaymentMethodForProduct);\n\n const productPrice = this.#getProductPriceByProductAndPlan(\n productType,\n lastSelectedPaymentMethodForProduct.plan,\n );\n // get the latest subscriptions state before computing trial eligibility\n await this.#getSubscriptions({ refreshBenefits: false });\n const isTrialRequested = this.#getIsTrialRequested(\n [productType],\n lastSelectedPaymentMethodForProduct.plan,\n );\n const currentSubscription = this.getSubscriptionByProduct(productType);\n\n this.#assertValidSubscriptionStateForCryptoApproval({\n productType,\n });\n // if subscription exists, this transaction is for changing payment method\n const isChangePaymentMethod = Boolean(currentSubscription);\n\n if (isChangePaymentMethod) {\n await this.updatePaymentMethod({\n paymentType: PAYMENT_TYPES.byCrypto,\n subscriptionId: (currentSubscription as Subscription).id,\n chainId,\n payerAddress: txMeta.txParams.from as Hex,\n tokenSymbol: lastSelectedPaymentMethodForProduct.paymentTokenSymbol,\n rawTransaction: rawTx as Hex,\n recurringInterval: productPrice.interval,\n billingCycles: productPrice.minBillingCycles,\n });\n } else {\n const params: StartCryptoSubscriptionRequest = {\n products: [productType],\n isTrialRequested,\n recurringInterval: productPrice.interval,\n billingCycles: productPrice.minBillingCycles,\n chainId,\n payerAddress: txMeta.txParams.from as Hex,\n tokenSymbol: lastSelectedPaymentMethodForProduct.paymentTokenSymbol,\n rawTransaction: rawTx as Hex,\n cryptoAuthMethod: CRYPTO_AUTH_METHODS.ERC20_APPROVAL,\n isSponsored,\n useTestClock: lastSelectedPaymentMethodForProduct.useTestClock,\n rewardAccountId,\n };\n await this.startSubscriptionWithCrypto(params);\n }\n\n // update the subscriptions state after subscription created in server\n await this.#getSubscriptions({ refreshBenefits: false });\n }\n\n /**\n * Get transaction params to create crypto approve transaction for subscription payment\n *\n * @param request - The request object\n * @param request.chainId - The chain ID\n * @param request.tokenAddress - The address of the token\n * @param request.productType - The product type\n * @param request.interval - The interval\n * @returns The crypto approve transaction params\n */\n getCryptoApproveTransactionParams(\n request: GetCryptoApproveTransactionRequest,\n ): GetCryptoApproveTransactionResponse {\n const { pricing } = this.state;\n if (!pricing) {\n throw new Error('Subscription pricing not found');\n }\n const product = pricing.products.find(\n (productInfo) => productInfo.name === request.productType,\n );\n if (!product) {\n throw new Error('Product price not found');\n }\n\n const price = product.prices.find(\n (productPrice) => productPrice.interval === request.interval,\n );\n if (!price) {\n throw new Error('Price not found');\n }\n\n const chainsPaymentInfo = this.#findCryptoPaymentMethod(\n request.productType,\n CRYPTO_AUTH_METHODS.ERC20_APPROVAL,\n );\n if (!chainsPaymentInfo) {\n throw new Error('Chains payment info not found');\n }\n const chainPaymentInfo = chainsPaymentInfo.chains?.find(\n (chain) => chain.chainId === request.chainId,\n );\n if (!chainPaymentInfo) {\n throw new Error('Invalid chain id');\n }\n const tokenPaymentInfo = chainPaymentInfo.tokens.find(\n (token) =>\n token.address.toLowerCase() ===\n request.paymentTokenAddress.toLowerCase(),\n );\n if (!tokenPaymentInfo) {\n throw new Error('Invalid token address');\n }\n\n const tokenApproveAmount = this.getTokenApproveAmount(\n price,\n tokenPaymentInfo,\n );\n\n return {\n approveAmount: tokenApproveAmount,\n paymentAddress: chainPaymentInfo.paymentAddress,\n paymentTokenAddress: request.paymentTokenAddress,\n chainId: request.chainId,\n };\n }\n\n async updatePaymentMethod(\n opts: UpdatePaymentMethodOpts,\n ): Promise<UpdatePaymentMethodCardResponse | Subscription[]> {\n if (opts.paymentType === PAYMENT_TYPES.byCard) {\n const { paymentType, ...cardRequest } = opts;\n return await this.messenger.call(\n 'SubscriptionService:updatePaymentMethodCard',\n cardRequest,\n );\n } else if (opts.paymentType === PAYMENT_TYPES.byCrypto) {\n const { paymentType, ...cryptoRequest } = opts;\n await this.messenger.call(\n 'SubscriptionService:updatePaymentMethodCrypto',\n cryptoRequest,\n );\n return await this.getSubscriptions();\n }\n throw new Error('Invalid payment type');\n }\n\n /**\n * Gets the billing portal URL.\n *\n * @returns The billing portal URL\n */\n async getBillingPortalUrl(): Promise<BillingPortalResponse> {\n return await this.messenger.call('SubscriptionService:getBillingPortalUrl');\n }\n\n /**\n * Cache the last selected payment method for a specific product.\n *\n * @param request - The request object.\n * @param request.product - The product to cache the payment method for.\n * @param request.paymentMethod - The payment method to cache.\n * @param request.paymentMethod.type - The type of the payment method.\n * @param request.paymentMethod.paymentTokenAddress - The payment token address.\n * @param request.paymentMethod.plan - The plan of the payment method.\n */\n cacheLastSelectedPaymentMethod(\n request: CacheLastSelectedPaymentMethodRequest,\n ): void {\n const { product, paymentMethod } = request;\n if (\n paymentMethod.type === PAYMENT_TYPES.byCrypto &&\n (!paymentMethod.paymentTokenAddress || !paymentMethod.paymentTokenSymbol)\n ) {\n throw new Error(\n SubscriptionControllerErrorMessage.PaymentTokenAddressAndSymbolRequiredForCrypto,\n );\n }\n\n this.update((state) => {\n state.lastSelectedPaymentMethod = {\n ...state.lastSelectedPaymentMethod,\n [product]: paymentMethod,\n };\n });\n }\n\n /**\n * Clear the last selected payment method for a specific product.\n *\n * @param product - The product to clear the payment method for.\n */\n clearLastSelectedPaymentMethod(product: ProductType): void {\n this.update((state) => {\n if (state.lastSelectedPaymentMethod) {\n const { [product]: _, ...rest } = state.lastSelectedPaymentMethod;\n state.lastSelectedPaymentMethod =\n rest as typeof state.lastSelectedPaymentMethod;\n }\n });\n }\n\n /**\n * Submit sponsorship intents to the Subscription Service backend.\n *\n * This is intended to be used together with the crypto subscription flow.\n * When the user has enabled the smart transaction feature, we will sponsor the gas fees for the subscription approval transaction.\n *\n * @param request - Request object containing the address and products.\n * @example {\n * address: '0x1234567890123456789012345678901234567890',\n * products: [ProductType.Shield],\n * recurringInterval: RecurringInterval.Month,\n * billingCycles: 1,\n * }\n * @returns resolves to true if the sponsorship is supported and intents were submitted successfully, false if the chain does not support sponsorship or the user has already trialed\n * @throws If the crypto payment method or chain is missing from pricing\n */\n async submitSponsorshipIntents(\n request: SubmitSponsorshipIntentsMethodParams,\n ): Promise<boolean> {\n if (request.products.length === 0) {\n throw new Error(\n SubscriptionControllerErrorMessage.SubscriptionProductsEmpty,\n );\n }\n\n this.#assertIsUserNotSubscribed({ products: request.products });\n\n const selectedPaymentMethod =\n this.state.lastSelectedPaymentMethod?.[request.products[0]];\n this.#assertIsPaymentMethodCrypto(selectedPaymentMethod);\n\n const cryptoAuthMethod =\n selectedPaymentMethod.cryptoAuthMethod ??\n CRYPTO_AUTH_METHODS.ERC20_APPROVAL;\n const isEligibleForTrialedSponsorship =\n this.#getIsEligibleForTrialedSponsorship(\n request.chainId,\n request.products,\n cryptoAuthMethod,\n );\n if (!isEligibleForTrialedSponsorship) {\n return false;\n }\n\n const { paymentTokenSymbol, plan } = selectedPaymentMethod;\n const productPrice = this.#getProductPriceByProductAndPlan(\n // we only support one product at a time for now\n request.products[0],\n plan,\n );\n const billingCycles = productPrice.minBillingCycles;\n\n await this.messenger.call('SubscriptionService:submitSponsorshipIntents', {\n ...request,\n paymentTokenSymbol,\n billingCycles,\n recurringInterval: plan,\n });\n return true;\n }\n\n /**\n * Submit a user event from the UI. (e.g. shield modal viewed)\n *\n * @param request - Request object containing the event to submit.\n * @example { event: SubscriptionUserEvent.ShieldEntryModalViewed, cohort: 'post_tx' }\n */\n async submitUserEvent(request: SubmitUserEventRequest): Promise<void> {\n await this.messenger.call('SubscriptionService:submitUserEvent', request);\n }\n\n /**\n * Assign user to a cohort.\n *\n * @param request - Request object containing the cohort to assign the user to.\n * @example { cohort: 'post_tx' }\n */\n async assignUserToCohort(request: AssignCohortRequest): Promise<void> {\n await this.messenger.call(\n 'SubscriptionService:assignUserToCohort',\n request,\n );\n }\n\n /**\n * Link rewards to a subscription.\n *\n * @param request - Request object containing the reward subscription ID.\n * @param request.subscriptionId - The ID of the subscription to link rewards to.\n * @param request.rewardAccountId - The account ID of the reward subscription to link to the subscription.\n * @example { subscriptionId: '1234567890', rewardAccountId: 'eip155:1:0x1234567890123456789012345678901234567890' }\n * @returns Resolves when the rewards are linked successfully.\n */\n async linkRewards(\n request: LinkRewardsRequest & { subscriptionId: string },\n ): Promise<void> {\n // assert that the user is subscribed to the subscription\n this.#assertIsUserSubscribed({ subscriptionId: request.subscriptionId });\n\n // link rewards to the subscription\n const response = await this.messenger.call(\n 'SubscriptionService:linkRewards',\n {\n rewardAccountId: request.rewardAccountId,\n },\n );\n if (!response.success) {\n throw new Error(SubscriptionControllerErrorMessage.LinkRewardsFailed);\n }\n }\n\n async _executePoll(): Promise<void> {\n await this.getSubscriptions();\n }\n\n async #refreshBenefitsIfActive(refreshBenefits = true): Promise<void> {\n if (!this.#hasActiveMoneyAccountPlusSubscription()) {\n if (this.state.benefits) {\n this.update((state) => {\n state.benefits = undefined;\n });\n }\n return;\n }\n\n if (!refreshBenefits) {\n return;\n }\n\n try {\n await this.getBenefits();\n } catch (error) {\n log('Failed to refresh subscription benefits', error);\n }\n }\n\n /**\n * Calculate total subscription price amount (approval amount) from price info\n * e.g: $8 per month * 12 months min billing cycles = $96\n *\n * @param price - The price info\n * @returns The price amount\n */\n #getSubscriptionPriceAmount(price: ProductPrice): string {\n // no need to use BigInt since max unitDecimals are always 2 for price\n const amount = new BigNumber(price.unitAmount)\n .div(10 ** price.unitDecimals)\n .multipliedBy(price.minBillingCycles)\n .toString();\n return amount;\n }\n\n /**\n * Calculate minimum subscription balance amount from price info\n *\n * @param price - The price info\n * @returns The balance amount\n */\n #getSubscriptionBalanceAmount(price: ProductPrice): string {\n // no need to use BigInt since max unitDecimals are always 2 for price\n const amount = new BigNumber(price.unitAmount)\n .div(10 ** price.unitDecimals)\n .multipliedBy(price.minBillingCyclesForBalance)\n .toString();\n return amount;\n }\n\n /**\n * Calculate token approve amount from price info\n *\n * @param price - The price info\n * @param tokenPaymentInfo - The token price info\n * @returns The token approve amount\n */\n getTokenApproveAmount(\n price: ProductPrice,\n tokenPaymentInfo: TokenPaymentInfo,\n ): string {\n const conversionRate =\n tokenPaymentInfo.conversionRate?.[\n price.currency as keyof NonNullable<TokenPaymentInfo['conversionRate']>\n ];\n if (!conversionRate) {\n throw new Error('Conversion rate not found');\n }\n // price of the product\n const priceAmount = new BigNumber(this.#getSubscriptionPriceAmount(price));\n\n const tokenDecimal = new BigNumber(10).pow(tokenPaymentInfo.decimals);\n const tokenAmount = priceAmount\n .multipliedBy(tokenDecimal)\n .div(conversionRate);\n return tokenAmount.toFixed(0);\n }\n\n /**\n * Calculate token minimum balance amount from price info\n *\n * @param price - The price info\n * @param tokenPaymentInfo - The token price info\n * @returns The token balance amount\n */\n getTokenMinimumBalanceAmount(\n price: ProductPrice,\n tokenPaymentInfo: TokenPaymentInfo,\n ): string {\n const conversionRate =\n tokenPaymentInfo.conversionRate?.[\n price.currency as keyof NonNullable<TokenPaymentInfo['conversionRate']>\n ];\n if (!conversionRate) {\n throw new Error('Conversion rate not found');\n }\n const balanceAmount = new BigNumber(\n this.#getSubscriptionBalanceAmount(price),\n );\n\n const tokenDecimal = new BigNumber(10).pow(tokenPaymentInfo.decimals);\n const tokenAmount = balanceAmount\n .multipliedBy(tokenDecimal)\n .div(conversionRate);\n return tokenAmount.toFixed(0);\n }\n\n /**\n * Clears the subscription state and resets to default values.\n */\n clearState(): void {\n const defaultState = getDefaultSubscriptionControllerState();\n this.update(() => {\n return defaultState;\n });\n }\n\n /**\n * Triggers an access token refresh.\n */\n triggerAccessTokenRefresh(): void {\n // We perform a sign out to clear the access token from the authentication\n // controller. Next time the access token is requested, a new access token\n // will be fetched.\n this.messenger.call('AuthenticationController:performSignOut');\n }\n\n #getProductPriceByProductAndPlan(\n productType: ProductType,\n plan: RecurringInterval,\n ): ProductPrice {\n const { pricing } = this.state;\n const productPricing = pricing?.products.find(\n (product) => product.name === productType,\n );\n const productPrice = productPricing?.prices.find(\n (price) => price.interval === plan,\n );\n if (!productPrice) {\n throw new Error(SubscriptionControllerErrorMessage.ProductPriceNotFound);\n }\n return productPrice;\n }\n\n #assertValidSubscriptionStateForCryptoApproval({\n productType,\n }: {\n productType: ProductType;\n }): void {\n const subscription = this.state.subscriptions.find((sub) =>\n sub.products.some((product) => product.name === productType),\n );\n\n const isValid =\n !subscription ||\n (\n [\n SUBSCRIPTION_STATUSES.pastDue,\n SUBSCRIPTION_STATUSES.unpaid,\n SUBSCRIPTION_STATUSES.paused,\n SUBSCRIPTION_STATUSES.provisional,\n SUBSCRIPTION_STATUSES.active,\n SUBSCRIPTION_STATUSES.trialing,\n ] as SubscriptionStatus[]\n ).includes(subscription.status);\n if (!isValid) {\n throw new Error(\n SubscriptionControllerErrorMessage.SubscriptionNotValidForCryptoApproval,\n );\n }\n }\n\n #assertIsUserNotSubscribed({ products }: { products: ProductType[] }): void {\n const subscription = this.state.subscriptions.find((sub) =>\n sub.products.some((product) => products.includes(product.name)),\n );\n\n if (\n subscription &&\n ACTIVE_SUBSCRIPTION_STATUSES.includes(subscription.status)\n ) {\n throw new Error(SubscriptionControllerErrorMessage.UserAlreadySubscribed);\n }\n }\n\n #assertIsActiveMoneyAccountPlusSubscriber(): void {\n if (!this.#hasActiveMoneyAccountPlusSubscription()) {\n if (this.state.benefits) {\n this.update((state) => {\n state.benefits = undefined;\n });\n }\n throw new Error(SubscriptionControllerErrorMessage.UserNotSubscribed);\n }\n }\n\n #assertIsUserSubscribed(request: { subscriptionId: string }): void {\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 /**\n * Asserts that the value is a valid crypto payment method.\n *\n * After this assert, `cryptoAuthMethod` and `useTestClock` remain optional\n * because persisted cache entries may omit them.\n *\n * @param value - The value to assert.\n * @throws an error if the value is not a valid crypto payment method.\n */\n #assertIsPaymentMethodCrypto(\n value: CachedLastSelectedPaymentMethod | undefined,\n ): asserts value is CachedLastSelectedPaymentMethod & {\n type: typeof PAYMENT_TYPES.byCrypto;\n paymentTokenAddress: Hex;\n paymentTokenSymbol: string;\n } {\n if (\n value?.type !== PAYMENT_TYPES.byCrypto ||\n !value.paymentTokenAddress ||\n !value.paymentTokenSymbol\n ) {\n throw new Error(\n SubscriptionControllerErrorMessage.PaymentMethodNotCrypto,\n );\n }\n }\n\n #hasActiveMoneyAccountPlusSubscription(): boolean {\n return this.state.subscriptions.some(\n (subscription) =>\n subscription.products.some(\n (product) => product.name === PRODUCT_TYPES.MONEY_ACCOUNT_PLUS,\n ) && ACTIVE_SUBSCRIPTION_STATUSES.includes(subscription.status),\n );\n }\n\n /**\n * Determines if the user is eligible for trialed sponsorship for the given chain and products.\n * The user is eligible if the chain supports sponsorship and the user has not trialed the provided products before.\n *\n * @param chainId - The chain ID\n * @param products - The products to check eligibility for\n * @param cryptoAuthMethod - The crypto authorization method of the selected payment method\n * @returns True if the user is eligible for trialed sponsorship, false otherwise\n */\n #getIsEligibleForTrialedSponsorship(\n chainId: Hex,\n products: ProductType[],\n cryptoAuthMethod: CryptoAuthMethod,\n ): boolean {\n const isSponsorshipSupported = this.#getChainSupportsSponsorship(\n chainId,\n products[0],\n cryptoAuthMethod,\n );\n\n // verify if the user has trialed the provided products before\n const hasTrialedBefore = this.state.trialedProducts.some((product) =>\n products.includes(product),\n );\n\n return isSponsorshipSupported && !hasTrialedBefore;\n }\n\n /**\n * Whether a trial should be requested for the given products and plan.\n * True only when every product has `trialPeriodDays > 0` and has not\n * already been trialed.\n *\n * @param products - The products to check.\n * @param plan - The recurring interval to look up pricing for.\n * @returns Whether a trial should be requested.\n */\n #getIsTrialRequested(\n products: ProductType[],\n plan: RecurringInterval,\n ): boolean {\n return products.every((productType) => {\n if (this.state.trialedProducts.includes(productType)) {\n return false;\n }\n const productPrice = this.#getProductPriceByProductAndPlan(\n productType,\n plan,\n );\n return productPrice.trialPeriodDays > 0;\n });\n }\n\n #findCryptoPaymentMethod(\n productType: ProductType,\n cryptoAuthMethod: CryptoAuthMethod,\n ): PricingCryptoPaymentMethod | undefined {\n const matches: {\n method: PricingCryptoPaymentMethod;\n explicit: boolean;\n }[] = [];\n\n for (const paymentMethod of this.state.pricing?.paymentMethods ?? []) {\n if (paymentMethod.type !== PAYMENT_TYPES.byCrypto) {\n continue;\n }\n\n const resolved = this.#resolveCryptoPaymentMethodDefaults(paymentMethod);\n if (!resolved) {\n continue;\n }\n\n if (\n resolved.cryptoAuthMethod === cryptoAuthMethod &&\n resolved.products.includes(productType)\n ) {\n matches.push({\n method: paymentMethod,\n explicit: resolved.explicit,\n });\n }\n }\n\n if (matches.length === 0) {\n return undefined;\n }\n\n const explicitMatches = matches.filter((match) => match.explicit);\n const candidates = explicitMatches.length > 0 ? explicitMatches : matches;\n\n if (candidates.length > 1) {\n throw new Error('Multiple matching crypto payment methods found');\n }\n\n return candidates[0].method;\n }\n\n /**\n * Resolves omitted `products` / `cryptoAuthMethod` on a crypto pricing row.\n * Legacy Shield + `erc20_approval` defaults apply only when both fields are\n * absent. If `products` is present, the list must be non-empty and\n * `cryptoAuthMethod` must be explicit; otherwise the row is ignored.\n *\n * @param paymentMethod - The crypto pricing row.\n * @returns Resolved products and auth method, or `undefined` if the row is\n * incomplete.\n */\n #resolveCryptoPaymentMethodDefaults(\n paymentMethod: PricingCryptoPaymentMethod,\n ):\n | {\n products: ProductType[];\n cryptoAuthMethod: CryptoAuthMethod;\n explicit: boolean;\n }\n | undefined {\n const productsPresent = paymentMethod.products !== undefined;\n const authPresent = paymentMethod.cryptoAuthMethod !== undefined;\n\n if (!productsPresent && !authPresent) {\n return {\n products: [PRODUCT_TYPES.SHIELD],\n cryptoAuthMethod: CRYPTO_AUTH_METHODS.ERC20_APPROVAL,\n explicit: false,\n };\n }\n\n if (!paymentMethod.products?.length || !paymentMethod.cryptoAuthMethod) {\n return undefined;\n }\n\n return {\n products: paymentMethod.products,\n cryptoAuthMethod: paymentMethod.cryptoAuthMethod,\n explicit: true,\n };\n }\n\n /**\n * Whether the given chain supports sponsorship for the product and auth method.\n *\n * @param chainId - The chain ID\n * @param productType - The product type\n * @param cryptoAuthMethod - The crypto authorization method to look up\n * @returns True if the chain row has sponsorship enabled, false if it is explicitly not sponsored\n * @throws If the crypto payment method or chain row is missing from pricing\n */\n #getChainSupportsSponsorship(\n chainId: Hex,\n productType: ProductType,\n cryptoAuthMethod: CryptoAuthMethod,\n ): boolean {\n const cryptoPaymentInfo = this.#findCryptoPaymentMethod(\n productType,\n cryptoAuthMethod,\n );\n if (!cryptoPaymentInfo) {\n throw new Error('Chains payment info not found');\n }\n\n const chainPaymentInfo = cryptoPaymentInfo.chains?.find(\n (chain) => chain.chainId === chainId,\n );\n if (!chainPaymentInfo) {\n throw new Error('Invalid chain id');\n }\n return Boolean(chainPaymentInfo.isSponsorshipSupported);\n }\n\n /**\n * Determines whether two trialed products arrays are equal by comparing all products in the arrays.\n *\n * @param oldTrialedProducts - The first trialed products array to compare.\n * @param newTrialedProducts - The second trialed products array to compare.\n * @returns True if the trialed products arrays are equal, false otherwise.\n */\n #areTrialedProductsEqual(\n oldTrialedProducts: ProductType[],\n newTrialedProducts: ProductType[],\n ): boolean {\n return (\n oldTrialedProducts.length === newTrialedProducts?.length &&\n oldTrialedProducts.every((product) =>\n newTrialedProducts?.includes(product),\n )\n );\n }\n\n /**\n * Compares product entitlement maps without treating object key order as a\n * change. Insertion-order-sensitive `JSON.stringify` can otherwise treat an\n * equivalent API payload as different and trigger `performSignOut`.\n *\n * @param oldProductEntitlements - Stored product entitlements.\n * @param newProductEntitlements - Freshly fetched product entitlements.\n * @returns True if the maps are equal regardless of key order.\n */\n #areProductEntitlementsEqual(\n oldProductEntitlements?: ProductEntitlements,\n newProductEntitlements?: ProductEntitlements,\n ): boolean {\n return deepEqual(\n oldProductEntitlements ?? {},\n newProductEntitlements ?? {},\n );\n }\n\n /**\n * Determines whether two subscription arrays are equal by comparing all properties\n * of each subscription in the arrays.\n *\n * @param oldSubs - The first subscription array to compare.\n * @param newSubs - The second subscription array to compare.\n * @returns True if the subscription arrays are equal, false otherwise.\n */\n #areSubscriptionsEqual(\n oldSubs: Subscription[],\n newSubs: Subscription[],\n ): boolean {\n // Check if arrays have different lengths\n if (oldSubs.length !== newSubs.length) {\n return false;\n }\n\n // Sort both arrays by id to ensure consistent comparison\n const sortedOldSubs = [...oldSubs].sort((a, b) => a.id.localeCompare(b.id));\n const sortedNewSubs = [...newSubs].sort((a, b) => a.id.localeCompare(b.id));\n\n // Check if all subscriptions are equal\n return sortedOldSubs.every((oldSub, index) => {\n const newSub = sortedNewSubs[index];\n return this.#isSubscriptionEqual(oldSub, newSub);\n });\n }\n\n #isSubscriptionEqual(oldSub?: Subscription, newSub?: Subscription): boolean {\n // not equal if one is undefined and the other is defined\n if (!oldSub || !newSub) {\n if (!oldSub && !newSub) {\n return true;\n }\n return false;\n }\n\n return (\n this.#stringifySubscription(oldSub) ===\n this.#stringifySubscription(newSub)\n );\n }\n\n #stringifySubscription(subscription: Subscription): string {\n const subsWithSortedProducts = {\n ...subscription,\n // order the products by name\n products: [...subscription.products].sort((a, b) =>\n a.name.localeCompare(b.name),\n ),\n };\n\n return JSON.stringify(subsWithSortedProducts);\n }\n}\n"]}
1
+ {"version":3,"file":"SubscriptionController.js","sourceRoot":"","sources":["../src/SubscriptionController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n StateMetadata,\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { AuthenticationController } from '@metamask/profile-sync-controller';\nimport { TransactionType } from '@metamask/transaction-controller';\nimport type { CaipAccountId, Hex } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\nimport deepEqual from 'fast-deep-equal';\n\nimport {\n ACTIVE_SUBSCRIPTION_STATUSES,\n controllerName,\n DEFAULT_POLLING_INTERVAL,\n SubscriptionControllerErrorMessage,\n} from './constants.js';\nimport { createModuleLogger, projectLogger } from './logger.js';\nimport type { SubscriptionControllerMethodActions } from './SubscriptionController-method-action-types.js';\nimport type {\n SubscriptionServiceAssignUserToCohortAction,\n SubscriptionServiceCancelSubscriptionAction,\n SubscriptionServiceGetBillingPortalUrlAction,\n SubscriptionServiceGetBenefitsAction,\n SubscriptionServiceGetPricingAction,\n SubscriptionServiceGetSubscriptionsAction,\n SubscriptionServiceGetSubscriptionsEligibilitiesAction,\n SubscriptionServiceLinkRewardsAction,\n SubscriptionServiceStartSubscriptionWithCardAction,\n SubscriptionServiceStartSubscriptionWithCryptoAction,\n SubscriptionServiceSubmitSponsorshipIntentsAction,\n SubscriptionServiceSubmitUserEventAction,\n SubscriptionServiceUnCancelSubscriptionAction,\n SubscriptionServiceUpdatePaymentMethodCardAction,\n SubscriptionServiceUpdatePaymentMethodCryptoAction,\n} from './SubscriptionService-method-action-types.js';\nimport {\n CRYPTO_AUTH_METHODS,\n PAYMENT_TYPES,\n PRODUCT_TYPES,\n SUBSCRIPTION_STATUSES,\n} from './types.js';\nimport type {\n AssignCohortRequest,\n BillingPortalResponse,\n CryptoAuthMethod,\n GetCryptoApproveTransactionRequest,\n GetCryptoApproveTransactionResponse,\n GetSubscriptionsEligibilitiesRequest,\n GetSubscriptionsResponse,\n ProductPrice,\n SubscriptionEligibility,\n StartCryptoSubscriptionRequest,\n SubmitSubscriptionCryptoApprovalRequest,\n SubmitUserEventRequest,\n TokenPaymentInfo,\n UpdatePaymentMethodCardResponse,\n UpdatePaymentMethodOpts,\n CachedLastSelectedPaymentMethod,\n CacheLastSelectedPaymentMethodRequest,\n SubmitSponsorshipIntentsMethodParams,\n RecurringInterval,\n SubscriptionStatus,\n LinkRewardsRequest,\n StartCryptoSubscriptionResponse,\n StartSubscriptionResponse,\n CancelSubscriptionRequest,\n PricingCryptoPaymentMethod,\n SubscriptionBenefitsResponse,\n SubscriptionBenefitsState,\n} from './types.js';\nimport type {\n PricingResponse,\n ProductType,\n ProductEntitlements,\n StartSubscriptionRequest,\n Subscription,\n} from './types.js';\n\nconst log = createModuleLogger(projectLogger, controllerName);\n\nexport type SubscriptionControllerState = {\n customerId?: string;\n trialedProducts: ProductType[];\n subscriptions: Subscription[];\n productEntitlements?: ProductEntitlements;\n pricing?: PricingResponse;\n benefits?: SubscriptionBenefitsState;\n /** The last subscription that user has subscribed to if any. */\n lastSubscription?: Subscription;\n /** The reward account ID if user has linked rewards to the subscription. */\n rewardAccountId?: CaipAccountId;\n /**\n * The last selected payment method for the user.\n * This is used to display the last selected payment method in the UI.\n * This state is also meant to be used internally to track the last selected payment method for the user. (e.g. for crypto subscriptions)\n */\n lastSelectedPaymentMethod?: Partial<\n Record<ProductType, CachedLastSelectedPaymentMethod>\n >;\n};\n\nexport type SubscriptionControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n SubscriptionControllerState\n>;\nexport type SubscriptionControllerActions =\n | SubscriptionControllerGetStateAction\n | SubscriptionControllerMethodActions;\n\ntype AllowedActions =\n | SubscriptionServiceGetPricingAction\n | SubscriptionServiceGetSubscriptionsAction\n | SubscriptionServiceGetBenefitsAction\n | SubscriptionServiceGetSubscriptionsEligibilitiesAction\n | SubscriptionServiceCancelSubscriptionAction\n | SubscriptionServiceUnCancelSubscriptionAction\n | SubscriptionServiceStartSubscriptionWithCardAction\n | SubscriptionServiceStartSubscriptionWithCryptoAction\n | SubscriptionServiceUpdatePaymentMethodCardAction\n | SubscriptionServiceUpdatePaymentMethodCryptoAction\n | SubscriptionServiceGetBillingPortalUrlAction\n | SubscriptionServiceSubmitSponsorshipIntentsAction\n | SubscriptionServiceSubmitUserEventAction\n | SubscriptionServiceAssignUserToCohortAction\n | SubscriptionServiceLinkRewardsAction\n | AuthenticationController.AuthenticationControllerPerformSignOutAction;\n\n// Events\nexport type SubscriptionControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n SubscriptionControllerState\n>;\nexport type SubscriptionControllerEvents =\n SubscriptionControllerStateChangeEvent;\n\ntype AllowedEvents = never;\n\n// Messenger\nexport type SubscriptionControllerMessenger = Messenger<\n typeof controllerName,\n SubscriptionControllerActions | AllowedActions,\n SubscriptionControllerEvents | AllowedEvents\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 * Polling interval to use for the subscription controller.\n *\n * @default 5 minutes.\n */\n pollingInterval?: number;\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 trialedProducts: [],\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 includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n productEntitlements: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n lastSubscription: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n customerId: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n rewardAccountId: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n trialedProducts: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n pricing: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n benefits: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n lastSelectedPaymentMethod: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n };\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'getPricing',\n 'getSubscriptions',\n 'getBenefits',\n 'getSubscriptionByProduct',\n 'getSubscriptionsEligibilities',\n 'cancelSubscription',\n 'unCancelSubscription',\n 'startSubscriptionWithCard',\n 'startSubscriptionWithCrypto',\n 'stopAllPolling',\n 'submitSubscriptionCryptoApproval',\n 'getCryptoApproveTransactionParams',\n 'updatePaymentMethod',\n 'getBillingPortalUrl',\n 'cacheLastSelectedPaymentMethod',\n 'clearLastSelectedPaymentMethod',\n 'submitSponsorshipIntents',\n 'submitUserEvent',\n 'assignUserToCohort',\n 'linkRewards',\n 'getTokenApproveAmount',\n 'getTokenMinimumBalanceAmount',\n 'clearState',\n 'triggerAccessTokenRefresh',\n] as const;\n\nexport class SubscriptionController extends StaticIntervalPollingController()<\n typeof controllerName,\n SubscriptionControllerState,\n SubscriptionControllerMessenger\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.pollingInterval - The polling interval to use for the subscription controller.\n */\n constructor(options: SubscriptionControllerOptions) {\n const {\n messenger,\n state,\n pollingInterval = DEFAULT_POLLING_INTERVAL,\n } = options;\n super({\n name: controllerName,\n metadata: subscriptionControllerMetadata,\n state: {\n ...getDefaultSubscriptionControllerState(),\n ...state,\n },\n messenger,\n });\n\n this.setIntervalLength(pollingInterval);\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Gets the pricing information from the subscription service.\n *\n * @returns The pricing information.\n */\n async getPricing(): Promise<PricingResponse> {\n const pricing = await this.messenger.call('SubscriptionService:getPricing');\n this.update((state) => {\n state.pricing = pricing;\n });\n return pricing;\n }\n\n async getSubscriptions(): Promise<Subscription[]> {\n return await this.#getSubscriptions();\n }\n\n async #getSubscriptions({\n refreshBenefits = true,\n }: { refreshBenefits?: boolean } = {}): Promise<Subscription[]> {\n const currentSubscriptions = this.state.subscriptions;\n const currentTrialedProducts = this.state.trialedProducts;\n const currentCustomerId = this.state.customerId;\n const currentLastSubscription = this.state.lastSubscription;\n const currentRewardAccountId = this.state.rewardAccountId;\n const currentProductEntitlements = this.state.productEntitlements;\n const currentSubscriptionState: GetSubscriptionsResponse = {\n customerId: currentCustomerId,\n subscriptions: currentSubscriptions,\n trialedProducts: currentTrialedProducts,\n lastSubscription: currentLastSubscription,\n rewardAccountId: currentRewardAccountId,\n productEntitlements: currentProductEntitlements,\n };\n\n const newSubscriptionState = await this.messenger.call(\n 'SubscriptionService:getSubscriptions',\n );\n\n this.#updateSubscriptionStateIfChanged(\n currentSubscriptionState,\n newSubscriptionState,\n );\n\n await this.#refreshBenefitsIfActive(refreshBenefits);\n\n return newSubscriptionState.subscriptions;\n }\n\n /**\n * Updates the subscription state and refreshes the access token when the\n * fetched subscription state differs from the current state.\n *\n * @param currentState - The subscription state captured before the request.\n * @param newState - The subscription state returned by the service.\n */\n #updateSubscriptionStateIfChanged(\n currentState: GetSubscriptionsResponse,\n newState: GetSubscriptionsResponse,\n ): void {\n const {\n subscriptions: currentSubscriptions,\n trialedProducts: currentTrialedProducts,\n customerId: currentCustomerId,\n lastSubscription: currentLastSubscription,\n rewardAccountId: currentRewardAccountId,\n productEntitlements: currentProductEntitlements,\n } = currentState;\n const {\n customerId: newCustomerId,\n subscriptions: newSubscriptions,\n trialedProducts: newTrialedProducts,\n lastSubscription: newLastSubscription,\n rewardAccountId: newRewardAccountId,\n productEntitlements: newProductEntitlements,\n } = newState;\n\n const areSubscriptionsEqual = this.#areSubscriptionsEqual(\n currentSubscriptions,\n newSubscriptions,\n );\n const areTrialedProductsEqual = this.#areTrialedProductsEqual(\n currentTrialedProducts,\n newTrialedProducts,\n );\n const isLastSubscriptionEqual = this.#isSubscriptionEqual(\n currentLastSubscription,\n newLastSubscription,\n );\n const areCustomerIdsEqual = currentCustomerId === newCustomerId;\n const areRewardAccountIdsEqual =\n currentRewardAccountId === newRewardAccountId;\n const areProductEntitlementsEqual = this.#areProductEntitlementsEqual(\n currentProductEntitlements,\n newProductEntitlements,\n );\n // only update the state if the subscriptions or trialed products are different\n // this prevents unnecessary state updates events, easier for the clients to handle\n\n // Only update the state if any subscription-related field changed. This\n // prevents unnecessary state change events for clients to handle.\n if (\n !areSubscriptionsEqual ||\n !isLastSubscriptionEqual ||\n !areTrialedProductsEqual ||\n !areCustomerIdsEqual ||\n !areRewardAccountIdsEqual ||\n !areProductEntitlementsEqual\n ) {\n this.update((state) => {\n state.subscriptions = newSubscriptions;\n state.customerId = newCustomerId;\n state.trialedProducts = newTrialedProducts;\n state.lastSubscription = newLastSubscription;\n state.rewardAccountId = newRewardAccountId;\n // Omitted entitlements are an empty map so selectors fail closed\n // instead of keeping last-known paid-feature flags.\n state.productEntitlements = newProductEntitlements ?? {};\n });\n // Trigger an access token refresh to ensure the user has the latest\n // access token after a subscription state change.\n this.triggerAccessTokenRefresh();\n }\n }\n\n /**\n * Gets and stores the user's subscription benefits.\n *\n * @returns The benefits response.\n * @throws If the user is not an active Money Account Plus subscriber or is\n * not eligible for benefits.\n */\n async getBenefits(): Promise<SubscriptionBenefitsResponse> {\n this.#assertIsActiveMoneyAccountPlusSubscriber();\n\n const benefits = await this.messenger.call(\n 'SubscriptionService:getBenefits',\n );\n\n // The subscription may have become inactive while the benefits request\n // was in flight. Re-check before persisting the response so stale\n // benefits cannot be restored after entitlement ends.\n this.#assertIsActiveMoneyAccountPlusSubscriber();\n\n this.update((state) => {\n state.benefits = benefits.eligible\n ? {\n billingPeriodId: benefits.billingPeriodId,\n ...benefits.products,\n }\n : undefined;\n });\n\n if (!benefits.eligible) {\n throw new Error(SubscriptionControllerErrorMessage.UserNotSubscribed);\n }\n\n return benefits;\n }\n\n /**\n * Get the subscription by product.\n *\n * @param productType - The product type.\n * @returns The subscription.\n */\n getSubscriptionByProduct(productType: ProductType): Subscription | undefined {\n return this.state.subscriptions.find((subscription) =>\n subscription.products.some((product) => product.name === productType),\n );\n }\n\n /**\n * Get the subscriptions eligibilities.\n *\n * @param request - Optional request object containing user balance to check cohort eligibility.\n * @returns The subscriptions eligibilities.\n */\n async getSubscriptionsEligibilities(\n request?: GetSubscriptionsEligibilitiesRequest,\n ): Promise<SubscriptionEligibility[]> {\n return await this.messenger.call(\n 'SubscriptionService:getSubscriptionsEligibilities',\n request,\n );\n }\n\n async cancelSubscription(request: CancelSubscriptionRequest): Promise<void> {\n this.#assertIsUserSubscribed({ subscriptionId: request.subscriptionId });\n\n const cancelledSubscription = await this.messenger.call(\n 'SubscriptionService:cancelSubscription',\n request,\n );\n\n this.update((state) => {\n state.subscriptions = state.subscriptions.map((subscription) =>\n subscription.id === request.subscriptionId\n ? { ...subscription, ...cancelledSubscription }\n : subscription,\n );\n });\n\n try {\n await this.#getSubscriptions();\n } catch (error) {\n log('Failed to refresh subscriptions after cancellation', error);\n\n // Preserve the existing best-effort benefits refresh behavior if the\n // canonical subscription refresh is unavailable.\n await this.#refreshBenefitsIfActive();\n }\n\n this.triggerAccessTokenRefresh();\n }\n\n async unCancelSubscription(request: {\n subscriptionId: string;\n }): Promise<void> {\n this.#assertIsUserSubscribed({ subscriptionId: request.subscriptionId });\n\n const uncancelledSubscription = await this.messenger.call(\n 'SubscriptionService:unCancelSubscription',\n {\n subscriptionId: request.subscriptionId,\n },\n );\n\n this.update((state) => {\n state.subscriptions = state.subscriptions.map((subscription) =>\n subscription.id === request.subscriptionId\n ? { ...subscription, ...uncancelledSubscription }\n : subscription,\n );\n });\n\n await this.#refreshBenefitsIfActive();\n\n this.triggerAccessTokenRefresh();\n }\n\n /**\n * Starts a card-paid subscription checkout session for the requested products\n * (e.g. Shield or Money Account Plus).\n *\n * `isTrialRequested` on the request is ignored and overwritten from pricing\n * (`trialPeriodDays > 0`) and `trialedProducts`.\n *\n * @param request - The start subscription request.\n * @returns The checkout session response.\n */\n async startSubscriptionWithCard(\n request: StartSubscriptionRequest,\n ): Promise<StartSubscriptionResponse> {\n // get the latest subscriptions state before computing trial eligibility\n await this.getSubscriptions();\n this.#assertIsUserNotSubscribed({ products: request.products });\n\n const response = await this.messenger.call(\n 'SubscriptionService:startSubscriptionWithCard',\n {\n ...request,\n isTrialRequested: this.#getIsTrialRequested(\n request.products,\n request.recurringInterval,\n ),\n },\n );\n // note: no need to trigger access token refresh after startSubscriptionWithCard request because this only return stripe checkout session url, subscription not created yet\n\n return response;\n }\n\n /**\n * Starts a crypto-paid subscription for the requested products\n * (e.g. Shield or Money Account Plus). Unlike card checkout, this\n * creates the subscription immediately, so local state is refreshed\n * afterwards.\n *\n * `isTrialRequested` on the request is ignored and overwritten from pricing\n * (`trialPeriodDays > 0`) and `trialedProducts`.\n *\n * @param request - The start crypto subscription request.\n * @returns The start crypto subscription response.\n * @throws If `products` is empty.\n */\n async startSubscriptionWithCrypto(\n request: StartCryptoSubscriptionRequest,\n ): Promise<StartCryptoSubscriptionResponse> {\n if (request.products.length === 0) {\n throw new Error(\n SubscriptionControllerErrorMessage.SubscriptionProductsEmpty,\n );\n }\n\n // get the latest subscriptions state before computing trial eligibility\n await this.#getSubscriptions({ refreshBenefits: false });\n this.#assertIsUserNotSubscribed({ products: request.products });\n const response = await this.messenger.call(\n 'SubscriptionService:startSubscriptionWithCrypto',\n {\n ...request,\n isTrialRequested: this.#getIsTrialRequested(\n request.products,\n request.recurringInterval,\n ),\n },\n );\n\n // Crypto start creates the subscription immediately (unlike card checkout).\n await this.getSubscriptions();\n\n return response;\n }\n\n /**\n * Submits a Shield ERC-20 crypto approval transaction to start or update a\n * crypto subscription.\n *\n * This handler is Shield / `TransactionType.shieldSubscriptionApprove` only.\n * Delegation-based products (e.g. Money Account) must call\n * `startSubscriptionWithCrypto` instead.\n *\n * @param request - The crypto approval request.\n * @param request.productType - The subscription product. Typed as\n * `typeof PRODUCT_TYPES.SHIELD` only at the moment (future might support more\n * product).\n * @param request.txMeta - The transaction metadata. Must have type\n * `TransactionType.shieldSubscriptionApprove`.\n * @param request.isSponsored - Whether the transaction is sponsored.\n * @param request.rewardAccountId - The account ID of the reward subscription\n * to link.\n * @throws If `productType` is not Shield or `txMeta.type` is not\n * `shieldSubscriptionApprove`.\n * @returns void\n */\n async submitSubscriptionCryptoApproval(\n request: SubmitSubscriptionCryptoApprovalRequest,\n ): Promise<void> {\n const { productType, txMeta, isSponsored, rewardAccountId } = request;\n if (\n // Widen for the runtime guard: JS / unsound callers may still pass a\n // non-Shield product.\n (productType as ProductType) !== PRODUCT_TYPES.SHIELD ||\n txMeta.type !== TransactionType.shieldSubscriptionApprove\n ) {\n throw new Error(\n SubscriptionControllerErrorMessage.CryptoApprovalRequiresShieldApprove,\n );\n }\n\n const { chainId, rawTx } = txMeta;\n if (!chainId || !rawTx) {\n throw new Error('Chain ID or raw transaction not found');\n }\n\n const { pricing, lastSelectedPaymentMethod } = this.state;\n if (!pricing) {\n throw new Error('Subscription pricing not found');\n }\n if (!lastSelectedPaymentMethod) {\n throw new Error('Last selected payment method not found');\n }\n const lastSelectedPaymentMethodForProduct =\n lastSelectedPaymentMethod[productType];\n this.#assertIsPaymentMethodCrypto(lastSelectedPaymentMethodForProduct);\n\n const productPrice = this.#getProductPriceByProductAndPlan(\n productType,\n lastSelectedPaymentMethodForProduct.plan,\n );\n // get the latest subscriptions state before computing trial eligibility\n await this.#getSubscriptions({ refreshBenefits: false });\n const isTrialRequested = this.#getIsTrialRequested(\n [productType],\n lastSelectedPaymentMethodForProduct.plan,\n );\n const currentSubscription = this.getSubscriptionByProduct(productType);\n\n this.#assertValidSubscriptionStateForCryptoApproval({\n productType,\n });\n // if subscription exists, this transaction is for changing payment method\n const isChangePaymentMethod = Boolean(currentSubscription);\n\n if (isChangePaymentMethod) {\n await this.updatePaymentMethod({\n paymentType: PAYMENT_TYPES.byCrypto,\n subscriptionId: (currentSubscription as Subscription).id,\n chainId,\n payerAddress: txMeta.txParams.from as Hex,\n tokenSymbol: lastSelectedPaymentMethodForProduct.paymentTokenSymbol,\n rawTransaction: rawTx as Hex,\n recurringInterval: productPrice.interval,\n billingCycles: productPrice.minBillingCycles,\n });\n } else {\n const params: StartCryptoSubscriptionRequest = {\n products: [productType],\n isTrialRequested,\n recurringInterval: productPrice.interval,\n billingCycles: productPrice.minBillingCycles,\n chainId,\n payerAddress: txMeta.txParams.from as Hex,\n tokenSymbol: lastSelectedPaymentMethodForProduct.paymentTokenSymbol,\n rawTransaction: rawTx as Hex,\n cryptoAuthMethod: CRYPTO_AUTH_METHODS.ERC20_APPROVAL,\n isSponsored,\n useTestClock: lastSelectedPaymentMethodForProduct.useTestClock,\n rewardAccountId,\n };\n await this.startSubscriptionWithCrypto(params);\n }\n\n // update the subscriptions state after subscription created in server\n await this.#getSubscriptions({ refreshBenefits: false });\n }\n\n /**\n * Get transaction params to create crypto approve transaction for subscription payment\n *\n * @param request - The request object\n * @param request.chainId - The chain ID\n * @param request.tokenAddress - The address of the token\n * @param request.productType - The product type\n * @param request.interval - The interval\n * @returns The crypto approve transaction params\n */\n getCryptoApproveTransactionParams(\n request: GetCryptoApproveTransactionRequest,\n ): GetCryptoApproveTransactionResponse {\n const { pricing } = this.state;\n if (!pricing) {\n throw new Error('Subscription pricing not found');\n }\n const product = pricing.products.find(\n (productInfo) => productInfo.name === request.productType,\n );\n if (!product) {\n throw new Error('Product price not found');\n }\n\n const price = product.prices.find(\n (productPrice) => productPrice.interval === request.interval,\n );\n if (!price) {\n throw new Error('Price not found');\n }\n\n const chainsPaymentInfo = this.#findCryptoPaymentMethod(\n request.productType,\n CRYPTO_AUTH_METHODS.ERC20_APPROVAL,\n );\n if (!chainsPaymentInfo) {\n throw new Error('Chains payment info not found');\n }\n const chainPaymentInfo = chainsPaymentInfo.chains?.find(\n (chain) => chain.chainId === request.chainId,\n );\n if (!chainPaymentInfo) {\n throw new Error('Invalid chain id');\n }\n const tokenPaymentInfo = chainPaymentInfo.tokens.find(\n (token) =>\n token.address.toLowerCase() ===\n request.paymentTokenAddress.toLowerCase(),\n );\n if (!tokenPaymentInfo) {\n throw new Error('Invalid token address');\n }\n\n const tokenApproveAmount = this.getTokenApproveAmount(\n price,\n tokenPaymentInfo,\n );\n\n return {\n approveAmount: tokenApproveAmount,\n paymentAddress: chainPaymentInfo.paymentAddress,\n paymentTokenAddress: request.paymentTokenAddress,\n chainId: request.chainId,\n };\n }\n\n async updatePaymentMethod(\n opts: UpdatePaymentMethodOpts,\n ): Promise<UpdatePaymentMethodCardResponse | Subscription[]> {\n if (opts.paymentType === PAYMENT_TYPES.byCard) {\n const { paymentType, ...cardRequest } = opts;\n return await this.messenger.call(\n 'SubscriptionService:updatePaymentMethodCard',\n cardRequest,\n );\n } else if (opts.paymentType === PAYMENT_TYPES.byCrypto) {\n const { paymentType, ...cryptoRequest } = opts;\n await this.messenger.call(\n 'SubscriptionService:updatePaymentMethodCrypto',\n cryptoRequest,\n );\n return await this.getSubscriptions();\n }\n throw new Error('Invalid payment type');\n }\n\n /**\n * Gets the billing portal URL.\n *\n * @returns The billing portal URL\n */\n async getBillingPortalUrl(): Promise<BillingPortalResponse> {\n return await this.messenger.call('SubscriptionService:getBillingPortalUrl');\n }\n\n /**\n * Cache the last selected payment method for a specific product.\n *\n * @param request - The request object.\n * @param request.product - The product to cache the payment method for.\n * @param request.paymentMethod - The payment method to cache.\n * @param request.paymentMethod.type - The type of the payment method.\n * @param request.paymentMethod.paymentTokenAddress - The payment token address.\n * @param request.paymentMethod.plan - The plan of the payment method.\n */\n cacheLastSelectedPaymentMethod(\n request: CacheLastSelectedPaymentMethodRequest,\n ): void {\n const { product, paymentMethod } = request;\n if (\n paymentMethod.type === PAYMENT_TYPES.byCrypto &&\n (!paymentMethod.paymentTokenAddress || !paymentMethod.paymentTokenSymbol)\n ) {\n throw new Error(\n SubscriptionControllerErrorMessage.PaymentTokenAddressAndSymbolRequiredForCrypto,\n );\n }\n\n this.update((state) => {\n state.lastSelectedPaymentMethod = {\n ...state.lastSelectedPaymentMethod,\n [product]: paymentMethod,\n };\n });\n }\n\n /**\n * Clear the last selected payment method for a specific product.\n *\n * @param product - The product to clear the payment method for.\n */\n clearLastSelectedPaymentMethod(product: ProductType): void {\n this.update((state) => {\n if (state.lastSelectedPaymentMethod) {\n const { [product]: _, ...rest } = state.lastSelectedPaymentMethod;\n state.lastSelectedPaymentMethod =\n rest as typeof state.lastSelectedPaymentMethod;\n }\n });\n }\n\n /**\n * Submit sponsorship intents to the Subscription Service backend.\n *\n * This is intended to be used together with the crypto subscription flow.\n * When the user has enabled the smart transaction feature, we will sponsor the gas fees for the subscription approval transaction.\n *\n * @param request - Request object containing the address and products.\n * @example {\n * address: '0x1234567890123456789012345678901234567890',\n * products: [ProductType.Shield],\n * recurringInterval: RecurringInterval.Month,\n * billingCycles: 1,\n * }\n * @returns resolves to true if the sponsorship is supported and intents were submitted successfully, false if the chain does not support sponsorship or the user has already trialed\n * @throws If the crypto payment method or chain is missing from pricing\n */\n async submitSponsorshipIntents(\n request: SubmitSponsorshipIntentsMethodParams,\n ): Promise<boolean> {\n if (request.products.length === 0) {\n throw new Error(\n SubscriptionControllerErrorMessage.SubscriptionProductsEmpty,\n );\n }\n\n this.#assertIsUserNotSubscribed({ products: request.products });\n\n const selectedPaymentMethod =\n this.state.lastSelectedPaymentMethod?.[request.products[0]];\n this.#assertIsPaymentMethodCrypto(selectedPaymentMethod);\n\n const cryptoAuthMethod =\n selectedPaymentMethod.cryptoAuthMethod ??\n CRYPTO_AUTH_METHODS.ERC20_APPROVAL;\n const isEligibleForTrialedSponsorship =\n this.#getIsEligibleForTrialedSponsorship(\n request.chainId,\n request.products,\n cryptoAuthMethod,\n );\n if (!isEligibleForTrialedSponsorship) {\n return false;\n }\n\n const { paymentTokenSymbol, plan } = selectedPaymentMethod;\n const productPrice = this.#getProductPriceByProductAndPlan(\n // we only support one product at a time for now\n request.products[0],\n plan,\n );\n const billingCycles = productPrice.minBillingCycles;\n\n await this.messenger.call('SubscriptionService:submitSponsorshipIntents', {\n ...request,\n paymentTokenSymbol,\n billingCycles,\n recurringInterval: plan,\n });\n return true;\n }\n\n /**\n * Submit a user event from the UI. (e.g. shield modal viewed)\n *\n * @param request - Request object containing the event to submit.\n * @example { event: SubscriptionUserEvent.ShieldEntryModalViewed, cohort: 'post_tx' }\n */\n async submitUserEvent(request: SubmitUserEventRequest): Promise<void> {\n await this.messenger.call('SubscriptionService:submitUserEvent', request);\n }\n\n /**\n * Assign user to a cohort.\n *\n * @param request - Request object containing the cohort to assign the user to.\n * @example { cohort: 'post_tx' }\n */\n async assignUserToCohort(request: AssignCohortRequest): Promise<void> {\n await this.messenger.call(\n 'SubscriptionService:assignUserToCohort',\n request,\n );\n }\n\n /**\n * Link rewards to a subscription.\n *\n * @param request - Request object containing the reward subscription ID.\n * @param request.subscriptionId - The ID of the subscription to link rewards to.\n * @param request.rewardAccountId - The account ID of the reward subscription to link to the subscription.\n * @example { subscriptionId: '1234567890', rewardAccountId: 'eip155:1:0x1234567890123456789012345678901234567890' }\n * @returns Resolves when the rewards are linked successfully.\n */\n async linkRewards(\n request: LinkRewardsRequest & { subscriptionId: string },\n ): Promise<void> {\n // assert that the user is subscribed to the subscription\n this.#assertIsUserSubscribed({ subscriptionId: request.subscriptionId });\n\n // link rewards to the subscription\n const response = await this.messenger.call(\n 'SubscriptionService:linkRewards',\n {\n rewardAccountId: request.rewardAccountId,\n },\n );\n if (!response.success) {\n throw new Error(SubscriptionControllerErrorMessage.LinkRewardsFailed);\n }\n }\n\n async _executePoll(): Promise<void> {\n await this.getSubscriptions();\n }\n\n async #refreshBenefitsIfActive(refreshBenefits = true): Promise<void> {\n if (!this.#hasActiveMoneyAccountPlusSubscription()) {\n if (this.state.benefits) {\n this.update((state) => {\n state.benefits = undefined;\n });\n }\n return;\n }\n\n if (!refreshBenefits) {\n return;\n }\n\n try {\n await this.getBenefits();\n } catch (error) {\n log('Failed to refresh subscription benefits', error);\n }\n }\n\n /**\n * Calculate total subscription price amount (approval amount) from price info\n * e.g: $8 per month * 12 months min billing cycles = $96\n *\n * @param price - The price info\n * @returns The price amount\n */\n #getSubscriptionPriceAmount(price: ProductPrice): string {\n // no need to use BigInt since max unitDecimals are always 2 for price\n const amount = new BigNumber(price.unitAmount)\n .div(10 ** price.unitDecimals)\n .multipliedBy(price.minBillingCycles)\n .toString();\n return amount;\n }\n\n /**\n * Calculate minimum subscription balance amount from price info\n *\n * @param price - The price info\n * @returns The balance amount\n */\n #getSubscriptionBalanceAmount(price: ProductPrice): string {\n // no need to use BigInt since max unitDecimals are always 2 for price\n const amount = new BigNumber(price.unitAmount)\n .div(10 ** price.unitDecimals)\n .multipliedBy(price.minBillingCyclesForBalance)\n .toString();\n return amount;\n }\n\n /**\n * Calculate token approve amount from price info\n *\n * @param price - The price info\n * @param tokenPaymentInfo - The token price info\n * @returns The token approve amount\n */\n getTokenApproveAmount(\n price: ProductPrice,\n tokenPaymentInfo: TokenPaymentInfo,\n ): string {\n const conversionRate =\n tokenPaymentInfo.conversionRate?.[\n price.currency as keyof NonNullable<TokenPaymentInfo['conversionRate']>\n ];\n if (!conversionRate) {\n throw new Error('Conversion rate not found');\n }\n // price of the product\n const priceAmount = new BigNumber(this.#getSubscriptionPriceAmount(price));\n\n const tokenDecimal = new BigNumber(10).pow(tokenPaymentInfo.decimals);\n const tokenAmount = priceAmount\n .multipliedBy(tokenDecimal)\n .div(conversionRate);\n return tokenAmount.toFixed(0);\n }\n\n /**\n * Calculate token minimum balance amount from price info\n *\n * @param price - The price info\n * @param tokenPaymentInfo - The token price info\n * @returns The token balance amount\n */\n getTokenMinimumBalanceAmount(\n price: ProductPrice,\n tokenPaymentInfo: TokenPaymentInfo,\n ): string {\n const conversionRate =\n tokenPaymentInfo.conversionRate?.[\n price.currency as keyof NonNullable<TokenPaymentInfo['conversionRate']>\n ];\n if (!conversionRate) {\n throw new Error('Conversion rate not found');\n }\n const balanceAmount = new BigNumber(\n this.#getSubscriptionBalanceAmount(price),\n );\n\n const tokenDecimal = new BigNumber(10).pow(tokenPaymentInfo.decimals);\n const tokenAmount = balanceAmount\n .multipliedBy(tokenDecimal)\n .div(conversionRate);\n return tokenAmount.toFixed(0);\n }\n\n /**\n * Clears the subscription state and resets to default values.\n */\n clearState(): void {\n const defaultState = getDefaultSubscriptionControllerState();\n this.update(() => {\n return defaultState;\n });\n }\n\n /**\n * Triggers an access token refresh.\n */\n triggerAccessTokenRefresh(): void {\n // We perform a sign out to clear the access token from the authentication\n // controller. Next time the access token is requested, a new access token\n // will be fetched.\n this.messenger.call('AuthenticationController:performSignOut');\n }\n\n #getProductPriceByProductAndPlan(\n productType: ProductType,\n plan: RecurringInterval,\n ): ProductPrice {\n const { pricing } = this.state;\n const productPricing = pricing?.products.find(\n (product) => product.name === productType,\n );\n const productPrice = productPricing?.prices.find(\n (price) => price.interval === plan,\n );\n if (!productPrice) {\n throw new Error(SubscriptionControllerErrorMessage.ProductPriceNotFound);\n }\n return productPrice;\n }\n\n #assertValidSubscriptionStateForCryptoApproval({\n productType,\n }: {\n productType: ProductType;\n }): void {\n const subscription = this.state.subscriptions.find((sub) =>\n sub.products.some((product) => product.name === productType),\n );\n\n const isValid =\n !subscription ||\n (\n [\n SUBSCRIPTION_STATUSES.pastDue,\n SUBSCRIPTION_STATUSES.unpaid,\n SUBSCRIPTION_STATUSES.paused,\n SUBSCRIPTION_STATUSES.provisional,\n SUBSCRIPTION_STATUSES.active,\n SUBSCRIPTION_STATUSES.trialing,\n ] as SubscriptionStatus[]\n ).includes(subscription.status);\n if (!isValid) {\n throw new Error(\n SubscriptionControllerErrorMessage.SubscriptionNotValidForCryptoApproval,\n );\n }\n }\n\n #assertIsUserNotSubscribed({ products }: { products: ProductType[] }): void {\n const subscription = this.state.subscriptions.find((sub) =>\n sub.products.some((product) => products.includes(product.name)),\n );\n\n if (\n subscription &&\n ACTIVE_SUBSCRIPTION_STATUSES.includes(subscription.status)\n ) {\n throw new Error(SubscriptionControllerErrorMessage.UserAlreadySubscribed);\n }\n }\n\n #assertIsActiveMoneyAccountPlusSubscriber(): void {\n if (!this.#hasActiveMoneyAccountPlusSubscription()) {\n if (this.state.benefits) {\n this.update((state) => {\n state.benefits = undefined;\n });\n }\n throw new Error(SubscriptionControllerErrorMessage.UserNotSubscribed);\n }\n }\n\n #assertIsUserSubscribed(request: { subscriptionId: string }): void {\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 /**\n * Asserts that the value is a valid crypto payment method.\n *\n * After this assert, `cryptoAuthMethod` and `useTestClock` remain optional\n * because persisted cache entries may omit them.\n *\n * @param value - The value to assert.\n * @throws an error if the value is not a valid crypto payment method.\n */\n #assertIsPaymentMethodCrypto(\n value: CachedLastSelectedPaymentMethod | undefined,\n ): asserts value is CachedLastSelectedPaymentMethod & {\n type: typeof PAYMENT_TYPES.byCrypto;\n paymentTokenAddress: Hex;\n paymentTokenSymbol: string;\n } {\n if (\n value?.type !== PAYMENT_TYPES.byCrypto ||\n !value.paymentTokenAddress ||\n !value.paymentTokenSymbol\n ) {\n throw new Error(\n SubscriptionControllerErrorMessage.PaymentMethodNotCrypto,\n );\n }\n }\n\n #hasActiveMoneyAccountPlusSubscription(): boolean {\n return this.state.subscriptions.some(\n (subscription) =>\n subscription.products.some(\n (product) => product.name === PRODUCT_TYPES.MONEY_ACCOUNT_PLUS,\n ) && ACTIVE_SUBSCRIPTION_STATUSES.includes(subscription.status),\n );\n }\n\n /**\n * Determines if the user is eligible for trialed sponsorship for the given chain and products.\n * The user is eligible if the chain supports sponsorship and the user has not trialed the provided products before.\n *\n * @param chainId - The chain ID\n * @param products - The products to check eligibility for\n * @param cryptoAuthMethod - The crypto authorization method of the selected payment method\n * @returns True if the user is eligible for trialed sponsorship, false otherwise\n */\n #getIsEligibleForTrialedSponsorship(\n chainId: Hex,\n products: ProductType[],\n cryptoAuthMethod: CryptoAuthMethod,\n ): boolean {\n const isSponsorshipSupported = this.#getChainSupportsSponsorship(\n chainId,\n products[0],\n cryptoAuthMethod,\n );\n\n // verify if the user has trialed the provided products before\n const hasTrialedBefore = this.state.trialedProducts.some((product) =>\n products.includes(product),\n );\n\n return isSponsorshipSupported && !hasTrialedBefore;\n }\n\n /**\n * Whether a trial should be requested for the given products and plan.\n * True only when every product has `trialPeriodDays > 0` and has not\n * already been trialed.\n *\n * @param products - The products to check.\n * @param plan - The recurring interval to look up pricing for.\n * @returns Whether a trial should be requested.\n */\n #getIsTrialRequested(\n products: ProductType[],\n plan: RecurringInterval,\n ): boolean {\n return products.every((productType) => {\n if (this.state.trialedProducts.includes(productType)) {\n return false;\n }\n const productPrice = this.#getProductPriceByProductAndPlan(\n productType,\n plan,\n );\n return productPrice.trialPeriodDays > 0;\n });\n }\n\n #findCryptoPaymentMethod(\n productType: ProductType,\n cryptoAuthMethod: CryptoAuthMethod,\n ): PricingCryptoPaymentMethod | undefined {\n const matches: {\n method: PricingCryptoPaymentMethod;\n explicit: boolean;\n }[] = [];\n\n for (const paymentMethod of this.state.pricing?.paymentMethods ?? []) {\n if (paymentMethod.type !== PAYMENT_TYPES.byCrypto) {\n continue;\n }\n\n const resolved = this.#resolveCryptoPaymentMethodDefaults(paymentMethod);\n if (!resolved) {\n continue;\n }\n\n if (\n resolved.cryptoAuthMethod === cryptoAuthMethod &&\n resolved.products.includes(productType)\n ) {\n matches.push({\n method: paymentMethod,\n explicit: resolved.explicit,\n });\n }\n }\n\n if (matches.length === 0) {\n return undefined;\n }\n\n const explicitMatches = matches.filter((match) => match.explicit);\n const candidates = explicitMatches.length > 0 ? explicitMatches : matches;\n\n if (candidates.length > 1) {\n throw new Error('Multiple matching crypto payment methods found');\n }\n\n return candidates[0].method;\n }\n\n /**\n * Resolves omitted `products` / `cryptoAuthMethod` on a crypto pricing row.\n * Legacy Shield + `erc20_approval` defaults apply only when both fields are\n * absent. If `products` is present, the list must be non-empty and\n * `cryptoAuthMethod` must be explicit; otherwise the row is ignored.\n *\n * @param paymentMethod - The crypto pricing row.\n * @returns Resolved products and auth method, or `undefined` if the row is\n * incomplete.\n */\n #resolveCryptoPaymentMethodDefaults(\n paymentMethod: PricingCryptoPaymentMethod,\n ):\n | {\n products: ProductType[];\n cryptoAuthMethod: CryptoAuthMethod;\n explicit: boolean;\n }\n | undefined {\n const productsPresent = paymentMethod.products !== undefined;\n const authPresent = paymentMethod.cryptoAuthMethod !== undefined;\n\n if (!productsPresent && !authPresent) {\n return {\n products: [PRODUCT_TYPES.SHIELD],\n cryptoAuthMethod: CRYPTO_AUTH_METHODS.ERC20_APPROVAL,\n explicit: false,\n };\n }\n\n if (!paymentMethod.products?.length || !paymentMethod.cryptoAuthMethod) {\n return undefined;\n }\n\n return {\n products: paymentMethod.products,\n cryptoAuthMethod: paymentMethod.cryptoAuthMethod,\n explicit: true,\n };\n }\n\n /**\n * Whether the given chain supports sponsorship for the product and auth method.\n *\n * @param chainId - The chain ID\n * @param productType - The product type\n * @param cryptoAuthMethod - The crypto authorization method to look up\n * @returns True if the chain row has sponsorship enabled, false if it is explicitly not sponsored\n * @throws If the crypto payment method or chain row is missing from pricing\n */\n #getChainSupportsSponsorship(\n chainId: Hex,\n productType: ProductType,\n cryptoAuthMethod: CryptoAuthMethod,\n ): boolean {\n const cryptoPaymentInfo = this.#findCryptoPaymentMethod(\n productType,\n cryptoAuthMethod,\n );\n if (!cryptoPaymentInfo) {\n throw new Error('Chains payment info not found');\n }\n\n const chainPaymentInfo = cryptoPaymentInfo.chains?.find(\n (chain) => chain.chainId === chainId,\n );\n if (!chainPaymentInfo) {\n throw new Error('Invalid chain id');\n }\n return Boolean(chainPaymentInfo.isSponsorshipSupported);\n }\n\n /**\n * Determines whether two trialed products arrays are equal by comparing all products in the arrays.\n *\n * @param oldTrialedProducts - The first trialed products array to compare.\n * @param newTrialedProducts - The second trialed products array to compare.\n * @returns True if the trialed products arrays are equal, false otherwise.\n */\n #areTrialedProductsEqual(\n oldTrialedProducts: ProductType[],\n newTrialedProducts: ProductType[],\n ): boolean {\n return (\n oldTrialedProducts.length === newTrialedProducts?.length &&\n oldTrialedProducts.every((product) =>\n newTrialedProducts?.includes(product),\n )\n );\n }\n\n /**\n * Compares product entitlement maps without treating object key order as a\n * change. Insertion-order-sensitive `JSON.stringify` can otherwise treat an\n * equivalent API payload as different and trigger `performSignOut`.\n *\n * @param oldProductEntitlements - Stored product entitlements.\n * @param newProductEntitlements - Freshly fetched product entitlements.\n * @returns True if the maps are equal regardless of key order.\n */\n #areProductEntitlementsEqual(\n oldProductEntitlements?: ProductEntitlements,\n newProductEntitlements?: ProductEntitlements,\n ): boolean {\n return deepEqual(\n oldProductEntitlements ?? {},\n newProductEntitlements ?? {},\n );\n }\n\n /**\n * Determines whether two subscription arrays are equal by comparing all properties\n * of each subscription in the arrays.\n *\n * @param oldSubs - The first subscription array to compare.\n * @param newSubs - The second subscription array to compare.\n * @returns True if the subscription arrays are equal, false otherwise.\n */\n #areSubscriptionsEqual(\n oldSubs: Subscription[],\n newSubs: Subscription[],\n ): boolean {\n // Check if arrays have different lengths\n if (oldSubs.length !== newSubs.length) {\n return false;\n }\n\n // Sort both arrays by id to ensure consistent comparison\n const sortedOldSubs = [...oldSubs].sort((a, b) => a.id.localeCompare(b.id));\n const sortedNewSubs = [...newSubs].sort((a, b) => a.id.localeCompare(b.id));\n\n // Check if all subscriptions are equal\n return sortedOldSubs.every((oldSub, index) => {\n const newSub = sortedNewSubs[index];\n return this.#isSubscriptionEqual(oldSub, newSub);\n });\n }\n\n #isSubscriptionEqual(oldSub?: Subscription, newSub?: Subscription): boolean {\n // not equal if one is undefined and the other is defined\n if (!oldSub || !newSub) {\n if (!oldSub && !newSub) {\n return true;\n }\n return false;\n }\n\n return (\n this.#stringifySubscription(oldSub) ===\n this.#stringifySubscription(newSub)\n );\n }\n\n #stringifySubscription(subscription: Subscription): string {\n const subsWithSortedProducts = {\n ...subscription,\n // order the products by name\n products: [...subscription.products].sort((a, b) =>\n a.name.localeCompare(b.name),\n ),\n };\n\n return JSON.stringify(subsWithSortedProducts);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"SubscriptionService.d.ts","sourceRoot":"","sources":["../src/SubscriptionService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,4BAA4B,EAC5B,oCAAoC,EACpC,kCAAkC,EACnC,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAE7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAGlF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,OAAO,EACL,GAAG,EAIJ,MAAM,gBAAgB,CAAC;AAOxB,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,8CAA8C,CAAC;AAcrG,OAAO,KAAK,EACV,mBAAmB,EACnB,qBAAqB,EACrB,yBAAyB,EACzB,oCAAoC,EACpC,wBAAwB,EACxB,kBAAkB,EAClB,eAAe,EACf,8BAA8B,EAC9B,+BAA+B,EAC/B,wBAAwB,EACxB,yBAAyB,EACzB,+BAA+B,EAC/B,sBAAsB,EACtB,YAAY,EACZ,8BAA8B,EAC9B,4BAA4B,EAC5B,uBAAuB,EACvB,8BAA8B,EAC9B,+BAA+B,EAC/B,gCAAgC,EACjC,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,WAAW,wBAAwB,CAAC;AAEjD,eAAO,MAAM,gBAAgB,QAAS,GAAG,QAAQ,MAAM,KAAG,MACN,CAAC;AAoBrD,MAAM,MAAM,0CAA0C,GACpD,kCAAkC,CAAC,OAAO,WAAW,CAAC,CAAC;AAEzD,MAAM,MAAM,0BAA0B,GAClC,gCAAgC,GAChC,0CAA0C,CAAC;AAE/C,KAAK,cAAc,GACf,wBAAwB,CAAC,4CAA4C,GACrE,wBAAwB,CAAC,+CAA+C,CAAC;AAE7E,KAAK,aAAa,GAAG,KAAK,CAAC;AAE3B,MAAM,MAAM,oCAAoC,GAAG,4BAA4B,CAC7E,OAAO,WAAW,CACnB,CAAC;AAEF,MAAM,MAAM,4CAA4C,GACtD,oCAAoC,CAAC,OAAO,WAAW,CAAC,CAAC;AAE3D,MAAM,MAAM,yBAAyB,GACjC,oCAAoC,GACpC,4CAA4C,CAAC;AAEjD,MAAM,MAAM,4BAA4B,GAAG,SAAS,CAClD,OAAO,WAAW,EAClB,0BAA0B,GAAG,cAAc,EAC3C,yBAAyB,GAAG,aAAa,CAC1C,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,SAAS,EAAE,4BAA4B,CAAC;IACxC;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,KAAK,CAAC;IAC7B,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAC1C,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,aAAa,CAAC,EAAE,0BAA0B,CAAC;CAC5C,CAAC;AAkBF;;;;;;;GAOG;AACH,qBAAa,mBAAoB,SAAQ,eAAe,CACtD,OAAO,WAAW,EAClB,4BAA4B,CAC7B;;IAOC,YAAY,EACV,SAAS,EACT,aAAgC,EAChC,GAAa,EACb,gBAAgB,EAChB,iBAAsB,EACtB,aAAkB,GACnB,EAAE,0BAA0B,EAgB5B;IAED;;;;OAIG;IACG,gBAAgB,IAAI,OAAO,CAAC,wBAAwB,CAAC,CAY1D;IAED;;;;OAIG;IACG,WAAW,IAAI,OAAO,CAAC,4BAA4B,CAAC,CAczD;IAED;;;;;OAKG;IACG,kBAAkB,CACtB,MAAM,EAAE,yBAAyB,GAChC,OAAO,CAAC,YAAY,CAAC,CAiBvB;IAED;;;;;;OAMG;IACG,oBAAoB,CAAC,MAAM,EAAE;QACjC,cAAc,EAAE,MAAM,CAAC;KACxB,GAAG,OAAO,CAAC,YAAY,CAAC,CAgBxB;IAED;;;;;;OAMG;IACG,yBAAyB,CAC7B,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,yBAAyB,CAAC,CAqBpC;IAED;;;;;;;;OAQG;IACG,2BAA2B,CAC/B,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,+BAA+B,CAAC,CAuB1C;IAED;;;;;OAKG;IACG,uBAAuB,CAC3B,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,+BAA+B,CAAC,CAmB1C;IAED;;;;OAIG;IACG,yBAAyB,CAC7B,OAAO,EAAE,gCAAgC,GACxC,OAAO,CAAC,IAAI,CAAC,CAiBf;IAED;;;;;OAKG;IACG,6BAA6B,CACjC,OAAO,CAAC,EAAE,oCAAoC,GAC7C,OAAO,CAAC,uBAAuB,EAAE,CAAC,CA4BpC;IAED;;;;;OAKG;IACG,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAYpE;IAED;;;;;OAKG;IACG,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAYpE;IAED;;;;;;;;OAQG;IACG,wBAAwB,CAC5B,OAAO,EAAE,+BAA+B,GACvC,OAAO,CAAC,IAAI,CAAC,CAaf;IAED;;;;;;OAMG;IACG,WAAW,CACf,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,8BAA8B,CAAC,CAczC;IAED;;;;OAIG;IACG,UAAU,IAAI,OAAO,CAAC,eAAe,CAAC,CAY3C;IAED;;;;OAIG;IACG,mBAAmB,IAAI,OAAO,CAAC,qBAAqB,CAAC,CAY1D;CAoKF"}
1
+ {"version":3,"file":"SubscriptionService.d.ts","sourceRoot":"","sources":["../src/SubscriptionService.ts"],"names":[],"mappings":"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"}
@@ -111,11 +111,17 @@ export class SubscriptionService extends BaseDataService {
111
111
  profileKey,
112
112
  bearerToken,
113
113
  methodName: 'cancelSubscription',
114
- requestParams: params,
114
+ requestParams: {
115
+ subscriptionId: params.subscriptionId,
116
+ cancelAtPeriodEnd: params.cancelAtPeriodEnd,
117
+ cancellationReason: params.cancellationReason,
118
+ },
115
119
  path,
116
120
  method: 'POST',
117
121
  body: {
118
122
  cancelAtPeriodEnd: params.cancelAtPeriodEnd,
123
+ cancellationReason: params.cancellationReason,
124
+ cancellationFeedback: params.cancellationFeedback,
119
125
  },
120
126
  errorMessage: SubscriptionServiceErrorMessage.FailedToCancelSubscription,
121
127
  });