@metamask-previews/subscription-controller 9.0.1-preview-e8a256c39 → 9.0.1-preview-429f77222
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 +2 -11
- package/dist/SubscriptionController.d.ts.map +1 -1
- package/dist/SubscriptionController.js +9 -1
- package/dist/SubscriptionController.js.map +1 -1
- package/dist/SubscriptionService.d.ts.map +1 -1
- package/dist/SubscriptionService.js +7 -1
- package/dist/SubscriptionService.js.map +1 -1
- package/dist/constants.d.ts +11 -16
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +17 -17
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +3 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -10
- package/dist/subscription-delegation/SubscriptionDelegationService-method-action-types.d.ts +0 -44
- package/dist/subscription-delegation/SubscriptionDelegationService-method-action-types.d.ts.map +0 -1
- package/dist/subscription-delegation/SubscriptionDelegationService-method-action-types.js +0 -6
- package/dist/subscription-delegation/SubscriptionDelegationService-method-action-types.js.map +0 -1
- package/dist/subscription-delegation/SubscriptionDelegationService.d.ts +0 -93
- package/dist/subscription-delegation/SubscriptionDelegationService.d.ts.map +0 -1
- package/dist/subscription-delegation/SubscriptionDelegationService.js +0 -290
- package/dist/subscription-delegation/SubscriptionDelegationService.js.map +0 -1
- package/dist/subscription-delegation/amount.d.ts +0 -49
- package/dist/subscription-delegation/amount.d.ts.map +0 -1
- package/dist/subscription-delegation/amount.js +0 -84
- package/dist/subscription-delegation/amount.js.map +0 -1
- package/dist/subscription-delegation/caveats.d.ts +0 -41
- package/dist/subscription-delegation/caveats.d.ts.map +0 -1
- package/dist/subscription-delegation/caveats.js +0 -59
- package/dist/subscription-delegation/caveats.js.map +0 -1
- package/dist/subscription-delegation/fingerprint.d.ts +0 -42
- package/dist/subscription-delegation/fingerprint.d.ts.map +0 -1
- package/dist/subscription-delegation/fingerprint.js +0 -80
- package/dist/subscription-delegation/fingerprint.js.map +0 -1
- package/dist/subscription-delegation/types.d.ts +0 -73
- package/dist/subscription-delegation/types.d.ts.map +0 -1
- package/dist/subscription-delegation/types.js +0 -10
- package/dist/subscription-delegation/types.js.map +0 -1
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAYA;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B;;OAEG;IACH,MAAM,EAAE,QAAQ;IAChB;;OAEG;IACH,kBAAkB,EAAE,oBAAoB;CAChC,CAAC;AAIX,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,aAAa,EAAE,eAAe;IAC9B,cAAc,EAAE,gBAAgB;IAChC,aAAa,EAAE,eAAe;IAC9B,UAAU,EAAE,YAAY;CAChB,CAAC;AAOX,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,WAAW,EAAE,aAAa;IAC1B,eAAe,EAAE,iBAAiB;CAC1B,CAAC;AAuBX;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC;;OAEG;IACH,cAAc,EAAE,gBAAgB;IAChC;;OAEG;IACH,UAAU,EAAE,YAAY;CAChB,CAAC;AAKX,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,MAAM,EAAE,MAAM;IACd,QAAQ,EAAE,QAAQ;CACV,CAAC;AAIX,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;CACJ,CAAC;AAKX,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,iBAAiB;IACjB,UAAU,EAAE,YAAY;IACxB,iBAAiB,EAAE,oBAAoB;IACvC,gBAAgB;IAChB,WAAW,EAAE,aAAa;IAC1B,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAE,QAAQ;IAChB,iBAAiB;IACjB,OAAO,EAAE,UAAU;IACnB,MAAM,EAAE,QAAQ;IAChB,mBAAmB;IACnB,QAAQ,EAAE,UAAU;IACpB,gBAAgB;IAChB,MAAM,EAAE,QAAQ;CACR,CAAC;AAKX,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,iBAAiB,EAAE,mBAAmB;IACtC,qBAAqB,EAAE,uBAAuB;IAC9C,WAAW,EAAE,aAAa;IAC1B,gCAAgC,EAAE,kCAAkC;CAC5D,CAAC;AAIX,MAAM,CAAC,MAAM,4BAA4B,GAAG;IAC1C,4BAA4B,EAAE,8BAA8B;IAC5D,6BAA6B,EAAE,+BAA+B;IAC9D,sDAAsD,EACpD,wDAAwD;IAC1D,oBAAoB,EAAE,sBAAsB;IAC5C,sBAAsB,EAAE,wBAAwB;CACxC,CAAC;AAKX,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;CACE,CAAC;AAsZX,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,OAAO,EAAE,SAAS;IAClB,WAAW,EAAE,aAAa;CAClB,CAAC;AAIX,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,UAAU,EAAE,MAAM;IAClB,aAAa,EAAE,SAAS;IACxB,aAAa,EAAE,SAAS;IACxB,eAAe,EAAE,WAAW;IAC5B,iBAAiB,EAAE,aAAa;IAChC,aAAa,EAAE,KAAK;CACZ,CAAC;AAsBX,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,sBAAsB,EAAE,2BAA2B;IACnD,oBAAoB,EAAE,wBAAwB;CACtC,CAAC","sourcesContent":["import type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { CaipAccountId, Hex } from '@metamask/utils';\n\n/**\n * Error response from the Subscription API.\n */\nexport type SubscriptionApiError = {\n errorCode?: string;\n message?: string;\n statusCode?: number;\n};\n\n/**\n * Supported subscription products.\n */\nexport const PRODUCT_TYPES = {\n /**\n * MetaMask Shield.\n */\n SHIELD: 'shield',\n /**\n * Money Account Plus (delegation-based crypto billing).\n */\n MONEY_ACCOUNT_PLUS: 'money_account_plus',\n} as const;\n\nexport type ProductType = (typeof PRODUCT_TYPES)[keyof typeof PRODUCT_TYPES];\n\nexport const MoneyAccountFeature = {\n SwapFeeWaiver: 'swapFeeWaiver',\n PerpsFeeWaiver: 'perpsFeeWaiver',\n PredictFreeTx: 'predictFreeTx',\n PremiumApy: 'premiumApy',\n} as const;\n\nexport type MoneyAccountFeature =\n (typeof MoneyAccountFeature)[keyof typeof MoneyAccountFeature];\n\nexport type MoneyAccountEntitlements = Record<MoneyAccountFeature, boolean>;\n\nexport const ShieldFeature = {\n ShieldClaim: 'shieldClaim',\n PrioritySupport: 'prioritySupport',\n} as const;\n\nexport type ShieldFeature = (typeof ShieldFeature)[keyof typeof ShieldFeature];\n\nexport type ShieldEntitlements = Record<ShieldFeature, boolean>;\n\nexport type MoneyAccountPlusClaim = {\n plan: string;\n entitlements: MoneyAccountEntitlements;\n};\n\nexport type ProductEntitlements = {\n [PRODUCT_TYPES.SHIELD]?: {\n entitlements: ShieldEntitlements;\n };\n [PRODUCT_TYPES.MONEY_ACCOUNT_PLUS]?: MoneyAccountPlusClaim;\n};\n\nexport type ProductEntitlementFeatureMap = {\n [PRODUCT_TYPES.SHIELD]: ShieldFeature;\n [PRODUCT_TYPES.MONEY_ACCOUNT_PLUS]: MoneyAccountFeature;\n};\n\n/**\n * How a crypto subscription is authorized.\n *\n * Use `erc20_approval` with `rawTransaction` (e.g. Shield). Use `delegation`\n * with `delegationHash` (e.g. Money Account Plus).\n */\nexport const CRYPTO_AUTH_METHODS = {\n /**\n * User signs an ERC-20 approve transaction.\n */\n ERC20_APPROVAL: 'erc20_approval',\n /**\n * User authorizes via a stored delegation hash.\n */\n DELEGATION: 'delegation',\n} as const;\n\nexport type CryptoAuthMethod =\n (typeof CRYPTO_AUTH_METHODS)[keyof typeof CRYPTO_AUTH_METHODS];\n\nexport const PAYMENT_TYPES = {\n byCard: 'card',\n byCrypto: 'crypto',\n} as const;\n\nexport type PaymentType = (typeof PAYMENT_TYPES)[keyof typeof PAYMENT_TYPES];\n\nexport const RECURRING_INTERVALS = {\n month: 'month',\n year: 'year',\n} as const;\n\nexport type RecurringInterval =\n (typeof RECURRING_INTERVALS)[keyof typeof RECURRING_INTERVALS];\n\nexport const SUBSCRIPTION_STATUSES = {\n // Initial states\n incomplete: 'incomplete',\n incompleteExpired: 'incomplete_expired',\n // Active states\n provisional: 'provisional',\n trialing: 'trialing',\n active: 'active',\n // Payment issues\n pastDue: 'past_due',\n unpaid: 'unpaid',\n // Cancelled states\n canceled: 'canceled',\n // Paused states\n paused: 'paused',\n} as const;\n\nexport type SubscriptionStatus =\n (typeof SUBSCRIPTION_STATUSES)[keyof typeof SUBSCRIPTION_STATUSES];\n\nexport const CANCEL_TYPES = {\n ALLOWED_IMMEDIATE: 'allowed_immediate',\n ALLOWED_AT_PERIOD_END: 'allowed_at_period_end',\n NOT_ALLOWED: 'not_allowed',\n NOT_ALLOWED_PENDING_VERIFICATION: 'not_allowed_pending_verification',\n} as const;\n\nexport type CancelType = (typeof CANCEL_TYPES)[keyof typeof CANCEL_TYPES];\n\nexport const CRYPTO_PAYMENT_METHOD_ERRORS = {\n APPROVAL_TRANSACTION_TOO_OLD: 'approval_transaction_too_old',\n APPROVAL_TRANSACTION_REVERTED: 'approval_transaction_reverted',\n APPROVAL_TRANSACTION_MAX_VERIFICATION_ATTEMPTS_REACHED:\n 'approval_transaction_max_verification_attempts_reached',\n INSUFFICIENT_BALANCE: 'insufficient_balance',\n INSUFFICIENT_ALLOWANCE: 'insufficient_allowance',\n} as const;\n\nexport type CryptoPaymentMethodError =\n (typeof CRYPTO_PAYMENT_METHOD_ERRORS)[keyof typeof CRYPTO_PAYMENT_METHOD_ERRORS];\n\nexport const MODAL_TYPE = {\n A: 'A',\n B: 'B',\n} as const;\n\nexport type ModalType = (typeof MODAL_TYPE)[keyof typeof MODAL_TYPE];\n\n/** only usd for now */\nexport type Currency = 'usd';\n\nexport type Product = {\n name: ProductType;\n currency: Currency;\n unitAmount: number;\n unitDecimals: number;\n};\n\n// state\nexport type Subscription = {\n id: string;\n products: Product[];\n currentPeriodStart: string; // ISO 8601\n currentPeriodEnd: string; // ISO 8601\n /** is subscription scheduled for cancellation */\n cancelAtPeriodEnd?: boolean;\n status: SubscriptionStatus;\n interval: RecurringInterval;\n paymentMethod: SubscriptionPaymentMethod;\n trialPeriodDays?: number;\n trialStart?: string; // ISO 8601\n trialEnd?: string; // ISO 8601\n /** Crypto payment only: next billing cycle date (e.g after 12 months) */\n endDate?: string; // ISO 8601\n /** The date the subscription was canceled. */\n canceledAt?: string; // ISO 8601\n /** The cancellation type indicating what cancellation options are available for this subscription. */\n cancelType: CancelType;\n /** The date the subscription was marked as inactive (paused/past_due/canceled). */\n inactiveAt?: string; // ISO 8601\n /** Whether the user is eligible for support features (priority support and filing claims). True for active subscriptions and inactive subscriptions within grace period. */\n isEligibleForSupport: boolean;\n billingCycles?: number;\n};\n\nexport type SubscriptionCardPaymentMethod = {\n type: Extract<PaymentType, 'card'>;\n card: {\n brand: string;\n /** display brand account for dual brand card */\n displayBrand: string;\n last4: string;\n };\n};\n\nexport type SubscriptionCryptoPaymentMethod = {\n type: Extract<PaymentType, 'crypto'>;\n crypto: {\n payerAddress: Hex;\n chainId: Hex;\n tokenSymbol: string;\n error?: CryptoPaymentMethodError;\n };\n};\n\nexport type SubscriptionPaymentMethod =\n | SubscriptionCardPaymentMethod\n | SubscriptionCryptoPaymentMethod;\n\nexport type GetSubscriptionsResponse = {\n customerId?: string;\n subscriptions: Subscription[];\n trialedProducts: ProductType[];\n productEntitlements?: ProductEntitlements;\n /** The last subscription that user has subscribed to if any. */\n lastSubscription?: Subscription;\n /** The reward account ID if user has linked rewards to the subscription. */\n rewardAccountId?: CaipAccountId;\n};\n\n/**\n * Benefits available to a subscription user.\n */\nexport type SwapsBenefitUsage = {\n feeBips: string | null;\n capMicroUsd?: number;\n consumedMicroUsd?: number;\n remainingMicroUsd: number | null;\n exhausted: boolean;\n};\n\nexport type PerpsBenefitUsage = {\n builderFeeBips: string | null;\n builderCode: string | null;\n capMicroUsd?: number;\n consumedMicroUsd?: number;\n remainingMicroUsd: number | null;\n exhausted: boolean;\n};\n\nexport type PredictBenefitUsage = {\n builderCode: string | null;\n capTxCount?: number;\n consumedTxCount?: number;\n remainingTxCount: number | null;\n exhausted: boolean;\n};\n\ntype SubscriptionBenefitsProducts = {\n swaps: SwapsBenefitUsage;\n perps: PerpsBenefitUsage;\n predict: PredictBenefitUsage;\n};\n\nexport type SubscriptionBenefitsResponse = {\n eligible: boolean;\n billingPeriodId: string | null;\n products: SubscriptionBenefitsProducts;\n};\n\n/**\n * Benefits state exposed to the UI.\n */\nexport type SubscriptionBenefitsState = SubscriptionBenefitsProducts & {\n billingPeriodId: string | null;\n};\n\nexport type StartSubscriptionRequest = {\n products: ProductType[];\n isTrialRequested: boolean;\n recurringInterval: RecurringInterval;\n successUrl?: string;\n cancelUrl?: string;\n useTestClock?: boolean;\n\n /**\n * Optional CAIP account ID of the rewards account to opt in alongside this\n * subscription. Required when the user wants to link rewards during\n * subscription creation.\n *\n * @example {\n * rewardAccountId: 'eip155:1:0x1234567890123456789012345678901234567890',\n * }\n */\n rewardAccountId?: CaipAccountId;\n};\n\nexport type StartSubscriptionResponse = {\n checkoutSessionUrl: string;\n};\n\ntype StartCryptoSubscriptionRequestBase = {\n products: ProductType[];\n isTrialRequested: boolean;\n recurringInterval: RecurringInterval;\n billingCycles: number;\n chainId: Hex;\n payerAddress: Hex;\n /**\n * e.g. \"USDC\"\n */\n tokenSymbol: string;\n isSponsored?: boolean;\n useTestClock?: boolean;\n /**\n * Optional CAIP account ID of the rewards account to opt in alongside this\n * subscription. Required when the user wants to link rewards during\n * subscription creation.\n *\n * @example {\n * rewardAccountId: 'eip155:1:0x1234567890123456789012345678901234567890',\n * }\n */\n rewardAccountId?: CaipAccountId;\n};\n\n/**\n * ERC-20 approval crypto subscription request (e.g. Shield).\n *\n * `cryptoAuthMethod` defaults to `CRYPTO_AUTH_METHODS.ERC20_APPROVAL` when\n * omitted.\n */\nexport type StartErc20CryptoSubscriptionRequest =\n StartCryptoSubscriptionRequestBase & {\n cryptoAuthMethod?: typeof CRYPTO_AUTH_METHODS.ERC20_APPROVAL;\n rawTransaction: Hex;\n delegationHash?: never;\n };\n\n/**\n * Delegation-based crypto subscription request (e.g. Money Account Plus).\n */\nexport type StartDelegationCryptoSubscriptionRequest =\n StartCryptoSubscriptionRequestBase & {\n cryptoAuthMethod: typeof CRYPTO_AUTH_METHODS.DELEGATION;\n delegationHash: Hex;\n rawTransaction?: never;\n };\n\n/**\n * Request to start a crypto subscription.\n *\n * Discriminated union of ERC-20 approval vs delegation. Provide\n * `rawTransaction` for ERC-20 approval (the default when `cryptoAuthMethod` is\n * omitted), or `delegationHash` with `cryptoAuthMethod: 'delegation'`.\n * Combining or omitting both is a type error, and is also rejected at runtime\n * by `startSubscriptionWithCrypto`.\n */\nexport type StartCryptoSubscriptionRequest =\n | StartErc20CryptoSubscriptionRequest\n | StartDelegationCryptoSubscriptionRequest;\n\nexport type StartCryptoSubscriptionResponse = {\n subscriptionId: string;\n status: SubscriptionStatus;\n};\n\n/**\n * General response type for the subscription API requests\n * which doesn't require any specific response data.\n */\nexport type SubscriptionApiGeneralResponse = {\n /**\n * Whether the request was successful.\n */\n success: boolean;\n /**\n * The message of the response.\n */\n message?: string;\n};\n\nexport type CancelSubscriptionRequest = {\n subscriptionId: string;\n /** Whether to cancel at the end of the current period */\n cancelAtPeriodEnd?: boolean;\n};\n\nexport type AuthUtils = {\n getAccessToken: () => Promise<string>;\n};\n\nexport type ProductPrice = {\n interval: RecurringInterval;\n unitAmount: number; // amount in the smallest unit of the currency, e.g., cents\n unitDecimals: number; // number of decimals for the smallest unit of the currency\n /** only usd for now */\n currency: Currency;\n trialPeriodDays: number;\n /** min billing cycles for approval */\n minBillingCycles: number;\n /** min billing cycles for account balance check */\n minBillingCyclesForBalance: number;\n};\n\nexport type ProductPricing = {\n name: ProductType;\n prices: ProductPrice[];\n};\n\ntype TokenPaymentInfoBase = {\n symbol: string;\n address: Hex;\n decimals: number;\n /**\n * example: {\n usd: '1.0',\n },\n */\n conversionRate?: {\n usd: string;\n };\n /**\n * Source tokens that can be converted into this settlement token.\n */\n sources?: TokenPaymentInfo[];\n};\n\n/**\n * Spot (non-vault) settlement token. Priced via `conversionRate` when provided.\n * `accountantAddress` is not present on this variant.\n */\nexport type SpotTokenPaymentInfo = TokenPaymentInfoBase & {\n isVaultShare?: false;\n};\n\n/**\n * Yield-bearing vault share priced via an accountant rate.\n */\nexport type VaultTokenPaymentInfo = TokenPaymentInfoBase & {\n isVaultShare: true;\n /**\n * Veda accountant address used to value this vault share.\n */\n accountantAddress: Hex;\n};\n\n/**\n * A settlement token in a pricing chain. Discriminated by `isVaultShare`:\n * vault shares require `accountantAddress`; spot tokens omit it.\n */\nexport type TokenPaymentInfo = SpotTokenPaymentInfo | VaultTokenPaymentInfo;\n\nexport type ChainPaymentInfo = {\n chainId: Hex;\n paymentAddress: Hex;\n /**\n * Delegate address clients authorize when using the delegation auth method.\n */\n delegateAddress?: Hex;\n tokens: TokenPaymentInfo[];\n /**\n * Whether the chain supports sponsorship for the trialed subscription approval transaction.\n * This is used to determine if the user can be sponsored for the gas fees for the trialed subscription approval transaction.\n */\n isSponsorshipSupported?: boolean;\n};\n\nexport type PricingCardPaymentMethod = {\n type: Extract<PaymentType, 'card'>;\n /**\n * Products that support this payment method.\n */\n products?: ProductType[];\n};\n\nexport type PricingCryptoPaymentMethod = {\n type: Extract<PaymentType, 'crypto'>;\n /**\n * Crypto authorization method. Omitted together with `products` on persisted\n * pre-multi-product pricing rows; those rows are treated as Shield + `erc20_approval`.\n * If `products` is set, this field must be explicit.\n */\n cryptoAuthMethod?: CryptoAuthMethod;\n /**\n * Products that support this payment method. Omitted together with\n * `cryptoAuthMethod` on persisted pre-multi-product pricing rows (treated as Shield).\n * If present, must be non-empty and paired with an explicit `cryptoAuthMethod`.\n */\n products?: ProductType[];\n chains?: ChainPaymentInfo[];\n};\n\n/**\n * A pricing payment-method row. Discriminated by `type`: card rows have no\n * crypto fields; crypto rows may include `cryptoAuthMethod` and `chains`.\n */\nexport type PricingPaymentMethod =\n | PricingCardPaymentMethod\n | PricingCryptoPaymentMethod;\n\nexport type PricingResponse = {\n products: ProductPricing[];\n paymentMethods: PricingPaymentMethod[];\n};\n\nexport type GetCryptoApproveTransactionRequest = {\n /**\n * payment chain ID\n */\n chainId: Hex;\n /**\n * Payment token address\n */\n paymentTokenAddress: Hex;\n productType: ProductType;\n interval: RecurringInterval;\n};\n\nexport type GetCryptoApproveTransactionResponse = {\n /**\n * The amount to approve\n * e.g: \"100000000\"\n */\n approveAmount: string;\n /**\n * The contract address (spender)\n */\n paymentAddress: Hex;\n /**\n * The payment token address\n */\n paymentTokenAddress: Hex;\n chainId: Hex;\n};\n\n/**\n * Request to submit a Shield ERC-20 crypto approval transaction.\n */\nexport type SubmitSubscriptionCryptoApprovalRequest = {\n /**\n * The subscription product. Typed as `typeof PRODUCT_TYPES.SHIELD` only at\n * the moment (future might support more product).\n */\n productType: typeof PRODUCT_TYPES.SHIELD;\n /**\n * The transaction metadata. Must have type\n * `TransactionType.shieldSubscriptionApprove`.\n */\n txMeta: TransactionMeta;\n /**\n * Whether the transaction is sponsored.\n */\n isSponsored?: boolean;\n /**\n * The account ID of the reward subscription to link.\n */\n rewardAccountId?: CaipAccountId;\n};\n\nexport const COHORT_NAMES = {\n POST_TX: 'post_tx',\n WALLET_HOME: 'wallet_home',\n} as const;\n\nexport type CohortName = (typeof COHORT_NAMES)[keyof typeof COHORT_NAMES];\n\nexport const BALANCE_CATEGORIES = {\n RANGE_0_99: '0-99',\n RANGE_100_999: '100-999',\n RANGE_1K_9_9K: '1k-9.9k',\n RANGE_10K_99_9K: '10k-99.9k',\n RANGE_100K_999_9K: '100k-999.9k',\n RANGE_1M_PLUS: '1M+',\n} as const;\n\nexport type BalanceCategory =\n (typeof BALANCE_CATEGORIES)[keyof typeof BALANCE_CATEGORIES];\n\nexport type Cohort = {\n cohort: string;\n eligibilityRate: number; // 0-1 probability of being assigned to this cohort\n priority: number; // lower number = higher priority\n eligible: boolean;\n};\n\nexport type SubscriptionEligibility = {\n product: ProductType;\n canSubscribe: boolean;\n canViewEntryModal: boolean;\n modalType?: ModalType;\n cohorts: Cohort[];\n assignedCohort: string | null;\n hasAssignedCohortExpired: boolean;\n};\n\nexport const SubscriptionUserEvent = {\n ShieldEntryModalViewed: 'shield_entry_modal_viewed',\n ShieldCohortAssigned: 'shield_cohort_assigned',\n} as const;\n\nexport type SubscriptionUserEventType =\n (typeof SubscriptionUserEvent)[keyof typeof SubscriptionUserEvent];\n\nexport type SubmitUserEventRequest = {\n event: SubscriptionUserEventType;\n cohort?: string;\n};\n\nexport type AssignCohortRequest = {\n cohort: string;\n};\n\nexport type GetSubscriptionsEligibilitiesRequest = {\n balanceCategory?: BalanceCategory;\n};\n\n/**\n * Request object for submitting sponsorship intents.\n */\nexport type SubmitSponsorshipIntentsRequest = {\n chainId: Hex;\n address: Hex;\n products: ProductType[];\n paymentTokenSymbol: string;\n recurringInterval: RecurringInterval;\n billingCycles: number;\n};\n\nexport type SubmitSponsorshipIntentsMethodParams = Pick<\n SubmitSponsorshipIntentsRequest,\n 'chainId' | 'address' | 'products'\n>;\n\nexport type ISubscriptionService = {\n getSubscriptions(): Promise<GetSubscriptionsResponse>;\n getBenefits(): Promise<SubscriptionBenefitsResponse>;\n cancelSubscription(request: CancelSubscriptionRequest): Promise<Subscription>;\n unCancelSubscription(request: {\n subscriptionId: string;\n }): Promise<Subscription>;\n /**\n * Starts a card-paid subscription checkout session for the requested products\n * (e.g. Shield or Money Account Plus).\n *\n * @param request - The start subscription request.\n * @returns The checkout session response.\n */\n startSubscriptionWithCard(\n request: StartSubscriptionRequest,\n ): Promise<StartSubscriptionResponse>;\n getBillingPortalUrl(): Promise<BillingPortalResponse>;\n getPricing(): Promise<PricingResponse>;\n startSubscriptionWithCrypto(\n request: StartCryptoSubscriptionRequest,\n ): Promise<StartCryptoSubscriptionResponse>;\n updatePaymentMethodCard(\n request: UpdatePaymentMethodCardRequest,\n ): Promise<UpdatePaymentMethodCardResponse>;\n updatePaymentMethodCrypto(\n request: UpdatePaymentMethodCryptoRequest,\n ): Promise<void>;\n getSubscriptionsEligibilities(\n request?: GetSubscriptionsEligibilitiesRequest,\n ): Promise<SubscriptionEligibility[]>;\n submitUserEvent(request: SubmitUserEventRequest): Promise<void>;\n assignUserToCohort(request: AssignCohortRequest): Promise<void>;\n\n /**\n * Link rewards to a subscription.\n */\n linkRewards(\n request: LinkRewardsRequest,\n ): Promise<SubscriptionApiGeneralResponse>;\n\n /**\n * Submit sponsorship intents to the Subscription Service backend.\n *\n * This is intended to be used together with the crypto subscription flow.\n * When the user has enabled the smart transaction feature, we will sponsor the gas fees for the subscription approval transaction.\n *\n * @param request - Request object containing the address and products.\n * @example {\n * address: '0x1234567890123456789012345678901234567890',\n * products: [ProductType.Shield],\n * recurringInterval: RecurringInterval.Month,\n * billingCycles: 1,\n * }\n */\n submitSponsorshipIntents(\n request: SubmitSponsorshipIntentsRequest,\n ): Promise<void>;\n};\n\nexport type UpdatePaymentMethodOpts =\n | ({\n paymentType: Extract<PaymentType, 'card'>;\n } & UpdatePaymentMethodCardRequest)\n | ({\n paymentType: Extract<PaymentType, 'crypto'>;\n } & UpdatePaymentMethodCryptoRequest);\n\nexport type UpdatePaymentMethodCardRequest = {\n /**\n * Subscription ID\n */\n subscriptionId: string;\n\n /**\n * Recurring interval\n */\n recurringInterval: RecurringInterval;\n successUrl?: string;\n cancelUrl?: string;\n};\n\nexport type UpdatePaymentMethodCardResponse = {\n redirectUrl: string;\n};\n\nexport type UpdatePaymentMethodCryptoRequest = {\n subscriptionId: string;\n chainId: Hex;\n payerAddress: Hex;\n tokenSymbol: string;\n /**\n * The raw transaction to pay for the subscription\n * Can be empty if retry after topping up balance\n */\n rawTransaction?: Hex;\n recurringInterval: RecurringInterval;\n billingCycles: number;\n};\n\nexport type BillingPortalResponse = {\n url: string;\n};\n\n/**\n * The cached result of last selected payment methods for the user.\n * These details are being cached to be used internally to track the last selected payment method for the user. (e.g. for crypto subscriptions)\n */\nexport type CachedLastSelectedPaymentMethod = {\n type: PaymentType;\n paymentTokenAddress?: Hex;\n paymentTokenSymbol?: string;\n plan: RecurringInterval;\n useTestClock?: boolean;\n /**\n * Crypto authorization method. Omitted on persisted cache entries written\n * before this field existed; treat as `erc20_approval` when missing.\n */\n cryptoAuthMethod?: CryptoAuthMethod;\n};\n\n/**\n * Request to cache the last selected payment method for a product.\n */\nexport type CacheLastSelectedPaymentMethodRequest = {\n /**\n * The product to cache the payment method for.\n */\n product: ProductType;\n /**\n * The payment method to cache.\n */\n paymentMethod: CachedLastSelectedPaymentMethod;\n};\n\n/**\n * Request object for linking rewards to a subscription.\n */\nexport type LinkRewardsRequest = {\n /**\n * The ID of the reward subscription to be linked to the subscription.\n *\n * @example {\n * rewardAccountId: 'eip155:1:0x1234567890123456789012345678901234567890',\n * }\n */\n rewardAccountId: CaipAccountId;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAcA;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B;;OAEG;IACH,MAAM,EAAE,QAAQ;IAChB;;OAEG;IACH,kBAAkB,EAAE,oBAAoB;CAChC,CAAC;AAIX,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,aAAa,EAAE,eAAe;IAC9B,cAAc,EAAE,gBAAgB;IAChC,aAAa,EAAE,eAAe;IAC9B,UAAU,EAAE,YAAY;CAChB,CAAC;AAOX,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,WAAW,EAAE,aAAa;IAC1B,eAAe,EAAE,iBAAiB;CAC1B,CAAC;AAuBX;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC;;OAEG;IACH,cAAc,EAAE,gBAAgB;IAChC;;OAEG;IACH,UAAU,EAAE,YAAY;CAChB,CAAC;AAKX,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,MAAM,EAAE,MAAM;IACd,QAAQ,EAAE,QAAQ;CACV,CAAC;AAIX,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;CACJ,CAAC;AAKX,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,iBAAiB;IACjB,UAAU,EAAE,YAAY;IACxB,iBAAiB,EAAE,oBAAoB;IACvC,gBAAgB;IAChB,WAAW,EAAE,aAAa;IAC1B,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAE,QAAQ;IAChB,iBAAiB;IACjB,OAAO,EAAE,UAAU;IACnB,MAAM,EAAE,QAAQ;IAChB,mBAAmB;IACnB,QAAQ,EAAE,UAAU;IACpB,gBAAgB;IAChB,MAAM,EAAE,QAAQ;CACR,CAAC;AAKX,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,iBAAiB,EAAE,mBAAmB;IACtC,qBAAqB,EAAE,uBAAuB;IAC9C,WAAW,EAAE,aAAa;IAC1B,gCAAgC,EAAE,kCAAkC;CAC5D,CAAC;AAOX,MAAM,CAAC,MAAM,4BAA4B,GAAG;IAC1C,4BAA4B,EAAE,8BAA8B;IAC5D,6BAA6B,EAAE,+BAA+B;IAC9D,sDAAsD,EACpD,wDAAwD;IAC1D,oBAAoB,EAAE,sBAAsB;IAC5C,sBAAsB,EAAE,wBAAwB;CACxC,CAAC;AAKX,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;CACE,CAAC;AA0ZX,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,OAAO,EAAE,SAAS;IAClB,WAAW,EAAE,aAAa;CAClB,CAAC;AAIX,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,UAAU,EAAE,MAAM;IAClB,aAAa,EAAE,SAAS;IACxB,aAAa,EAAE,SAAS;IACxB,eAAe,EAAE,WAAW;IAC5B,iBAAiB,EAAE,aAAa;IAChC,aAAa,EAAE,KAAK;CACZ,CAAC;AAsBX,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,sBAAsB,EAAE,2BAA2B;IACnD,oBAAoB,EAAE,wBAAwB;CACtC,CAAC","sourcesContent":["import type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { CaipAccountId, Hex } from '@metamask/utils';\n\nimport type { CANCELLATION_REASONS } from './constants.js';\n\n/**\n * Error response from the Subscription API.\n */\nexport type SubscriptionApiError = {\n errorCode?: string;\n message?: string;\n statusCode?: number;\n};\n\n/**\n * Supported subscription products.\n */\nexport const PRODUCT_TYPES = {\n /**\n * MetaMask Shield.\n */\n SHIELD: 'shield',\n /**\n * Money Account Plus (delegation-based crypto billing).\n */\n MONEY_ACCOUNT_PLUS: 'money_account_plus',\n} as const;\n\nexport type ProductType = (typeof PRODUCT_TYPES)[keyof typeof PRODUCT_TYPES];\n\nexport const MoneyAccountFeature = {\n SwapFeeWaiver: 'swapFeeWaiver',\n PerpsFeeWaiver: 'perpsFeeWaiver',\n PredictFreeTx: 'predictFreeTx',\n PremiumApy: 'premiumApy',\n} as const;\n\nexport type MoneyAccountFeature =\n (typeof MoneyAccountFeature)[keyof typeof MoneyAccountFeature];\n\nexport type MoneyAccountEntitlements = Record<MoneyAccountFeature, boolean>;\n\nexport const ShieldFeature = {\n ShieldClaim: 'shieldClaim',\n PrioritySupport: 'prioritySupport',\n} as const;\n\nexport type ShieldFeature = (typeof ShieldFeature)[keyof typeof ShieldFeature];\n\nexport type ShieldEntitlements = Record<ShieldFeature, boolean>;\n\nexport type MoneyAccountPlusClaim = {\n plan: string;\n entitlements: MoneyAccountEntitlements;\n};\n\nexport type ProductEntitlements = {\n [PRODUCT_TYPES.SHIELD]?: {\n entitlements: ShieldEntitlements;\n };\n [PRODUCT_TYPES.MONEY_ACCOUNT_PLUS]?: MoneyAccountPlusClaim;\n};\n\nexport type ProductEntitlementFeatureMap = {\n [PRODUCT_TYPES.SHIELD]: ShieldFeature;\n [PRODUCT_TYPES.MONEY_ACCOUNT_PLUS]: MoneyAccountFeature;\n};\n\n/**\n * How a crypto subscription is authorized.\n *\n * Use `erc20_approval` with `rawTransaction` (e.g. Shield). Use `delegation`\n * with `delegationHash` (e.g. Money Account Plus).\n */\nexport const CRYPTO_AUTH_METHODS = {\n /**\n * User signs an ERC-20 approve transaction.\n */\n ERC20_APPROVAL: 'erc20_approval',\n /**\n * User authorizes via a stored delegation hash.\n */\n DELEGATION: 'delegation',\n} as const;\n\nexport type CryptoAuthMethod =\n (typeof CRYPTO_AUTH_METHODS)[keyof typeof CRYPTO_AUTH_METHODS];\n\nexport const PAYMENT_TYPES = {\n byCard: 'card',\n byCrypto: 'crypto',\n} as const;\n\nexport type PaymentType = (typeof PAYMENT_TYPES)[keyof typeof PAYMENT_TYPES];\n\nexport const RECURRING_INTERVALS = {\n month: 'month',\n year: 'year',\n} as const;\n\nexport type RecurringInterval =\n (typeof RECURRING_INTERVALS)[keyof typeof RECURRING_INTERVALS];\n\nexport const SUBSCRIPTION_STATUSES = {\n // Initial states\n incomplete: 'incomplete',\n incompleteExpired: 'incomplete_expired',\n // Active states\n provisional: 'provisional',\n trialing: 'trialing',\n active: 'active',\n // Payment issues\n pastDue: 'past_due',\n unpaid: 'unpaid',\n // Cancelled states\n canceled: 'canceled',\n // Paused states\n paused: 'paused',\n} as const;\n\nexport type SubscriptionStatus =\n (typeof SUBSCRIPTION_STATUSES)[keyof typeof SUBSCRIPTION_STATUSES];\n\nexport const CANCEL_TYPES = {\n ALLOWED_IMMEDIATE: 'allowed_immediate',\n ALLOWED_AT_PERIOD_END: 'allowed_at_period_end',\n NOT_ALLOWED: 'not_allowed',\n NOT_ALLOWED_PENDING_VERIFICATION: 'not_allowed_pending_verification',\n} as const;\n\nexport type CancelType = (typeof CANCEL_TYPES)[keyof typeof CANCEL_TYPES];\n\nexport type CancellationReasonCode =\n (typeof CANCELLATION_REASONS)[keyof typeof CANCELLATION_REASONS];\n\nexport const CRYPTO_PAYMENT_METHOD_ERRORS = {\n APPROVAL_TRANSACTION_TOO_OLD: 'approval_transaction_too_old',\n APPROVAL_TRANSACTION_REVERTED: 'approval_transaction_reverted',\n APPROVAL_TRANSACTION_MAX_VERIFICATION_ATTEMPTS_REACHED:\n 'approval_transaction_max_verification_attempts_reached',\n INSUFFICIENT_BALANCE: 'insufficient_balance',\n INSUFFICIENT_ALLOWANCE: 'insufficient_allowance',\n} as const;\n\nexport type CryptoPaymentMethodError =\n (typeof CRYPTO_PAYMENT_METHOD_ERRORS)[keyof typeof CRYPTO_PAYMENT_METHOD_ERRORS];\n\nexport const MODAL_TYPE = {\n A: 'A',\n B: 'B',\n} as const;\n\nexport type ModalType = (typeof MODAL_TYPE)[keyof typeof MODAL_TYPE];\n\n/** only usd for now */\nexport type Currency = 'usd';\n\nexport type Product = {\n name: ProductType;\n currency: Currency;\n unitAmount: number;\n unitDecimals: number;\n};\n\n// state\nexport type Subscription = {\n id: string;\n products: Product[];\n currentPeriodStart: string; // ISO 8601\n currentPeriodEnd: string; // ISO 8601\n /** is subscription scheduled for cancellation */\n cancelAtPeriodEnd?: boolean;\n status: SubscriptionStatus;\n interval: RecurringInterval;\n paymentMethod: SubscriptionPaymentMethod;\n trialPeriodDays?: number;\n trialStart?: string; // ISO 8601\n trialEnd?: string; // ISO 8601\n /** Crypto payment only: next billing cycle date (e.g after 12 months) */\n endDate?: string; // ISO 8601\n /** The date the subscription was canceled. */\n canceledAt?: string; // ISO 8601\n /** The cancellation type indicating what cancellation options are available for this subscription. */\n cancelType: CancelType;\n /** The date the subscription was marked as inactive (paused/past_due/canceled). */\n inactiveAt?: string; // ISO 8601\n /** Whether the user is eligible for support features (priority support and filing claims). True for active subscriptions and inactive subscriptions within grace period. */\n isEligibleForSupport: boolean;\n billingCycles?: number;\n};\n\nexport type SubscriptionCardPaymentMethod = {\n type: Extract<PaymentType, 'card'>;\n card: {\n brand: string;\n /** display brand account for dual brand card */\n displayBrand: string;\n last4: string;\n };\n};\n\nexport type SubscriptionCryptoPaymentMethod = {\n type: Extract<PaymentType, 'crypto'>;\n crypto: {\n payerAddress: Hex;\n chainId: Hex;\n tokenSymbol: string;\n error?: CryptoPaymentMethodError;\n };\n};\n\nexport type SubscriptionPaymentMethod =\n | SubscriptionCardPaymentMethod\n | SubscriptionCryptoPaymentMethod;\n\nexport type GetSubscriptionsResponse = {\n customerId?: string;\n subscriptions: Subscription[];\n trialedProducts: ProductType[];\n productEntitlements?: ProductEntitlements;\n /** The last subscription that user has subscribed to if any. */\n lastSubscription?: Subscription;\n /** The reward account ID if user has linked rewards to the subscription. */\n rewardAccountId?: CaipAccountId;\n};\n\n/**\n * Benefits available to a subscription user.\n */\nexport type SwapsBenefitUsage = {\n feeBips: string | null;\n capMicroUsd?: number;\n consumedMicroUsd?: number;\n remainingMicroUsd: number | null;\n exhausted: boolean;\n};\n\nexport type PerpsBenefitUsage = {\n builderFeeBips: string | null;\n builderCode: string | null;\n capMicroUsd?: number;\n consumedMicroUsd?: number;\n remainingMicroUsd: number | null;\n exhausted: boolean;\n};\n\nexport type PredictBenefitUsage = {\n builderCode: string | null;\n capTxCount?: number;\n consumedTxCount?: number;\n remainingTxCount: number | null;\n exhausted: boolean;\n};\n\ntype SubscriptionBenefitsProducts = {\n swaps: SwapsBenefitUsage;\n perps: PerpsBenefitUsage;\n predict: PredictBenefitUsage;\n};\n\nexport type SubscriptionBenefitsResponse = {\n eligible: boolean;\n billingPeriodId: string | null;\n products: SubscriptionBenefitsProducts;\n};\n\n/**\n * Benefits state exposed to the UI.\n */\nexport type SubscriptionBenefitsState = SubscriptionBenefitsProducts & {\n billingPeriodId: string | null;\n};\n\nexport type StartSubscriptionRequest = {\n products: ProductType[];\n isTrialRequested: boolean;\n recurringInterval: RecurringInterval;\n successUrl?: string;\n cancelUrl?: string;\n useTestClock?: boolean;\n\n /**\n * Optional CAIP account ID of the rewards account to opt in alongside this\n * subscription. Required when the user wants to link rewards during\n * subscription creation.\n *\n * @example {\n * rewardAccountId: 'eip155:1:0x1234567890123456789012345678901234567890',\n * }\n */\n rewardAccountId?: CaipAccountId;\n};\n\nexport type StartSubscriptionResponse = {\n checkoutSessionUrl: string;\n};\n\ntype StartCryptoSubscriptionRequestBase = {\n products: ProductType[];\n isTrialRequested: boolean;\n recurringInterval: RecurringInterval;\n billingCycles: number;\n chainId: Hex;\n payerAddress: Hex;\n /**\n * e.g. \"USDC\"\n */\n tokenSymbol: string;\n isSponsored?: boolean;\n useTestClock?: boolean;\n /**\n * Optional CAIP account ID of the rewards account to opt in alongside this\n * subscription. Required when the user wants to link rewards during\n * subscription creation.\n *\n * @example {\n * rewardAccountId: 'eip155:1:0x1234567890123456789012345678901234567890',\n * }\n */\n rewardAccountId?: CaipAccountId;\n};\n\n/**\n * ERC-20 approval crypto subscription request (e.g. Shield).\n *\n * `cryptoAuthMethod` defaults to `CRYPTO_AUTH_METHODS.ERC20_APPROVAL` when\n * omitted.\n */\nexport type StartErc20CryptoSubscriptionRequest =\n StartCryptoSubscriptionRequestBase & {\n cryptoAuthMethod?: typeof CRYPTO_AUTH_METHODS.ERC20_APPROVAL;\n rawTransaction: Hex;\n delegationHash?: never;\n };\n\n/**\n * Delegation-based crypto subscription request (e.g. Money Account Plus).\n */\nexport type StartDelegationCryptoSubscriptionRequest =\n StartCryptoSubscriptionRequestBase & {\n cryptoAuthMethod: typeof CRYPTO_AUTH_METHODS.DELEGATION;\n delegationHash: Hex;\n rawTransaction?: never;\n };\n\n/**\n * Request to start a crypto subscription.\n *\n * Discriminated union of ERC-20 approval vs delegation. Provide\n * `rawTransaction` for ERC-20 approval (the default when `cryptoAuthMethod` is\n * omitted), or `delegationHash` with `cryptoAuthMethod: 'delegation'`.\n * Combining or omitting both is a type error, and is also rejected at runtime\n * by `startSubscriptionWithCrypto`.\n */\nexport type StartCryptoSubscriptionRequest =\n | StartErc20CryptoSubscriptionRequest\n | StartDelegationCryptoSubscriptionRequest;\n\nexport type StartCryptoSubscriptionResponse = {\n subscriptionId: string;\n status: SubscriptionStatus;\n};\n\n/**\n * General response type for the subscription API requests\n * which doesn't require any specific response data.\n */\nexport type SubscriptionApiGeneralResponse = {\n /**\n * Whether the request was successful.\n */\n success: boolean;\n /**\n * The message of the response.\n */\n message?: string;\n};\n\nexport type CancelSubscriptionRequest = {\n subscriptionId: string;\n /** Whether to cancel at the end of the current period */\n cancelAtPeriodEnd?: boolean;\n /** Stable reason code for the cancellation. */\n cancellationReason?: CancellationReasonCode;\n /** Optional free-text feedback for the cancellation. */\n cancellationFeedback?: string;\n};\n\nexport type AuthUtils = {\n getAccessToken: () => Promise<string>;\n};\n\nexport type ProductPrice = {\n interval: RecurringInterval;\n unitAmount: number; // amount in the smallest unit of the currency, e.g., cents\n unitDecimals: number; // number of decimals for the smallest unit of the currency\n /** only usd for now */\n currency: Currency;\n trialPeriodDays: number;\n /** min billing cycles for approval */\n minBillingCycles: number;\n /** min billing cycles for account balance check */\n minBillingCyclesForBalance: number;\n};\n\nexport type ProductPricing = {\n name: ProductType;\n prices: ProductPrice[];\n};\n\ntype TokenPaymentInfoBase = {\n symbol: string;\n address: Hex;\n decimals: number;\n /**\n * example: {\n usd: '1.0',\n },\n */\n conversionRate?: {\n usd: string;\n };\n /**\n * Source tokens that can be converted into this settlement token.\n */\n sources?: TokenPaymentInfo[];\n};\n\n/**\n * Spot (non-vault) settlement token. Priced via `conversionRate` when provided.\n * `accountantAddress` is not present on this variant.\n */\nexport type SpotTokenPaymentInfo = TokenPaymentInfoBase & {\n isVaultShare?: false;\n};\n\n/**\n * Yield-bearing vault share priced via an accountant rate.\n */\nexport type VaultTokenPaymentInfo = TokenPaymentInfoBase & {\n isVaultShare: true;\n /**\n * Veda accountant address used to value this vault share.\n */\n accountantAddress: Hex;\n};\n\n/**\n * A settlement token in a pricing chain. Discriminated by `isVaultShare`:\n * vault shares require `accountantAddress`; spot tokens omit it.\n */\nexport type TokenPaymentInfo = SpotTokenPaymentInfo | VaultTokenPaymentInfo;\n\nexport type ChainPaymentInfo = {\n chainId: Hex;\n paymentAddress: Hex;\n /**\n * Delegate address clients authorize when using the delegation auth method.\n */\n delegateAddress?: Hex;\n tokens: TokenPaymentInfo[];\n /**\n * Whether the chain supports sponsorship for the trialed subscription approval transaction.\n * This is used to determine if the user can be sponsored for the gas fees for the trialed subscription approval transaction.\n */\n isSponsorshipSupported?: boolean;\n};\n\nexport type PricingCardPaymentMethod = {\n type: Extract<PaymentType, 'card'>;\n /**\n * Products that support this payment method.\n */\n products?: ProductType[];\n};\n\nexport type PricingCryptoPaymentMethod = {\n type: Extract<PaymentType, 'crypto'>;\n /**\n * Crypto authorization method. Omitted together with `products` on persisted\n * pre-multi-product pricing rows; those rows are treated as Shield + `erc20_approval`.\n * If `products` is set, this field must be explicit.\n */\n cryptoAuthMethod?: CryptoAuthMethod;\n /**\n * Products that support this payment method. Omitted together with\n * `cryptoAuthMethod` on persisted pre-multi-product pricing rows (treated as Shield).\n * If present, must be non-empty and paired with an explicit `cryptoAuthMethod`.\n */\n products?: ProductType[];\n chains?: ChainPaymentInfo[];\n};\n\n/**\n * A pricing payment-method row. Discriminated by `type`: card rows have no\n * crypto fields; crypto rows may include `cryptoAuthMethod` and `chains`.\n */\nexport type PricingPaymentMethod =\n | PricingCardPaymentMethod\n | PricingCryptoPaymentMethod;\n\nexport type PricingResponse = {\n products: ProductPricing[];\n paymentMethods: PricingPaymentMethod[];\n};\n\nexport type GetCryptoApproveTransactionRequest = {\n /**\n * payment chain ID\n */\n chainId: Hex;\n /**\n * Payment token address\n */\n paymentTokenAddress: Hex;\n productType: ProductType;\n interval: RecurringInterval;\n};\n\nexport type GetCryptoApproveTransactionResponse = {\n /**\n * The amount to approve\n * e.g: \"100000000\"\n */\n approveAmount: string;\n /**\n * The contract address (spender)\n */\n paymentAddress: Hex;\n /**\n * The payment token address\n */\n paymentTokenAddress: Hex;\n chainId: Hex;\n};\n\n/**\n * Request to submit a Shield ERC-20 crypto approval transaction.\n */\nexport type SubmitSubscriptionCryptoApprovalRequest = {\n /**\n * The subscription product. Typed as `typeof PRODUCT_TYPES.SHIELD` only at\n * the moment (future might support more product).\n */\n productType: typeof PRODUCT_TYPES.SHIELD;\n /**\n * The transaction metadata. Must have type\n * `TransactionType.shieldSubscriptionApprove`.\n */\n txMeta: TransactionMeta;\n /**\n * Whether the transaction is sponsored.\n */\n isSponsored?: boolean;\n /**\n * The account ID of the reward subscription to link.\n */\n rewardAccountId?: CaipAccountId;\n};\n\nexport const COHORT_NAMES = {\n POST_TX: 'post_tx',\n WALLET_HOME: 'wallet_home',\n} as const;\n\nexport type CohortName = (typeof COHORT_NAMES)[keyof typeof COHORT_NAMES];\n\nexport const BALANCE_CATEGORIES = {\n RANGE_0_99: '0-99',\n RANGE_100_999: '100-999',\n RANGE_1K_9_9K: '1k-9.9k',\n RANGE_10K_99_9K: '10k-99.9k',\n RANGE_100K_999_9K: '100k-999.9k',\n RANGE_1M_PLUS: '1M+',\n} as const;\n\nexport type BalanceCategory =\n (typeof BALANCE_CATEGORIES)[keyof typeof BALANCE_CATEGORIES];\n\nexport type Cohort = {\n cohort: string;\n eligibilityRate: number; // 0-1 probability of being assigned to this cohort\n priority: number; // lower number = higher priority\n eligible: boolean;\n};\n\nexport type SubscriptionEligibility = {\n product: ProductType;\n canSubscribe: boolean;\n canViewEntryModal: boolean;\n modalType?: ModalType;\n cohorts: Cohort[];\n assignedCohort: string | null;\n hasAssignedCohortExpired: boolean;\n};\n\nexport const SubscriptionUserEvent = {\n ShieldEntryModalViewed: 'shield_entry_modal_viewed',\n ShieldCohortAssigned: 'shield_cohort_assigned',\n} as const;\n\nexport type SubscriptionUserEventType =\n (typeof SubscriptionUserEvent)[keyof typeof SubscriptionUserEvent];\n\nexport type SubmitUserEventRequest = {\n event: SubscriptionUserEventType;\n cohort?: string;\n};\n\nexport type AssignCohortRequest = {\n cohort: string;\n};\n\nexport type GetSubscriptionsEligibilitiesRequest = {\n balanceCategory?: BalanceCategory;\n};\n\n/**\n * Request object for submitting sponsorship intents.\n */\nexport type SubmitSponsorshipIntentsRequest = {\n chainId: Hex;\n address: Hex;\n products: ProductType[];\n paymentTokenSymbol: string;\n recurringInterval: RecurringInterval;\n billingCycles: number;\n};\n\nexport type SubmitSponsorshipIntentsMethodParams = Pick<\n SubmitSponsorshipIntentsRequest,\n 'chainId' | 'address' | 'products'\n>;\n\nexport type ISubscriptionService = {\n getSubscriptions(): Promise<GetSubscriptionsResponse>;\n getBenefits(): Promise<SubscriptionBenefitsResponse>;\n cancelSubscription(request: CancelSubscriptionRequest): Promise<Subscription>;\n unCancelSubscription(request: {\n subscriptionId: string;\n }): Promise<Subscription>;\n /**\n * Starts a card-paid subscription checkout session for the requested products\n * (e.g. Shield or Money Account Plus).\n *\n * @param request - The start subscription request.\n * @returns The checkout session response.\n */\n startSubscriptionWithCard(\n request: StartSubscriptionRequest,\n ): Promise<StartSubscriptionResponse>;\n getBillingPortalUrl(): Promise<BillingPortalResponse>;\n getPricing(): Promise<PricingResponse>;\n startSubscriptionWithCrypto(\n request: StartCryptoSubscriptionRequest,\n ): Promise<StartCryptoSubscriptionResponse>;\n updatePaymentMethodCard(\n request: UpdatePaymentMethodCardRequest,\n ): Promise<UpdatePaymentMethodCardResponse>;\n updatePaymentMethodCrypto(\n request: UpdatePaymentMethodCryptoRequest,\n ): Promise<void>;\n getSubscriptionsEligibilities(\n request?: GetSubscriptionsEligibilitiesRequest,\n ): Promise<SubscriptionEligibility[]>;\n submitUserEvent(request: SubmitUserEventRequest): Promise<void>;\n assignUserToCohort(request: AssignCohortRequest): Promise<void>;\n\n /**\n * Link rewards to a subscription.\n */\n linkRewards(\n request: LinkRewardsRequest,\n ): Promise<SubscriptionApiGeneralResponse>;\n\n /**\n * Submit sponsorship intents to the Subscription Service backend.\n *\n * This is intended to be used together with the crypto subscription flow.\n * When the user has enabled the smart transaction feature, we will sponsor the gas fees for the subscription approval transaction.\n *\n * @param request - Request object containing the address and products.\n * @example {\n * address: '0x1234567890123456789012345678901234567890',\n * products: [ProductType.Shield],\n * recurringInterval: RecurringInterval.Month,\n * billingCycles: 1,\n * }\n */\n submitSponsorshipIntents(\n request: SubmitSponsorshipIntentsRequest,\n ): Promise<void>;\n};\n\nexport type UpdatePaymentMethodOpts =\n | ({\n paymentType: Extract<PaymentType, 'card'>;\n } & UpdatePaymentMethodCardRequest)\n | ({\n paymentType: Extract<PaymentType, 'crypto'>;\n } & UpdatePaymentMethodCryptoRequest);\n\nexport type UpdatePaymentMethodCardRequest = {\n /**\n * Subscription ID\n */\n subscriptionId: string;\n\n /**\n * Recurring interval\n */\n recurringInterval: RecurringInterval;\n successUrl?: string;\n cancelUrl?: string;\n};\n\nexport type UpdatePaymentMethodCardResponse = {\n redirectUrl: string;\n};\n\nexport type UpdatePaymentMethodCryptoRequest = {\n subscriptionId: string;\n chainId: Hex;\n payerAddress: Hex;\n tokenSymbol: string;\n /**\n * The raw transaction to pay for the subscription\n * Can be empty if retry after topping up balance\n */\n rawTransaction?: Hex;\n recurringInterval: RecurringInterval;\n billingCycles: number;\n};\n\nexport type BillingPortalResponse = {\n url: string;\n};\n\n/**\n * The cached result of last selected payment methods for the user.\n * These details are being cached to be used internally to track the last selected payment method for the user. (e.g. for crypto subscriptions)\n */\nexport type CachedLastSelectedPaymentMethod = {\n type: PaymentType;\n paymentTokenAddress?: Hex;\n paymentTokenSymbol?: string;\n plan: RecurringInterval;\n useTestClock?: boolean;\n /**\n * Crypto authorization method. Omitted on persisted cache entries written\n * before this field existed; treat as `erc20_approval` when missing.\n */\n cryptoAuthMethod?: CryptoAuthMethod;\n};\n\n/**\n * Request to cache the last selected payment method for a product.\n */\nexport type CacheLastSelectedPaymentMethodRequest = {\n /**\n * The product to cache the payment method for.\n */\n product: ProductType;\n /**\n * The payment method to cache.\n */\n paymentMethod: CachedLastSelectedPaymentMethod;\n};\n\n/**\n * Request object for linking rewards to a subscription.\n */\nexport type LinkRewardsRequest = {\n /**\n * The ID of the reward subscription to be linked to the subscription.\n *\n * @example {\n * rewardAccountId: 'eip155:1:0x1234567890123456789012345678901234567890',\n * }\n */\n rewardAccountId: CaipAccountId;\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask-previews/subscription-controller",
|
|
3
|
-
"version": "9.0.1-preview-
|
|
3
|
+
"version": "9.0.1-preview-429f77222",
|
|
4
4
|
"description": "Handle user subscription",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Ethereum",
|
|
@@ -50,20 +50,12 @@
|
|
|
50
50
|
"test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@metamask/authenticated-user-storage": "^4.0.0",
|
|
54
53
|
"@metamask/base-controller": "^10.0.0",
|
|
55
54
|
"@metamask/base-data-service": "^2.0.0",
|
|
56
|
-
"@metamask/chomp-api-service": "^5.0.0",
|
|
57
55
|
"@metamask/controller-utils": "^13.0.0",
|
|
58
|
-
"@metamask/delegation-controller": "^4.0.0",
|
|
59
|
-
"@metamask/delegation-core": "^2.2.1",
|
|
60
|
-
"@metamask/delegation-deployments": "^1.4.0",
|
|
61
56
|
"@metamask/messenger": "^3.0.0",
|
|
62
|
-
"@metamask/money-account-balance-service": "^3.0.0",
|
|
63
|
-
"@metamask/money-account-utils": "^2.0.0",
|
|
64
57
|
"@metamask/polling-controller": "^17.0.0",
|
|
65
58
|
"@metamask/profile-sync-controller": "^32.1.0",
|
|
66
|
-
"@metamask/remote-feature-flag-controller": "^7.0.0",
|
|
67
59
|
"@metamask/superstruct": "^3.4.1",
|
|
68
60
|
"@metamask/transaction-controller": "^70.0.0",
|
|
69
61
|
"@metamask/utils": "^11.12.0",
|
|
@@ -77,7 +69,6 @@
|
|
|
77
69
|
"@typescript/native": "npm:typescript@^7.0.2",
|
|
78
70
|
"deepmerge": "^4.2.2",
|
|
79
71
|
"jest": "^30.4.2",
|
|
80
|
-
"jest-environment-node": "^30.4.1",
|
|
81
72
|
"rimraf": "^5.0.5",
|
|
82
73
|
"ts-jest": "^29.4.11",
|
|
83
74
|
"tsx": "^4.20.5",
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file is auto generated.
|
|
3
|
-
* Do not edit manually.
|
|
4
|
-
*/
|
|
5
|
-
import type { SubscriptionDelegationService } from './SubscriptionDelegationService.js';
|
|
6
|
-
/**
|
|
7
|
-
* Checks whether the Money Account holds enough convertible mUSD value to
|
|
8
|
-
* cover pricing `unitAmount × minBillingCyclesForBalance`.
|
|
9
|
-
*
|
|
10
|
-
* @param request - Payer address and pricing amount fields.
|
|
11
|
-
* @returns Balance comparison in mUSD base units (6 decimals).
|
|
12
|
-
*/
|
|
13
|
-
export type SubscriptionDelegationServiceCheckMoneyAccountBalanceAction = {
|
|
14
|
-
type: `SubscriptionDelegationService:checkMoneyAccountBalance`;
|
|
15
|
-
handler: SubscriptionDelegationService['checkMoneyAccountBalance'];
|
|
16
|
-
};
|
|
17
|
-
/**
|
|
18
|
-
* Prepares a cash-subscription delegation and returns its hash.
|
|
19
|
-
*
|
|
20
|
-
* Reuses a stored AUS delegation that matches the semantic fingerprint when
|
|
21
|
-
* one exists (ensuring a CHOMP intent is active for its hash, unless
|
|
22
|
-
* `skipChompInteractions` is true). Reuse classifies period `startDate` as
|
|
23
|
-
* trial-deferred (`> now`) vs immediately redeemable, matching creation.
|
|
24
|
-
* If there is no match, builds, signs, optionally verifies with CHOMP,
|
|
25
|
-
* persists, and optionally registers a new delegation.
|
|
26
|
-
*
|
|
27
|
-
* When `skipChompInteractions` is true (required for alpha), CHOMP verify
|
|
28
|
-
* and intent calls are skipped; the returned hash is computed locally. The
|
|
29
|
-
* default CHOMP-enabled path requires a follow-up chomp-api-service release
|
|
30
|
-
* that accepts `'cash-subscription'` intent metadata.
|
|
31
|
-
*
|
|
32
|
-
* @param request - Authoritative pricing and payer details for the delegation.
|
|
33
|
-
* @returns The delegation hash (CHOMP-verified unless skipped) and whether it
|
|
34
|
-
* was created or reused.
|
|
35
|
-
*/
|
|
36
|
-
export type SubscriptionDelegationServicePrepareDelegationAction = {
|
|
37
|
-
type: `SubscriptionDelegationService:prepareDelegation`;
|
|
38
|
-
handler: SubscriptionDelegationService['prepareDelegation'];
|
|
39
|
-
};
|
|
40
|
-
/**
|
|
41
|
-
* Union of all SubscriptionDelegationService action types.
|
|
42
|
-
*/
|
|
43
|
-
export type SubscriptionDelegationServiceMethodActions = SubscriptionDelegationServiceCheckMoneyAccountBalanceAction | SubscriptionDelegationServicePrepareDelegationAction;
|
|
44
|
-
//# sourceMappingURL=SubscriptionDelegationService-method-action-types.d.ts.map
|
package/dist/subscription-delegation/SubscriptionDelegationService-method-action-types.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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;;;;;;;;;;;;;;;;;;GAkBG;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
DELETED
|
@@ -1 +0,0 @@
|
|
|
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,93 +0,0 @@
|
|
|
1
|
-
import type { AuthenticatedUserStorageServiceCreateDelegationAction, AuthenticatedUserStorageServiceListDelegationsAction } from '@metamask/authenticated-user-storage';
|
|
2
|
-
import type { ChompApiServiceCreateIntentsAction, ChompApiServiceGetIntentsByAddressAction, ChompApiServiceVerifyDelegationAction } from '@metamask/chomp-api-service';
|
|
3
|
-
import type { DelegationControllerSignDelegationAction } from '@metamask/delegation-controller';
|
|
4
|
-
import type { Messenger } from '@metamask/messenger';
|
|
5
|
-
import type { MoneyAccountBalanceServiceFetchBalanceWithFallbackAction } from '@metamask/money-account-balance-service';
|
|
6
|
-
import type { RemoteFeatureFlagControllerGetStateAction } from '@metamask/remote-feature-flag-controller';
|
|
7
|
-
import type { SubscriptionControllerGetPricingAction } from '../SubscriptionController-method-action-types.js';
|
|
8
|
-
import type { SubscriptionDelegationServiceMethodActions } from './SubscriptionDelegationService-method-action-types.js';
|
|
9
|
-
import type { MoneyAccountBalanceCheckRequest, MoneyAccountBalanceCheckResult, PrepareSubscriptionDelegationRequest, PreparedSubscriptionDelegation } from './types.js';
|
|
10
|
-
/**
|
|
11
|
-
* The name of the {@link SubscriptionDelegationService}, used to namespace the
|
|
12
|
-
* service's actions and events.
|
|
13
|
-
*/
|
|
14
|
-
export declare const serviceName = "SubscriptionDelegationService";
|
|
15
|
-
/**
|
|
16
|
-
* Actions that {@link SubscriptionDelegationService} exposes to other consumers.
|
|
17
|
-
*/
|
|
18
|
-
export type SubscriptionDelegationServiceActions = SubscriptionDelegationServiceMethodActions;
|
|
19
|
-
/**
|
|
20
|
-
* Actions from other messengers that {@link SubscriptionDelegationServiceMessenger} calls.
|
|
21
|
-
*/
|
|
22
|
-
type AllowedActions = AuthenticatedUserStorageServiceListDelegationsAction | AuthenticatedUserStorageServiceCreateDelegationAction | ChompApiServiceVerifyDelegationAction | ChompApiServiceCreateIntentsAction | ChompApiServiceGetIntentsByAddressAction | DelegationControllerSignDelegationAction | MoneyAccountBalanceServiceFetchBalanceWithFallbackAction | RemoteFeatureFlagControllerGetStateAction | SubscriptionControllerGetPricingAction;
|
|
23
|
-
/**
|
|
24
|
-
* Events that {@link SubscriptionDelegationService} exposes to other consumers.
|
|
25
|
-
*/
|
|
26
|
-
export type SubscriptionDelegationServiceEvents = never;
|
|
27
|
-
type AllowedEvents = never;
|
|
28
|
-
/**
|
|
29
|
-
* The messenger which is restricted to actions and events accessed by
|
|
30
|
-
* {@link SubscriptionDelegationService}.
|
|
31
|
-
*/
|
|
32
|
-
export type SubscriptionDelegationServiceMessenger = Messenger<typeof serviceName, SubscriptionDelegationServiceActions | AllowedActions, SubscriptionDelegationServiceEvents | AllowedEvents>;
|
|
33
|
-
/**
|
|
34
|
-
* Options for constructing {@link SubscriptionDelegationService}.
|
|
35
|
-
*/
|
|
36
|
-
export type SubscriptionDelegationServiceOptions = {
|
|
37
|
-
messenger: SubscriptionDelegationServiceMessenger;
|
|
38
|
-
};
|
|
39
|
-
/**
|
|
40
|
-
* Stateless orchestrator for cash-subscription delegation setup.
|
|
41
|
-
*
|
|
42
|
-
* Owns the workflow: size periodic caveats → sign → CHOMP verify → persist to
|
|
43
|
-
* Authenticated User Storage → register CHOMP intent. Returns a verified
|
|
44
|
-
* `delegationHash` for `SubscriptionController.startSubscriptionWithCrypto`.
|
|
45
|
-
*
|
|
46
|
-
* Alpha callers must pass `skipChompInteractions: true` until a follow-up
|
|
47
|
-
* `@metamask/chomp-api-service` release accepts `'cash-subscription'` intent
|
|
48
|
-
* metadata. The CHOMP-enabled path (`skipChompInteractions` unset/false)
|
|
49
|
-
* remains dormant and is not production-ready without that package support.
|
|
50
|
-
*
|
|
51
|
-
* Each call resolves the Money Account chain from remote feature flags, then
|
|
52
|
-
* resolves its price, payment token, and delegate from `SubscriptionController`
|
|
53
|
-
* pricing. The pricing `delegateAddress` is used as both the delegation
|
|
54
|
-
* `delegate` and the RedeemerEnforcer redeemer.
|
|
55
|
-
*
|
|
56
|
-
* Does not own subscription state; `SubscriptionController` does not depend on
|
|
57
|
-
* this service. Only Money Account Plus is supported.
|
|
58
|
-
*/
|
|
59
|
-
export declare class SubscriptionDelegationService {
|
|
60
|
-
#private;
|
|
61
|
-
readonly name: typeof serviceName;
|
|
62
|
-
constructor(options: SubscriptionDelegationServiceOptions);
|
|
63
|
-
/**
|
|
64
|
-
* Checks whether the Money Account holds enough convertible mUSD value to
|
|
65
|
-
* cover pricing `unitAmount × minBillingCyclesForBalance`.
|
|
66
|
-
*
|
|
67
|
-
* @param request - Payer address and pricing amount fields.
|
|
68
|
-
* @returns Balance comparison in mUSD base units (6 decimals).
|
|
69
|
-
*/
|
|
70
|
-
checkMoneyAccountBalance(request: MoneyAccountBalanceCheckRequest): Promise<MoneyAccountBalanceCheckResult>;
|
|
71
|
-
/**
|
|
72
|
-
* Prepares a cash-subscription delegation and returns its hash.
|
|
73
|
-
*
|
|
74
|
-
* Reuses a stored AUS delegation that matches the semantic fingerprint when
|
|
75
|
-
* one exists (ensuring a CHOMP intent is active for its hash, unless
|
|
76
|
-
* `skipChompInteractions` is true). Reuse classifies period `startDate` as
|
|
77
|
-
* trial-deferred (`> now`) vs immediately redeemable, matching creation.
|
|
78
|
-
* If there is no match, builds, signs, optionally verifies with CHOMP,
|
|
79
|
-
* persists, and optionally registers a new delegation.
|
|
80
|
-
*
|
|
81
|
-
* When `skipChompInteractions` is true (required for alpha), CHOMP verify
|
|
82
|
-
* and intent calls are skipped; the returned hash is computed locally. The
|
|
83
|
-
* default CHOMP-enabled path requires a follow-up chomp-api-service release
|
|
84
|
-
* that accepts `'cash-subscription'` intent metadata.
|
|
85
|
-
*
|
|
86
|
-
* @param request - Authoritative pricing and payer details for the delegation.
|
|
87
|
-
* @returns The delegation hash (CHOMP-verified unless skipped) and whether it
|
|
88
|
-
* was created or reused.
|
|
89
|
-
*/
|
|
90
|
-
prepareDelegation(request: PrepareSubscriptionDelegationRequest): Promise<PreparedSubscriptionDelegation>;
|
|
91
|
-
}
|
|
92
|
-
export {};
|
|
93
|
-
//# sourceMappingURL=SubscriptionDelegationService.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SubscriptionDelegationService.d.ts","sourceRoot":"","sources":["../../src/subscription-delegation/SubscriptionDelegationService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,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;AAoB/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;AA8B3D;;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;;;;;;;;;;;;;;;;;;;GAmBG;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;;;;;;;;;;;;;;;;;;OAkBG;IACG,iBAAiB,CACrB,OAAO,EAAE,oCAAoC,GAC5C,OAAO,CAAC,8BAA8B,CAAC,CA+JzC;CAuGF"}
|
|
@@ -1,290 +0,0 @@
|
|
|
1
|
-
import { hashDelegation } from '@metamask/delegation-core';
|
|
2
|
-
import { DELEGATOR_CONTRACTS } from '@metamask/delegation-deployments';
|
|
3
|
-
import { getMoneyAccountVaultConfig, MUSD_DECIMALS, } from '@metamask/money-account-utils';
|
|
4
|
-
import { add0x, hexToNumber } from '@metamask/utils';
|
|
5
|
-
import { SubscriptionDelegationServiceErrorMessage } from '../constants.js';
|
|
6
|
-
import { CRYPTO_AUTH_METHODS, PAYMENT_TYPES, PRODUCT_TYPES } from '../types.js';
|
|
7
|
-
import { assertPositiveInteger, calculatePeriodAmount, getDelegationStartDate, getPeriodDuration, } from './amount.js';
|
|
8
|
-
import { buildUnsignedSubscriptionDelegation } from './caveats.js';
|
|
9
|
-
import { equalsIgnoreCase, makeMatchesSubscriptionDelegation, } from './fingerprint.js';
|
|
10
|
-
import { CASH_SUBSCRIPTION_DELEGATION_TYPE } from './types.js';
|
|
11
|
-
/**
|
|
12
|
-
* The name of the {@link SubscriptionDelegationService}, used to namespace the
|
|
13
|
-
* service's actions and events.
|
|
14
|
-
*/
|
|
15
|
-
export const serviceName = 'SubscriptionDelegationService';
|
|
16
|
-
const MESSENGER_EXPOSED_METHODS = [
|
|
17
|
-
'prepareDelegation',
|
|
18
|
-
'checkMoneyAccountBalance',
|
|
19
|
-
];
|
|
20
|
-
const DELEGATION_FRAMEWORK_VERSION = '1.3.0';
|
|
21
|
-
function resolveEnforcers(chainId) {
|
|
22
|
-
const contracts = DELEGATOR_CONTRACTS[DELEGATION_FRAMEWORK_VERSION]?.[hexToNumber(chainId)];
|
|
23
|
-
if (!contracts?.ValueLteEnforcer ||
|
|
24
|
-
!contracts.ERC20PeriodTransferEnforcer ||
|
|
25
|
-
!contracts.RedeemerEnforcer) {
|
|
26
|
-
throw new Error(`${SubscriptionDelegationServiceErrorMessage.DelegationContractsNotFound}: ${chainId}`);
|
|
27
|
-
}
|
|
28
|
-
return {
|
|
29
|
-
valueLte: contracts.ValueLteEnforcer,
|
|
30
|
-
erc20TokenPeriodTransfer: contracts.ERC20PeriodTransferEnforcer,
|
|
31
|
-
redeemer: contracts.RedeemerEnforcer,
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Stateless orchestrator for cash-subscription delegation setup.
|
|
36
|
-
*
|
|
37
|
-
* Owns the workflow: size periodic caveats → sign → CHOMP verify → persist to
|
|
38
|
-
* Authenticated User Storage → register CHOMP intent. Returns a verified
|
|
39
|
-
* `delegationHash` for `SubscriptionController.startSubscriptionWithCrypto`.
|
|
40
|
-
*
|
|
41
|
-
* Alpha callers must pass `skipChompInteractions: true` until a follow-up
|
|
42
|
-
* `@metamask/chomp-api-service` release accepts `'cash-subscription'` intent
|
|
43
|
-
* metadata. The CHOMP-enabled path (`skipChompInteractions` unset/false)
|
|
44
|
-
* remains dormant and is not production-ready without that package support.
|
|
45
|
-
*
|
|
46
|
-
* Each call resolves the Money Account chain from remote feature flags, then
|
|
47
|
-
* resolves its price, payment token, and delegate from `SubscriptionController`
|
|
48
|
-
* pricing. The pricing `delegateAddress` is used as both the delegation
|
|
49
|
-
* `delegate` and the RedeemerEnforcer redeemer.
|
|
50
|
-
*
|
|
51
|
-
* Does not own subscription state; `SubscriptionController` does not depend on
|
|
52
|
-
* this service. Only Money Account Plus is supported.
|
|
53
|
-
*/
|
|
54
|
-
export class SubscriptionDelegationService {
|
|
55
|
-
name = serviceName;
|
|
56
|
-
#messenger;
|
|
57
|
-
constructor(options) {
|
|
58
|
-
this.#messenger = options.messenger;
|
|
59
|
-
this.#messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Checks whether the Money Account holds enough convertible mUSD value to
|
|
63
|
-
* cover pricing `unitAmount × minBillingCyclesForBalance`.
|
|
64
|
-
*
|
|
65
|
-
* @param request - Payer address and pricing amount fields.
|
|
66
|
-
* @returns Balance comparison in mUSD base units (6 decimals).
|
|
67
|
-
*/
|
|
68
|
-
async checkMoneyAccountBalance(request) {
|
|
69
|
-
const { price } = await this.#resolveConfiguration(request.product, request.recurringInterval);
|
|
70
|
-
return this.#compareMoneyAccountBalance(request.payerAddress, price);
|
|
71
|
-
}
|
|
72
|
-
async #compareMoneyAccountBalance(payerAddress, price) {
|
|
73
|
-
assertPositiveInteger(price.minBillingCyclesForBalance, SubscriptionDelegationServiceErrorMessage.InvalidMinimumFundingCycles);
|
|
74
|
-
const periodAmount = calculatePeriodAmount({
|
|
75
|
-
unitAmount: price.unitAmount,
|
|
76
|
-
unitDecimals: price.unitDecimals,
|
|
77
|
-
tokenDecimals: MUSD_DECIMALS,
|
|
78
|
-
});
|
|
79
|
-
const requiredBalance = periodAmount * BigInt(price.minBillingCyclesForBalance);
|
|
80
|
-
const { totalBalance } = await this.#messenger.call('MoneyAccountBalanceService:fetchBalanceWithFallback', payerAddress);
|
|
81
|
-
return {
|
|
82
|
-
hasSufficientBalance: BigInt(totalBalance) >= requiredBalance,
|
|
83
|
-
balance: totalBalance,
|
|
84
|
-
requiredBalance: requiredBalance.toString(),
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Prepares a cash-subscription delegation and returns its hash.
|
|
89
|
-
*
|
|
90
|
-
* Reuses a stored AUS delegation that matches the semantic fingerprint when
|
|
91
|
-
* one exists (ensuring a CHOMP intent is active for its hash, unless
|
|
92
|
-
* `skipChompInteractions` is true). Reuse classifies period `startDate` as
|
|
93
|
-
* trial-deferred (`> now`) vs immediately redeemable, matching creation.
|
|
94
|
-
* If there is no match, builds, signs, optionally verifies with CHOMP,
|
|
95
|
-
* persists, and optionally registers a new delegation.
|
|
96
|
-
*
|
|
97
|
-
* When `skipChompInteractions` is true (required for alpha), CHOMP verify
|
|
98
|
-
* and intent calls are skipped; the returned hash is computed locally. The
|
|
99
|
-
* default CHOMP-enabled path requires a follow-up chomp-api-service release
|
|
100
|
-
* that accepts `'cash-subscription'` intent metadata.
|
|
101
|
-
*
|
|
102
|
-
* @param request - Authoritative pricing and payer details for the delegation.
|
|
103
|
-
* @returns The delegation hash (CHOMP-verified unless skipped) and whether it
|
|
104
|
-
* was created or reused.
|
|
105
|
-
*/
|
|
106
|
-
async prepareDelegation(request) {
|
|
107
|
-
if (request.product !== PRODUCT_TYPES.MONEY_ACCOUNT_PLUS) {
|
|
108
|
-
throw new Error(SubscriptionDelegationServiceErrorMessage.UnsupportedProduct);
|
|
109
|
-
}
|
|
110
|
-
const skipChomp = Boolean(request.skipChompInteractions);
|
|
111
|
-
const { chainId, delegateAddress, enforcers, price, token } = await this.#resolveConfiguration(request.product, request.recurringInterval);
|
|
112
|
-
if (request.checkBalance) {
|
|
113
|
-
const { hasSufficientBalance } = await this.#compareMoneyAccountBalance(request.payerAddress, price);
|
|
114
|
-
if (!hasSufficientBalance) {
|
|
115
|
-
throw new Error(SubscriptionDelegationServiceErrorMessage.InsufficientBalance);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
const periodAmount = calculatePeriodAmount({
|
|
119
|
-
unitAmount: price.unitAmount,
|
|
120
|
-
unitDecimals: price.unitDecimals,
|
|
121
|
-
tokenDecimals: token.decimals,
|
|
122
|
-
});
|
|
123
|
-
const periodDuration = getPeriodDuration(request.recurringInterval);
|
|
124
|
-
const nowSeconds = Math.floor(Date.now() / 1000);
|
|
125
|
-
const startDate = getDelegationStartDate({
|
|
126
|
-
nowSeconds,
|
|
127
|
-
trialPeriodDays: request.isTrialRequested
|
|
128
|
-
? price.trialPeriodDays
|
|
129
|
-
: undefined,
|
|
130
|
-
});
|
|
131
|
-
const isTrialDeferred = startDate > nowSeconds;
|
|
132
|
-
const matches = makeMatchesSubscriptionDelegation({
|
|
133
|
-
delegatorAddress: request.payerAddress,
|
|
134
|
-
delegateAddress,
|
|
135
|
-
chainId,
|
|
136
|
-
tokenAddress: token.address,
|
|
137
|
-
periodAmount,
|
|
138
|
-
periodDuration,
|
|
139
|
-
nowSeconds,
|
|
140
|
-
isTrialDeferred,
|
|
141
|
-
enforcers,
|
|
142
|
-
});
|
|
143
|
-
const existingDelegations = await this.#messenger.call('AuthenticatedUserStorageService:listDelegations');
|
|
144
|
-
const reusable = existingDelegations.find(matches);
|
|
145
|
-
if (reusable) {
|
|
146
|
-
if (!skipChomp) {
|
|
147
|
-
await this.#ensureIntent({
|
|
148
|
-
account: request.payerAddress,
|
|
149
|
-
chainId,
|
|
150
|
-
delegationHash: reusable.metadata.delegationHash,
|
|
151
|
-
allowance: reusable.metadata.allowance,
|
|
152
|
-
tokenSymbol: reusable.metadata.tokenSymbol,
|
|
153
|
-
tokenAddress: reusable.metadata.tokenAddress,
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
return {
|
|
157
|
-
delegationHash: reusable.metadata.delegationHash,
|
|
158
|
-
disposition: 'reused',
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
const unsigned = buildUnsignedSubscriptionDelegation({
|
|
162
|
-
delegateAddress,
|
|
163
|
-
delegatorAddress: request.payerAddress,
|
|
164
|
-
enforcers,
|
|
165
|
-
tokenAddress: token.address,
|
|
166
|
-
periodAmount,
|
|
167
|
-
periodDuration,
|
|
168
|
-
startDate,
|
|
169
|
-
});
|
|
170
|
-
const signature = (await this.#messenger.call('DelegationController:signDelegation', { delegation: unsigned, chainId }));
|
|
171
|
-
const signedDelegation = { ...unsigned, signature };
|
|
172
|
-
const delegationHash = hashDelegation({
|
|
173
|
-
...unsigned,
|
|
174
|
-
salt: BigInt(unsigned.salt),
|
|
175
|
-
signature,
|
|
176
|
-
});
|
|
177
|
-
if (!skipChomp) {
|
|
178
|
-
const verifyResult = await this.#messenger.call('ChompApiService:verifyDelegation', {
|
|
179
|
-
signedDelegation,
|
|
180
|
-
chainId,
|
|
181
|
-
});
|
|
182
|
-
if (!verifyResult.valid) {
|
|
183
|
-
throw new Error(`${SubscriptionDelegationServiceErrorMessage.ChompRejectedDelegation}: ${verifyResult.errors?.join(', ') ?? 'unknown error'}`);
|
|
184
|
-
}
|
|
185
|
-
if (!verifyResult.delegationHash) {
|
|
186
|
-
throw new Error(SubscriptionDelegationServiceErrorMessage.ChompMissingDelegationHash);
|
|
187
|
-
}
|
|
188
|
-
if (!equalsIgnoreCase(verifyResult.delegationHash, delegationHash)) {
|
|
189
|
-
throw new Error(SubscriptionDelegationServiceErrorMessage.ChompDelegationHashMismatch);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
const allowance = add0x(periodAmount.toString(16));
|
|
193
|
-
await this.#messenger.call('AuthenticatedUserStorageService:createDelegation', {
|
|
194
|
-
signedDelegation,
|
|
195
|
-
metadata: {
|
|
196
|
-
delegationHash,
|
|
197
|
-
chainIdHex: chainId,
|
|
198
|
-
allowance,
|
|
199
|
-
tokenSymbol: token.symbol,
|
|
200
|
-
tokenAddress: token.address,
|
|
201
|
-
type: CASH_SUBSCRIPTION_DELEGATION_TYPE,
|
|
202
|
-
},
|
|
203
|
-
});
|
|
204
|
-
if (!skipChomp) {
|
|
205
|
-
await this.#createIntent({
|
|
206
|
-
account: request.payerAddress,
|
|
207
|
-
chainId,
|
|
208
|
-
delegationHash,
|
|
209
|
-
allowance,
|
|
210
|
-
tokenSymbol: token.symbol,
|
|
211
|
-
tokenAddress: token.address,
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
return {
|
|
215
|
-
delegationHash,
|
|
216
|
-
disposition: 'created',
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
async #resolveConfiguration(product, recurringInterval) {
|
|
220
|
-
const { remoteFeatureFlags } = this.#messenger.call('RemoteFeatureFlagController:getState');
|
|
221
|
-
const vaultConfig = getMoneyAccountVaultConfig(remoteFeatureFlags);
|
|
222
|
-
if (!vaultConfig) {
|
|
223
|
-
throw new Error(SubscriptionDelegationServiceErrorMessage.MissingMoneyAccountVaultConfig);
|
|
224
|
-
}
|
|
225
|
-
const { chainId } = vaultConfig;
|
|
226
|
-
const enforcers = resolveEnforcers(chainId);
|
|
227
|
-
const pricing = await this.#messenger.call('SubscriptionController:getPricing');
|
|
228
|
-
const price = pricing.products
|
|
229
|
-
.find((entry) => entry.name === product)
|
|
230
|
-
?.prices.find((entry) => entry.interval === recurringInterval);
|
|
231
|
-
const paymentMethod = pricing.paymentMethods.find((entry) => entry.type === PAYMENT_TYPES.byCrypto &&
|
|
232
|
-
entry.cryptoAuthMethod === CRYPTO_AUTH_METHODS.DELEGATION &&
|
|
233
|
-
entry.products?.includes(product) === true);
|
|
234
|
-
const chain = paymentMethod?.chains?.find((entry) => entry.chainId === chainId);
|
|
235
|
-
const token = chain?.tokens[0];
|
|
236
|
-
if (!price || !chain?.delegateAddress || !token) {
|
|
237
|
-
throw new Error(SubscriptionDelegationServiceErrorMessage.PricingConfigurationNotFound);
|
|
238
|
-
}
|
|
239
|
-
return {
|
|
240
|
-
chainId,
|
|
241
|
-
delegateAddress: chain.delegateAddress,
|
|
242
|
-
enforcers,
|
|
243
|
-
price,
|
|
244
|
-
token,
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
|
-
/**
|
|
248
|
-
* Ensures an active CHOMP intent exists for the given delegation hash,
|
|
249
|
-
* registering one when missing or revoked.
|
|
250
|
-
*
|
|
251
|
-
* @param params - Intent identity and metadata.
|
|
252
|
-
* @param params.account - Delegator / payer address.
|
|
253
|
-
* @param params.chainId - Chain ID of the delegation.
|
|
254
|
-
* @param params.delegationHash - Hash of the stored delegation.
|
|
255
|
-
* @param params.allowance - Period allowance stored with the delegation.
|
|
256
|
-
* @param params.tokenSymbol - Payment token symbol.
|
|
257
|
-
* @param params.tokenAddress - Payment token address.
|
|
258
|
-
*/
|
|
259
|
-
async #ensureIntent(params) {
|
|
260
|
-
const existingIntents = await this.#messenger.call('ChompApiService:getIntentsByAddress', params.account);
|
|
261
|
-
const hasActiveIntent = existingIntents.some((intent) => equalsIgnoreCase(intent.delegationHash, params.delegationHash) &&
|
|
262
|
-
intent.status === 'active');
|
|
263
|
-
if (hasActiveIntent) {
|
|
264
|
-
return;
|
|
265
|
-
}
|
|
266
|
-
await this.#createIntent(params);
|
|
267
|
-
}
|
|
268
|
-
async #createIntent(params) {
|
|
269
|
-
// Published `@metamask/chomp-api-service` only types intent metadata as
|
|
270
|
-
// `'cash-deposit' | 'cash-withdrawal'`. The dormant production path still
|
|
271
|
-
// passes `'cash-subscription'`; a follow-up chomp-api-service release must
|
|
272
|
-
// accept that discriminator before this path is production-ready. Alpha
|
|
273
|
-
// callers must use `skipChompInteractions: true` so this method is not
|
|
274
|
-
// reached.
|
|
275
|
-
await this.#messenger.call('ChompApiService:createIntents', [
|
|
276
|
-
{
|
|
277
|
-
account: params.account,
|
|
278
|
-
delegationHash: params.delegationHash,
|
|
279
|
-
chainId: params.chainId,
|
|
280
|
-
metadata: {
|
|
281
|
-
allowance: params.allowance,
|
|
282
|
-
tokenSymbol: params.tokenSymbol,
|
|
283
|
-
tokenAddress: params.tokenAddress,
|
|
284
|
-
type: CASH_SUBSCRIPTION_DELEGATION_TYPE,
|
|
285
|
-
},
|
|
286
|
-
},
|
|
287
|
-
]);
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
//# sourceMappingURL=SubscriptionDelegationService.js.map
|