@metamask-previews/subscription-controller 8.0.1-preview-3866c0ff1 → 8.0.1-preview-e3275932a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/CHANGELOG.md +0 -1
  2. package/dist/SubscriptionController-method-action-types.cjs +7 -0
  3. package/dist/SubscriptionController-method-action-types.cjs.map +1 -0
  4. package/dist/{SubscriptionController-method-action-types.d.ts → SubscriptionController-method-action-types.d.cts} +2 -2
  5. package/dist/SubscriptionController-method-action-types.d.cts.map +1 -0
  6. package/dist/SubscriptionController-method-action-types.d.mts +250 -0
  7. package/dist/SubscriptionController-method-action-types.d.mts.map +1 -0
  8. package/dist/{SubscriptionController-method-action-types.js → SubscriptionController-method-action-types.mjs} +1 -1
  9. package/dist/SubscriptionController-method-action-types.mjs.map +1 -0
  10. package/dist/SubscriptionController.cjs +744 -0
  11. package/dist/SubscriptionController.cjs.map +1 -0
  12. package/dist/{SubscriptionController.d.ts → SubscriptionController.d.cts} +18 -18
  13. package/dist/SubscriptionController.d.cts.map +1 -0
  14. package/dist/SubscriptionController.d.mts +258 -0
  15. package/dist/SubscriptionController.d.mts.map +1 -0
  16. package/dist/{SubscriptionController.js → SubscriptionController.mjs} +180 -262
  17. package/dist/SubscriptionController.mjs.map +1 -0
  18. package/dist/SubscriptionService-method-action-types.cjs +7 -0
  19. package/dist/SubscriptionService-method-action-types.cjs.map +1 -0
  20. package/dist/{SubscriptionService-method-action-types.d.ts → SubscriptionService-method-action-types.d.cts} +2 -2
  21. package/dist/SubscriptionService-method-action-types.d.cts.map +1 -0
  22. package/dist/SubscriptionService-method-action-types.d.mts +155 -0
  23. package/dist/SubscriptionService-method-action-types.d.mts.map +1 -0
  24. package/dist/{SubscriptionService-method-action-types.js → SubscriptionService-method-action-types.mjs} +1 -1
  25. package/dist/SubscriptionService-method-action-types.mjs.map +1 -0
  26. package/dist/SubscriptionService-structs.cjs +158 -0
  27. package/dist/SubscriptionService-structs.cjs.map +1 -0
  28. package/dist/{SubscriptionService-structs.d.ts → SubscriptionService-structs.d.cts} +134 -134
  29. package/dist/SubscriptionService-structs.d.cts.map +1 -0
  30. package/dist/SubscriptionService-structs.d.mts +721 -0
  31. package/dist/SubscriptionService-structs.d.mts.map +1 -0
  32. package/dist/{SubscriptionService-structs.js → SubscriptionService-structs.mjs} +4 -4
  33. package/dist/SubscriptionService-structs.mjs.map +1 -0
  34. package/dist/SubscriptionService.cjs +477 -0
  35. package/dist/SubscriptionService.cjs.map +1 -0
  36. package/dist/{SubscriptionService.d.ts → SubscriptionService.d.cts} +10 -10
  37. package/dist/SubscriptionService.d.cts.map +1 -0
  38. package/dist/SubscriptionService.d.mts +149 -0
  39. package/dist/SubscriptionService.d.mts.map +1 -0
  40. package/dist/{SubscriptionService.js → SubscriptionService.mjs} +141 -139
  41. package/dist/SubscriptionService.mjs.map +1 -0
  42. package/dist/constants.cjs +73 -0
  43. package/dist/constants.cjs.map +1 -0
  44. package/dist/{constants.d.ts → constants.d.cts} +1 -1
  45. package/dist/constants.d.cts.map +1 -0
  46. package/dist/constants.d.mts +49 -0
  47. package/dist/constants.d.mts.map +1 -0
  48. package/dist/{constants.js → constants.mjs} +3 -3
  49. package/dist/constants.mjs.map +1 -0
  50. package/dist/errors.cjs +72 -0
  51. package/dist/errors.cjs.map +1 -0
  52. package/dist/{errors.d.ts → errors.d.cts} +2 -2
  53. package/dist/errors.d.cts.map +1 -0
  54. package/dist/errors.d.mts +34 -0
  55. package/dist/errors.d.mts.map +1 -0
  56. package/dist/{errors.js → errors.mjs} +1 -5
  57. package/dist/errors.mjs.map +1 -0
  58. package/dist/index.cjs +29 -0
  59. package/dist/index.cjs.map +1 -0
  60. package/dist/{index.d.ts → index.d.cts} +11 -11
  61. package/dist/index.d.cts.map +1 -0
  62. package/dist/index.d.mts +11 -0
  63. package/dist/index.d.mts.map +1 -0
  64. package/dist/{index.js → index.mjs} +6 -6
  65. package/dist/index.mjs.map +1 -0
  66. package/dist/logger.cjs +8 -0
  67. package/dist/logger.cjs.map +1 -0
  68. package/dist/logger.d.cts +5 -0
  69. package/dist/logger.d.cts.map +1 -0
  70. package/dist/logger.d.mts +5 -0
  71. package/dist/logger.d.mts.map +1 -0
  72. package/dist/logger.mjs +5 -0
  73. package/dist/logger.mjs.map +1 -0
  74. package/dist/types.cjs +90 -0
  75. package/dist/types.cjs.map +1 -0
  76. package/dist/{types.d.ts → types.d.cts} +41 -41
  77. package/dist/types.d.cts.map +1 -0
  78. package/dist/types.d.mts +574 -0
  79. package/dist/types.d.mts.map +1 -0
  80. package/dist/{types.js → types.mjs} +1 -1
  81. package/dist/types.mjs.map +1 -0
  82. package/package.json +16 -12
  83. package/dist/SubscriptionController-method-action-types.d.ts.map +0 -1
  84. package/dist/SubscriptionController-method-action-types.js.map +0 -1
  85. package/dist/SubscriptionController.d.ts.map +0 -1
  86. package/dist/SubscriptionController.js.map +0 -1
  87. package/dist/SubscriptionService-method-action-types.d.ts.map +0 -1
  88. package/dist/SubscriptionService-method-action-types.js.map +0 -1
  89. package/dist/SubscriptionService-structs.d.ts.map +0 -1
  90. package/dist/SubscriptionService-structs.js.map +0 -1
  91. package/dist/SubscriptionService.d.ts.map +0 -1
  92. package/dist/SubscriptionService.js.map +0 -1
  93. package/dist/constants.d.ts.map +0 -1
  94. package/dist/constants.js.map +0 -1
  95. package/dist/errors.d.ts.map +0 -1
  96. package/dist/errors.js.map +0 -1
  97. package/dist/index.d.ts.map +0 -1
  98. package/dist/index.js.map +0 -1
  99. package/dist/logger.d.ts +0 -4
  100. package/dist/logger.d.ts.map +0 -1
  101. package/dist/logger.js +0 -5
  102. package/dist/logger.js.map +0 -1
  103. package/dist/types.d.ts.map +0 -1
  104. package/dist/types.js.map +0 -1
