@metamask/subscription-controller 9.1.0 → 10.0.0
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 +27 -1
- package/dist/SubscriptionService-structs.d.ts +150 -36
- package/dist/SubscriptionService-structs.d.ts.map +1 -1
- package/dist/SubscriptionService-structs.js +46 -12
- package/dist/SubscriptionService-structs.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/selectors.d.ts +41 -1
- package/dist/selectors.d.ts.map +1 -1
- package/dist/selectors.js +65 -0
- package/dist/selectors.js.map +1 -1
- package/dist/subscription-delegation/SubscriptionDelegationService-method-action-types.d.ts +5 -0
- package/dist/subscription-delegation/SubscriptionDelegationService-method-action-types.d.ts.map +1 -1
- package/dist/subscription-delegation/SubscriptionDelegationService-method-action-types.js.map +1 -1
- package/dist/subscription-delegation/SubscriptionDelegationService.d.ts +6 -1
- package/dist/subscription-delegation/SubscriptionDelegationService.d.ts.map +1 -1
- package/dist/subscription-delegation/SubscriptionDelegationService.js +35 -15
- package/dist/subscription-delegation/SubscriptionDelegationService.js.map +1 -1
- package/dist/subscription-delegation/fingerprint.d.ts +11 -0
- package/dist/subscription-delegation/fingerprint.d.ts.map +1 -1
- package/dist/subscription-delegation/fingerprint.js +40 -0
- package/dist/subscription-delegation/fingerprint.js.map +1 -1
- package/dist/types.d.ts +107 -17
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +39 -0
- package/dist/types.js.map +1 -1
- package/package.json +10 -10
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export type { SubscriptionControllerActions, SubscriptionControllerState, SubscriptionControllerEvents, SubscriptionControllerGetStateAction, SubscriptionControllerMessenger, SubscriptionControllerOptions, SubscriptionControllerStateChangeEvent, } from './SubscriptionController.js';
|
|
2
2
|
export type { SubscriptionControllerGetPricingAction, SubscriptionControllerGetSubscriptionsAction, SubscriptionControllerGetBenefitsAction, SubscriptionControllerGetSubscriptionByProductAction, SubscriptionControllerGetSubscriptionsEligibilitiesAction, SubscriptionControllerCancelSubscriptionAction, SubscriptionControllerUnCancelSubscriptionAction, SubscriptionControllerStartSubscriptionWithCardAction, SubscriptionControllerStartSubscriptionWithCryptoAction, SubscriptionControllerSubmitSubscriptionCryptoApprovalAction, SubscriptionControllerGetCryptoApproveTransactionParamsAction, SubscriptionControllerUpdatePaymentMethodAction, SubscriptionControllerGetBillingPortalUrlAction, SubscriptionControllerCacheLastSelectedPaymentMethodAction, SubscriptionControllerClearLastSelectedPaymentMethodAction, SubscriptionControllerSubmitSponsorshipIntentsAction, SubscriptionControllerSubmitUserEventAction, SubscriptionControllerAssignUserToCohortAction, SubscriptionControllerLinkRewardsAction, SubscriptionControllerGetTokenApproveAmountAction, SubscriptionControllerGetTokenMinimumBalanceAmountAction, SubscriptionControllerClearStateAction, SubscriptionControllerTriggerAccessTokenRefreshAction, SubscriptionControllerStopAllPollingAction, } from './SubscriptionController-method-action-types.js';
|
|
3
3
|
export { SubscriptionController, getDefaultSubscriptionControllerState, } from './SubscriptionController.js';
|
|
4
|
-
export type { SubscriptionApiError, Subscription, PerpsBenefitUsage, PredictBenefitUsage, SubscriptionBenefitsResponse, SubscriptionBenefitsState, SwapsBenefitUsage, AuthUtils, CancelSubscriptionRequest, CancelType, CancellationReasonCode, ISubscriptionService, StartCryptoSubscriptionRequest, StartDelegationCryptoSubscriptionRequest, StartErc20CryptoSubscriptionRequest, StartCryptoSubscriptionResponse, StartSubscriptionRequest, StartSubscriptionResponse, GetCryptoApproveTransactionRequest, GetCryptoApproveTransactionResponse, SubmitSubscriptionCryptoApprovalRequest, SubscriptionCardPaymentMethod, SubscriptionCryptoPaymentMethod, SubscriptionPaymentMethod, SubmitUserEventRequest, SubmitSponsorshipIntentsRequest, SubscriptionEligibility, SubscriptionUserEventType, RecurringInterval, SubscriptionStatus, PaymentType, Product, ProductType, ProductPrice, ProductPricing, TokenPaymentInfo, SpotTokenPaymentInfo, VaultTokenPaymentInfo, ChainPaymentInfo, Currency, CryptoAuthMethod, PricingPaymentMethod, PricingCardPaymentMethod, PricingCryptoPaymentMethod, PricingResponse, UpdatePaymentMethodOpts, BillingPortalResponse, CryptoPaymentMethodError, UpdatePaymentMethodCryptoRequest, UpdatePaymentMethodCardRequest, UpdatePaymentMethodCardResponse, CachedLastSelectedPaymentMethod, CacheLastSelectedPaymentMethodRequest, SubmitSponsorshipIntentsMethodParams, Cohort, CohortName, BalanceCategory, AssignCohortRequest, GetSubscriptionsEligibilitiesRequest, ModalType, MoneyAccountEntitlements, MoneyAccountPlusClaim, ProductEntitlementFeatureMap, ProductEntitlements, ShieldEntitlements, } from './types.js';
|
|
5
|
-
export { CANCEL_TYPES, CRYPTO_PAYMENT_METHOD_ERRORS, SUBSCRIPTION_STATUSES, PRODUCT_TYPES, RECURRING_INTERVALS, PAYMENT_TYPES, CRYPTO_AUTH_METHODS, SubscriptionUserEvent, COHORT_NAMES, BALANCE_CATEGORIES, MODAL_TYPE, MoneyAccountFeature, ShieldFeature, } from './types.js';
|
|
4
|
+
export type { SubscriptionApiError, Subscription, PerpsBenefitUsage, PredictBenefitUsage, SubscriptionBenefitsResponse, SubscriptionBenefitsState, SwapsBenefitUsage, AuthUtils, CancelSubscriptionRequest, CancelType, CancellationReasonCode, ISubscriptionService, StartCryptoSubscriptionRequest, StartDelegationCryptoSubscriptionRequest, StartErc20CryptoSubscriptionRequest, StartCryptoSubscriptionResponse, StartSubscriptionRequest, StartSubscriptionResponse, GetCryptoApproveTransactionRequest, GetCryptoApproveTransactionResponse, SubmitSubscriptionCryptoApprovalRequest, SubscriptionCardPaymentMethod, SubscriptionCryptoPaymentMethod, SubscriptionPaymentMethod, SubscriptionInvoice, InvoicePaymentStatus, SubmitUserEventRequest, SubmitSponsorshipIntentsRequest, SubscriptionEligibility, SubscriptionUserEventType, RecurringInterval, SubscriptionStatus, PaymentType, Product, ProductType, ProductPrice, ProductPricing, TokenPaymentInfo, SpotTokenPaymentInfo, VaultTokenPaymentInfo, VaultName, ChainPaymentInfo, Currency, CryptoAuthMethod, PricingPaymentMethod, PricingCardPaymentMethod, PricingCryptoPaymentMethod, PricingResponse, UpdatePaymentMethodOpts, BillingPortalResponse, CryptoPaymentMethodError, CryptoPaymentError, UpdateErc20PaymentMethodCryptoRequest, UpdateDelegationPaymentMethodCryptoRequest, UpdatePaymentMethodCryptoRequest, UpdatePaymentMethodCardRequest, UpdatePaymentMethodCardResponse, CachedLastSelectedPaymentMethod, CacheLastSelectedPaymentMethodRequest, SubmitSponsorshipIntentsMethodParams, Cohort, CohortName, BalanceCategory, AssignCohortRequest, GetSubscriptionsEligibilitiesRequest, ModalType, MoneyAccountEntitlements, MoneyAccountPlusClaim, ProductEntitlementFeatureMap, ProductEntitlements, ShieldEntitlements, } from './types.js';
|
|
5
|
+
export { CANCEL_TYPES, CRYPTO_PAYMENT_METHOD_ERRORS, CRYPTO_PAYMENT_ERRORS, INVOICE_PAYMENT_STATUSES, SUBSCRIPTION_STATUSES, PRODUCT_TYPES, RECURRING_INTERVALS, PAYMENT_TYPES, CRYPTO_AUTH_METHODS, VAULT_NAMES, isVaultShareToken, SubscriptionUserEvent, COHORT_NAMES, BALANCE_CATEGORIES, MODAL_TYPE, MoneyAccountFeature, ShieldFeature, } from './types.js';
|
|
6
6
|
export { CANCELLATION_REASONS } from './constants.js';
|
|
7
|
-
export { selectHasEntitlement, selectIsActiveSubscriber, selectIsUsageAvailable, } from './selectors.js';
|
|
7
|
+
export { selectHasEntitlement, selectIsActiveSubscriber, selectIsUsageAvailable, selectIsPaymentFailed, selectPaymentFailureReason, selectIsRenewalNeeded, selectIsDelegationExhausted, } from './selectors.js';
|
|
8
8
|
export { SubscriptionServiceError } from './errors.js';
|
|
9
9
|
export { Env, SubscriptionControllerErrorMessage, SubscriptionServiceErrorMessage, SubscriptionDelegationServiceErrorMessage, } from './constants.js';
|
|
10
10
|
export type { SubscriptionServiceOptions, SubscriptionServiceMessenger, SubscriptionServiceActions, SubscriptionServiceEvents, SubscriptionServiceCacheUpdatedEvent, SubscriptionServiceGranularCacheUpdatedEvent, SubscriptionServiceInvalidateQueriesAction, } from './SubscriptionService.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,6BAA6B,EAC7B,2BAA2B,EAC3B,4BAA4B,EAC5B,oCAAoC,EACpC,+BAA+B,EAC/B,6BAA6B,EAC7B,sCAAsC,GACvC,MAAM,6BAA6B,CAAC;AACrC,YAAY,EACV,sCAAsC,EACtC,4CAA4C,EAC5C,uCAAuC,EACvC,oDAAoD,EACpD,yDAAyD,EACzD,8CAA8C,EAC9C,gDAAgD,EAChD,qDAAqD,EACrD,uDAAuD,EACvD,4DAA4D,EAC5D,6DAA6D,EAC7D,+CAA+C,EAC/C,+CAA+C,EAC/C,0DAA0D,EAC1D,0DAA0D,EAC1D,oDAAoD,EACpD,2CAA2C,EAC3C,8CAA8C,EAC9C,uCAAuC,EACvC,iDAAiD,EACjD,wDAAwD,EACxD,sCAAsC,EACtC,qDAAqD,EACrD,0CAA0C,GAC3C,MAAM,iDAAiD,CAAC;AACzD,OAAO,EACL,sBAAsB,EACtB,qCAAqC,GACtC,MAAM,6BAA6B,CAAC;AACrC,YAAY,EACV,oBAAoB,EACpB,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,4BAA4B,EAC5B,yBAAyB,EACzB,iBAAiB,EACjB,SAAS,EACT,yBAAyB,EACzB,UAAU,EACV,sBAAsB,EACtB,oBAAoB,EACpB,8BAA8B,EAC9B,wCAAwC,EACxC,mCAAmC,EACnC,+BAA+B,EAC/B,wBAAwB,EACxB,yBAAyB,EACzB,kCAAkC,EAClC,mCAAmC,EACnC,uCAAuC,EACvC,6BAA6B,EAC7B,+BAA+B,EAC/B,yBAAyB,EACzB,sBAAsB,EACtB,+BAA+B,EAC/B,uBAAuB,EACvB,yBAAyB,EACzB,iBAAiB,EACjB,kBAAkB,EAClB,WAAW,EACX,OAAO,EACP,WAAW,EACX,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,EAChB,QAAQ,EACR,gBAAgB,EAChB,oBAAoB,EACpB,wBAAwB,EACxB,0BAA0B,EAC1B,eAAe,EACf,uBAAuB,EACvB,qBAAqB,EACrB,wBAAwB,EACxB,gCAAgC,EAChC,8BAA8B,EAC9B,+BAA+B,EAC/B,+BAA+B,EAC/B,qCAAqC,EACrC,oCAAoC,EACpC,MAAM,EACN,UAAU,EACV,eAAe,EACf,mBAAmB,EACnB,oCAAoC,EACpC,SAAS,EACT,wBAAwB,EACxB,qBAAqB,EACrB,4BAA4B,EAC5B,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,YAAY,EACZ,4BAA4B,EAC5B,qBAAqB,EACrB,aAAa,EACb,mBAAmB,EACnB,aAAa,EACb,mBAAmB,EACnB,qBAAqB,EACrB,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,mBAAmB,EACnB,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,sBAAsB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { SubscriptionController, getDefaultSubscriptionControllerState, } from './SubscriptionController.js';
|
|
2
|
-
export { CANCEL_TYPES, CRYPTO_PAYMENT_METHOD_ERRORS, SUBSCRIPTION_STATUSES, PRODUCT_TYPES, RECURRING_INTERVALS, PAYMENT_TYPES, CRYPTO_AUTH_METHODS, SubscriptionUserEvent, COHORT_NAMES, BALANCE_CATEGORIES, MODAL_TYPE, MoneyAccountFeature, ShieldFeature, } from './types.js';
|
|
2
|
+
export { CANCEL_TYPES, CRYPTO_PAYMENT_METHOD_ERRORS, CRYPTO_PAYMENT_ERRORS, INVOICE_PAYMENT_STATUSES, SUBSCRIPTION_STATUSES, PRODUCT_TYPES, RECURRING_INTERVALS, PAYMENT_TYPES, CRYPTO_AUTH_METHODS, VAULT_NAMES, isVaultShareToken, SubscriptionUserEvent, COHORT_NAMES, BALANCE_CATEGORIES, MODAL_TYPE, MoneyAccountFeature, ShieldFeature, } from './types.js';
|
|
3
3
|
export { CANCELLATION_REASONS } from './constants.js';
|
|
4
|
-
export { selectHasEntitlement, selectIsActiveSubscriber, selectIsUsageAvailable, } from './selectors.js';
|
|
4
|
+
export { selectHasEntitlement, selectIsActiveSubscriber, selectIsUsageAvailable, selectIsPaymentFailed, selectPaymentFailureReason, selectIsRenewalNeeded, selectIsDelegationExhausted, } from './selectors.js';
|
|
5
5
|
export { SubscriptionServiceError } from './errors.js';
|
|
6
6
|
export { Env, SubscriptionControllerErrorMessage, SubscriptionServiceErrorMessage, SubscriptionDelegationServiceErrorMessage, } from './constants.js';
|
|
7
7
|
export { SubscriptionService, serviceName as subscriptionServiceName, SUBSCRIPTION_URL, } from './SubscriptionService.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAmCA,OAAO,EACL,sBAAsB,EACtB,qCAAqC,GACtC,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAmCA,OAAO,EACL,sBAAsB,EACtB,qCAAqC,GACtC,MAAM,6BAA6B,CAAC;AA0ErC,OAAO,EACL,YAAY,EACZ,4BAA4B,EAC5B,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACrB,aAAa,EACb,mBAAmB,EACnB,aAAa,EACb,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,qBAAqB,EACrB,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,mBAAmB,EACnB,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,sBAAsB,EACtB,qBAAqB,EACrB,0BAA0B,EAC1B,qBAAqB,EACrB,2BAA2B,GAC5B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EACL,GAAG,EACH,kCAAkC,EAClC,+BAA+B,EAC/B,yCAAyC,GAC1C,MAAM,gBAAgB,CAAC;AAUxB,OAAO,EACL,mBAAmB,EACnB,WAAW,IAAI,uBAAuB,EACtC,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAyBlC,OAAO,EACL,6BAA6B,EAC7B,WAAW,IAAI,iCAAiC,GACjD,MAAM,4DAA4D,CAAC;AASpE,OAAO,EAAE,iCAAiC,EAAE,MAAM,oCAAoC,CAAC","sourcesContent":["export type {\n SubscriptionControllerActions,\n SubscriptionControllerState,\n SubscriptionControllerEvents,\n SubscriptionControllerGetStateAction,\n SubscriptionControllerMessenger,\n SubscriptionControllerOptions,\n SubscriptionControllerStateChangeEvent,\n} from './SubscriptionController.js';\nexport type {\n SubscriptionControllerGetPricingAction,\n SubscriptionControllerGetSubscriptionsAction,\n SubscriptionControllerGetBenefitsAction,\n SubscriptionControllerGetSubscriptionByProductAction,\n SubscriptionControllerGetSubscriptionsEligibilitiesAction,\n SubscriptionControllerCancelSubscriptionAction,\n SubscriptionControllerUnCancelSubscriptionAction,\n SubscriptionControllerStartSubscriptionWithCardAction,\n SubscriptionControllerStartSubscriptionWithCryptoAction,\n SubscriptionControllerSubmitSubscriptionCryptoApprovalAction,\n SubscriptionControllerGetCryptoApproveTransactionParamsAction,\n SubscriptionControllerUpdatePaymentMethodAction,\n SubscriptionControllerGetBillingPortalUrlAction,\n SubscriptionControllerCacheLastSelectedPaymentMethodAction,\n SubscriptionControllerClearLastSelectedPaymentMethodAction,\n SubscriptionControllerSubmitSponsorshipIntentsAction,\n SubscriptionControllerSubmitUserEventAction,\n SubscriptionControllerAssignUserToCohortAction,\n SubscriptionControllerLinkRewardsAction,\n SubscriptionControllerGetTokenApproveAmountAction,\n SubscriptionControllerGetTokenMinimumBalanceAmountAction,\n SubscriptionControllerClearStateAction,\n SubscriptionControllerTriggerAccessTokenRefreshAction,\n SubscriptionControllerStopAllPollingAction,\n} from './SubscriptionController-method-action-types.js';\nexport {\n SubscriptionController,\n getDefaultSubscriptionControllerState,\n} from './SubscriptionController.js';\nexport type {\n SubscriptionApiError,\n Subscription,\n PerpsBenefitUsage,\n PredictBenefitUsage,\n SubscriptionBenefitsResponse,\n SubscriptionBenefitsState,\n SwapsBenefitUsage,\n AuthUtils,\n CancelSubscriptionRequest,\n CancelType,\n CancellationReasonCode,\n ISubscriptionService,\n StartCryptoSubscriptionRequest,\n StartDelegationCryptoSubscriptionRequest,\n StartErc20CryptoSubscriptionRequest,\n StartCryptoSubscriptionResponse,\n StartSubscriptionRequest,\n StartSubscriptionResponse,\n GetCryptoApproveTransactionRequest,\n GetCryptoApproveTransactionResponse,\n SubmitSubscriptionCryptoApprovalRequest,\n SubscriptionCardPaymentMethod,\n SubscriptionCryptoPaymentMethod,\n SubscriptionPaymentMethod,\n SubscriptionInvoice,\n InvoicePaymentStatus,\n SubmitUserEventRequest,\n SubmitSponsorshipIntentsRequest,\n SubscriptionEligibility,\n SubscriptionUserEventType,\n RecurringInterval,\n SubscriptionStatus,\n PaymentType,\n Product,\n ProductType,\n ProductPrice,\n ProductPricing,\n TokenPaymentInfo,\n SpotTokenPaymentInfo,\n VaultTokenPaymentInfo,\n VaultName,\n ChainPaymentInfo,\n Currency,\n CryptoAuthMethod,\n PricingPaymentMethod,\n PricingCardPaymentMethod,\n PricingCryptoPaymentMethod,\n PricingResponse,\n UpdatePaymentMethodOpts,\n BillingPortalResponse,\n CryptoPaymentMethodError,\n CryptoPaymentError,\n UpdateErc20PaymentMethodCryptoRequest,\n UpdateDelegationPaymentMethodCryptoRequest,\n UpdatePaymentMethodCryptoRequest,\n UpdatePaymentMethodCardRequest,\n UpdatePaymentMethodCardResponse,\n CachedLastSelectedPaymentMethod,\n CacheLastSelectedPaymentMethodRequest,\n SubmitSponsorshipIntentsMethodParams,\n Cohort,\n CohortName,\n BalanceCategory,\n AssignCohortRequest,\n GetSubscriptionsEligibilitiesRequest,\n ModalType,\n MoneyAccountEntitlements,\n MoneyAccountPlusClaim,\n ProductEntitlementFeatureMap,\n ProductEntitlements,\n ShieldEntitlements,\n} from './types.js';\nexport {\n CANCEL_TYPES,\n CRYPTO_PAYMENT_METHOD_ERRORS,\n CRYPTO_PAYMENT_ERRORS,\n INVOICE_PAYMENT_STATUSES,\n SUBSCRIPTION_STATUSES,\n PRODUCT_TYPES,\n RECURRING_INTERVALS,\n PAYMENT_TYPES,\n CRYPTO_AUTH_METHODS,\n VAULT_NAMES,\n isVaultShareToken,\n SubscriptionUserEvent,\n COHORT_NAMES,\n BALANCE_CATEGORIES,\n MODAL_TYPE,\n MoneyAccountFeature,\n ShieldFeature,\n} from './types.js';\nexport { CANCELLATION_REASONS } from './constants.js';\nexport {\n selectHasEntitlement,\n selectIsActiveSubscriber,\n selectIsUsageAvailable,\n selectIsPaymentFailed,\n selectPaymentFailureReason,\n selectIsRenewalNeeded,\n selectIsDelegationExhausted,\n} from './selectors.js';\nexport { SubscriptionServiceError } from './errors.js';\nexport {\n Env,\n SubscriptionControllerErrorMessage,\n SubscriptionServiceErrorMessage,\n SubscriptionDelegationServiceErrorMessage,\n} from './constants.js';\nexport type {\n SubscriptionServiceOptions,\n SubscriptionServiceMessenger,\n SubscriptionServiceActions,\n SubscriptionServiceEvents,\n SubscriptionServiceCacheUpdatedEvent,\n SubscriptionServiceGranularCacheUpdatedEvent,\n SubscriptionServiceInvalidateQueriesAction,\n} from './SubscriptionService.js';\nexport {\n SubscriptionService,\n serviceName as subscriptionServiceName,\n SUBSCRIPTION_URL,\n} from './SubscriptionService.js';\nexport type {\n SubscriptionServiceGetSubscriptionsAction,\n SubscriptionServiceGetBenefitsAction,\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} from './SubscriptionService-method-action-types.js';\n\nexport type {\n SubscriptionDelegationServiceActions,\n SubscriptionDelegationServiceEvents,\n SubscriptionDelegationServiceMessenger,\n SubscriptionDelegationServiceOptions,\n} from './subscription-delegation/SubscriptionDelegationService.js';\nexport {\n SubscriptionDelegationService,\n serviceName as subscriptionDelegationServiceName,\n} from './subscription-delegation/SubscriptionDelegationService.js';\nexport type { SubscriptionDelegationServicePrepareDelegationAction } from './subscription-delegation/SubscriptionDelegationService-method-action-types.js';\nexport type { SubscriptionDelegationServiceCheckMoneyAccountBalanceAction } from './subscription-delegation/SubscriptionDelegationService-method-action-types.js';\nexport type {\n MoneyAccountBalanceCheckRequest,\n MoneyAccountBalanceCheckResult,\n PrepareSubscriptionDelegationRequest,\n PreparedSubscriptionDelegation,\n} from './subscription-delegation/types.js';\nexport { CASH_SUBSCRIPTION_DELEGATION_TYPE } from './subscription-delegation/types.js';\n"]}
|
package/dist/selectors.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { SubscriptionControllerState } from './SubscriptionController.js';
|
|
2
|
-
import type { ProductEntitlementFeatureMap, ProductType } from './types.js';
|
|
2
|
+
import type { CryptoPaymentError, ProductEntitlementFeatureMap, ProductType } from './types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Returns whether a specific product feature entitlement is enabled.
|
|
5
5
|
*
|
|
@@ -35,4 +35,44 @@ export declare function selectIsUsageAvailable<TProduct extends ProductType>(sta
|
|
|
35
35
|
* @returns Whether the user is an active subscriber for the product.
|
|
36
36
|
*/
|
|
37
37
|
export declare function selectIsActiveSubscriber(state: SubscriptionControllerState, productType: ProductType): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Returns whether the product's latest crypto payment failed.
|
|
40
|
+
*
|
|
41
|
+
* The result is based on the latest invoice status. Payment-method setup
|
|
42
|
+
* errors in `paymentMethod.crypto.error` are intentionally not treated as
|
|
43
|
+
* invoice execution failures by this selector.
|
|
44
|
+
*
|
|
45
|
+
* @param state - The subscription controller state.
|
|
46
|
+
* @param productType - The product whose payment state is queried.
|
|
47
|
+
* @returns Whether the latest crypto payment failed.
|
|
48
|
+
*/
|
|
49
|
+
export declare function selectIsPaymentFailed(state: SubscriptionControllerState, productType: ProductType): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Returns the raw Subscription API execution error for the latest crypto
|
|
52
|
+
* payment.
|
|
53
|
+
*
|
|
54
|
+
* @param state - The subscription controller state.
|
|
55
|
+
* @param productType - The product whose payment failure is queried.
|
|
56
|
+
* @returns The raw payment execution error, if present.
|
|
57
|
+
*/
|
|
58
|
+
export declare function selectPaymentFailureReason(state: SubscriptionControllerState, productType: ProductType): CryptoPaymentError | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Returns whether the latest payment needs renewal or delegation recovery.
|
|
61
|
+
*
|
|
62
|
+
* The Subscription API signals this through `lastInvoice.errorCode` rather
|
|
63
|
+
* than a derived boolean.
|
|
64
|
+
*
|
|
65
|
+
* @param state - The subscription controller state.
|
|
66
|
+
* @param productType - The product whose renewal state is queried.
|
|
67
|
+
* @returns Whether renewal/recovery can be offered.
|
|
68
|
+
*/
|
|
69
|
+
export declare function selectIsRenewalNeeded(state: SubscriptionControllerState, productType: ProductType): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Returns whether the delegation has exhausted its allowance.
|
|
72
|
+
*
|
|
73
|
+
* @param state - The subscription controller state.
|
|
74
|
+
* @param productType - The product whose delegation state is queried.
|
|
75
|
+
* @returns Whether the delegation allowance is exhausted.
|
|
76
|
+
*/
|
|
77
|
+
export declare function selectIsDelegationExhausted(state: SubscriptionControllerState, productType: ProductType): boolean;
|
|
38
78
|
//# sourceMappingURL=selectors.d.ts.map
|
package/dist/selectors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectors.d.ts","sourceRoot":"","sources":["../src/selectors.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"selectors.d.ts","sourceRoot":"","sources":["../src/selectors.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAM/E,OAAO,KAAK,EACV,kBAAkB,EAClB,4BAA4B,EAC5B,WAAW,EAEZ,MAAM,YAAY,CAAC;AA2BpB;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,SAAS,WAAW,EAC/D,KAAK,EAAE,2BAA2B,EAClC,WAAW,EAAE,QAAQ,EACrB,OAAO,EAAE,4BAA4B,CAAC,QAAQ,CAAC,GAC9C,OAAO,CAOT;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,SAAS,WAAW,EACjE,KAAK,EAAE,2BAA2B,EAClC,WAAW,EAAE,QAAQ,EACrB,OAAO,EAAE,4BAA4B,CAAC,QAAQ,CAAC,GAC9C,OAAO,CAET;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,2BAA2B,EAClC,WAAW,EAAE,WAAW,GACvB,OAAO,CAMT;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,2BAA2B,EAClC,WAAW,EAAE,WAAW,GACvB,OAAO,CAOT;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,2BAA2B,EAClC,WAAW,EAAE,WAAW,GACvB,kBAAkB,GAAG,SAAS,CAEhC;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,2BAA2B,EAClC,WAAW,EAAE,WAAW,GACvB,OAAO,CAOT;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,2BAA2B,EAClC,WAAW,EAAE,WAAW,GACvB,OAAO,CAKT"}
|
package/dist/selectors.js
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import { ACTIVE_SUBSCRIPTION_STATUSES } from './constants.js';
|
|
2
|
+
import { CRYPTO_PAYMENT_ERRORS, INVOICE_PAYMENT_STATUSES, PAYMENT_TYPES, } from './types.js';
|
|
3
|
+
function getSubscriptionByProduct(state, productType) {
|
|
4
|
+
return state.subscriptions.find((subscription) => subscription.products.some((product) => product.name === productType));
|
|
5
|
+
}
|
|
6
|
+
function getPaymentExecutionError(state, productType) {
|
|
7
|
+
const subscription = getSubscriptionByProduct(state, productType);
|
|
8
|
+
if (subscription?.paymentMethod.type !== PAYMENT_TYPES.byCrypto ||
|
|
9
|
+
subscription.lastInvoice?.status !== INVOICE_PAYMENT_STATUSES.FAILED) {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
return subscription.lastInvoice?.errorCode;
|
|
13
|
+
}
|
|
2
14
|
/**
|
|
3
15
|
* Returns whether a specific product feature entitlement is enabled.
|
|
4
16
|
*
|
|
@@ -43,4 +55,57 @@ export function selectIsActiveSubscriber(state, productType) {
|
|
|
43
55
|
return state.subscriptions.some((subscription) => ACTIVE_SUBSCRIPTION_STATUSES.includes(subscription.status) &&
|
|
44
56
|
subscription.products.some((product) => product.name === productType));
|
|
45
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Returns whether the product's latest crypto payment failed.
|
|
60
|
+
*
|
|
61
|
+
* The result is based on the latest invoice status. Payment-method setup
|
|
62
|
+
* errors in `paymentMethod.crypto.error` are intentionally not treated as
|
|
63
|
+
* invoice execution failures by this selector.
|
|
64
|
+
*
|
|
65
|
+
* @param state - The subscription controller state.
|
|
66
|
+
* @param productType - The product whose payment state is queried.
|
|
67
|
+
* @returns Whether the latest crypto payment failed.
|
|
68
|
+
*/
|
|
69
|
+
export function selectIsPaymentFailed(state, productType) {
|
|
70
|
+
const subscription = getSubscriptionByProduct(state, productType);
|
|
71
|
+
return Boolean(subscription?.paymentMethod.type === PAYMENT_TYPES.byCrypto &&
|
|
72
|
+
subscription.lastInvoice?.status === INVOICE_PAYMENT_STATUSES.FAILED);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Returns the raw Subscription API execution error for the latest crypto
|
|
76
|
+
* payment.
|
|
77
|
+
*
|
|
78
|
+
* @param state - The subscription controller state.
|
|
79
|
+
* @param productType - The product whose payment failure is queried.
|
|
80
|
+
* @returns The raw payment execution error, if present.
|
|
81
|
+
*/
|
|
82
|
+
export function selectPaymentFailureReason(state, productType) {
|
|
83
|
+
return getPaymentExecutionError(state, productType);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Returns whether the latest payment needs renewal or delegation recovery.
|
|
87
|
+
*
|
|
88
|
+
* The Subscription API signals this through `lastInvoice.errorCode` rather
|
|
89
|
+
* than a derived boolean.
|
|
90
|
+
*
|
|
91
|
+
* @param state - The subscription controller state.
|
|
92
|
+
* @param productType - The product whose renewal state is queried.
|
|
93
|
+
* @returns Whether renewal/recovery can be offered.
|
|
94
|
+
*/
|
|
95
|
+
export function selectIsRenewalNeeded(state, productType) {
|
|
96
|
+
const errorCode = getPaymentExecutionError(state, productType);
|
|
97
|
+
return (errorCode === CRYPTO_PAYMENT_ERRORS.INSUFFICIENT_BALANCE ||
|
|
98
|
+
errorCode === CRYPTO_PAYMENT_ERRORS.DELEGATION_NOT_FOUND);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Returns whether the delegation has exhausted its allowance.
|
|
102
|
+
*
|
|
103
|
+
* @param state - The subscription controller state.
|
|
104
|
+
* @param productType - The product whose delegation state is queried.
|
|
105
|
+
* @returns Whether the delegation allowance is exhausted.
|
|
106
|
+
*/
|
|
107
|
+
export function selectIsDelegationExhausted(state, productType) {
|
|
108
|
+
return (getPaymentExecutionError(state, productType) ===
|
|
109
|
+
CRYPTO_PAYMENT_ERRORS.EXCEEDS_DELEGATION_ALLOWANCE);
|
|
110
|
+
}
|
|
46
111
|
//# sourceMappingURL=selectors.js.map
|
package/dist/selectors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectors.js","sourceRoot":"","sources":["../src/selectors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"selectors.js","sourceRoot":"","sources":["../src/selectors.ts"],"names":[],"mappings":"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","sourcesContent":["import { ACTIVE_SUBSCRIPTION_STATUSES } from './constants.js';\nimport type { SubscriptionControllerState } from './SubscriptionController.js';\nimport {\n CRYPTO_PAYMENT_ERRORS,\n INVOICE_PAYMENT_STATUSES,\n PAYMENT_TYPES,\n} from './types.js';\nimport type {\n CryptoPaymentError,\n ProductEntitlementFeatureMap,\n ProductType,\n Subscription,\n} from './types.js';\n\nfunction getSubscriptionByProduct(\n state: SubscriptionControllerState,\n productType: ProductType,\n): Subscription | undefined {\n return state.subscriptions.find((subscription) =>\n subscription.products.some((product) => product.name === productType),\n );\n}\n\nfunction getPaymentExecutionError(\n state: SubscriptionControllerState,\n productType: ProductType,\n): CryptoPaymentError | undefined {\n const subscription = getSubscriptionByProduct(state, productType);\n\n if (\n subscription?.paymentMethod.type !== PAYMENT_TYPES.byCrypto ||\n subscription.lastInvoice?.status !== INVOICE_PAYMENT_STATUSES.FAILED\n ) {\n return undefined;\n }\n\n return subscription.lastInvoice?.errorCode;\n}\n\n/**\n * Returns whether a specific product feature entitlement is enabled.\n *\n * Use this to gate paid UX. Missing products or missing features fail closed\n * (`false`). Combine with `selectIsActiveSubscriber` when that is the\n * product rule; this selector only reads the entitlement boolean.\n *\n * @param state - The subscription controller state.\n * @param productType - The product whose entitlement is queried.\n * @param feature - The feature whose entitlement flag is queried.\n * @returns Whether the feature entitlement is true.\n */\nexport function selectHasEntitlement<TProduct extends ProductType>(\n state: SubscriptionControllerState,\n productType: TProduct,\n feature: ProductEntitlementFeatureMap[TProduct],\n): boolean {\n const entitlements = state.productEntitlements?.[productType]\n ?.entitlements as\n | Record<ProductEntitlementFeatureMap[TProduct], boolean>\n | undefined;\n\n return Boolean(entitlements?.[feature]);\n}\n\n/**\n * Usage availability currently matches entitlement because the server folds\n * metered-cap exhaustion into the entitlement flag. Keeping this selector\n * separate gives consumers a stable API if explicit usage claims are added.\n *\n * @param state - The subscription controller state.\n * @param productType - The product whose usage availability is queried.\n * @param feature - The feature whose usage availability is queried.\n * @returns Whether usage is currently available for the feature.\n */\nexport function selectIsUsageAvailable<TProduct extends ProductType>(\n state: SubscriptionControllerState,\n productType: TProduct,\n feature: ProductEntitlementFeatureMap[TProduct],\n): boolean {\n return selectHasEntitlement(state, productType, feature);\n}\n\n/**\n * Returns whether the user has an active subscription for a specific product.\n *\n * Active includes `active`, `trialing`, and `provisional`. Missing products\n * and non-active statuses fail closed (`false`).\n *\n * @param state - The subscription controller state.\n * @param productType - The product to check.\n * @returns Whether the user is an active subscriber for the product.\n */\nexport function selectIsActiveSubscriber(\n state: SubscriptionControllerState,\n productType: ProductType,\n): boolean {\n return state.subscriptions.some(\n (subscription) =>\n ACTIVE_SUBSCRIPTION_STATUSES.includes(subscription.status) &&\n subscription.products.some((product) => product.name === productType),\n );\n}\n\n/**\n * Returns whether the product's latest crypto payment failed.\n *\n * The result is based on the latest invoice status. Payment-method setup\n * errors in `paymentMethod.crypto.error` are intentionally not treated as\n * invoice execution failures by this selector.\n *\n * @param state - The subscription controller state.\n * @param productType - The product whose payment state is queried.\n * @returns Whether the latest crypto payment failed.\n */\nexport function selectIsPaymentFailed(\n state: SubscriptionControllerState,\n productType: ProductType,\n): boolean {\n const subscription = getSubscriptionByProduct(state, productType);\n\n return Boolean(\n subscription?.paymentMethod.type === PAYMENT_TYPES.byCrypto &&\n subscription.lastInvoice?.status === INVOICE_PAYMENT_STATUSES.FAILED,\n );\n}\n\n/**\n * Returns the raw Subscription API execution error for the latest crypto\n * payment.\n *\n * @param state - The subscription controller state.\n * @param productType - The product whose payment failure is queried.\n * @returns The raw payment execution error, if present.\n */\nexport function selectPaymentFailureReason(\n state: SubscriptionControllerState,\n productType: ProductType,\n): CryptoPaymentError | undefined {\n return getPaymentExecutionError(state, productType);\n}\n\n/**\n * Returns whether the latest payment needs renewal or delegation recovery.\n *\n * The Subscription API signals this through `lastInvoice.errorCode` rather\n * than a derived boolean.\n *\n * @param state - The subscription controller state.\n * @param productType - The product whose renewal state is queried.\n * @returns Whether renewal/recovery can be offered.\n */\nexport function selectIsRenewalNeeded(\n state: SubscriptionControllerState,\n productType: ProductType,\n): boolean {\n const errorCode = getPaymentExecutionError(state, productType);\n\n return (\n errorCode === CRYPTO_PAYMENT_ERRORS.INSUFFICIENT_BALANCE ||\n errorCode === CRYPTO_PAYMENT_ERRORS.DELEGATION_NOT_FOUND\n );\n}\n\n/**\n * Returns whether the delegation has exhausted its allowance.\n *\n * @param state - The subscription controller state.\n * @param productType - The product whose delegation state is queried.\n * @returns Whether the delegation allowance is exhausted.\n */\nexport function selectIsDelegationExhausted(\n state: SubscriptionControllerState,\n productType: ProductType,\n): boolean {\n return (\n getPaymentExecutionError(state, productType) ===\n CRYPTO_PAYMENT_ERRORS.EXCEEDS_DELEGATION_ALLOWANCE\n );\n}\n"]}
|
|
@@ -21,6 +21,9 @@ export type SubscriptionDelegationServiceCheckMoneyAccountBalanceAction = {
|
|
|
21
21
|
* one exists (ensuring a CHOMP intent is active for its hash, unless
|
|
22
22
|
* `skipChompInteractions` is true). Reuse classifies period `startDate` as
|
|
23
23
|
* trial-deferred (`> now`) vs immediately redeemable, matching creation.
|
|
24
|
+
* When several records match, the latest period `startDate` is reused
|
|
25
|
+
* so a `forceNew` replacement is preferred over an older equivalent
|
|
26
|
+
* permission.
|
|
24
27
|
* If there is no match, builds, signs, optionally verifies with CHOMP,
|
|
25
28
|
* persists, and optionally registers a new delegation.
|
|
26
29
|
*
|
|
@@ -30,6 +33,8 @@ export type SubscriptionDelegationServiceCheckMoneyAccountBalanceAction = {
|
|
|
30
33
|
* that accepts `'cash-subscription'` intent metadata.
|
|
31
34
|
*
|
|
32
35
|
* @param request - Authoritative pricing and payer details for the delegation.
|
|
36
|
+
* @param forceNew - Whether to create a replacement instead of reusing a
|
|
37
|
+
* matching stored delegation.
|
|
33
38
|
* @returns The delegation hash (CHOMP-verified unless skipped) and whether it
|
|
34
39
|
* was created or reused.
|
|
35
40
|
*/
|
package/dist/subscription-delegation/SubscriptionDelegationService-method-action-types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubscriptionDelegationService-method-action-types.d.ts","sourceRoot":"","sources":["../../src/subscription-delegation/SubscriptionDelegationService-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AAExF;;;;;;GAMG;AACH,MAAM,MAAM,2DAA2D,GAAG;IACxE,IAAI,EAAE,wDAAwD,CAAC;IAC/D,OAAO,EAAE,6BAA6B,CAAC,0BAA0B,CAAC,CAAC;CACpE,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"SubscriptionDelegationService-method-action-types.d.ts","sourceRoot":"","sources":["../../src/subscription-delegation/SubscriptionDelegationService-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AAExF;;;;;;GAMG;AACH,MAAM,MAAM,2DAA2D,GAAG;IACxE,IAAI,EAAE,wDAAwD,CAAC;IAC/D,OAAO,EAAE,6BAA6B,CAAC,0BAA0B,CAAC,CAAC;CACpE,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,MAAM,oDAAoD,GAAG;IACjE,IAAI,EAAE,iDAAiD,CAAC;IACxD,OAAO,EAAE,6BAA6B,CAAC,mBAAmB,CAAC,CAAC;CAC7D,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,0CAA0C,GAClD,2DAA2D,GAC3D,oDAAoD,CAAC"}
|
package/dist/subscription-delegation/SubscriptionDelegationService-method-action-types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubscriptionDelegationService-method-action-types.js","sourceRoot":"","sources":["../../src/subscription-delegation/SubscriptionDelegationService-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { SubscriptionDelegationService } from './SubscriptionDelegationService.js';\n\n/**\n * Checks whether the Money Account holds enough convertible mUSD value to\n * cover pricing `unitAmount × minBillingCyclesForBalance`.\n *\n * @param request - Payer address and pricing amount fields.\n * @returns Balance comparison in mUSD base units (6 decimals).\n */\nexport type SubscriptionDelegationServiceCheckMoneyAccountBalanceAction = {\n type: `SubscriptionDelegationService:checkMoneyAccountBalance`;\n handler: SubscriptionDelegationService['checkMoneyAccountBalance'];\n};\n\n/**\n * Prepares a cash-subscription delegation and returns its hash.\n *\n * Reuses a stored AUS delegation that matches the semantic fingerprint when\n * one exists (ensuring a CHOMP intent is active for its hash, unless\n * `skipChompInteractions` is true). Reuse classifies period `startDate` as\n * trial-deferred (`> now`) vs immediately redeemable, matching creation.\n * If there is no match, builds, signs, optionally verifies with CHOMP,\n * persists, and optionally registers a new delegation.\n *\n * When `skipChompInteractions` is true (required for alpha), CHOMP verify\n * and intent calls are skipped; the returned hash is computed locally. The\n * default CHOMP-enabled path requires a follow-up chomp-api-service release\n * that accepts `'cash-subscription'` intent metadata.\n *\n * @param request - Authoritative pricing and payer details for the delegation.\n * @returns The delegation hash (CHOMP-verified unless skipped) and whether it\n * was created or reused.\n */\nexport type SubscriptionDelegationServicePrepareDelegationAction = {\n type: `SubscriptionDelegationService:prepareDelegation`;\n handler: SubscriptionDelegationService['prepareDelegation'];\n};\n\n/**\n * Union of all SubscriptionDelegationService action types.\n */\nexport type SubscriptionDelegationServiceMethodActions =\n | SubscriptionDelegationServiceCheckMoneyAccountBalanceAction\n | SubscriptionDelegationServicePrepareDelegationAction;\n"]}
|
|
1
|
+
{"version":3,"file":"SubscriptionDelegationService-method-action-types.js","sourceRoot":"","sources":["../../src/subscription-delegation/SubscriptionDelegationService-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { SubscriptionDelegationService } from './SubscriptionDelegationService.js';\n\n/**\n * Checks whether the Money Account holds enough convertible mUSD value to\n * cover pricing `unitAmount × minBillingCyclesForBalance`.\n *\n * @param request - Payer address and pricing amount fields.\n * @returns Balance comparison in mUSD base units (6 decimals).\n */\nexport type SubscriptionDelegationServiceCheckMoneyAccountBalanceAction = {\n type: `SubscriptionDelegationService:checkMoneyAccountBalance`;\n handler: SubscriptionDelegationService['checkMoneyAccountBalance'];\n};\n\n/**\n * Prepares a cash-subscription delegation and returns its hash.\n *\n * Reuses a stored AUS delegation that matches the semantic fingerprint when\n * one exists (ensuring a CHOMP intent is active for its hash, unless\n * `skipChompInteractions` is true). Reuse classifies period `startDate` as\n * trial-deferred (`> now`) vs immediately redeemable, matching creation.\n * When several records match, the latest period `startDate` is reused\n * so a `forceNew` replacement is preferred over an older equivalent\n * permission.\n * If there is no match, builds, signs, optionally verifies with CHOMP,\n * persists, and optionally registers a new delegation.\n *\n * When `skipChompInteractions` is true (required for alpha), CHOMP verify\n * and intent calls are skipped; the returned hash is computed locally. The\n * default CHOMP-enabled path requires a follow-up chomp-api-service release\n * that accepts `'cash-subscription'` intent metadata.\n *\n * @param request - Authoritative pricing and payer details for the delegation.\n * @param forceNew - Whether to create a replacement instead of reusing a\n * matching stored delegation.\n * @returns The delegation hash (CHOMP-verified unless skipped) and whether it\n * was created or reused.\n */\nexport type SubscriptionDelegationServicePrepareDelegationAction = {\n type: `SubscriptionDelegationService:prepareDelegation`;\n handler: SubscriptionDelegationService['prepareDelegation'];\n};\n\n/**\n * Union of all SubscriptionDelegationService action types.\n */\nexport type SubscriptionDelegationServiceMethodActions =\n | SubscriptionDelegationServiceCheckMoneyAccountBalanceAction\n | SubscriptionDelegationServicePrepareDelegationAction;\n"]}
|
|
@@ -74,6 +74,9 @@ export declare class SubscriptionDelegationService {
|
|
|
74
74
|
* one exists (ensuring a CHOMP intent is active for its hash, unless
|
|
75
75
|
* `skipChompInteractions` is true). Reuse classifies period `startDate` as
|
|
76
76
|
* trial-deferred (`> now`) vs immediately redeemable, matching creation.
|
|
77
|
+
* When several records match, the latest period `startDate` is reused
|
|
78
|
+
* so a `forceNew` replacement is preferred over an older equivalent
|
|
79
|
+
* permission.
|
|
77
80
|
* If there is no match, builds, signs, optionally verifies with CHOMP,
|
|
78
81
|
* persists, and optionally registers a new delegation.
|
|
79
82
|
*
|
|
@@ -83,10 +86,12 @@ export declare class SubscriptionDelegationService {
|
|
|
83
86
|
* that accepts `'cash-subscription'` intent metadata.
|
|
84
87
|
*
|
|
85
88
|
* @param request - Authoritative pricing and payer details for the delegation.
|
|
89
|
+
* @param forceNew - Whether to create a replacement instead of reusing a
|
|
90
|
+
* matching stored delegation.
|
|
86
91
|
* @returns The delegation hash (CHOMP-verified unless skipped) and whether it
|
|
87
92
|
* was created or reused.
|
|
88
93
|
*/
|
|
89
|
-
prepareDelegation(request: PrepareSubscriptionDelegationRequest): Promise<PreparedSubscriptionDelegation>;
|
|
94
|
+
prepareDelegation(request: PrepareSubscriptionDelegationRequest, forceNew?: boolean): Promise<PreparedSubscriptionDelegation>;
|
|
90
95
|
}
|
|
91
96
|
export {};
|
|
92
97
|
//# sourceMappingURL=SubscriptionDelegationService.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubscriptionDelegationService.d.ts","sourceRoot":"","sources":["../../src/subscription-delegation/SubscriptionDelegationService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"SubscriptionDelegationService.d.ts","sourceRoot":"","sources":["../../src/subscription-delegation/SubscriptionDelegationService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,qDAAqD,EACrD,oDAAoD,EACrD,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EACV,kCAAkC,EAClC,wCAAwC,EACxC,qCAAqC,EACtC,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,wCAAwC,EAAE,MAAM,iCAAiC,CAAC;AAGhG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,wDAAwD,EAAE,MAAM,yCAAyC,CAAC;AAKxH,OAAO,KAAK,EAAE,yCAAyC,EAAE,MAAM,0CAA0C,CAAC;AAK1G,OAAO,KAAK,EAAE,sCAAsC,EAAE,MAAM,kDAAkD,CAAC;AAqB/G,OAAO,KAAK,EAAE,0CAA0C,EAAE,MAAM,wDAAwD,CAAC;AACzH,OAAO,KAAK,EACV,+BAA+B,EAC/B,8BAA8B,EAC9B,oCAAoC,EACpC,8BAA8B,EAE/B,MAAM,YAAY,CAAC;AAGpB;;;GAGG;AACH,eAAO,MAAM,WAAW,kCAAkC,CAAC;AAyB3D;;GAEG;AACH,MAAM,MAAM,oCAAoC,GAC9C,0CAA0C,CAAC;AAE7C;;GAEG;AACH,KAAK,cAAc,GACf,oDAAoD,GACpD,qDAAqD,GACrD,qCAAqC,GACrC,kCAAkC,GAClC,wCAAwC,GACxC,wCAAwC,GACxC,wDAAwD,GACxD,yCAAyC,GACzC,sCAAsC,CAAC;AAE3C;;GAEG;AACH,MAAM,MAAM,mCAAmC,GAAG,KAAK,CAAC;AAExD,KAAK,aAAa,GAAG,KAAK,CAAC;AAE3B;;;GAGG;AACH,MAAM,MAAM,sCAAsC,GAAG,SAAS,CAC5D,OAAO,WAAW,EAClB,oCAAoC,GAAG,cAAc,EACrD,mCAAmC,GAAG,aAAa,CACpD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oCAAoC,GAAG;IACjD,SAAS,EAAE,sCAAsC,CAAC;CACnD,CAAC;AAmBF;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,6BAA6B;;IACxC,QAAQ,CAAC,IAAI,EAAE,OAAO,WAAW,CAAe;IAIhD,YAAY,OAAO,EAAE,oCAAoC,EAOxD;IAED;;;;;;OAMG;IACG,wBAAwB,CAC5B,OAAO,EAAE,+BAA+B,GACvC,OAAO,CAAC,8BAA8B,CAAC,CAMzC;IA+BD;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACG,iBAAiB,CACrB,OAAO,EAAE,oCAAoC,EAC7C,QAAQ,UAAQ,GACf,OAAO,CAAC,8BAA8B,CAAC,CA4JzC;CAkJF"}
|
|
@@ -6,7 +6,7 @@ import { SubscriptionDelegationServiceErrorMessage } from '../constants.js';
|
|
|
6
6
|
import { CRYPTO_AUTH_METHODS, PAYMENT_TYPES, PRODUCT_TYPES } from '../types.js';
|
|
7
7
|
import { assertPositiveInteger, calculatePeriodAmount, getDelegationStartDate, getPeriodDuration, } from './amount.js';
|
|
8
8
|
import { buildUnsignedSubscriptionDelegation } from './caveats.js';
|
|
9
|
-
import { equalsIgnoreCase, makeMatchesSubscriptionDelegation, } from './fingerprint.js';
|
|
9
|
+
import { equalsIgnoreCase, makeMatchesSubscriptionDelegation, pickLatestMatchingSubscriptionDelegation, } from './fingerprint.js';
|
|
10
10
|
import { CASH_SUBSCRIPTION_DELEGATION_TYPE } from './types.js';
|
|
11
11
|
/**
|
|
12
12
|
* The name of the {@link SubscriptionDelegationService}, used to namespace the
|
|
@@ -87,6 +87,9 @@ export class SubscriptionDelegationService {
|
|
|
87
87
|
* one exists (ensuring a CHOMP intent is active for its hash, unless
|
|
88
88
|
* `skipChompInteractions` is true). Reuse classifies period `startDate` as
|
|
89
89
|
* trial-deferred (`> now`) vs immediately redeemable, matching creation.
|
|
90
|
+
* When several records match, the latest period `startDate` is reused
|
|
91
|
+
* so a `forceNew` replacement is preferred over an older equivalent
|
|
92
|
+
* permission.
|
|
90
93
|
* If there is no match, builds, signs, optionally verifies with CHOMP,
|
|
91
94
|
* persists, and optionally registers a new delegation.
|
|
92
95
|
*
|
|
@@ -96,10 +99,12 @@ export class SubscriptionDelegationService {
|
|
|
96
99
|
* that accepts `'cash-subscription'` intent metadata.
|
|
97
100
|
*
|
|
98
101
|
* @param request - Authoritative pricing and payer details for the delegation.
|
|
102
|
+
* @param forceNew - Whether to create a replacement instead of reusing a
|
|
103
|
+
* matching stored delegation.
|
|
99
104
|
* @returns The delegation hash (CHOMP-verified unless skipped) and whether it
|
|
100
105
|
* was created or reused.
|
|
101
106
|
*/
|
|
102
|
-
async prepareDelegation(request) {
|
|
107
|
+
async prepareDelegation(request, forceNew = false) {
|
|
103
108
|
if (request.product !== PRODUCT_TYPES.MONEY_ACCOUNT_PLUS) {
|
|
104
109
|
throw new Error(SubscriptionDelegationServiceErrorMessage.UnsupportedProduct);
|
|
105
110
|
}
|
|
@@ -125,19 +130,19 @@ export class SubscriptionDelegationService {
|
|
|
125
130
|
: undefined,
|
|
126
131
|
});
|
|
127
132
|
const isTrialDeferred = startDate > nowSeconds;
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
133
|
+
const reusable = forceNew
|
|
134
|
+
? undefined
|
|
135
|
+
: await this.#findReusableDelegation({
|
|
136
|
+
request,
|
|
137
|
+
chainId,
|
|
138
|
+
delegateAddress,
|
|
139
|
+
tokenAddress: token.address,
|
|
140
|
+
periodAmount,
|
|
141
|
+
periodDuration,
|
|
142
|
+
nowSeconds,
|
|
143
|
+
isTrialDeferred,
|
|
144
|
+
enforcers,
|
|
145
|
+
});
|
|
141
146
|
if (reusable) {
|
|
142
147
|
if (!skipChomp) {
|
|
143
148
|
await this.#ensureIntent({
|
|
@@ -212,6 +217,21 @@ export class SubscriptionDelegationService {
|
|
|
212
217
|
disposition: 'created',
|
|
213
218
|
};
|
|
214
219
|
}
|
|
220
|
+
async #findReusableDelegation({ request, chainId, delegateAddress, tokenAddress, periodAmount, periodDuration, nowSeconds, isTrialDeferred, enforcers, }) {
|
|
221
|
+
const matches = makeMatchesSubscriptionDelegation({
|
|
222
|
+
delegatorAddress: request.payerAddress,
|
|
223
|
+
delegateAddress,
|
|
224
|
+
chainId,
|
|
225
|
+
tokenAddress,
|
|
226
|
+
periodAmount,
|
|
227
|
+
periodDuration,
|
|
228
|
+
nowSeconds,
|
|
229
|
+
isTrialDeferred,
|
|
230
|
+
enforcers,
|
|
231
|
+
});
|
|
232
|
+
const existingDelegations = await this.#messenger.call('AuthenticatedUserStorageService:listDelegations');
|
|
233
|
+
return pickLatestMatchingSubscriptionDelegation(existingDelegations.filter(matches), enforcers);
|
|
234
|
+
}
|
|
215
235
|
async #resolveConfiguration(product, recurringInterval) {
|
|
216
236
|
const { remoteFeatureFlags } = this.#messenger.call('RemoteFeatureFlagController:getState');
|
|
217
237
|
const vaultConfig = getMoneyAccountVaultConfig(remoteFeatureFlags);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubscriptionDelegationService.js","sourceRoot":"","sources":["../../src/subscription-delegation/SubscriptionDelegationService.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AuthenticatedUserStorageServiceCreateDelegationAction,\n AuthenticatedUserStorageServiceListDelegationsAction,\n} from '@metamask/authenticated-user-storage';\nimport type {\n ChompApiServiceCreateIntentsAction,\n ChompApiServiceGetIntentsByAddressAction,\n ChompApiServiceVerifyDelegationAction,\n} from '@metamask/chomp-api-service';\nimport type { DelegationControllerSignDelegationAction } from '@metamask/delegation-controller';\nimport { hashDelegation } from '@metamask/delegation-core';\nimport { DELEGATOR_CONTRACTS } from '@metamask/delegation-deployments';\nimport type { Messenger } from '@metamask/messenger';\nimport type { MoneyAccountBalanceServiceFetchBalanceWithFallbackAction } from '@metamask/money-account-balance-service';\nimport {\n getMoneyAccountVaultConfig,\n MUSD_DECIMALS,\n} from '@metamask/money-account-utils';\nimport type { RemoteFeatureFlagControllerGetStateAction } from '@metamask/remote-feature-flag-controller';\nimport { add0x, hexToNumber } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\n\nimport { SubscriptionDelegationServiceErrorMessage } from '../constants.js';\nimport type { SubscriptionControllerGetPricingAction } from '../SubscriptionController-method-action-types.js';\nimport { CRYPTO_AUTH_METHODS, PAYMENT_TYPES, PRODUCT_TYPES } from '../types.js';\nimport type {\n ProductPrice,\n ProductType,\n PricingCryptoPaymentMethod,\n RecurringInterval,\n TokenPaymentInfo,\n} from '../types.js';\nimport {\n assertPositiveInteger,\n calculatePeriodAmount,\n getDelegationStartDate,\n getPeriodDuration,\n} from './amount.js';\nimport { buildUnsignedSubscriptionDelegation } from './caveats.js';\nimport {\n equalsIgnoreCase,\n makeMatchesSubscriptionDelegation,\n} from './fingerprint.js';\nimport type { SubscriptionDelegationServiceMethodActions } from './SubscriptionDelegationService-method-action-types.js';\nimport type {\n MoneyAccountBalanceCheckRequest,\n MoneyAccountBalanceCheckResult,\n PrepareSubscriptionDelegationRequest,\n PreparedSubscriptionDelegation,\n SubscriptionDelegationEnforcers,\n} from './types.js';\nimport { CASH_SUBSCRIPTION_DELEGATION_TYPE } from './types.js';\n\n/**\n * The name of the {@link SubscriptionDelegationService}, used to namespace the\n * service's actions and events.\n */\nexport const serviceName = 'SubscriptionDelegationService';\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'prepareDelegation',\n 'checkMoneyAccountBalance',\n] as const;\n\nconst DELEGATION_FRAMEWORK_VERSION = '1.3.0';\n\nfunction resolveEnforcers(chainId: Hex): SubscriptionDelegationEnforcers {\n const contracts =\n DELEGATOR_CONTRACTS[DELEGATION_FRAMEWORK_VERSION]?.[hexToNumber(chainId)];\n\n if (!contracts?.ValueLteEnforcer || !contracts.ERC20PeriodTransferEnforcer) {\n throw new Error(\n `${SubscriptionDelegationServiceErrorMessage.DelegationContractsNotFound}: ${chainId}`,\n );\n }\n\n return {\n valueLte: contracts.ValueLteEnforcer,\n erc20TokenPeriodTransfer: contracts.ERC20PeriodTransferEnforcer,\n };\n}\n\n/**\n * Actions that {@link SubscriptionDelegationService} exposes to other consumers.\n */\nexport type SubscriptionDelegationServiceActions =\n SubscriptionDelegationServiceMethodActions;\n\n/**\n * Actions from other messengers that {@link SubscriptionDelegationServiceMessenger} calls.\n */\ntype AllowedActions =\n | AuthenticatedUserStorageServiceListDelegationsAction\n | AuthenticatedUserStorageServiceCreateDelegationAction\n | ChompApiServiceVerifyDelegationAction\n | ChompApiServiceCreateIntentsAction\n | ChompApiServiceGetIntentsByAddressAction\n | DelegationControllerSignDelegationAction\n | MoneyAccountBalanceServiceFetchBalanceWithFallbackAction\n | RemoteFeatureFlagControllerGetStateAction\n | SubscriptionControllerGetPricingAction;\n\n/**\n * Events that {@link SubscriptionDelegationService} exposes to other consumers.\n */\nexport type SubscriptionDelegationServiceEvents = never;\n\ntype AllowedEvents = never;\n\n/**\n * The messenger which is restricted to actions and events accessed by\n * {@link SubscriptionDelegationService}.\n */\nexport type SubscriptionDelegationServiceMessenger = Messenger<\n typeof serviceName,\n SubscriptionDelegationServiceActions | AllowedActions,\n SubscriptionDelegationServiceEvents | AllowedEvents\n>;\n\n/**\n * Options for constructing {@link SubscriptionDelegationService}.\n */\nexport type SubscriptionDelegationServiceOptions = {\n messenger: SubscriptionDelegationServiceMessenger;\n};\n\ntype SubscriptionIntentParams = {\n account: Hex;\n chainId: Hex;\n delegationHash: Hex;\n allowance: Hex;\n tokenSymbol: string;\n tokenAddress: Hex;\n};\n\ntype ResolvedSubscriptionDelegationConfig = {\n chainId: Hex;\n delegateAddress: Hex;\n enforcers: SubscriptionDelegationEnforcers;\n price: ProductPrice;\n token: TokenPaymentInfo;\n};\n\n/**\n * Stateless orchestrator for cash-subscription delegation setup.\n *\n * Owns the workflow: size periodic caveats → sign → CHOMP verify → persist to\n * Authenticated User Storage → register CHOMP intent. Returns a verified\n * `delegationHash` for `SubscriptionController.startSubscriptionWithCrypto`.\n *\n * Alpha callers must pass `skipChompInteractions: true` until a follow-up\n * `@metamask/chomp-api-service` release accepts `'cash-subscription'` intent\n * metadata. The CHOMP-enabled path (`skipChompInteractions` unset/false)\n * remains dormant and is not production-ready without that package support.\n *\n * Each call resolves the Money Account chain from remote feature flags, then\n * resolves its price, payment token, and delegate from `SubscriptionController`\n * pricing. The pricing `delegateAddress` is used as the delegation `delegate`.\n *\n * Does not own subscription state; `SubscriptionController` does not depend on\n * this service. Only Money Account Plus is supported.\n */\nexport class SubscriptionDelegationService {\n readonly name: typeof serviceName = serviceName;\n\n readonly #messenger: SubscriptionDelegationServiceMessenger;\n\n constructor(options: SubscriptionDelegationServiceOptions) {\n this.#messenger = options.messenger;\n\n this.#messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Checks whether the Money Account holds enough convertible mUSD value to\n * cover pricing `unitAmount × minBillingCyclesForBalance`.\n *\n * @param request - Payer address and pricing amount fields.\n * @returns Balance comparison in mUSD base units (6 decimals).\n */\n async checkMoneyAccountBalance(\n request: MoneyAccountBalanceCheckRequest,\n ): Promise<MoneyAccountBalanceCheckResult> {\n const { price } = await this.#resolveConfiguration(\n request.product,\n request.recurringInterval,\n );\n return this.#compareMoneyAccountBalance(request.payerAddress, price);\n }\n\n async #compareMoneyAccountBalance(\n payerAddress: Hex,\n price: ProductPrice,\n ): Promise<MoneyAccountBalanceCheckResult> {\n assertPositiveInteger(\n price.minBillingCyclesForBalance,\n SubscriptionDelegationServiceErrorMessage.InvalidMinimumFundingCycles,\n );\n\n const periodAmount = calculatePeriodAmount({\n unitAmount: price.unitAmount,\n unitDecimals: price.unitDecimals,\n tokenDecimals: MUSD_DECIMALS,\n });\n const requiredBalance =\n periodAmount * BigInt(price.minBillingCyclesForBalance);\n\n const { totalBalance } = await this.#messenger.call(\n 'MoneyAccountBalanceService:fetchBalanceWithFallback',\n payerAddress,\n );\n\n return {\n hasSufficientBalance: BigInt(totalBalance) >= requiredBalance,\n balance: totalBalance,\n requiredBalance: requiredBalance.toString(),\n };\n }\n\n /**\n * Prepares a cash-subscription delegation and returns its hash.\n *\n * Reuses a stored AUS delegation that matches the semantic fingerprint when\n * one exists (ensuring a CHOMP intent is active for its hash, unless\n * `skipChompInteractions` is true). Reuse classifies period `startDate` as\n * trial-deferred (`> now`) vs immediately redeemable, matching creation.\n * If there is no match, builds, signs, optionally verifies with CHOMP,\n * persists, and optionally registers a new delegation.\n *\n * When `skipChompInteractions` is true (required for alpha), CHOMP verify\n * and intent calls are skipped; the returned hash is computed locally. The\n * default CHOMP-enabled path requires a follow-up chomp-api-service release\n * that accepts `'cash-subscription'` intent metadata.\n *\n * @param request - Authoritative pricing and payer details for the delegation.\n * @returns The delegation hash (CHOMP-verified unless skipped) and whether it\n * was created or reused.\n */\n async prepareDelegation(\n request: PrepareSubscriptionDelegationRequest,\n ): Promise<PreparedSubscriptionDelegation> {\n if (request.product !== PRODUCT_TYPES.MONEY_ACCOUNT_PLUS) {\n throw new Error(\n SubscriptionDelegationServiceErrorMessage.UnsupportedProduct,\n );\n }\n\n const skipChomp = Boolean(request.skipChompInteractions);\n\n const { chainId, delegateAddress, enforcers, price, token } =\n await this.#resolveConfiguration(\n request.product,\n request.recurringInterval,\n );\n\n if (request.checkBalance) {\n const { hasSufficientBalance } = await this.#compareMoneyAccountBalance(\n request.payerAddress,\n price,\n );\n if (!hasSufficientBalance) {\n throw new Error(\n SubscriptionDelegationServiceErrorMessage.InsufficientBalance,\n );\n }\n }\n\n const periodAmount = calculatePeriodAmount({\n unitAmount: price.unitAmount,\n unitDecimals: price.unitDecimals,\n tokenDecimals: token.decimals,\n });\n const periodDuration = getPeriodDuration(request.recurringInterval);\n const nowSeconds = Math.floor(Date.now() / 1000);\n const startDate = getDelegationStartDate({\n nowSeconds,\n trialPeriodDays: request.isTrialRequested\n ? price.trialPeriodDays\n : undefined,\n });\n const isTrialDeferred = startDate > nowSeconds;\n\n const matches = makeMatchesSubscriptionDelegation({\n delegatorAddress: request.payerAddress,\n delegateAddress,\n chainId,\n tokenAddress: token.address,\n periodAmount,\n periodDuration,\n nowSeconds,\n isTrialDeferred,\n enforcers,\n });\n\n const existingDelegations = await this.#messenger.call(\n 'AuthenticatedUserStorageService:listDelegations',\n );\n const reusable = existingDelegations.find(matches);\n if (reusable) {\n if (!skipChomp) {\n await this.#ensureIntent({\n account: request.payerAddress,\n chainId,\n delegationHash: reusable.metadata.delegationHash,\n allowance: reusable.metadata.allowance,\n tokenSymbol: reusable.metadata.tokenSymbol,\n tokenAddress: reusable.metadata.tokenAddress,\n });\n }\n return {\n delegationHash: reusable.metadata.delegationHash,\n disposition: 'reused',\n };\n }\n\n const unsigned = buildUnsignedSubscriptionDelegation({\n delegateAddress,\n delegatorAddress: request.payerAddress,\n enforcers,\n tokenAddress: token.address,\n periodAmount,\n periodDuration,\n startDate,\n });\n\n const signature = (await this.#messenger.call(\n 'DelegationController:signDelegation',\n { delegation: unsigned, chainId },\n )) as Hex;\n\n const signedDelegation = { ...unsigned, signature };\n\n const delegationHash = hashDelegation({\n ...unsigned,\n salt: BigInt(unsigned.salt),\n signature,\n });\n\n if (!skipChomp) {\n const verifyResult = await this.#messenger.call(\n 'ChompApiService:verifyDelegation',\n {\n signedDelegation,\n chainId,\n },\n );\n\n if (!verifyResult.valid) {\n throw new Error(\n `${SubscriptionDelegationServiceErrorMessage.ChompRejectedDelegation}: ${\n verifyResult.errors?.join(', ') ?? 'unknown error'\n }`,\n );\n }\n\n if (!verifyResult.delegationHash) {\n throw new Error(\n SubscriptionDelegationServiceErrorMessage.ChompMissingDelegationHash,\n );\n }\n if (!equalsIgnoreCase(verifyResult.delegationHash, delegationHash)) {\n throw new Error(\n SubscriptionDelegationServiceErrorMessage.ChompDelegationHashMismatch,\n );\n }\n }\n\n const allowance: Hex = add0x(periodAmount.toString(16));\n\n await this.#messenger.call(\n 'AuthenticatedUserStorageService:createDelegation',\n {\n signedDelegation,\n metadata: {\n delegationHash,\n chainIdHex: chainId,\n allowance,\n tokenSymbol: token.symbol,\n tokenAddress: token.address,\n type: CASH_SUBSCRIPTION_DELEGATION_TYPE,\n },\n },\n );\n\n if (!skipChomp) {\n await this.#createIntent({\n account: request.payerAddress,\n chainId,\n delegationHash,\n allowance,\n tokenSymbol: token.symbol,\n tokenAddress: token.address,\n });\n }\n\n return {\n delegationHash,\n disposition: 'created',\n };\n }\n\n async #resolveConfiguration(\n product: ProductType,\n recurringInterval: RecurringInterval,\n ): Promise<ResolvedSubscriptionDelegationConfig> {\n const { remoteFeatureFlags } = this.#messenger.call(\n 'RemoteFeatureFlagController:getState',\n );\n const vaultConfig = getMoneyAccountVaultConfig(remoteFeatureFlags);\n if (!vaultConfig) {\n throw new Error(\n SubscriptionDelegationServiceErrorMessage.MissingMoneyAccountVaultConfig,\n );\n }\n\n const { chainId } = vaultConfig;\n const enforcers = resolveEnforcers(chainId);\n const pricing = await this.#messenger.call(\n 'SubscriptionController:getPricing',\n );\n const price = pricing.products\n .find((entry) => entry.name === product)\n ?.prices?.find((entry) => entry.interval === recurringInterval);\n const paymentMethod = pricing.paymentMethods.find(\n (entry): entry is PricingCryptoPaymentMethod =>\n entry.type === PAYMENT_TYPES.byCrypto &&\n entry.cryptoAuthMethod === CRYPTO_AUTH_METHODS.DELEGATION &&\n entry.products?.includes(product) === true,\n );\n const chain = paymentMethod?.chains?.find(\n (entry) => entry.chainId === chainId,\n );\n const token = chain?.tokens[0];\n if (!price || !chain?.delegateAddress || !token) {\n throw new Error(\n SubscriptionDelegationServiceErrorMessage.PricingConfigurationNotFound,\n );\n }\n\n return {\n chainId,\n delegateAddress: chain.delegateAddress,\n enforcers,\n price,\n token,\n };\n }\n\n /**\n * Ensures an active CHOMP intent exists for the given delegation hash,\n * registering one when missing or revoked.\n *\n * @param params - Intent identity and metadata.\n * @param params.account - Delegator / payer address.\n * @param params.chainId - Chain ID of the delegation.\n * @param params.delegationHash - Hash of the stored delegation.\n * @param params.allowance - Period allowance stored with the delegation.\n * @param params.tokenSymbol - Payment token symbol.\n * @param params.tokenAddress - Payment token address.\n */\n async #ensureIntent(params: SubscriptionIntentParams): Promise<void> {\n const existingIntents = await this.#messenger.call(\n 'ChompApiService:getIntentsByAddress',\n params.account,\n );\n\n const hasActiveIntent = existingIntents.some(\n (intent) =>\n equalsIgnoreCase(intent.delegationHash, params.delegationHash) &&\n intent.status === 'active',\n );\n\n if (hasActiveIntent) {\n return;\n }\n\n await this.#createIntent(params);\n }\n\n async #createIntent(params: SubscriptionIntentParams): Promise<void> {\n // Published `@metamask/chomp-api-service` only types intent metadata as\n // `'cash-deposit' | 'cash-withdrawal'`. The dormant production path still\n // passes `'cash-subscription'`; a follow-up chomp-api-service release must\n // accept that discriminator before this path is production-ready. Alpha\n // callers must use `skipChompInteractions: true` so this method is not\n // reached.\n await this.#messenger.call('ChompApiService:createIntents', [\n {\n account: params.account,\n delegationHash: params.delegationHash,\n chainId: params.chainId,\n metadata: {\n allowance: params.allowance,\n tokenSymbol: params.tokenSymbol,\n tokenAddress: params.tokenAddress,\n type: CASH_SUBSCRIPTION_DELEGATION_TYPE as\n | 'cash-deposit'\n | 'cash-withdrawal',\n },\n },\n ]);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SubscriptionDelegationService.js","sourceRoot":"","sources":["../../src/subscription-delegation/SubscriptionDelegationService.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n DelegationResponse,\n AuthenticatedUserStorageServiceCreateDelegationAction,\n AuthenticatedUserStorageServiceListDelegationsAction,\n} from '@metamask/authenticated-user-storage';\nimport type {\n ChompApiServiceCreateIntentsAction,\n ChompApiServiceGetIntentsByAddressAction,\n ChompApiServiceVerifyDelegationAction,\n} from '@metamask/chomp-api-service';\nimport type { DelegationControllerSignDelegationAction } from '@metamask/delegation-controller';\nimport { hashDelegation } from '@metamask/delegation-core';\nimport { DELEGATOR_CONTRACTS } from '@metamask/delegation-deployments';\nimport type { Messenger } from '@metamask/messenger';\nimport type { MoneyAccountBalanceServiceFetchBalanceWithFallbackAction } from '@metamask/money-account-balance-service';\nimport {\n getMoneyAccountVaultConfig,\n MUSD_DECIMALS,\n} from '@metamask/money-account-utils';\nimport type { RemoteFeatureFlagControllerGetStateAction } from '@metamask/remote-feature-flag-controller';\nimport { add0x, hexToNumber } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\n\nimport { SubscriptionDelegationServiceErrorMessage } from '../constants.js';\nimport type { SubscriptionControllerGetPricingAction } from '../SubscriptionController-method-action-types.js';\nimport { CRYPTO_AUTH_METHODS, PAYMENT_TYPES, PRODUCT_TYPES } from '../types.js';\nimport type {\n ProductPrice,\n ProductType,\n PricingCryptoPaymentMethod,\n RecurringInterval,\n TokenPaymentInfo,\n} from '../types.js';\nimport {\n assertPositiveInteger,\n calculatePeriodAmount,\n getDelegationStartDate,\n getPeriodDuration,\n} from './amount.js';\nimport { buildUnsignedSubscriptionDelegation } from './caveats.js';\nimport {\n equalsIgnoreCase,\n makeMatchesSubscriptionDelegation,\n pickLatestMatchingSubscriptionDelegation,\n} from './fingerprint.js';\nimport type { SubscriptionDelegationServiceMethodActions } from './SubscriptionDelegationService-method-action-types.js';\nimport type {\n MoneyAccountBalanceCheckRequest,\n MoneyAccountBalanceCheckResult,\n PrepareSubscriptionDelegationRequest,\n PreparedSubscriptionDelegation,\n SubscriptionDelegationEnforcers,\n} from './types.js';\nimport { CASH_SUBSCRIPTION_DELEGATION_TYPE } from './types.js';\n\n/**\n * The name of the {@link SubscriptionDelegationService}, used to namespace the\n * service's actions and events.\n */\nexport const serviceName = 'SubscriptionDelegationService';\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'prepareDelegation',\n 'checkMoneyAccountBalance',\n] as const;\n\nconst DELEGATION_FRAMEWORK_VERSION = '1.3.0';\n\nfunction resolveEnforcers(chainId: Hex): SubscriptionDelegationEnforcers {\n const contracts =\n DELEGATOR_CONTRACTS[DELEGATION_FRAMEWORK_VERSION]?.[hexToNumber(chainId)];\n\n if (!contracts?.ValueLteEnforcer || !contracts.ERC20PeriodTransferEnforcer) {\n throw new Error(\n `${SubscriptionDelegationServiceErrorMessage.DelegationContractsNotFound}: ${chainId}`,\n );\n }\n\n return {\n valueLte: contracts.ValueLteEnforcer,\n erc20TokenPeriodTransfer: contracts.ERC20PeriodTransferEnforcer,\n };\n}\n\n/**\n * Actions that {@link SubscriptionDelegationService} exposes to other consumers.\n */\nexport type SubscriptionDelegationServiceActions =\n SubscriptionDelegationServiceMethodActions;\n\n/**\n * Actions from other messengers that {@link SubscriptionDelegationServiceMessenger} calls.\n */\ntype AllowedActions =\n | AuthenticatedUserStorageServiceListDelegationsAction\n | AuthenticatedUserStorageServiceCreateDelegationAction\n | ChompApiServiceVerifyDelegationAction\n | ChompApiServiceCreateIntentsAction\n | ChompApiServiceGetIntentsByAddressAction\n | DelegationControllerSignDelegationAction\n | MoneyAccountBalanceServiceFetchBalanceWithFallbackAction\n | RemoteFeatureFlagControllerGetStateAction\n | SubscriptionControllerGetPricingAction;\n\n/**\n * Events that {@link SubscriptionDelegationService} exposes to other consumers.\n */\nexport type SubscriptionDelegationServiceEvents = never;\n\ntype AllowedEvents = never;\n\n/**\n * The messenger which is restricted to actions and events accessed by\n * {@link SubscriptionDelegationService}.\n */\nexport type SubscriptionDelegationServiceMessenger = Messenger<\n typeof serviceName,\n SubscriptionDelegationServiceActions | AllowedActions,\n SubscriptionDelegationServiceEvents | AllowedEvents\n>;\n\n/**\n * Options for constructing {@link SubscriptionDelegationService}.\n */\nexport type SubscriptionDelegationServiceOptions = {\n messenger: SubscriptionDelegationServiceMessenger;\n};\n\ntype SubscriptionIntentParams = {\n account: Hex;\n chainId: Hex;\n delegationHash: Hex;\n allowance: Hex;\n tokenSymbol: string;\n tokenAddress: Hex;\n};\n\ntype ResolvedSubscriptionDelegationConfig = {\n chainId: Hex;\n delegateAddress: Hex;\n enforcers: SubscriptionDelegationEnforcers;\n price: ProductPrice;\n token: TokenPaymentInfo;\n};\n\n/**\n * Stateless orchestrator for cash-subscription delegation setup.\n *\n * Owns the workflow: size periodic caveats → sign → CHOMP verify → persist to\n * Authenticated User Storage → register CHOMP intent. Returns a verified\n * `delegationHash` for `SubscriptionController.startSubscriptionWithCrypto`.\n *\n * Alpha callers must pass `skipChompInteractions: true` until a follow-up\n * `@metamask/chomp-api-service` release accepts `'cash-subscription'` intent\n * metadata. The CHOMP-enabled path (`skipChompInteractions` unset/false)\n * remains dormant and is not production-ready without that package support.\n *\n * Each call resolves the Money Account chain from remote feature flags, then\n * resolves its price, payment token, and delegate from `SubscriptionController`\n * pricing. The pricing `delegateAddress` is used as the delegation `delegate`.\n *\n * Does not own subscription state; `SubscriptionController` does not depend on\n * this service. Only Money Account Plus is supported.\n */\nexport class SubscriptionDelegationService {\n readonly name: typeof serviceName = serviceName;\n\n readonly #messenger: SubscriptionDelegationServiceMessenger;\n\n constructor(options: SubscriptionDelegationServiceOptions) {\n this.#messenger = options.messenger;\n\n this.#messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Checks whether the Money Account holds enough convertible mUSD value to\n * cover pricing `unitAmount × minBillingCyclesForBalance`.\n *\n * @param request - Payer address and pricing amount fields.\n * @returns Balance comparison in mUSD base units (6 decimals).\n */\n async checkMoneyAccountBalance(\n request: MoneyAccountBalanceCheckRequest,\n ): Promise<MoneyAccountBalanceCheckResult> {\n const { price } = await this.#resolveConfiguration(\n request.product,\n request.recurringInterval,\n );\n return this.#compareMoneyAccountBalance(request.payerAddress, price);\n }\n\n async #compareMoneyAccountBalance(\n payerAddress: Hex,\n price: ProductPrice,\n ): Promise<MoneyAccountBalanceCheckResult> {\n assertPositiveInteger(\n price.minBillingCyclesForBalance,\n SubscriptionDelegationServiceErrorMessage.InvalidMinimumFundingCycles,\n );\n\n const periodAmount = calculatePeriodAmount({\n unitAmount: price.unitAmount,\n unitDecimals: price.unitDecimals,\n tokenDecimals: MUSD_DECIMALS,\n });\n const requiredBalance =\n periodAmount * BigInt(price.minBillingCyclesForBalance);\n\n const { totalBalance } = await this.#messenger.call(\n 'MoneyAccountBalanceService:fetchBalanceWithFallback',\n payerAddress,\n );\n\n return {\n hasSufficientBalance: BigInt(totalBalance) >= requiredBalance,\n balance: totalBalance,\n requiredBalance: requiredBalance.toString(),\n };\n }\n\n /**\n * Prepares a cash-subscription delegation and returns its hash.\n *\n * Reuses a stored AUS delegation that matches the semantic fingerprint when\n * one exists (ensuring a CHOMP intent is active for its hash, unless\n * `skipChompInteractions` is true). Reuse classifies period `startDate` as\n * trial-deferred (`> now`) vs immediately redeemable, matching creation.\n * When several records match, the latest period `startDate` is reused\n * so a `forceNew` replacement is preferred over an older equivalent\n * permission.\n * If there is no match, builds, signs, optionally verifies with CHOMP,\n * persists, and optionally registers a new delegation.\n *\n * When `skipChompInteractions` is true (required for alpha), CHOMP verify\n * and intent calls are skipped; the returned hash is computed locally. The\n * default CHOMP-enabled path requires a follow-up chomp-api-service release\n * that accepts `'cash-subscription'` intent metadata.\n *\n * @param request - Authoritative pricing and payer details for the delegation.\n * @param forceNew - Whether to create a replacement instead of reusing a\n * matching stored delegation.\n * @returns The delegation hash (CHOMP-verified unless skipped) and whether it\n * was created or reused.\n */\n async prepareDelegation(\n request: PrepareSubscriptionDelegationRequest,\n forceNew = false,\n ): Promise<PreparedSubscriptionDelegation> {\n if (request.product !== PRODUCT_TYPES.MONEY_ACCOUNT_PLUS) {\n throw new Error(\n SubscriptionDelegationServiceErrorMessage.UnsupportedProduct,\n );\n }\n\n const skipChomp = Boolean(request.skipChompInteractions);\n\n const { chainId, delegateAddress, enforcers, price, token } =\n await this.#resolveConfiguration(\n request.product,\n request.recurringInterval,\n );\n\n if (request.checkBalance) {\n const { hasSufficientBalance } = await this.#compareMoneyAccountBalance(\n request.payerAddress,\n price,\n );\n if (!hasSufficientBalance) {\n throw new Error(\n SubscriptionDelegationServiceErrorMessage.InsufficientBalance,\n );\n }\n }\n\n const periodAmount = calculatePeriodAmount({\n unitAmount: price.unitAmount,\n unitDecimals: price.unitDecimals,\n tokenDecimals: token.decimals,\n });\n const periodDuration = getPeriodDuration(request.recurringInterval);\n const nowSeconds = Math.floor(Date.now() / 1000);\n const startDate = getDelegationStartDate({\n nowSeconds,\n trialPeriodDays: request.isTrialRequested\n ? price.trialPeriodDays\n : undefined,\n });\n const isTrialDeferred = startDate > nowSeconds;\n\n const reusable = forceNew\n ? undefined\n : await this.#findReusableDelegation({\n request,\n chainId,\n delegateAddress,\n tokenAddress: token.address,\n periodAmount,\n periodDuration,\n nowSeconds,\n isTrialDeferred,\n enforcers,\n });\n if (reusable) {\n if (!skipChomp) {\n await this.#ensureIntent({\n account: request.payerAddress,\n chainId,\n delegationHash: reusable.metadata.delegationHash,\n allowance: reusable.metadata.allowance,\n tokenSymbol: reusable.metadata.tokenSymbol,\n tokenAddress: reusable.metadata.tokenAddress,\n });\n }\n return {\n delegationHash: reusable.metadata.delegationHash,\n disposition: 'reused',\n };\n }\n\n const unsigned = buildUnsignedSubscriptionDelegation({\n delegateAddress,\n delegatorAddress: request.payerAddress,\n enforcers,\n tokenAddress: token.address,\n periodAmount,\n periodDuration,\n startDate,\n });\n\n const signature = (await this.#messenger.call(\n 'DelegationController:signDelegation',\n { delegation: unsigned, chainId },\n )) as Hex;\n\n const signedDelegation = { ...unsigned, signature };\n\n const delegationHash = hashDelegation({\n ...unsigned,\n salt: BigInt(unsigned.salt),\n signature,\n });\n\n if (!skipChomp) {\n const verifyResult = await this.#messenger.call(\n 'ChompApiService:verifyDelegation',\n {\n signedDelegation,\n chainId,\n },\n );\n\n if (!verifyResult.valid) {\n throw new Error(\n `${SubscriptionDelegationServiceErrorMessage.ChompRejectedDelegation}: ${\n verifyResult.errors?.join(', ') ?? 'unknown error'\n }`,\n );\n }\n\n if (!verifyResult.delegationHash) {\n throw new Error(\n SubscriptionDelegationServiceErrorMessage.ChompMissingDelegationHash,\n );\n }\n if (!equalsIgnoreCase(verifyResult.delegationHash, delegationHash)) {\n throw new Error(\n SubscriptionDelegationServiceErrorMessage.ChompDelegationHashMismatch,\n );\n }\n }\n\n const allowance: Hex = add0x(periodAmount.toString(16));\n\n await this.#messenger.call(\n 'AuthenticatedUserStorageService:createDelegation',\n {\n signedDelegation,\n metadata: {\n delegationHash,\n chainIdHex: chainId,\n allowance,\n tokenSymbol: token.symbol,\n tokenAddress: token.address,\n type: CASH_SUBSCRIPTION_DELEGATION_TYPE,\n },\n },\n );\n\n if (!skipChomp) {\n await this.#createIntent({\n account: request.payerAddress,\n chainId,\n delegationHash,\n allowance,\n tokenSymbol: token.symbol,\n tokenAddress: token.address,\n });\n }\n\n return {\n delegationHash,\n disposition: 'created',\n };\n }\n\n async #findReusableDelegation({\n request,\n chainId,\n delegateAddress,\n tokenAddress,\n periodAmount,\n periodDuration,\n nowSeconds,\n isTrialDeferred,\n enforcers,\n }: {\n request: PrepareSubscriptionDelegationRequest;\n chainId: Hex;\n delegateAddress: Hex;\n tokenAddress: Hex;\n periodAmount: bigint;\n periodDuration: number;\n nowSeconds: number;\n isTrialDeferred: boolean;\n enforcers: SubscriptionDelegationEnforcers;\n }): Promise<DelegationResponse | undefined> {\n const matches = makeMatchesSubscriptionDelegation({\n delegatorAddress: request.payerAddress,\n delegateAddress,\n chainId,\n tokenAddress,\n periodAmount,\n periodDuration,\n nowSeconds,\n isTrialDeferred,\n enforcers,\n });\n\n const existingDelegations = await this.#messenger.call(\n 'AuthenticatedUserStorageService:listDelegations',\n );\n\n return pickLatestMatchingSubscriptionDelegation(\n existingDelegations.filter(matches),\n enforcers,\n );\n }\n\n async #resolveConfiguration(\n product: ProductType,\n recurringInterval: RecurringInterval,\n ): Promise<ResolvedSubscriptionDelegationConfig> {\n const { remoteFeatureFlags } = this.#messenger.call(\n 'RemoteFeatureFlagController:getState',\n );\n const vaultConfig = getMoneyAccountVaultConfig(remoteFeatureFlags);\n if (!vaultConfig) {\n throw new Error(\n SubscriptionDelegationServiceErrorMessage.MissingMoneyAccountVaultConfig,\n );\n }\n\n const { chainId } = vaultConfig;\n const enforcers = resolveEnforcers(chainId);\n const pricing = await this.#messenger.call(\n 'SubscriptionController:getPricing',\n );\n const price = pricing.products\n .find((entry) => entry.name === product)\n ?.prices?.find((entry) => entry.interval === recurringInterval);\n const paymentMethod = pricing.paymentMethods.find(\n (entry): entry is PricingCryptoPaymentMethod =>\n entry.type === PAYMENT_TYPES.byCrypto &&\n entry.cryptoAuthMethod === CRYPTO_AUTH_METHODS.DELEGATION &&\n entry.products?.includes(product) === true,\n );\n const chain = paymentMethod?.chains?.find(\n (entry) => entry.chainId === chainId,\n );\n const token = chain?.tokens[0];\n if (!price || !chain?.delegateAddress || !token) {\n throw new Error(\n SubscriptionDelegationServiceErrorMessage.PricingConfigurationNotFound,\n );\n }\n\n return {\n chainId,\n delegateAddress: chain.delegateAddress,\n enforcers,\n price,\n token,\n };\n }\n\n /**\n * Ensures an active CHOMP intent exists for the given delegation hash,\n * registering one when missing or revoked.\n *\n * @param params - Intent identity and metadata.\n * @param params.account - Delegator / payer address.\n * @param params.chainId - Chain ID of the delegation.\n * @param params.delegationHash - Hash of the stored delegation.\n * @param params.allowance - Period allowance stored with the delegation.\n * @param params.tokenSymbol - Payment token symbol.\n * @param params.tokenAddress - Payment token address.\n */\n async #ensureIntent(params: SubscriptionIntentParams): Promise<void> {\n const existingIntents = await this.#messenger.call(\n 'ChompApiService:getIntentsByAddress',\n params.account,\n );\n\n const hasActiveIntent = existingIntents.some(\n (intent) =>\n equalsIgnoreCase(intent.delegationHash, params.delegationHash) &&\n intent.status === 'active',\n );\n\n if (hasActiveIntent) {\n return;\n }\n\n await this.#createIntent(params);\n }\n\n async #createIntent(params: SubscriptionIntentParams): Promise<void> {\n // Published `@metamask/chomp-api-service` only types intent metadata as\n // `'cash-deposit' | 'cash-withdrawal'`. The dormant production path still\n // passes `'cash-subscription'`; a follow-up chomp-api-service release must\n // accept that discriminator before this path is production-ready. Alpha\n // callers must use `skipChompInteractions: true` so this method is not\n // reached.\n await this.#messenger.call('ChompApiService:createIntents', [\n {\n account: params.account,\n delegationHash: params.delegationHash,\n chainId: params.chainId,\n metadata: {\n allowance: params.allowance,\n tokenSymbol: params.tokenSymbol,\n tokenAddress: params.tokenAddress,\n type: CASH_SUBSCRIPTION_DELEGATION_TYPE as\n | 'cash-deposit'\n | 'cash-withdrawal',\n },\n },\n ]);\n }\n}\n"]}
|
|
@@ -39,4 +39,15 @@ export declare function equalsIgnoreCase(left: string, right: string): boolean;
|
|
|
39
39
|
* @returns Predicate over {@link DelegationResponse}.
|
|
40
40
|
*/
|
|
41
41
|
export declare function makeMatchesSubscriptionDelegation(expected: SubscriptionDelegationFingerprint): (entry: DelegationResponse) => boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Returns the fingerprint match with the latest period `startDate`.
|
|
44
|
+
*
|
|
45
|
+
* Equal `startDate`s keep list order. A delegation whose `startDate` cannot
|
|
46
|
+
* be read sorts last.
|
|
47
|
+
*
|
|
48
|
+
* @param matches - Fingerprint-matching AUS delegations, in list order.
|
|
49
|
+
* @param enforcers - Enforcer addresses used to read `startDate`.
|
|
50
|
+
* @returns The preferred match, or `undefined` when `matches` is empty.
|
|
51
|
+
*/
|
|
52
|
+
export declare function pickLatestMatchingSubscriptionDelegation(matches: readonly DelegationResponse[], enforcers: SubscriptionDelegationEnforcers): DelegationResponse | undefined;
|
|
42
53
|
//# sourceMappingURL=fingerprint.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../src/subscription-delegation/fingerprint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAK/E,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAE3C,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,YAAY,CAAC;AAGlE,MAAM,MAAM,iCAAiC,GAAG;IAC9C,gBAAgB,EAAE,GAAG,CAAC;IACtB,eAAe,EAAE,GAAG,CAAC;IACrB,OAAO,EAAE,GAAG,CAAC;IACb,YAAY,EAAE,GAAG,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,+BAA+B,CAAC;CAC5C,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAErE;AAED;;;;;;;;;GASG;AACH,wBAAgB,iCAAiC,CAC/C,QAAQ,EAAE,iCAAiC,GAC1C,CAAC,KAAK,EAAE,kBAAkB,KAAK,OAAO,CAsExC"}
|
|
1
|
+
{"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../src/subscription-delegation/fingerprint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAK/E,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAE3C,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,YAAY,CAAC;AAGlE,MAAM,MAAM,iCAAiC,GAAG;IAC9C,gBAAgB,EAAE,GAAG,CAAC;IACtB,eAAe,EAAE,GAAG,CAAC;IACrB,OAAO,EAAE,GAAG,CAAC;IACb,YAAY,EAAE,GAAG,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,+BAA+B,CAAC;CAC5C,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAErE;AAED;;;;;;;;;GASG;AACH,wBAAgB,iCAAiC,CAC/C,QAAQ,EAAE,iCAAiC,GAC1C,CAAC,KAAK,EAAE,kBAAkB,KAAK,OAAO,CAsExC;AA8BD;;;;;;;;;GASG;AACH,wBAAgB,wCAAwC,CACtD,OAAO,EAAE,SAAS,kBAAkB,EAAE,EACtC,SAAS,EAAE,+BAA+B,GACzC,kBAAkB,GAAG,SAAS,CAYhC"}
|