@metamask-previews/subscription-controller 6.2.2-preview-58a4a8b71 → 6.2.2-preview-4c8a5dfcb
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -1
- package/dist/SubscriptionController.cjs +18 -26
- package/dist/SubscriptionController.cjs.map +1 -1
- package/dist/SubscriptionController.d.cts +5 -9
- package/dist/SubscriptionController.d.cts.map +1 -1
- package/dist/SubscriptionController.d.mts +5 -9
- package/dist/SubscriptionController.d.mts.map +1 -1
- package/dist/SubscriptionController.mjs +18 -26
- package/dist/SubscriptionController.mjs.map +1 -1
- package/dist/SubscriptionService-method-action-types.cjs +7 -0
- package/dist/SubscriptionService-method-action-types.cjs.map +1 -0
- package/dist/SubscriptionService-method-action-types.d.cts +151 -0
- package/dist/SubscriptionService-method-action-types.d.cts.map +1 -0
- package/dist/SubscriptionService-method-action-types.d.mts +151 -0
- package/dist/SubscriptionService-method-action-types.d.mts.map +1 -0
- package/dist/SubscriptionService-method-action-types.mjs +6 -0
- package/dist/SubscriptionService-method-action-types.mjs.map +1 -0
- package/dist/SubscriptionService-structs.cjs +135 -0
- package/dist/SubscriptionService-structs.cjs.map +1 -0
- package/dist/SubscriptionService-structs.d.cts +773 -0
- package/dist/SubscriptionService-structs.d.cts.map +1 -0
- package/dist/SubscriptionService-structs.d.mts +773 -0
- package/dist/SubscriptionService-structs.d.mts.map +1 -0
- package/dist/SubscriptionService-structs.mjs +132 -0
- package/dist/SubscriptionService-structs.mjs.map +1 -0
- package/dist/SubscriptionService.cjs +257 -87
- package/dist/SubscriptionService.cjs.map +1 -1
- package/dist/SubscriptionService.d.cts +90 -10
- package/dist/SubscriptionService.d.cts.map +1 -1
- package/dist/SubscriptionService.d.mts +90 -10
- package/dist/SubscriptionService.d.mts.map +1 -1
- package/dist/SubscriptionService.mjs +257 -87
- package/dist/SubscriptionService.mjs.map +1 -1
- package/dist/index.cjs +3 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +4 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -2
|
@@ -1,15 +1,9 @@
|
|
|
1
|
-
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
-
};
|
|
7
1
|
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
2
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
3
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
4
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
5
|
};
|
|
12
|
-
var _SubscriptionController_instances,
|
|
6
|
+
var _SubscriptionController_instances, _SubscriptionController_getSubscriptionPriceAmount, _SubscriptionController_getSubscriptionBalanceAmount, _SubscriptionController_getProductPriceByProductAndPlan, _SubscriptionController_assertValidSubscriptionStateForCryptoApproval, _SubscriptionController_assertIsUserNotSubscribed, _SubscriptionController_assertIsUserSubscribed, _SubscriptionController_assertIsPaymentMethodCrypto, _SubscriptionController_getIsEligibleForTrialedSponsorship, _SubscriptionController_getChainSupportsSponsorship, _SubscriptionController_areTrialedProductsEqual, _SubscriptionController_areSubscriptionsEqual, _SubscriptionController_isSubscriptionEqual, _SubscriptionController_stringifySubscription;
|
|
13
7
|
import { StaticIntervalPollingController } from "@metamask/polling-controller";
|
|
14
8
|
import { TransactionType } from "@metamask/transaction-controller";
|
|
15
9
|
import { BigNumber } from "bignumber.js";
|
|
@@ -109,10 +103,10 @@ export class SubscriptionController extends StaticIntervalPollingController() {
|
|
|
109
103
|
* @param options - The options for the SubscriptionController.
|
|
110
104
|
* @param options.messenger - A restricted messenger.
|
|
111
105
|
* @param options.state - Initial state to set on this controller.
|
|
112
|
-
* @param options.subscriptionService - The subscription service for communicating with subscription server.
|
|
113
106
|
* @param options.pollingInterval - The polling interval to use for the subscription controller.
|
|
114
107
|
*/
|
|
115
|
-
constructor(
|
|
108
|
+
constructor(options) {
|
|
109
|
+
const { messenger, state, pollingInterval = DEFAULT_POLLING_INTERVAL, } = options;
|
|
116
110
|
super({
|
|
117
111
|
name: controllerName,
|
|
118
112
|
metadata: subscriptionControllerMetadata,
|
|
@@ -123,9 +117,7 @@ export class SubscriptionController extends StaticIntervalPollingController() {
|
|
|
123
117
|
messenger,
|
|
124
118
|
});
|
|
125
119
|
_SubscriptionController_instances.add(this);
|
|
126
|
-
_SubscriptionController_subscriptionService.set(this, void 0);
|
|
127
120
|
this.setIntervalLength(pollingInterval);
|
|
128
|
-
__classPrivateFieldSet(this, _SubscriptionController_subscriptionService, subscriptionService, "f");
|
|
129
121
|
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
130
122
|
}
|
|
131
123
|
/**
|
|
@@ -134,7 +126,7 @@ export class SubscriptionController extends StaticIntervalPollingController() {
|
|
|
134
126
|
* @returns The pricing information.
|
|
135
127
|
*/
|
|
136
128
|
async getPricing() {
|
|
137
|
-
const pricing = await
|
|
129
|
+
const pricing = await this.messenger.call('SubscriptionService:getPricing');
|
|
138
130
|
this.update((state) => {
|
|
139
131
|
state.pricing = pricing;
|
|
140
132
|
});
|
|
@@ -146,7 +138,7 @@ export class SubscriptionController extends StaticIntervalPollingController() {
|
|
|
146
138
|
const currentCustomerId = this.state.customerId;
|
|
147
139
|
const currentLastSubscription = this.state.lastSubscription;
|
|
148
140
|
const currentRewardAccountId = this.state.rewardAccountId;
|
|
149
|
-
const { customerId: newCustomerId, subscriptions: newSubscriptions, trialedProducts: newTrialedProducts, lastSubscription: newLastSubscription, rewardAccountId: newRewardAccountId, } = await
|
|
141
|
+
const { customerId: newCustomerId, subscriptions: newSubscriptions, trialedProducts: newTrialedProducts, lastSubscription: newLastSubscription, rewardAccountId: newRewardAccountId, } = await this.messenger.call('SubscriptionService:getSubscriptions');
|
|
150
142
|
// check if the new subscriptions are different from the current subscriptions
|
|
151
143
|
const areSubscriptionsEqual = __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_areSubscriptionsEqual).call(this, currentSubscriptions, newSubscriptions);
|
|
152
144
|
// check if the new trialed products are different from the current trialed products
|
|
@@ -190,11 +182,11 @@ export class SubscriptionController extends StaticIntervalPollingController() {
|
|
|
190
182
|
* @returns The subscriptions eligibilities.
|
|
191
183
|
*/
|
|
192
184
|
async getSubscriptionsEligibilities(request) {
|
|
193
|
-
return await
|
|
185
|
+
return await this.messenger.call('SubscriptionService:getSubscriptionsEligibilities', request);
|
|
194
186
|
}
|
|
195
187
|
async cancelSubscription(request) {
|
|
196
188
|
__classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_assertIsUserSubscribed).call(this, { subscriptionId: request.subscriptionId });
|
|
197
|
-
const cancelledSubscription = await
|
|
189
|
+
const cancelledSubscription = await this.messenger.call('SubscriptionService:cancelSubscription', request);
|
|
198
190
|
this.update((state) => {
|
|
199
191
|
state.subscriptions = state.subscriptions.map((subscription) => subscription.id === request.subscriptionId
|
|
200
192
|
? { ...subscription, ...cancelledSubscription }
|
|
@@ -204,7 +196,7 @@ export class SubscriptionController extends StaticIntervalPollingController() {
|
|
|
204
196
|
}
|
|
205
197
|
async unCancelSubscription(request) {
|
|
206
198
|
__classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_assertIsUserSubscribed).call(this, { subscriptionId: request.subscriptionId });
|
|
207
|
-
const uncancelledSubscription = await
|
|
199
|
+
const uncancelledSubscription = await this.messenger.call('SubscriptionService:unCancelSubscription', {
|
|
208
200
|
subscriptionId: request.subscriptionId,
|
|
209
201
|
});
|
|
210
202
|
this.update((state) => {
|
|
@@ -216,13 +208,13 @@ export class SubscriptionController extends StaticIntervalPollingController() {
|
|
|
216
208
|
}
|
|
217
209
|
async startShieldSubscriptionWithCard(request) {
|
|
218
210
|
__classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_assertIsUserNotSubscribed).call(this, { products: request.products });
|
|
219
|
-
const response = await
|
|
211
|
+
const response = await this.messenger.call('SubscriptionService:startSubscriptionWithCard', request);
|
|
220
212
|
// note: no need to trigger access token refresh after startSubscriptionWithCard request because this only return stripe checkout session url, subscription not created yet
|
|
221
213
|
return response;
|
|
222
214
|
}
|
|
223
215
|
async startSubscriptionWithCrypto(request) {
|
|
224
216
|
__classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_assertIsUserNotSubscribed).call(this, { products: request.products });
|
|
225
|
-
const response = await
|
|
217
|
+
const response = await this.messenger.call('SubscriptionService:startSubscriptionWithCrypto', request);
|
|
226
218
|
return response;
|
|
227
219
|
}
|
|
228
220
|
/**
|
|
@@ -338,11 +330,11 @@ export class SubscriptionController extends StaticIntervalPollingController() {
|
|
|
338
330
|
async updatePaymentMethod(opts) {
|
|
339
331
|
if (opts.paymentType === PAYMENT_TYPES.byCard) {
|
|
340
332
|
const { paymentType, ...cardRequest } = opts;
|
|
341
|
-
return await
|
|
333
|
+
return await this.messenger.call('SubscriptionService:updatePaymentMethodCard', cardRequest);
|
|
342
334
|
}
|
|
343
335
|
else if (opts.paymentType === PAYMENT_TYPES.byCrypto) {
|
|
344
336
|
const { paymentType, ...cryptoRequest } = opts;
|
|
345
|
-
await
|
|
337
|
+
await this.messenger.call('SubscriptionService:updatePaymentMethodCrypto', cryptoRequest);
|
|
346
338
|
return await this.getSubscriptions();
|
|
347
339
|
}
|
|
348
340
|
throw new Error('Invalid payment type');
|
|
@@ -353,7 +345,7 @@ export class SubscriptionController extends StaticIntervalPollingController() {
|
|
|
353
345
|
* @returns The billing portal URL
|
|
354
346
|
*/
|
|
355
347
|
async getBillingPortalUrl() {
|
|
356
|
-
return await
|
|
348
|
+
return await this.messenger.call('SubscriptionService:getBillingPortalUrl');
|
|
357
349
|
}
|
|
358
350
|
/**
|
|
359
351
|
* Cache the last selected payment method for a specific product.
|
|
@@ -422,7 +414,7 @@ export class SubscriptionController extends StaticIntervalPollingController() {
|
|
|
422
414
|
// we only support one product at a time for now
|
|
423
415
|
request.products[0], plan);
|
|
424
416
|
const billingCycles = productPrice.minBillingCycles;
|
|
425
|
-
await
|
|
417
|
+
await this.messenger.call('SubscriptionService:submitSponsorshipIntents', {
|
|
426
418
|
...request,
|
|
427
419
|
paymentTokenSymbol,
|
|
428
420
|
billingCycles,
|
|
@@ -437,7 +429,7 @@ export class SubscriptionController extends StaticIntervalPollingController() {
|
|
|
437
429
|
* @example { event: SubscriptionUserEvent.ShieldEntryModalViewed, cohort: 'post_tx' }
|
|
438
430
|
*/
|
|
439
431
|
async submitUserEvent(request) {
|
|
440
|
-
await
|
|
432
|
+
await this.messenger.call('SubscriptionService:submitUserEvent', request);
|
|
441
433
|
}
|
|
442
434
|
/**
|
|
443
435
|
* Assign user to a cohort.
|
|
@@ -446,7 +438,7 @@ export class SubscriptionController extends StaticIntervalPollingController() {
|
|
|
446
438
|
* @example { cohort: 'post_tx' }
|
|
447
439
|
*/
|
|
448
440
|
async assignUserToCohort(request) {
|
|
449
|
-
await
|
|
441
|
+
await this.messenger.call('SubscriptionService:assignUserToCohort', request);
|
|
450
442
|
}
|
|
451
443
|
/**
|
|
452
444
|
* Link rewards to a subscription.
|
|
@@ -461,7 +453,7 @@ export class SubscriptionController extends StaticIntervalPollingController() {
|
|
|
461
453
|
// assert that the user is subscribed to the subscription
|
|
462
454
|
__classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_assertIsUserSubscribed).call(this, { subscriptionId: request.subscriptionId });
|
|
463
455
|
// link rewards to the subscription
|
|
464
|
-
const response = await
|
|
456
|
+
const response = await this.messenger.call('SubscriptionService:linkRewards', {
|
|
465
457
|
rewardAccountId: request.rewardAccountId,
|
|
466
458
|
});
|
|
467
459
|
if (!response.success) {
|
|
@@ -529,7 +521,7 @@ export class SubscriptionController extends StaticIntervalPollingController() {
|
|
|
529
521
|
this.messenger.call('AuthenticationController:performSignOut');
|
|
530
522
|
}
|
|
531
523
|
}
|
|
532
|
-
|
|
524
|
+
_SubscriptionController_instances = new WeakSet(), _SubscriptionController_getSubscriptionPriceAmount = function _SubscriptionController_getSubscriptionPriceAmount(price) {
|
|
533
525
|
// no need to use BigInt since max unitDecimals are always 2 for price
|
|
534
526
|
const amount = new BigNumber(price.unitAmount)
|
|
535
527
|
.div(10 ** price.unitDecimals)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubscriptionController.mjs","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 type { TransactionMeta } from '@metamask/transaction-controller';\nimport { TransactionType } from '@metamask/transaction-controller';\nimport type { CaipAccountId, Hex } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport {\n ACTIVE_SUBSCRIPTION_STATUSES,\n controllerName,\n DEFAULT_POLLING_INTERVAL,\n SubscriptionControllerErrorMessage,\n} from './constants.js';\nimport type { SubscriptionControllerMethodActions } from './SubscriptionController-method-action-types.js';\nimport {\n PAYMENT_TYPES,\n PRODUCT_TYPES,\n SUBSCRIPTION_STATUSES,\n} from './types.js';\nimport type {\n AssignCohortRequest,\n BillingPortalResponse,\n GetCryptoApproveTransactionRequest,\n GetCryptoApproveTransactionResponse,\n GetSubscriptionsEligibilitiesRequest,\n ProductPrice,\n SubscriptionEligibility,\n StartCryptoSubscriptionRequest,\n SubmitUserEventRequest,\n TokenPaymentInfo,\n UpdatePaymentMethodCardResponse,\n UpdatePaymentMethodOpts,\n CachedLastSelectedPaymentMethod,\n SubmitSponsorshipIntentsMethodParams,\n RecurringInterval,\n SubscriptionStatus,\n LinkRewardsRequest,\n StartCryptoSubscriptionResponse,\n StartSubscriptionResponse,\n CancelSubscriptionRequest,\n} from './types.js';\nimport type {\n ISubscriptionService,\n PricingResponse,\n ProductType,\n StartSubscriptionRequest,\n Subscription,\n} from './types.js';\n\nexport type SubscriptionControllerState = {\n customerId?: string;\n trialedProducts: ProductType[];\n subscriptions: Subscription[];\n pricing?: PricingResponse;\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?: Record<\n ProductType,\n CachedLastSelectedPaymentMethod\n >;\n};\n\nexport type SubscriptionControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n SubscriptionControllerState\n>;\nexport type SubscriptionControllerActions =\n | SubscriptionControllerGetStateAction\n | SubscriptionControllerMethodActions;\n\nexport type AllowedActions =\n | AuthenticationController.AuthenticationControllerGetBearerTokenAction\n | AuthenticationController.AuthenticationControllerPerformSignOutAction;\n\n// Events\nexport type SubscriptionControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n SubscriptionControllerState\n>;\nexport type SubscriptionControllerEvents =\n SubscriptionControllerStateChangeEvent;\n\nexport type AllowedEvents =\n AuthenticationController.AuthenticationControllerStateChangeEvent;\n\n// Messenger\nexport type SubscriptionControllerMessenger = 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 * Subscription service to use for the subscription controller.\n */\n subscriptionService: ISubscriptionService;\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 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 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 'getSubscriptionByProduct',\n 'getSubscriptionsEligibilities',\n 'cancelSubscription',\n 'unCancelSubscription',\n 'startShieldSubscriptionWithCard',\n 'startSubscriptionWithCrypto',\n 'stopAllPolling',\n 'submitShieldSubscriptionCryptoApproval',\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 readonly #subscriptionService: ISubscriptionService;\n\n /**\n * Creates a new SubscriptionController instance.\n *\n * @param options - The options for the SubscriptionController.\n * @param options.messenger - A restricted messenger.\n * @param options.state - Initial state to set on this controller.\n * @param options.subscriptionService - The subscription service for communicating with subscription server.\n * @param options.pollingInterval - The polling interval to use for the subscription controller.\n */\n constructor({\n messenger,\n state,\n subscriptionService,\n pollingInterval = DEFAULT_POLLING_INTERVAL,\n }: SubscriptionControllerOptions) {\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.#subscriptionService = subscriptionService;\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.#subscriptionService.getPricing();\n this.update((state) => {\n state.pricing = pricing;\n });\n return pricing;\n }\n\n async getSubscriptions(): 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\n const {\n customerId: newCustomerId,\n subscriptions: newSubscriptions,\n trialedProducts: newTrialedProducts,\n lastSubscription: newLastSubscription,\n rewardAccountId: newRewardAccountId,\n } = await this.#subscriptionService.getSubscriptions();\n\n // check if the new subscriptions are different from the current subscriptions\n const areSubscriptionsEqual = this.#areSubscriptionsEqual(\n currentSubscriptions,\n newSubscriptions,\n );\n // check if the new trialed products are different from the current trialed products\n const areTrialedProductsEqual = this.#areTrialedProductsEqual(\n currentTrialedProducts,\n newTrialedProducts,\n );\n // check if the new last subscription is different from the current last subscription\n const isLastSubscriptionEqual = this.#isSubscriptionEqual(\n currentLastSubscription,\n newLastSubscription,\n );\n\n const areCustomerIdsEqual = currentCustomerId === newCustomerId;\n const areRewardAccountIdsEqual =\n currentRewardAccountId === newRewardAccountId;\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 if (\n !areSubscriptionsEqual ||\n !isLastSubscriptionEqual ||\n !areTrialedProductsEqual ||\n !areCustomerIdsEqual ||\n !areRewardAccountIdsEqual\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 });\n // trigger access token refresh to ensure the user has the latest access token if subscription state change\n this.triggerAccessTokenRefresh();\n }\n\n return newSubscriptions;\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.#subscriptionService.getSubscriptionsEligibilities(\n request,\n );\n }\n\n async cancelSubscription(request: CancelSubscriptionRequest): Promise<void> {\n this.#assertIsUserSubscribed({ subscriptionId: request.subscriptionId });\n\n const cancelledSubscription =\n await this.#subscriptionService.cancelSubscription(request);\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 this.triggerAccessTokenRefresh();\n }\n\n async unCancelSubscription(request: {\n subscriptionId: string;\n }): Promise<void> {\n this.#assertIsUserSubscribed({ subscriptionId: request.subscriptionId });\n\n const uncancelledSubscription =\n await this.#subscriptionService.unCancelSubscription({\n subscriptionId: request.subscriptionId,\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 this.triggerAccessTokenRefresh();\n }\n\n async startShieldSubscriptionWithCard(\n request: StartSubscriptionRequest,\n ): Promise<StartSubscriptionResponse> {\n this.#assertIsUserNotSubscribed({ products: request.products });\n\n const response =\n await this.#subscriptionService.startSubscriptionWithCard(request);\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 async startSubscriptionWithCrypto(\n request: StartCryptoSubscriptionRequest,\n ): Promise<StartCryptoSubscriptionResponse> {\n this.#assertIsUserNotSubscribed({ products: request.products });\n const response =\n await this.#subscriptionService.startSubscriptionWithCrypto(request);\n\n return response;\n }\n\n /**\n * Handles shield subscription crypto approval transactions.\n *\n * @param txMeta - The transaction metadata.\n * @param isSponsored - Whether the transaction is sponsored.\n * @param rewardAccountId - The account ID of the reward subscription to link to the shield subscription.\n * @returns void\n */\n async submitShieldSubscriptionCryptoApproval(\n txMeta: TransactionMeta,\n isSponsored?: boolean,\n rewardAccountId?: CaipAccountId,\n ): Promise<void> {\n if (txMeta.type !== TransactionType.shieldSubscriptionApprove) {\n return;\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, trialedProducts, 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 lastSelectedPaymentMethodShield =\n lastSelectedPaymentMethod[PRODUCT_TYPES.SHIELD];\n this.#assertIsPaymentMethodCrypto(lastSelectedPaymentMethodShield);\n\n const productPrice = this.#getProductPriceByProductAndPlan(\n PRODUCT_TYPES.SHIELD,\n lastSelectedPaymentMethodShield.plan,\n );\n const isTrialed = trialedProducts?.includes(PRODUCT_TYPES.SHIELD);\n // get the latest subscriptions state to check if the user has an active shield subscription\n await this.getSubscriptions();\n const currentSubscription = this.state.subscriptions.find((subscription) =>\n subscription.products.some(\n (product) => product.name === PRODUCT_TYPES.SHIELD,\n ),\n );\n\n this.#assertValidSubscriptionStateForCryptoApproval({\n productType: PRODUCT_TYPES.SHIELD,\n });\n // if shield 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: lastSelectedPaymentMethodShield.paymentTokenSymbol,\n rawTransaction: rawTx as Hex,\n recurringInterval: productPrice.interval,\n billingCycles: productPrice.minBillingCycles,\n });\n } else {\n const params = {\n products: [PRODUCT_TYPES.SHIELD],\n isTrialRequested: !isTrialed,\n recurringInterval: productPrice.interval,\n billingCycles: productPrice.minBillingCycles,\n chainId,\n payerAddress: txMeta.txParams.from as Hex,\n tokenSymbol: lastSelectedPaymentMethodShield.paymentTokenSymbol,\n rawTransaction: rawTx as Hex,\n isSponsored,\n useTestClock: lastSelectedPaymentMethodShield.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();\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 = pricing.paymentMethods.find(\n (paymentMethod) => paymentMethod.type === PAYMENT_TYPES.byCrypto,\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.#subscriptionService.updatePaymentMethodCard(\n cardRequest,\n );\n } else if (opts.paymentType === PAYMENT_TYPES.byCrypto) {\n const { paymentType, ...cryptoRequest } = opts;\n await this.#subscriptionService.updatePaymentMethodCrypto(cryptoRequest);\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.#subscriptionService.getBillingPortalUrl();\n }\n\n /**\n * Cache the last selected payment method for a specific product.\n *\n * @param product - The product to cache the payment method for.\n * @param paymentMethod - The payment method to cache.\n * @param paymentMethod.type - The type of the payment method.\n * @param paymentMethod.paymentTokenAddress - The payment token address.\n * @param paymentMethod.plan - The plan of the payment method.\n * @param paymentMethod.product - The product of the payment method.\n */\n cacheLastSelectedPaymentMethod(\n product: ProductType,\n paymentMethod: CachedLastSelectedPaymentMethod,\n ): void {\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 otherwise\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 isEligibleForTrialedSponsorship =\n this.#getIsEligibleForTrialedSponsorship(\n request.chainId,\n request.products,\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.#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.#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.#subscriptionService.assignUserToCohort(request);\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.#subscriptionService.linkRewards({\n rewardAccountId: request.rewardAccountId,\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 /**\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 typeof 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 typeof 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 #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 * @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 Required<CachedLastSelectedPaymentMethod> {\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 /**\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 * @returns True if the user is eligible for trialed sponsorship, false otherwise\n */\n #getIsEligibleForTrialedSponsorship(\n chainId: Hex,\n products: ProductType[],\n ): boolean {\n const isSponsorshipSupported = this.#getChainSupportsSponsorship(chainId);\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 #getChainSupportsSponsorship(chainId: Hex): boolean {\n const cryptoPaymentInfo = this.state.pricing?.paymentMethods.find(\n (paymentMethod) => paymentMethod.type === PAYMENT_TYPES.byCrypto,\n );\n\n const isSponsorshipSupported = cryptoPaymentInfo?.chains?.find(\n (chain) => chain.chainId === chainId,\n )?.isSponsorshipSupported;\n return Boolean(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 * 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.mjs","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 type { TransactionMeta } from '@metamask/transaction-controller';\nimport { TransactionType } from '@metamask/transaction-controller';\nimport type { CaipAccountId, Hex } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport {\n ACTIVE_SUBSCRIPTION_STATUSES,\n controllerName,\n DEFAULT_POLLING_INTERVAL,\n SubscriptionControllerErrorMessage,\n} from './constants.js';\nimport type { SubscriptionControllerMethodActions } from './SubscriptionController-method-action-types.js';\nimport type {\n SubscriptionServiceAssignUserToCohortAction,\n SubscriptionServiceCancelSubscriptionAction,\n SubscriptionServiceGetBillingPortalUrlAction,\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 PAYMENT_TYPES,\n PRODUCT_TYPES,\n SUBSCRIPTION_STATUSES,\n} from './types.js';\nimport type {\n AssignCohortRequest,\n BillingPortalResponse,\n GetCryptoApproveTransactionRequest,\n GetCryptoApproveTransactionResponse,\n GetSubscriptionsEligibilitiesRequest,\n ProductPrice,\n SubscriptionEligibility,\n StartCryptoSubscriptionRequest,\n SubmitUserEventRequest,\n TokenPaymentInfo,\n UpdatePaymentMethodCardResponse,\n UpdatePaymentMethodOpts,\n CachedLastSelectedPaymentMethod,\n SubmitSponsorshipIntentsMethodParams,\n RecurringInterval,\n SubscriptionStatus,\n LinkRewardsRequest,\n StartCryptoSubscriptionResponse,\n StartSubscriptionResponse,\n CancelSubscriptionRequest,\n} from './types.js';\nimport type {\n PricingResponse,\n ProductType,\n StartSubscriptionRequest,\n Subscription,\n} from './types.js';\n\nexport type SubscriptionControllerState = {\n customerId?: string;\n trialedProducts: ProductType[];\n subscriptions: Subscription[];\n pricing?: PricingResponse;\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?: Record<\n ProductType,\n 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 | 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 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 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 'getSubscriptionByProduct',\n 'getSubscriptionsEligibilities',\n 'cancelSubscription',\n 'unCancelSubscription',\n 'startShieldSubscriptionWithCard',\n 'startSubscriptionWithCrypto',\n 'stopAllPolling',\n 'submitShieldSubscriptionCryptoApproval',\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 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\n const {\n customerId: newCustomerId,\n subscriptions: newSubscriptions,\n trialedProducts: newTrialedProducts,\n lastSubscription: newLastSubscription,\n rewardAccountId: newRewardAccountId,\n } = await this.messenger.call('SubscriptionService:getSubscriptions');\n\n // check if the new subscriptions are different from the current subscriptions\n const areSubscriptionsEqual = this.#areSubscriptionsEqual(\n currentSubscriptions,\n newSubscriptions,\n );\n // check if the new trialed products are different from the current trialed products\n const areTrialedProductsEqual = this.#areTrialedProductsEqual(\n currentTrialedProducts,\n newTrialedProducts,\n );\n // check if the new last subscription is different from the current last subscription\n const isLastSubscriptionEqual = this.#isSubscriptionEqual(\n currentLastSubscription,\n newLastSubscription,\n );\n\n const areCustomerIdsEqual = currentCustomerId === newCustomerId;\n const areRewardAccountIdsEqual =\n currentRewardAccountId === newRewardAccountId;\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 if (\n !areSubscriptionsEqual ||\n !isLastSubscriptionEqual ||\n !areTrialedProductsEqual ||\n !areCustomerIdsEqual ||\n !areRewardAccountIdsEqual\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 });\n // trigger access token refresh to ensure the user has the latest access token if subscription state change\n this.triggerAccessTokenRefresh();\n }\n\n return newSubscriptions;\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 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 this.triggerAccessTokenRefresh();\n }\n\n async startShieldSubscriptionWithCard(\n request: StartSubscriptionRequest,\n ): Promise<StartSubscriptionResponse> {\n this.#assertIsUserNotSubscribed({ products: request.products });\n\n const response = await this.messenger.call(\n 'SubscriptionService:startSubscriptionWithCard',\n request,\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 async startSubscriptionWithCrypto(\n request: StartCryptoSubscriptionRequest,\n ): Promise<StartCryptoSubscriptionResponse> {\n this.#assertIsUserNotSubscribed({ products: request.products });\n const response = await this.messenger.call(\n 'SubscriptionService:startSubscriptionWithCrypto',\n request,\n );\n\n return response;\n }\n\n /**\n * Handles shield subscription crypto approval transactions.\n *\n * @param txMeta - The transaction metadata.\n * @param isSponsored - Whether the transaction is sponsored.\n * @param rewardAccountId - The account ID of the reward subscription to link to the shield subscription.\n * @returns void\n */\n async submitShieldSubscriptionCryptoApproval(\n txMeta: TransactionMeta,\n isSponsored?: boolean,\n rewardAccountId?: CaipAccountId,\n ): Promise<void> {\n if (txMeta.type !== TransactionType.shieldSubscriptionApprove) {\n return;\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, trialedProducts, 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 lastSelectedPaymentMethodShield =\n lastSelectedPaymentMethod[PRODUCT_TYPES.SHIELD];\n this.#assertIsPaymentMethodCrypto(lastSelectedPaymentMethodShield);\n\n const productPrice = this.#getProductPriceByProductAndPlan(\n PRODUCT_TYPES.SHIELD,\n lastSelectedPaymentMethodShield.plan,\n );\n const isTrialed = trialedProducts?.includes(PRODUCT_TYPES.SHIELD);\n // get the latest subscriptions state to check if the user has an active shield subscription\n await this.getSubscriptions();\n const currentSubscription = this.state.subscriptions.find((subscription) =>\n subscription.products.some(\n (product) => product.name === PRODUCT_TYPES.SHIELD,\n ),\n );\n\n this.#assertValidSubscriptionStateForCryptoApproval({\n productType: PRODUCT_TYPES.SHIELD,\n });\n // if shield 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: lastSelectedPaymentMethodShield.paymentTokenSymbol,\n rawTransaction: rawTx as Hex,\n recurringInterval: productPrice.interval,\n billingCycles: productPrice.minBillingCycles,\n });\n } else {\n const params = {\n products: [PRODUCT_TYPES.SHIELD],\n isTrialRequested: !isTrialed,\n recurringInterval: productPrice.interval,\n billingCycles: productPrice.minBillingCycles,\n chainId,\n payerAddress: txMeta.txParams.from as Hex,\n tokenSymbol: lastSelectedPaymentMethodShield.paymentTokenSymbol,\n rawTransaction: rawTx as Hex,\n isSponsored,\n useTestClock: lastSelectedPaymentMethodShield.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();\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 = pricing.paymentMethods.find(\n (paymentMethod) => paymentMethod.type === PAYMENT_TYPES.byCrypto,\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 product - The product to cache the payment method for.\n * @param paymentMethod - The payment method to cache.\n * @param paymentMethod.type - The type of the payment method.\n * @param paymentMethod.paymentTokenAddress - The payment token address.\n * @param paymentMethod.plan - The plan of the payment method.\n * @param paymentMethod.product - The product of the payment method.\n */\n cacheLastSelectedPaymentMethod(\n product: ProductType,\n paymentMethod: CachedLastSelectedPaymentMethod,\n ): void {\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 otherwise\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 isEligibleForTrialedSponsorship =\n this.#getIsEligibleForTrialedSponsorship(\n request.chainId,\n request.products,\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 /**\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 typeof 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 typeof 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 #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 * @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 Required<CachedLastSelectedPaymentMethod> {\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 /**\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 * @returns True if the user is eligible for trialed sponsorship, false otherwise\n */\n #getIsEligibleForTrialedSponsorship(\n chainId: Hex,\n products: ProductType[],\n ): boolean {\n const isSponsorshipSupported = this.#getChainSupportsSponsorship(chainId);\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 #getChainSupportsSponsorship(chainId: Hex): boolean {\n const cryptoPaymentInfo = this.state.pricing?.paymentMethods.find(\n (paymentMethod) => paymentMethod.type === PAYMENT_TYPES.byCrypto,\n );\n\n const isSponsorshipSupported = cryptoPaymentInfo?.chains?.find(\n (chain) => chain.chainId === chainId,\n )?.isSponsorshipSupported;\n return Boolean(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 * 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"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubscriptionService-method-action-types.cjs","sourceRoot":"","sources":["../src/SubscriptionService-method-action-types.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { SubscriptionService } from './SubscriptionService.js';\n\n/**\n * Fetches the user's subscriptions.\n *\n * @returns The subscriptions response.\n */\nexport type SubscriptionServiceGetSubscriptionsAction = {\n type: `SubscriptionService:getSubscriptions`;\n handler: SubscriptionService['getSubscriptions'];\n};\n\n/**\n * Cancels a subscription.\n *\n * @param params - The cancel subscription request.\n * @returns The updated subscription.\n */\nexport type SubscriptionServiceCancelSubscriptionAction = {\n type: `SubscriptionService:cancelSubscription`;\n handler: SubscriptionService['cancelSubscription'];\n};\n\n/**\n * Reverses a pending subscription cancellation.\n *\n * @param params - The uncancel subscription request.\n * @param params.subscriptionId - The subscription ID to uncancel.\n * @returns The updated subscription.\n */\nexport type SubscriptionServiceUnCancelSubscriptionAction = {\n type: `SubscriptionService:unCancelSubscription`;\n handler: SubscriptionService['unCancelSubscription'];\n};\n\n/**\n * Starts a subscription with a card payment method.\n *\n * @param request - The start subscription request.\n * @returns The checkout session response.\n */\nexport type SubscriptionServiceStartSubscriptionWithCardAction = {\n type: `SubscriptionService:startSubscriptionWithCard`;\n handler: SubscriptionService['startSubscriptionWithCard'];\n};\n\n/**\n * Starts a subscription with a crypto payment method.\n *\n * @param request - The start crypto subscription request.\n * @returns The created subscription response.\n */\nexport type SubscriptionServiceStartSubscriptionWithCryptoAction = {\n type: `SubscriptionService:startSubscriptionWithCrypto`;\n handler: SubscriptionService['startSubscriptionWithCrypto'];\n};\n\n/**\n * Updates a subscription's card payment method.\n *\n * @param request - The update payment method request.\n * @returns The redirect URL response.\n */\nexport type SubscriptionServiceUpdatePaymentMethodCardAction = {\n type: `SubscriptionService:updatePaymentMethodCard`;\n handler: SubscriptionService['updatePaymentMethodCard'];\n};\n\n/**\n * Updates a subscription's crypto payment method.\n *\n * @param request - The update payment method request.\n */\nexport type SubscriptionServiceUpdatePaymentMethodCryptoAction = {\n type: `SubscriptionService:updatePaymentMethodCrypto`;\n handler: SubscriptionService['updatePaymentMethodCrypto'];\n};\n\n/**\n * Get the eligibility for a shield subscription.\n *\n * @param request - Optional request object containing user balance category to check cohort eligibility\n * @returns The eligibility for a shield subscription\n */\nexport type SubscriptionServiceGetSubscriptionsEligibilitiesAction = {\n type: `SubscriptionService:getSubscriptionsEligibilities`;\n handler: SubscriptionService['getSubscriptionsEligibilities'];\n};\n\n/**\n * Submit a user event. (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 */\nexport type SubscriptionServiceSubmitUserEventAction = {\n type: `SubscriptionService:submitUserEvent`;\n handler: SubscriptionService['submitUserEvent'];\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 */\nexport type SubscriptionServiceAssignUserToCohortAction = {\n type: `SubscriptionService:assignUserToCohort`;\n handler: SubscriptionService['assignUserToCohort'];\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 { address: '0x1234567890123456789012345678901234567890', products: [ProductType.Shield] }\n */\nexport type SubscriptionServiceSubmitSponsorshipIntentsAction = {\n type: `SubscriptionService:submitSponsorshipIntents`;\n handler: SubscriptionService['submitSponsorshipIntents'];\n};\n\n/**\n * Link rewards to a subscription.\n *\n * @param request - Request object containing the reward account ID.\n * @example { rewardAccountId: 'eip155:1:0x1234567890123456789012345678901234567890' }\n * @returns The response from the API.\n */\nexport type SubscriptionServiceLinkRewardsAction = {\n type: `SubscriptionService:linkRewards`;\n handler: SubscriptionService['linkRewards'];\n};\n\n/**\n * Fetches subscription pricing information.\n *\n * @returns The pricing response.\n */\nexport type SubscriptionServiceGetPricingAction = {\n type: `SubscriptionService:getPricing`;\n handler: SubscriptionService['getPricing'];\n};\n\n/**\n * Fetches the billing portal URL.\n *\n * @returns The billing portal response.\n */\nexport type SubscriptionServiceGetBillingPortalUrlAction = {\n type: `SubscriptionService:getBillingPortalUrl`;\n handler: SubscriptionService['getBillingPortalUrl'];\n};\n\n/**\n * Union of all SubscriptionService action types.\n */\nexport type SubscriptionServiceMethodActions =\n | SubscriptionServiceGetSubscriptionsAction\n | SubscriptionServiceCancelSubscriptionAction\n | SubscriptionServiceUnCancelSubscriptionAction\n | SubscriptionServiceStartSubscriptionWithCardAction\n | SubscriptionServiceStartSubscriptionWithCryptoAction\n | SubscriptionServiceUpdatePaymentMethodCardAction\n | SubscriptionServiceUpdatePaymentMethodCryptoAction\n | SubscriptionServiceGetSubscriptionsEligibilitiesAction\n | SubscriptionServiceSubmitUserEventAction\n | SubscriptionServiceAssignUserToCohortAction\n | SubscriptionServiceSubmitSponsorshipIntentsAction\n | SubscriptionServiceLinkRewardsAction\n | SubscriptionServiceGetPricingAction\n | SubscriptionServiceGetBillingPortalUrlAction;\n"]}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is auto generated.
|
|
3
|
+
* Do not edit manually.
|
|
4
|
+
*/
|
|
5
|
+
import type { SubscriptionService } from "./SubscriptionService.cjs";
|
|
6
|
+
/**
|
|
7
|
+
* Fetches the user's subscriptions.
|
|
8
|
+
*
|
|
9
|
+
* @returns The subscriptions response.
|
|
10
|
+
*/
|
|
11
|
+
export type SubscriptionServiceGetSubscriptionsAction = {
|
|
12
|
+
type: `SubscriptionService:getSubscriptions`;
|
|
13
|
+
handler: SubscriptionService['getSubscriptions'];
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Cancels a subscription.
|
|
17
|
+
*
|
|
18
|
+
* @param params - The cancel subscription request.
|
|
19
|
+
* @returns The updated subscription.
|
|
20
|
+
*/
|
|
21
|
+
export type SubscriptionServiceCancelSubscriptionAction = {
|
|
22
|
+
type: `SubscriptionService:cancelSubscription`;
|
|
23
|
+
handler: SubscriptionService['cancelSubscription'];
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Reverses a pending subscription cancellation.
|
|
27
|
+
*
|
|
28
|
+
* @param params - The uncancel subscription request.
|
|
29
|
+
* @param params.subscriptionId - The subscription ID to uncancel.
|
|
30
|
+
* @returns The updated subscription.
|
|
31
|
+
*/
|
|
32
|
+
export type SubscriptionServiceUnCancelSubscriptionAction = {
|
|
33
|
+
type: `SubscriptionService:unCancelSubscription`;
|
|
34
|
+
handler: SubscriptionService['unCancelSubscription'];
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Starts a subscription with a card payment method.
|
|
38
|
+
*
|
|
39
|
+
* @param request - The start subscription request.
|
|
40
|
+
* @returns The checkout session response.
|
|
41
|
+
*/
|
|
42
|
+
export type SubscriptionServiceStartSubscriptionWithCardAction = {
|
|
43
|
+
type: `SubscriptionService:startSubscriptionWithCard`;
|
|
44
|
+
handler: SubscriptionService['startSubscriptionWithCard'];
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Starts a subscription with a crypto payment method.
|
|
48
|
+
*
|
|
49
|
+
* @param request - The start crypto subscription request.
|
|
50
|
+
* @returns The created subscription response.
|
|
51
|
+
*/
|
|
52
|
+
export type SubscriptionServiceStartSubscriptionWithCryptoAction = {
|
|
53
|
+
type: `SubscriptionService:startSubscriptionWithCrypto`;
|
|
54
|
+
handler: SubscriptionService['startSubscriptionWithCrypto'];
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Updates a subscription's card payment method.
|
|
58
|
+
*
|
|
59
|
+
* @param request - The update payment method request.
|
|
60
|
+
* @returns The redirect URL response.
|
|
61
|
+
*/
|
|
62
|
+
export type SubscriptionServiceUpdatePaymentMethodCardAction = {
|
|
63
|
+
type: `SubscriptionService:updatePaymentMethodCard`;
|
|
64
|
+
handler: SubscriptionService['updatePaymentMethodCard'];
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Updates a subscription's crypto payment method.
|
|
68
|
+
*
|
|
69
|
+
* @param request - The update payment method request.
|
|
70
|
+
*/
|
|
71
|
+
export type SubscriptionServiceUpdatePaymentMethodCryptoAction = {
|
|
72
|
+
type: `SubscriptionService:updatePaymentMethodCrypto`;
|
|
73
|
+
handler: SubscriptionService['updatePaymentMethodCrypto'];
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Get the eligibility for a shield subscription.
|
|
77
|
+
*
|
|
78
|
+
* @param request - Optional request object containing user balance category to check cohort eligibility
|
|
79
|
+
* @returns The eligibility for a shield subscription
|
|
80
|
+
*/
|
|
81
|
+
export type SubscriptionServiceGetSubscriptionsEligibilitiesAction = {
|
|
82
|
+
type: `SubscriptionService:getSubscriptionsEligibilities`;
|
|
83
|
+
handler: SubscriptionService['getSubscriptionsEligibilities'];
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Submit a user event. (e.g. shield modal viewed)
|
|
87
|
+
*
|
|
88
|
+
* @param request - Request object containing the event to submit.
|
|
89
|
+
* @example { event: SubscriptionUserEvent.ShieldEntryModalViewed, cohort: 'post_tx' }
|
|
90
|
+
*/
|
|
91
|
+
export type SubscriptionServiceSubmitUserEventAction = {
|
|
92
|
+
type: `SubscriptionService:submitUserEvent`;
|
|
93
|
+
handler: SubscriptionService['submitUserEvent'];
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Assign user to a cohort.
|
|
97
|
+
*
|
|
98
|
+
* @param request - Request object containing the cohort to assign the user to.
|
|
99
|
+
* @example { cohort: 'post_tx' }
|
|
100
|
+
*/
|
|
101
|
+
export type SubscriptionServiceAssignUserToCohortAction = {
|
|
102
|
+
type: `SubscriptionService:assignUserToCohort`;
|
|
103
|
+
handler: SubscriptionService['assignUserToCohort'];
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Submit sponsorship intents to the Subscription Service backend.
|
|
107
|
+
*
|
|
108
|
+
* This is intended to be used together with the crypto subscription flow.
|
|
109
|
+
* When the user has enabled the smart transaction feature, we will sponsor the gas fees for the subscription approval transaction.
|
|
110
|
+
*
|
|
111
|
+
* @param request - Request object containing the address and products.
|
|
112
|
+
* @example { address: '0x1234567890123456789012345678901234567890', products: [ProductType.Shield] }
|
|
113
|
+
*/
|
|
114
|
+
export type SubscriptionServiceSubmitSponsorshipIntentsAction = {
|
|
115
|
+
type: `SubscriptionService:submitSponsorshipIntents`;
|
|
116
|
+
handler: SubscriptionService['submitSponsorshipIntents'];
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* Link rewards to a subscription.
|
|
120
|
+
*
|
|
121
|
+
* @param request - Request object containing the reward account ID.
|
|
122
|
+
* @example { rewardAccountId: 'eip155:1:0x1234567890123456789012345678901234567890' }
|
|
123
|
+
* @returns The response from the API.
|
|
124
|
+
*/
|
|
125
|
+
export type SubscriptionServiceLinkRewardsAction = {
|
|
126
|
+
type: `SubscriptionService:linkRewards`;
|
|
127
|
+
handler: SubscriptionService['linkRewards'];
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* Fetches subscription pricing information.
|
|
131
|
+
*
|
|
132
|
+
* @returns The pricing response.
|
|
133
|
+
*/
|
|
134
|
+
export type SubscriptionServiceGetPricingAction = {
|
|
135
|
+
type: `SubscriptionService:getPricing`;
|
|
136
|
+
handler: SubscriptionService['getPricing'];
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* Fetches the billing portal URL.
|
|
140
|
+
*
|
|
141
|
+
* @returns The billing portal response.
|
|
142
|
+
*/
|
|
143
|
+
export type SubscriptionServiceGetBillingPortalUrlAction = {
|
|
144
|
+
type: `SubscriptionService:getBillingPortalUrl`;
|
|
145
|
+
handler: SubscriptionService['getBillingPortalUrl'];
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* Union of all SubscriptionService action types.
|
|
149
|
+
*/
|
|
150
|
+
export type SubscriptionServiceMethodActions = SubscriptionServiceGetSubscriptionsAction | SubscriptionServiceCancelSubscriptionAction | SubscriptionServiceUnCancelSubscriptionAction | SubscriptionServiceStartSubscriptionWithCardAction | SubscriptionServiceStartSubscriptionWithCryptoAction | SubscriptionServiceUpdatePaymentMethodCardAction | SubscriptionServiceUpdatePaymentMethodCryptoAction | SubscriptionServiceGetSubscriptionsEligibilitiesAction | SubscriptionServiceSubmitUserEventAction | SubscriptionServiceAssignUserToCohortAction | SubscriptionServiceSubmitSponsorshipIntentsAction | SubscriptionServiceLinkRewardsAction | SubscriptionServiceGetPricingAction | SubscriptionServiceGetBillingPortalUrlAction;
|
|
151
|
+
//# sourceMappingURL=SubscriptionService-method-action-types.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubscriptionService-method-action-types.d.cts","sourceRoot":"","sources":["../src/SubscriptionService-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,kCAAiC;AAEpE;;;;GAIG;AACH,MAAM,MAAM,yCAAyC,GAAG;IACtD,IAAI,EAAE,sCAAsC,CAAC;IAC7C,OAAO,EAAE,mBAAmB,CAAC,kBAAkB,CAAC,CAAC;CAClD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,wCAAwC,CAAC;IAC/C,OAAO,EAAE,mBAAmB,CAAC,oBAAoB,CAAC,CAAC;CACpD,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,6CAA6C,GAAG;IAC1D,IAAI,EAAE,0CAA0C,CAAC;IACjD,OAAO,EAAE,mBAAmB,CAAC,sBAAsB,CAAC,CAAC;CACtD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,kDAAkD,GAAG;IAC/D,IAAI,EAAE,+CAA+C,CAAC;IACtD,OAAO,EAAE,mBAAmB,CAAC,2BAA2B,CAAC,CAAC;CAC3D,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,oDAAoD,GAAG;IACjE,IAAI,EAAE,iDAAiD,CAAC;IACxD,OAAO,EAAE,mBAAmB,CAAC,6BAA6B,CAAC,CAAC;CAC7D,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,gDAAgD,GAAG;IAC7D,IAAI,EAAE,6CAA6C,CAAC;IACpD,OAAO,EAAE,mBAAmB,CAAC,yBAAyB,CAAC,CAAC;CACzD,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,kDAAkD,GAAG;IAC/D,IAAI,EAAE,+CAA+C,CAAC;IACtD,OAAO,EAAE,mBAAmB,CAAC,2BAA2B,CAAC,CAAC;CAC3D,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,sDAAsD,GAAG;IACnE,IAAI,EAAE,mDAAmD,CAAC;IAC1D,OAAO,EAAE,mBAAmB,CAAC,+BAA+B,CAAC,CAAC;CAC/D,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,wCAAwC,GAAG;IACrD,IAAI,EAAE,qCAAqC,CAAC;IAC5C,OAAO,EAAE,mBAAmB,CAAC,iBAAiB,CAAC,CAAC;CACjD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,wCAAwC,CAAC;IAC/C,OAAO,EAAE,mBAAmB,CAAC,oBAAoB,CAAC,CAAC;CACpD,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,iDAAiD,GAAG;IAC9D,IAAI,EAAE,8CAA8C,CAAC;IACrD,OAAO,EAAE,mBAAmB,CAAC,0BAA0B,CAAC,CAAC;CAC1D,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,oCAAoC,GAAG;IACjD,IAAI,EAAE,iCAAiC,CAAC;IACxC,OAAO,EAAE,mBAAmB,CAAC,aAAa,CAAC,CAAC;CAC7C,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,mCAAmC,GAAG;IAChD,IAAI,EAAE,gCAAgC,CAAC;IACvC,OAAO,EAAE,mBAAmB,CAAC,YAAY,CAAC,CAAC;CAC5C,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,4CAA4C,GAAG;IACzD,IAAI,EAAE,yCAAyC,CAAC;IAChD,OAAO,EAAE,mBAAmB,CAAC,qBAAqB,CAAC,CAAC;CACrD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gCAAgC,GACxC,yCAAyC,GACzC,2CAA2C,GAC3C,6CAA6C,GAC7C,kDAAkD,GAClD,oDAAoD,GACpD,gDAAgD,GAChD,kDAAkD,GAClD,sDAAsD,GACtD,wCAAwC,GACxC,2CAA2C,GAC3C,iDAAiD,GACjD,oCAAoC,GACpC,mCAAmC,GACnC,4CAA4C,CAAC"}
|