@@ -1,8 +1,14 @@
1
- import { StaticIntervalPollingController } from '@metamask/polling-controller';
2
- import { TransactionType } from '@metamask/transaction-controller';
3
- import { BigNumber } from 'bignumber.js';
4
- import { ACTIVE_SUBSCRIPTION_STATUSES, controllerName, DEFAULT_POLLING_INTERVAL, SubscriptionControllerErrorMessage, } from './constants.js';
5
- import { CRYPTO_AUTH_METHODS, PAYMENT_TYPES, PRODUCT_TYPES, SUBSCRIPTION_STATUSES, } from './types.js';
1
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
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");
4
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
+ };
6
+ var _SubscriptionController_instances, _SubscriptionController_getSubscriptionPriceAmount, _SubscriptionController_getSubscriptionBalanceAmount, _SubscriptionController_getProductPriceByProductAndPlan, _SubscriptionController_assertValidSubscriptionStateForCryptoApproval, _SubscriptionController_assertIsUserNotSubscribed, _SubscriptionController_assertIsUserSubscribed, _SubscriptionController_assertIsPaymentMethodCrypto, _SubscriptionController_getIsEligibleForTrialedSponsorship, _SubscriptionController_getIsTrialRequested, _SubscriptionController_findCryptoPaymentMethod, _SubscriptionController_resolveCryptoPaymentMethodDefaults, _SubscriptionController_getChainSupportsSponsorship, _SubscriptionController_areTrialedProductsEqual, _SubscriptionController_areSubscriptionsEqual, _SubscriptionController_isSubscriptionEqual, _SubscriptionController_stringifySubscription;
7
+ import { StaticIntervalPollingController } from "@metamask/polling-controller";
8
+ import { TransactionType } from "@metamask/transaction-controller";
9
+ import { BigNumber } from "bignumber.js";
10
+ import { ACTIVE_SUBSCRIPTION_STATUSES, controllerName, DEFAULT_POLLING_INTERVAL, SubscriptionControllerErrorMessage } from "./constants.mjs";
11
+ import { CRYPTO_AUTH_METHODS, PAYMENT_TYPES, PRODUCT_TYPES, SUBSCRIPTION_STATUSES } from "./types.mjs";
6
12
  /**
7
13
  * Get the default state for the Subscription Controller.
8
14
  *
@@ -110,6 +116,7 @@ export class SubscriptionController extends StaticIntervalPollingController() {
110
116
  },
111
117
  messenger,
112
118
  });
119
+ _SubscriptionController_instances.add(this);
113
120
  this.setIntervalLength(pollingInterval);
114
121
  this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
115
122
  }
@@ -133,11 +140,11 @@ export class SubscriptionController extends StaticIntervalPollingController() {
133
140
  const currentRewardAccountId = this.state.rewardAccountId;
134
141
  const { customerId: newCustomerId, subscriptions: newSubscriptions, trialedProducts: newTrialedProducts, lastSubscription: newLastSubscription, rewardAccountId: newRewardAccountId, } = await this.messenger.call('SubscriptionService:getSubscriptions');
135
142
  // check if the new subscriptions are different from the current subscriptions
136
- const areSubscriptionsEqual = this.#areSubscriptionsEqual(currentSubscriptions, newSubscriptions);
143
+ const areSubscriptionsEqual = __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_areSubscriptionsEqual).call(this, currentSubscriptions, newSubscriptions);
137
144
  // check if the new trialed products are different from the current trialed products
138
- const areTrialedProductsEqual = this.#areTrialedProductsEqual(currentTrialedProducts, newTrialedProducts);
145
+ const areTrialedProductsEqual = __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_areTrialedProductsEqual).call(this, currentTrialedProducts, newTrialedProducts);
139
146
  // check if the new last subscription is different from the current last subscription
140
- const isLastSubscriptionEqual = this.#isSubscriptionEqual(currentLastSubscription, newLastSubscription);
147
+ const isLastSubscriptionEqual = __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_isSubscriptionEqual).call(this, currentLastSubscription, newLastSubscription);
141
148
  const areCustomerIdsEqual = currentCustomerId === newCustomerId;
142
149
  const areRewardAccountIdsEqual = currentRewardAccountId === newRewardAccountId;
143
150
  // only update the state if the subscriptions or trialed products are different
@@ -178,7 +185,7 @@ export class SubscriptionController extends StaticIntervalPollingController() {
178
185
  return await this.messenger.call('SubscriptionService:getSubscriptionsEligibilities', request);
179
186
  }
180
187
  async cancelSubscription(request) {
181
- this.#assertIsUserSubscribed({ subscriptionId: request.subscriptionId });
188
+ __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_assertIsUserSubscribed).call(this, { subscriptionId: request.subscriptionId });
182
189
  const cancelledSubscription = await this.messenger.call('SubscriptionService:cancelSubscription', request);
183
190
  this.update((state) => {
184
191
  state.subscriptions = state.subscriptions.map((subscription) => subscription.id === request.subscriptionId
@@ -188,7 +195,7 @@ export class SubscriptionController extends StaticIntervalPollingController() {
188
195
  this.triggerAccessTokenRefresh();
189
196
  }
190
197
  async unCancelSubscription(request) {
191
- this.#assertIsUserSubscribed({ subscriptionId: request.subscriptionId });
198
+ __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_assertIsUserSubscribed).call(this, { subscriptionId: request.subscriptionId });
192
199
  const uncancelledSubscription = await this.messenger.call('SubscriptionService:unCancelSubscription', {
193
200
  subscriptionId: request.subscriptionId,
194
201
  });
@@ -212,10 +219,10 @@ export class SubscriptionController extends StaticIntervalPollingController() {
212
219
  async startSubscriptionWithCard(request) {
213
220
  // get the latest subscriptions state before computing trial eligibility
214
221
  await this.getSubscriptions();
215
- this.#assertIsUserNotSubscribed({ products: request.products });
222
+ __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_assertIsUserNotSubscribed).call(this, { products: request.products });
216
223
  const response = await this.messenger.call('SubscriptionService:startSubscriptionWithCard', {
217
224
  ...request,
218
- isTrialRequested: this.#getIsTrialRequested(request.products, request.recurringInterval),
225
+ isTrialRequested: __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_getIsTrialRequested).call(this, request.products, request.recurringInterval),
219
226
  });
220
227
  // note: no need to trigger access token refresh after startSubscriptionWithCard request because this only return stripe checkout session url, subscription not created yet
221
228
  return response;
@@ -239,10 +246,10 @@ export class SubscriptionController extends StaticIntervalPollingController() {
239
246
  }
240
247
  // get the latest subscriptions state before computing trial eligibility
241
248
  await this.getSubscriptions();
242
- this.#assertIsUserNotSubscribed({ products: request.products });
249
+ __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_assertIsUserNotSubscribed).call(this, { products: request.products });
243
250
  const response = await this.messenger.call('SubscriptionService:startSubscriptionWithCrypto', {
244
251
  ...request,
245
- isTrialRequested: this.#getIsTrialRequested(request.products, request.recurringInterval),
252
+ isTrialRequested: __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_getIsTrialRequested).call(this, request.products, request.recurringInterval),
246
253
  });
247
254
  // Crypto start creates the subscription immediately (unlike card checkout).
248
255
  await this.getSubscriptions();
@@ -290,13 +297,13 @@ export class SubscriptionController extends StaticIntervalPollingController() {
290
297
  throw new Error('Last selected payment method not found');
291
298
  }
292
299
  const lastSelectedPaymentMethodForProduct = lastSelectedPaymentMethod[productType];
293
- this.#assertIsPaymentMethodCrypto(lastSelectedPaymentMethodForProduct);
294
- const productPrice = this.#getProductPriceByProductAndPlan(productType, lastSelectedPaymentMethodForProduct.plan);
300
+ __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_assertIsPaymentMethodCrypto).call(this, lastSelectedPaymentMethodForProduct);
301
+ const productPrice = __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_getProductPriceByProductAndPlan).call(this, productType, lastSelectedPaymentMethodForProduct.plan);
295
302
  // get the latest subscriptions state before computing trial eligibility
296
303
  await this.getSubscriptions();
297
- const isTrialRequested = this.#getIsTrialRequested([productType], lastSelectedPaymentMethodForProduct.plan);
304
+ const isTrialRequested = __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_getIsTrialRequested).call(this, [productType], lastSelectedPaymentMethodForProduct.plan);
298
305
  const currentSubscription = this.getSubscriptionByProduct(productType);
299
- this.#assertValidSubscriptionStateForCryptoApproval({
306
+ __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_assertValidSubscriptionStateForCryptoApproval).call(this, {
300
307
  productType,
301
308
  });
302
309
  // if subscription exists, this transaction is for changing payment method
@@ -356,7 +363,7 @@ export class SubscriptionController extends StaticIntervalPollingController() {
356
363
  if (!price) {
357
364
  throw new Error('Price not found');
358
365
  }
359
- const chainsPaymentInfo = this.#findCryptoPaymentMethod(request.productType, CRYPTO_AUTH_METHODS.ERC20_APPROVAL);
366
+ const chainsPaymentInfo = __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_findCryptoPaymentMethod).call(this, request.productType, CRYPTO_AUTH_METHODS.ERC20_APPROVAL);
360
367
  if (!chainsPaymentInfo) {
361
368
  throw new Error('Chains payment info not found');
362
369
  }
@@ -454,17 +461,17 @@ export class SubscriptionController extends StaticIntervalPollingController() {
454
461
  if (request.products.length === 0) {
455
462
  throw new Error(SubscriptionControllerErrorMessage.SubscriptionProductsEmpty);
456
463
  }
457
- this.#assertIsUserNotSubscribed({ products: request.products });
464
+ __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_assertIsUserNotSubscribed).call(this, { products: request.products });
458
465
  const selectedPaymentMethod = this.state.lastSelectedPaymentMethod?.[request.products[0]];
459
- this.#assertIsPaymentMethodCrypto(selectedPaymentMethod);
466
+ __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_assertIsPaymentMethodCrypto).call(this, selectedPaymentMethod);
460
467
  const cryptoAuthMethod = selectedPaymentMethod.cryptoAuthMethod ??
461
468
  CRYPTO_AUTH_METHODS.ERC20_APPROVAL;
462
- const isEligibleForTrialedSponsorship = this.#getIsEligibleForTrialedSponsorship(request.chainId, request.products, cryptoAuthMethod);
469
+ const isEligibleForTrialedSponsorship = __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_getIsEligibleForTrialedSponsorship).call(this, request.chainId, request.products, cryptoAuthMethod);
463
470
  if (!isEligibleForTrialedSponsorship) {
464
471
  return false;
465
472
  }
466
473
  const { paymentTokenSymbol, plan } = selectedPaymentMethod;
467
- const productPrice = this.#getProductPriceByProductAndPlan(
474
+ const productPrice = __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_getProductPriceByProductAndPlan).call(this,
468
475
  // we only support one product at a time for now
469
476
  request.products[0], plan);
470
477
  const billingCycles = productPrice.minBillingCycles;
@@ -505,7 +512,7 @@ export class SubscriptionController extends StaticIntervalPollingController() {
505
512
  */
