@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.
- package/CHANGELOG.md +0 -1
- package/dist/SubscriptionController-method-action-types.cjs +7 -0
- package/dist/SubscriptionController-method-action-types.cjs.map +1 -0
- package/dist/{SubscriptionController-method-action-types.d.ts → SubscriptionController-method-action-types.d.cts} +2 -2
- package/dist/SubscriptionController-method-action-types.d.cts.map +1 -0
- package/dist/SubscriptionController-method-action-types.d.mts +250 -0
- package/dist/SubscriptionController-method-action-types.d.mts.map +1 -0
- package/dist/{SubscriptionController-method-action-types.js → SubscriptionController-method-action-types.mjs} +1 -1
- package/dist/SubscriptionController-method-action-types.mjs.map +1 -0
- package/dist/SubscriptionController.cjs +744 -0
- package/dist/SubscriptionController.cjs.map +1 -0
- package/dist/{SubscriptionController.d.ts → SubscriptionController.d.cts} +18 -18
- package/dist/SubscriptionController.d.cts.map +1 -0
- package/dist/SubscriptionController.d.mts +258 -0
- package/dist/SubscriptionController.d.mts.map +1 -0
- package/dist/{SubscriptionController.js → SubscriptionController.mjs} +180 -262
- package/dist/SubscriptionController.mjs.map +1 -0
- 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.ts → SubscriptionService-method-action-types.d.cts} +2 -2
- package/dist/SubscriptionService-method-action-types.d.cts.map +1 -0
- package/dist/SubscriptionService-method-action-types.d.mts +155 -0
- package/dist/SubscriptionService-method-action-types.d.mts.map +1 -0
- package/dist/{SubscriptionService-method-action-types.js → SubscriptionService-method-action-types.mjs} +1 -1
- package/dist/SubscriptionService-method-action-types.mjs.map +1 -0
- package/dist/SubscriptionService-structs.cjs +158 -0
- package/dist/SubscriptionService-structs.cjs.map +1 -0
- package/dist/{SubscriptionService-structs.d.ts → SubscriptionService-structs.d.cts} +134 -134
- package/dist/SubscriptionService-structs.d.cts.map +1 -0
- package/dist/SubscriptionService-structs.d.mts +721 -0
- package/dist/SubscriptionService-structs.d.mts.map +1 -0
- package/dist/{SubscriptionService-structs.js → SubscriptionService-structs.mjs} +4 -4
- package/dist/SubscriptionService-structs.mjs.map +1 -0
- package/dist/SubscriptionService.cjs +477 -0
- package/dist/SubscriptionService.cjs.map +1 -0
- package/dist/{SubscriptionService.d.ts → SubscriptionService.d.cts} +10 -10
- package/dist/SubscriptionService.d.cts.map +1 -0
- package/dist/SubscriptionService.d.mts +149 -0
- package/dist/SubscriptionService.d.mts.map +1 -0
- package/dist/{SubscriptionService.js → SubscriptionService.mjs} +141 -139
- package/dist/SubscriptionService.mjs.map +1 -0
- package/dist/constants.cjs +73 -0
- package/dist/constants.cjs.map +1 -0
- package/dist/{constants.d.ts → constants.d.cts} +1 -1
- package/dist/constants.d.cts.map +1 -0
- package/dist/constants.d.mts +49 -0
- package/dist/constants.d.mts.map +1 -0
- package/dist/{constants.js → constants.mjs} +3 -3
- package/dist/constants.mjs.map +1 -0
- package/dist/errors.cjs +72 -0
- package/dist/errors.cjs.map +1 -0
- package/dist/{errors.d.ts → errors.d.cts} +2 -2
- package/dist/errors.d.cts.map +1 -0
- package/dist/errors.d.mts +34 -0
- package/dist/errors.d.mts.map +1 -0
- package/dist/{errors.js → errors.mjs} +1 -5
- package/dist/errors.mjs.map +1 -0
- package/dist/index.cjs +29 -0
- package/dist/index.cjs.map +1 -0
- package/dist/{index.d.ts → index.d.cts} +11 -11
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +11 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/{index.js → index.mjs} +6 -6
- package/dist/index.mjs.map +1 -0
- package/dist/logger.cjs +8 -0
- package/dist/logger.cjs.map +1 -0
- package/dist/logger.d.cts +5 -0
- package/dist/logger.d.cts.map +1 -0
- package/dist/logger.d.mts +5 -0
- package/dist/logger.d.mts.map +1 -0
- package/dist/logger.mjs +5 -0
- package/dist/logger.mjs.map +1 -0
- package/dist/types.cjs +90 -0
- package/dist/types.cjs.map +1 -0
- package/dist/{types.d.ts → types.d.cts} +41 -41
- package/dist/types.d.cts.map +1 -0
- package/dist/types.d.mts +574 -0
- package/dist/types.d.mts.map +1 -0
- package/dist/{types.js → types.mjs} +1 -1
- package/dist/types.mjs.map +1 -0
- package/package.json +16 -12
- package/dist/SubscriptionController-method-action-types.d.ts.map +0 -1
- package/dist/SubscriptionController-method-action-types.js.map +0 -1
- package/dist/SubscriptionController.d.ts.map +0 -1
- package/dist/SubscriptionController.js.map +0 -1
- package/dist/SubscriptionService-method-action-types.d.ts.map +0 -1
- package/dist/SubscriptionService-method-action-types.js.map +0 -1
- package/dist/SubscriptionService-structs.d.ts.map +0 -1
- package/dist/SubscriptionService-structs.js.map +0 -1
- package/dist/SubscriptionService.d.ts.map +0 -1
- package/dist/SubscriptionService.js.map +0 -1
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/logger.d.ts +0 -4
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js +0 -5
- package/dist/logger.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
294
|
-
const productPrice = this
|
|
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
|
|
304
|
+
const isTrialRequested = __classPrivateFieldGet(this, _SubscriptionController_instances, "m", _SubscriptionController_getIsTrialRequested).call(this, [productType], lastSelectedPaymentMethodForProduct.plan);
|
|
298
305
|
const currentSubscription = this.getSubscriptionByProduct(productType);
|
|
299
|
-
this
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
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
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
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
|
-
|
|
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
|
-
|
|
675
|
-
|
|
676
|
-
|
|
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
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
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:
|
|
744
|
-
cryptoAuthMethod:
|
|
745
|
-
explicit:
|
|
682
|
+
products: [PRODUCT_TYPES.SHIELD],
|
|
683
|
+
cryptoAuthMethod: CRYPTO_AUTH_METHODS.ERC20_APPROVAL,
|
|
684
|
+
explicit: false,
|
|
746
685
|
};
|
|
747
686
|
}
|
|
748
|
-
|
|
749
|
-
|
|
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
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
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
|