506
513
  async linkRewards(request) {
507
514
  // assert that the user is subscribed to the subscription
508
- this.#assertIsUserSubscribed({ subscriptionId: request.subscriptionId });
515
+ __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_assertIsUserSubscribed).call(this, { subscriptionId: request.subscriptionId });
509
516
  // link rewards to the subscription
510
517
  const response = await this.messenger.call('SubscriptionService:linkRewards', {
511
518
  rewardAccountId: request.rewardAccountId,
@@ -517,35 +524,6 @@ export class SubscriptionController extends StaticIntervalPollingController() {
517
524
  async _executePoll() {
518
525
  await this.getSubscriptions();
519
526
  }
520
- /**
521
- * Calculate total subscription price amount (approval amount) from price info
522
- * e.g: $8 per month * 12 months min billing cycles = $96
523
- *
524
- * @param price - The price info
525
- * @returns The price amount
526
- */
527
- #getSubscriptionPriceAmount(price) {
528
- // no need to use BigInt since max unitDecimals are always 2 for price
529
- const amount = new BigNumber(price.unitAmount)
530
- .div(10 ** price.unitDecimals)
531
- .multipliedBy(price.minBillingCycles)
532
- .toString();
533
- return amount;
534
- }
535
- /**
536
- * Calculate minimum subscription balance amount from price info
537
- *
538
- * @param price - The price info
539
- * @returns The balance amount
540
- */
541
- #getSubscriptionBalanceAmount(price) {
542
- // no need to use BigInt since max unitDecimals are always 2 for price
543
- const amount = new BigNumber(price.unitAmount)
544
- .div(10 ** price.unitDecimals)
545
- .multipliedBy(price.minBillingCyclesForBalance)
546
- .toString();
547
- return amount;
548
- }
549
527
  /**
550
528
  * Calculate token approve amount from price info
551
529
  *
@@ -559,7 +537,7 @@ export class SubscriptionController extends StaticIntervalPollingController() {
559
537
  throw new Error('Conversion rate not found');
560
538
  }
561
539
  // price of the product
562
- const priceAmount = new BigNumber(this.#getSubscriptionPriceAmount(price));
540
+ const priceAmount = new BigNumber(__classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_getSubscriptionPriceAmount).call(this, price));
563
541
  const tokenDecimal = new BigNumber(10).pow(tokenPaymentInfo.decimals);
564
542
  const tokenAmount = priceAmount
565
543
  .multipliedBy(tokenDecimal)
@@ -578,7 +556,7 @@ export class SubscriptionController extends StaticIntervalPollingController() {
578
556
  if (!conversionRate) {
579
557
  throw new Error('Conversion rate not found');
580
558
  }
581
- const balanceAmount = new BigNumber(this.#getSubscriptionBalanceAmount(price));
559
+ const balanceAmount = new BigNumber(__classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_getSubscriptionBalanceAmount).call(this, price));
582
560
  const tokenDecimal = new BigNumber(10).pow(tokenPaymentInfo.decimals);
583
561
  const tokenAmount = balanceAmount
584
562
  .multipliedBy(tokenDecimal)
@@ -603,219 +581,159 @@ export class SubscriptionController extends StaticIntervalPollingController() {
603
581
  // will be fetched.
604
582
  this.messenger.call('AuthenticationController:performSignOut');
605
583
  }
606
- #getProductPriceByProductAndPlan(productType, plan) {
607
- const { pricing } = this.state;
608
- const productPricing = pricing?.products.find((product) => product.name === productType);
609
- const productPrice = productPricing?.prices.find((price) => price.interval === plan);
610
- if (!productPrice) {
611
- throw new Error(SubscriptionControllerErrorMessage.ProductPriceNotFound);
612
- }
613
- return productPrice;
614
- }
615
- #assertValidSubscriptionStateForCryptoApproval({ productType, }) {
616
- const subscription = this.state.subscriptions.find((sub) => sub.products.some((product) => product.name === productType));
617
- const isValid = !subscription ||
618
- [
619
- SUBSCRIPTION_STATUSES.pastDue,
620
- SUBSCRIPTION_STATUSES.unpaid,
621
- SUBSCRIPTION_STATUSES.paused,
622
- SUBSCRIPTION_STATUSES.provisional,
623
- SUBSCRIPTION_STATUSES.active,
624
- SUBSCRIPTION_STATUSES.trialing,
625
- ].includes(subscription.status);
626
- if (!isValid) {
627
- throw new Error(SubscriptionControllerErrorMessage.SubscriptionNotValidForCryptoApproval);
628
- }
629
- }
630
- #assertIsUserNotSubscribed({ products }) {
631
- const subscription = this.state.subscriptions.find((sub) => sub.products.some((product) => products.includes(product.name)));
632
- if (subscription &&
633
- ACTIVE_SUBSCRIPTION_STATUSES.includes(subscription.status)) {
634
- throw new Error(SubscriptionControllerErrorMessage.UserAlreadySubscribed);
635
- }
636
- }
637
- #assertIsUserSubscribed(request) {
638
- if (!this.state.subscriptions.find((subscription) => subscription.id === request.subscriptionId)) {
639
- throw new Error(SubscriptionControllerErrorMessage.UserNotSubscribed);
584
+ }
585
+ _SubscriptionController_instances = new WeakSet(), _SubscriptionController_getSubscriptionPriceAmount = function _SubscriptionController_getSubscriptionPriceAmount(price) {
586
+ // no need to use BigInt since max unitDecimals are always 2 for price
587
+ const amount = new BigNumber(price.unitAmount)
588
+ .div(10 ** price.unitDecimals)
589
+ .multipliedBy(price.minBillingCycles)
590
+ .toString();
591
+ return amount;
592
+ }, _SubscriptionController_getSubscriptionBalanceAmount = function _SubscriptionController_getSubscriptionBalanceAmount(price) {
593
+ // no need to use BigInt since max unitDecimals are always 2 for price
594
+ const amount = new BigNumber(price.unitAmount)
595
+ .div(10 ** price.unitDecimals)
596
+ .multipliedBy(price.minBillingCyclesForBalance)
597
+ .toString();
598
+ return amount;
599
+ }, _SubscriptionController_getProductPriceByProductAndPlan = function _SubscriptionController_getProductPriceByProductAndPlan(productType, plan) {
600
+ const { pricing } = this.state;
601
+ const productPricing = pricing?.products.find((product) => product.name === productType);
602
+ const productPrice = productPricing?.prices.find((price) => price.interval === plan);
603
+ if (!productPrice) {
604
+ throw new Error(SubscriptionControllerErrorMessage.ProductPriceNotFound);
605
+ }
606
+ return productPrice;
607
+ }, _SubscriptionController_assertValidSubscriptionStateForCryptoApproval = function _SubscriptionController_assertValidSubscriptionStateForCryptoApproval({ productType, }) {
608
+ const subscription = this.state.subscriptions.find((sub) => sub.products.some((product) => product.name === productType));
609
+ const isValid = !subscription ||
610
+ [
611
+ SUBSCRIPTION_STATUSES.pastDue,
612
+ SUBSCRIPTION_STATUSES.unpaid,
613
+ SUBSCRIPTION_STATUSES.paused,
614
+ SUBSCRIPTION_STATUSES.provisional,
615
+ SUBSCRIPTION_STATUSES.active,
616
+ SUBSCRIPTION_STATUSES.trialing,
617
+ ].includes(subscription.status);
618
+ if (!isValid) {
619
+ throw new Error(SubscriptionControllerErrorMessage.SubscriptionNotValidForCryptoApproval);
620
+ }
621
+ }, _SubscriptionController_assertIsUserNotSubscribed = function _SubscriptionController_assertIsUserNotSubscribed({ products }) {
622
+ const subscription = this.state.subscriptions.find((sub) => sub.products.some((product) => products.includes(product.name)));
623
+ if (subscription &&
624
+ ACTIVE_SUBSCRIPTION_STATUSES.includes(subscription.status)) {
625
+ throw new Error(SubscriptionControllerErrorMessage.UserAlreadySubscribed);
626
+ }
627
+ }, _SubscriptionController_assertIsUserSubscribed = function _SubscriptionController_assertIsUserSubscribed(request) {
628
+ if (!this.state.subscriptions.find((subscription) => subscription.id === request.subscriptionId)) {
629
+ throw new Error(SubscriptionControllerErrorMessage.UserNotSubscribed);
630
+ }
631
+ }, _SubscriptionController_assertIsPaymentMethodCrypto = function _SubscriptionController_assertIsPaymentMethodCrypto(value) {
632
+ if (value?.type !== PAYMENT_TYPES.byCrypto ||
633
+ !value.paymentTokenAddress ||
634
+ !value.paymentTokenSymbol) {
635
+ throw new Error(SubscriptionControllerErrorMessage.PaymentMethodNotCrypto);
636
+ }
637
+ }, _SubscriptionController_getIsEligibleForTrialedSponsorship = function _SubscriptionController_getIsEligibleForTrialedSponsorship(chainId, products, cryptoAuthMethod) {
638
+ const isSponsorshipSupported = __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_getChainSupportsSponsorship).call(this, chainId, products[0], cryptoAuthMethod);
639
+ // verify if the user has trialed the provided products before
640
+ const hasTrialedBefore = this.state.trialedProducts.some((product) => products.includes(product));
641
+ return isSponsorshipSupported && !hasTrialedBefore;
642
+ }, _SubscriptionController_getIsTrialRequested = function _SubscriptionController_getIsTrialRequested(products, plan) {
643
+ return products.every((productType) => {
644
+ if (this.state.trialedProducts.includes(productType)) {
645
+ return false;
640
646
  }
641
- }
642
- /**
643
- * Asserts that the value is a valid crypto payment method.
644
- *
645
- * After this assert, `cryptoAuthMethod` and `useTestClock` remain optional
646
- * because persisted cache entries may omit them.
647
- *
648
- * @param value - The value to assert.
649
- * @throws an error if the value is not a valid crypto payment method.
650
- */
651
- #assertIsPaymentMethodCrypto(value) {
652
- if (value?.type !== PAYMENT_TYPES.byCrypto ||
653
- !value.paymentTokenAddress ||
654
- !value.paymentTokenSymbol) {
655
- throw new Error(SubscriptionControllerErrorMessage.PaymentMethodNotCrypto);
647
+ const productPrice = __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_getProductPriceByProductAndPlan).call(this, productType, plan);
648
+ return productPrice.trialPeriodDays > 0;
649
+ });
650
+ }, _SubscriptionController_findCryptoPaymentMethod = function _SubscriptionController_findCryptoPaymentMethod(productType, cryptoAuthMethod) {
651
+ const matches = [];
652
+ for (const paymentMethod of this.state.pricing?.paymentMethods ?? []) {
653
+ if (paymentMethod.type !== PAYMENT_TYPES.byCrypto) {
654
+ continue;
655
+ }
656
+ const resolved = __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_resolveCryptoPaymentMethodDefaults).call(this, paymentMethod);
657
+ if (!resolved) {
658
+ continue;
659
+ }
660
+ if (resolved.cryptoAuthMethod === cryptoAuthMethod &&
661
+ resolved.products.includes(productType)) {
662
+ matches.push({
663
+ method: paymentMethod,
664
+ explicit: resolved.explicit,
665
+ });
656
666
  }
657
667
  }
658
- /**
659
- * Determines if the user is eligible for trialed sponsorship for the given chain and products.
660
- * The user is eligible if the chain supports sponsorship and the user has not trialed the provided products before.
661
- *
662
- * @param chainId - The chain ID
663
- * @param products - The products to check eligibility for
664
- * @param cryptoAuthMethod - The crypto authorization method of the selected payment method
665
- * @returns True if the user is eligible for trialed sponsorship, false otherwise
666
- */
667
- #getIsEligibleForTrialedSponsorship(chainId, products, cryptoAuthMethod) {
668
- const isSponsorshipSupported = this.#getChainSupportsSponsorship(chainId, products[0], cryptoAuthMethod);
669
- // verify if the user has trialed the provided products before
670
- const hasTrialedBefore = this.state.trialedProducts.some((product) => products.includes(product));
671
- return isSponsorshipSupported && !hasTrialedBefore;
668
+ if (matches.length === 0) {
669
+ return undefined;
672
670
  }
673
- /**
674
- * Whether a trial should be requested for the given products and plan.
675
- * True only when every product has `trialPeriodDays > 0` and has not
676
- * already been trialed.
677
- *
678
- * @param products - The products to check.
679
- * @param plan - The recurring interval to look up pricing for.
680
- * @returns Whether a trial should be requested.
681
- */
682
- #getIsTrialRequested(products, plan) {
683
- return products.every((productType) => {
684
- if (this.state.trialedProducts.includes(productType)) {
685
- return false;
686
- }
687
- const productPrice = this.#getProductPriceByProductAndPlan(productType, plan);
688
- return productPrice.trialPeriodDays > 0;
689
- });
690
- }
691
- #findCryptoPaymentMethod(productType, cryptoAuthMethod) {
692
- const matches = [];
693
- for (const paymentMethod of this.state.pricing?.paymentMethods ?? []) {
694
- if (paymentMethod.type !== PAYMENT_TYPES.byCrypto) {
695
- continue;
696
- }
697
- const resolved = this.#resolveCryptoPaymentMethodDefaults(paymentMethod);
698
- if (!resolved) {
699
- continue;
700
- }
701
- if (resolved.cryptoAuthMethod === cryptoAuthMethod &&
702
- resolved.products.includes(productType)) {
703
- matches.push({
704
- method: paymentMethod,
705
- explicit: resolved.explicit,
706
- });
707
- }
708
- }
709
- if (matches.length === 0) {
710
- return undefined;
711
- }
712
- const explicitMatches = matches.filter((match) => match.explicit);
713
- const candidates = explicitMatches.length > 0 ? explicitMatches : matches;
714
- if (candidates.length > 1) {
715
- throw new Error('Multiple matching crypto payment methods found');
716
- }
717
- return candidates[0].method;
671
+ const explicitMatches = matches.filter((match) => match.explicit);
672
+ const candidates = explicitMatches.length > 0 ? explicitMatches : matches;
673
+ if (candidates.length > 1) {
674
+ throw new Error('Multiple matching crypto payment methods found');
718
675
  }
719
- /**
720
- * Resolves omitted `products` / `cryptoAuthMethod` on a crypto pricing row.
721
- * Legacy Shield + `erc20_approval` defaults apply only when both fields are
722
- * absent. If `products` is present, the list must be non-empty and
723
- * `cryptoAuthMethod` must be explicit; otherwise the row is ignored.
724
- *
725
- * @param paymentMethod - The crypto pricing row.
726
- * @returns Resolved products and auth method, or `undefined` if the row is
727
- * incomplete.
728
- */
729
- #resolveCryptoPaymentMethodDefaults(paymentMethod) {
730
- const productsPresent = paymentMethod.products !== undefined;
731
- const authPresent = paymentMethod.cryptoAuthMethod !== undefined;
732
- if (!productsPresent && !authPresent) {
733
- return {
734
- products: [PRODUCT_TYPES.SHIELD],
735
- cryptoAuthMethod: CRYPTO_AUTH_METHODS.ERC20_APPROVAL,
736
- explicit: false,
737
- };
738
- }
739
- if (!paymentMethod.products?.length || !paymentMethod.cryptoAuthMethod) {
740
- return undefined;
741
- }
676
+ return candidates[0].method;
677
+ }, _SubscriptionController_resolveCryptoPaymentMethodDefaults = function _SubscriptionController_resolveCryptoPaymentMethodDefaults(paymentMethod) {
678
+ const productsPresent = paymentMethod.products !== undefined;
679
+ const authPresent = paymentMethod.cryptoAuthMethod !== undefined;
680
+ if (!productsPresent && !authPresent) {
742
681
  return {
743
- products: paymentMethod.products,
744
- cryptoAuthMethod: paymentMethod.cryptoAuthMethod,
745
- explicit: true,
682
+ products: [PRODUCT_TYPES.SHIELD],
683
+ cryptoAuthMethod: CRYPTO_AUTH_METHODS.ERC20_APPROVAL,
684
+ explicit: false,
746
685
  };
747
686
  }
748
- /**
749
- * Whether the given chain supports sponsorship for the product and auth method.
750
- *
751
- * @param chainId - The chain ID
752
- * @param productType - The product type
753
- * @param cryptoAuthMethod - The crypto authorization method to look up
754
- * @returns True if the chain row has sponsorship enabled, false if it is explicitly not sponsored
755
- * @throws If the crypto payment method or chain row is missing from pricing
756
- */
757
- #getChainSupportsSponsorship(chainId, productType, cryptoAuthMethod) {
758
- const cryptoPaymentInfo = this.#findCryptoPaymentMethod(productType, cryptoAuthMethod);
759
- if (!cryptoPaymentInfo) {
760
- throw new Error('Chains payment info not found');
761
- }
762
- const chainPaymentInfo = cryptoPaymentInfo.chains?.find((chain) => chain.chainId === chainId);
763
- if (!chainPaymentInfo) {
764
- throw new Error('Invalid chain id');
765
- }
766
- return Boolean(chainPaymentInfo.isSponsorshipSupported);
767
- }
768
- /**
769
- * Determines whether two trialed products arrays are equal by comparing all products in the arrays.
770
- *
771
- * @param oldTrialedProducts - The first trialed products array to compare.
772
- * @param newTrialedProducts - The second trialed products array to compare.
773
- * @returns True if the trialed products arrays are equal, false otherwise.
774
- */
775
- #areTrialedProductsEqual(oldTrialedProducts, newTrialedProducts) {
776
- return (oldTrialedProducts.length === newTrialedProducts?.length &&
777
- oldTrialedProducts.every((product) => newTrialedProducts?.includes(product)));
778
- }
779
- /**
780
- * Determines whether two subscription arrays are equal by comparing all properties
781
- * of each subscription in the arrays.
782
- *
783
- * @param oldSubs - The first subscription array to compare.
784
- * @param newSubs - The second subscription array to compare.
785
- * @returns True if the subscription arrays are equal, false otherwise.
786
- */
787
- #areSubscriptionsEqual(oldSubs, newSubs) {
788
- // Check if arrays have different lengths
789
- if (oldSubs.length !== newSubs.length) {
790
- return false;
791
- }
792
- // Sort both arrays by id to ensure consistent comparison
793
- const sortedOldSubs = [...oldSubs].sort((a, b) => a.id.localeCompare(b.id));
794
- const sortedNewSubs = [...newSubs].sort((a, b) => a.id.localeCompare(b.id));
795
- // Check if all subscriptions are equal
796
- return sortedOldSubs.every((oldSub, index) => {
797
- const newSub = sortedNewSubs[index];
798
- return this.#isSubscriptionEqual(oldSub, newSub);
799
- });
687
+ if (!paymentMethod.products?.length || !paymentMethod.cryptoAuthMethod) {
688
+ return undefined;
800
689
  }
801
- #isSubscriptionEqual(oldSub, newSub) {
802
- // not equal if one is undefined and the other is defined
803
- if (!oldSub || !newSub) {
804
- if (!oldSub && !newSub) {
805
- return true;
806
- }
807
- return false;
808
- }
809
- return (this.#stringifySubscription(oldSub) ===
810
- this.#stringifySubscription(newSub));
811
- }
812
- #stringifySubscription(subscription) {
813
- const subsWithSortedProducts = {
814
- ...subscription,
815
- // order the products by name
816
- products: [...subscription.products].sort((a, b) => a.name.localeCompare(b.name)),
817
- };
818
- return JSON.stringify(subsWithSortedProducts);
819
- }
820
- }
821
- //# sourceMappingURL=SubscriptionController.js.map
690
+ return {
691
+ products: paymentMethod.products,
692
+ cryptoAuthMethod: paymentMethod.cryptoAuthMethod,
693
+ explicit: true,
694
+ };
695
+ }, _SubscriptionController_getChainSupportsSponsorship = function _SubscriptionController_getChainSupportsSponsorship(chainId, productType, cryptoAuthMethod) {
696
+ const cryptoPaymentInfo = __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_findCryptoPaymentMethod).call(this, productType, cryptoAuthMethod);
697
+ if (!cryptoPaymentInfo) {
698
+ throw new Error('Chains payment info not found');
699
+ }
700
+ const chainPaymentInfo = cryptoPaymentInfo.chains?.find((chain) => chain.chainId === chainId);
701
+ if (!chainPaymentInfo) {
702
+ throw new Error('Invalid chain id');
703
+ }
704
+ return Boolean(chainPaymentInfo.isSponsorshipSupported);
705
+ }, _SubscriptionController_areTrialedProductsEqual = function _SubscriptionController_areTrialedProductsEqual(oldTrialedProducts, newTrialedProducts) {
706
+ return (oldTrialedProducts.length === newTrialedProducts?.length &&
707
+ oldTrialedProducts.every((product) => newTrialedProducts?.includes(product)));
708
+ }, _SubscriptionController_areSubscriptionsEqual = function _SubscriptionController_areSubscriptionsEqual(oldSubs, newSubs) {
709
+ // Check if arrays have different lengths
710
+ if (oldSubs.length !== newSubs.length) {
711
+ return false;
712
+ }
713
+ // Sort both arrays by id to ensure consistent comparison
714
+ const sortedOldSubs = [...oldSubs].sort((a, b) => a.id.localeCompare(b.id));
715
+ const sortedNewSubs = [...newSubs].sort((a, b) => a.id.localeCompare(b.id));
716
+ // Check if all subscriptions are equal
717
+ return sortedOldSubs.every((oldSub, index) => {
718
+ const newSub = sortedNewSubs[index];
719
+ return __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_isSubscriptionEqual).call(this, oldSub, newSub);
720
+ });
721
+ }, _SubscriptionController_isSubscriptionEqual = function _SubscriptionController_isSubscriptionEqual(oldSub, newSub) {
722
+ // not equal if one is undefined and the other is defined
723
+ if (!oldSub || !newSub) {
724
+ if (!oldSub && !newSub) {
725
+ return true;
726
+ }
727
+ return false;
728
+ }
729
+ return (__classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_stringifySubscription).call(this, oldSub) ===
730
+ __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_stringifySubscription).call(this, newSub));
731
+ }, _SubscriptionController_stringifySubscription = function _SubscriptionController_stringifySubscription(subscription) {
732
+ const subsWithSortedProducts = {
733
+ ...subscription,
734
+ // order the products by name
735
+ products: [...subscription.products].sort((a, b) => a.name.localeCompare(b.name)),
736
+ };
737
+ return JSON.stringify(subsWithSortedProducts);
738
+ };
739
+ //# sourceMappingURL=SubscriptionController.mjs.map