@mpgd/platform 0.20.0 → 0.22.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/dist/commerce-conformance.d.ts +34 -51
- package/dist/commerce-conformance.js +72 -465
- package/dist/commerce-contract.d.ts +31 -2
- package/dist/commerce-wallet.d.ts +324 -0
- package/dist/commerce-wallet.js +2087 -0
- package/dist/commerce.d.ts +34 -5
- package/dist/commerce.js +238 -10
- package/package.json +6 -2
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import { type tags } from 'typia';
|
|
2
|
+
import { type ActiveSubscription, type CommerceAuthorityCapabilities, type CommerceBillingAuthority, type CommerceCapabilities, type CommerceCatalogCapabilities, type CommerceErrorCode, type CommerceErrorInfo, type CommerceEvent, type CommerceLifecycleCapabilities, type CommerceLogicalProductId, type CommerceProvider, type CommercePurchaseCapabilities, type CreditDebit, type CreditEntitlement, type CreditLot, type CreditLotOrigin, type CreditLotSpendScope, type CreditMembershipScope, type CreditMembershipTerms, type CreditOffer, type CreditSpendResult, type CreditWalletClient, type CreditWalletSubscribeInput, type StoreId } from './commerce.js';
|
|
3
|
+
import type { IsoTimestamp, NonEmptyString, NonNegativeInteger } from './commerce-contract.js';
|
|
4
|
+
import type { PlatformEvidenceEnvelope, PlatformProviderAvailability } from './index.js';
|
|
5
|
+
/**
|
|
6
|
+
* Commerce v2 credit wallet contract (RFC "Credit wallet", "Credit lots",
|
|
7
|
+
* "Billing authority and memberships", "Subscriptions"). The consuming
|
|
8
|
+
* project implements `CreditWalletClient` against its own wallet service;
|
|
9
|
+
* this module supplies the rules both sides share, the provider that turns a
|
|
10
|
+
* client into a `CommerceProvider`, and a reference in-memory wallet that the
|
|
11
|
+
* conformance runner and consumer tests can run the wallet vectors against.
|
|
12
|
+
* Pure in-process code: no Phaser, DOM, network, or SDK imports. Nothing here
|
|
13
|
+
* grants: a spend debits the wallet's own lots, the entitlement it creates is
|
|
14
|
+
* a pointer the reconciler still verifies with the ledger, and a lot is
|
|
15
|
+
* credited only from a ledger grant keyed by its entry id.
|
|
16
|
+
*/
|
|
17
|
+
export type { CommerceBillingAuthority, CreditBalance, CreditDebit, CreditEntitlement, CreditLot, CreditLotChannel, CreditLotOrigin, CreditLotSpendScope, CreditMembershipScope, CreditMembershipTerms, CreditOffer, CreditPrice, CreditSpendInput, CreditSpendResult, CreditWalletClient, CreditWalletSubscribeInput, } from './commerce.js';
|
|
18
|
+
export { assertCreditBalance, assertCreditEntitlement, assertCreditLot, assertCreditOffer, assertCreditSpendInput, assertCreditSpendResult, } from './commerce.js';
|
|
19
|
+
/** Canonical `YYYY-MM-DDTHH:mm:ssZ`; milliseconds are kept only when non-zero. */
|
|
20
|
+
export declare function normalizeIsoTimestamp(input: string): string;
|
|
21
|
+
/** The integer components of an ISO-8601 duration (`P1Y2M3W4DT5H6M7S`). */
|
|
22
|
+
export interface IsoDurationParts {
|
|
23
|
+
readonly years: number;
|
|
24
|
+
readonly months: number;
|
|
25
|
+
readonly weeks: number;
|
|
26
|
+
readonly days: number;
|
|
27
|
+
readonly hours: number;
|
|
28
|
+
readonly minutes: number;
|
|
29
|
+
readonly seconds: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Parses a positive ISO-8601 duration a membership period accepts (`P30D`,
|
|
33
|
+
* `P1M`, `PT12H`, ...). Zero-length durations (`P0D`, `PT0S`), a bare `P` or
|
|
34
|
+
* `PT`, and a `T` with no time components are rejected, so a period can
|
|
35
|
+
* never renew without time passing.
|
|
36
|
+
*/
|
|
37
|
+
export declare function parseIsoDuration(duration: string): IsoDurationParts | undefined;
|
|
38
|
+
export declare function isIsoDuration(duration: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Adds `times` ISO-8601 durations to a timestamp in UTC. Years and months are
|
|
41
|
+
* calendar months with the day clamped to the target month's length
|
|
42
|
+
* (`2026-01-31` + `P1M` is `2026-02-28`), so a membership's periods are
|
|
43
|
+
* anchored on its start date: period `n` ends at `startedAt + (n + 1) × period`
|
|
44
|
+
* rather than drifting from the previous period's end.
|
|
45
|
+
*/
|
|
46
|
+
export declare function addIsoDuration(at: string, duration: string, times?: number): string;
|
|
47
|
+
/** Profiles whose distribution requires store billing for digital goods; their authority is always `store`. */
|
|
48
|
+
export declare const storeBillingAuthorityProfiles: readonly ["google-play", "app-store"];
|
|
49
|
+
/** Profiles whose authority defaults to `host`; every other profile defaults to `store`. */
|
|
50
|
+
export declare const hostBillingAuthorityProfiles: readonly ["web", "web-preview"];
|
|
51
|
+
export declare function isCommerceBillingAuthority(value: unknown): value is CommerceBillingAuthority;
|
|
52
|
+
/** The RFC default for a release profile before any project override. */
|
|
53
|
+
export declare function defaultCommerceBillingAuthority(profile: string): CommerceBillingAuthority;
|
|
54
|
+
/**
|
|
55
|
+
* Resolves a target's billing authority from its release profile. `google-play`
|
|
56
|
+
* and `app-store` are always `store` and reject a `host` override (D-02: both
|
|
57
|
+
* stores require their own billing for digital entitlements). `web` and
|
|
58
|
+
* `web-preview` default to `host`, every other profile to `store`, and a
|
|
59
|
+
* project may override those after its own policy review.
|
|
60
|
+
*/
|
|
61
|
+
export declare function resolveCommerceBillingAuthority(profile: string, override?: CommerceBillingAuthority): CommerceBillingAuthority;
|
|
62
|
+
export type CreditScope = 'title' | 'cross-title';
|
|
63
|
+
/**
|
|
64
|
+
* `creditScope` per store id: which stores count as off-store, so their lots
|
|
65
|
+
* are spendable across titles. Absent entries are `title`; the kit's reference
|
|
66
|
+
* stores keep that default.
|
|
67
|
+
*/
|
|
68
|
+
export type CreditScopeRegistry = Readonly<Record<string, CreditScope>>;
|
|
69
|
+
/** Stores whose lots are always title-scoped; neither a registry nor a promotion can make them `cross-title`. */
|
|
70
|
+
export declare const titleScopedCreditStores: readonly ["google-play", "app-store"];
|
|
71
|
+
export declare function isTitleScopedCreditStore(store: string): boolean;
|
|
72
|
+
/** Rejects a registry that marks Google Play or the App Store `cross-title`, or holds an unknown scope. */
|
|
73
|
+
export declare function assertCreditScopeRegistry(registry: CreditScopeRegistry): CreditScopeRegistry;
|
|
74
|
+
export declare const assertCreditLotSpendScope: (input: unknown) => CreditLotSpendScope;
|
|
75
|
+
export interface DeriveCreditLotSpendScopeOptions {
|
|
76
|
+
/** Scope a promotion lot was issued with; rejected for store and off-store lots, whose scope is derived. */
|
|
77
|
+
readonly explicit?: CreditLotSpendScope;
|
|
78
|
+
readonly creditScope?: CreditScopeRegistry;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Derives a lot's `spendScope` from its origin (RFC "Credit lots"): a lot
|
|
82
|
+
* bought through a store is `title`-scoped to its purchasing title, an
|
|
83
|
+
* off-store lot is `cross-title`, and a promotion lot carries the scope it was
|
|
84
|
+
* issued with (`title` by default). A registry entry overrides the channel for
|
|
85
|
+
* store and off-store lots. A lot attributed to Google Play or the App Store is
|
|
86
|
+
* always `title`, whatever the channel, registry, or issued scope says.
|
|
87
|
+
*/
|
|
88
|
+
export declare function deriveCreditLotSpendScope(origin: CreditLotOrigin, options?: DeriveCreditLotSpendScopeOptions): CreditLotSpendScope;
|
|
89
|
+
/** RFC spend order: earliest `expiresAt` (none last), `title` before `cross-title`, oldest `createdAt`, then `lotId`. */
|
|
90
|
+
export declare function compareCreditLotSpendOrder(left: CreditLot, right: CreditLot): number;
|
|
91
|
+
export interface CreditLotEligibility {
|
|
92
|
+
readonly titleId: string;
|
|
93
|
+
readonly currency: string;
|
|
94
|
+
/**
|
|
95
|
+
* `title` (the default) spends that title's lots and `cross-title` lots;
|
|
96
|
+
* `platform` spends `cross-title` lots only, as a platform-scoped membership
|
|
97
|
+
* does.
|
|
98
|
+
*/
|
|
99
|
+
readonly scope?: CreditMembershipScope;
|
|
100
|
+
/** ISO-8601 timestamp or epoch milliseconds; a lot whose `expiresAt` is not after it is excluded. */
|
|
101
|
+
readonly now: string | number;
|
|
102
|
+
/**
|
|
103
|
+
* When set, a lot created after this instant is excluded. A catch-up
|
|
104
|
+
* renewal passes the boundary of the period it pays for, so credits granted
|
|
105
|
+
* after that period ended cannot fund it retroactively.
|
|
106
|
+
*/
|
|
107
|
+
readonly createdBy?: string | number;
|
|
108
|
+
}
|
|
109
|
+
/** Whether a lot may fund a spend: same currency, credit left, not expired, and in scope. */
|
|
110
|
+
export declare function isCreditLotEligible(lot: CreditLot, criteria: CreditLotEligibility): boolean;
|
|
111
|
+
/** The eligible lots of a spend in the order they are consumed; the input is not mutated. */
|
|
112
|
+
export declare function selectEligibleCreditLots(lots: readonly CreditLot[], criteria: CreditLotEligibility): readonly CreditLot[];
|
|
113
|
+
export declare function sumCreditLotRemaining(lots: readonly CreditLot[]): number;
|
|
114
|
+
export declare function sumCreditDebits(debits: readonly CreditDebit[]): number;
|
|
115
|
+
export declare function sameCreditAmount(left: number, right: number): boolean;
|
|
116
|
+
/** The whole number of `unit` prices in `amount`, or `undefined` when `amount` is not a positive multiple. */
|
|
117
|
+
export declare function creditPriceMultiple(amount: number, unit: number): number | undefined;
|
|
118
|
+
export type CreditDebitPlan = {
|
|
119
|
+
readonly status: 'debited';
|
|
120
|
+
readonly debits: readonly CreditDebit[];
|
|
121
|
+
} | {
|
|
122
|
+
readonly status: 'rejected';
|
|
123
|
+
readonly error: CommerceErrorInfo;
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
* Plans the debits of `amount` across eligible lots in spend order without
|
|
127
|
+
* mutating them. A spend the lots cannot cover is rejected with
|
|
128
|
+
* `INSUFFICIENT_BALANCE` and plans nothing.
|
|
129
|
+
*/
|
|
130
|
+
export declare function planCreditDebits(eligible: readonly CreditLot[], amount: number): CreditDebitPlan;
|
|
131
|
+
/** Prefix of every scheduled membership debit key; a client spend cannot use it. */
|
|
132
|
+
export declare const membershipDebitKeyPrefix = "membership:";
|
|
133
|
+
/** `membership:<subscriptionId>:<periodIndex>`, so a repeated scheduler tick cannot charge a period twice. */
|
|
134
|
+
export declare function createMembershipRenewalKey(subscriptionId: string, periodIndex: number): string;
|
|
135
|
+
export type CreditSubscriptionEventType = 'subscriptionStarted' | 'subscriptionRenewed' | 'subscriptionLapsed' | 'subscriptionRevoked';
|
|
136
|
+
export declare const creditSubscriptionEventTypes: readonly ["subscriptionStarted", "subscriptionRenewed", "subscriptionLapsed", "subscriptionRevoked"];
|
|
137
|
+
/** `<subscriptionId>:<periodIndex>:<type>`, so redelivery of a lifecycle event is idempotent. */
|
|
138
|
+
export declare function createCreditSubscriptionEventId(subscriptionId: string, periodIndex: number, type: CreditSubscriptionEventType): string;
|
|
139
|
+
/** A membership lifecycle event as the wallet service records and pushes it. */
|
|
140
|
+
export interface CreditSubscriptionEvent {
|
|
141
|
+
readonly eventId: NonEmptyString;
|
|
142
|
+
readonly type: CreditSubscriptionEventType;
|
|
143
|
+
readonly subscriptionId: NonEmptyString;
|
|
144
|
+
readonly logicalId: CommerceLogicalProductId;
|
|
145
|
+
readonly periodIndex: NonNegativeInteger;
|
|
146
|
+
readonly expiresAt: IsoTimestamp;
|
|
147
|
+
/** Why a membership lapsed, for example INSUFFICIENT_BALANCE. */
|
|
148
|
+
readonly reason?: CommerceErrorCode;
|
|
149
|
+
}
|
|
150
|
+
/** A ledger grant the wallet owner credits as a lot; `ledgerEntryId` becomes the `lotId`. */
|
|
151
|
+
export interface CreditLotGrant {
|
|
152
|
+
readonly ledgerEntryId: NonEmptyString;
|
|
153
|
+
readonly currency: NonEmptyString;
|
|
154
|
+
readonly amount: number & tags.ExclusiveMinimum<0>;
|
|
155
|
+
readonly origin: CreditLotOrigin;
|
|
156
|
+
readonly createdAt: IsoTimestamp;
|
|
157
|
+
readonly expiresAt?: IsoTimestamp;
|
|
158
|
+
}
|
|
159
|
+
/** A debit with the idempotency key of the spend that made it. */
|
|
160
|
+
export interface CreditScheduledDebit extends CreditDebit {
|
|
161
|
+
readonly idempotencyKey: NonEmptyString;
|
|
162
|
+
}
|
|
163
|
+
export interface CreditRedeemInput {
|
|
164
|
+
readonly entitlementId: NonEmptyString;
|
|
165
|
+
/** The ledger entry that granted the entitlement; a redeem without one is refused. */
|
|
166
|
+
readonly ledgerEntryId: NonEmptyString;
|
|
167
|
+
}
|
|
168
|
+
export interface CreditMembershipStartInput {
|
|
169
|
+
readonly subscriptionId: NonEmptyString;
|
|
170
|
+
readonly titleId: NonEmptyString;
|
|
171
|
+
readonly logicalId: CommerceLogicalProductId;
|
|
172
|
+
readonly terms: CreditMembershipTerms;
|
|
173
|
+
}
|
|
174
|
+
export type CreditMembershipStartResult = {
|
|
175
|
+
readonly status: 'started';
|
|
176
|
+
readonly subscription: ActiveSubscription;
|
|
177
|
+
/** The period-0 entitlement, `membership:<subscriptionId>:0`. */
|
|
178
|
+
readonly entitlementId: NonEmptyString;
|
|
179
|
+
readonly debits: readonly CreditDebit[];
|
|
180
|
+
readonly createdAt: IsoTimestamp;
|
|
181
|
+
/** The id was already started with these terms; the original period-0 debits are returned. */
|
|
182
|
+
readonly alreadyProcessed?: boolean;
|
|
183
|
+
} | {
|
|
184
|
+
readonly status: 'rejected';
|
|
185
|
+
readonly error: CommerceErrorInfo;
|
|
186
|
+
};
|
|
187
|
+
/** The `CreditSpendResult` a membership start answers a `spend` with. */
|
|
188
|
+
export declare function creditSpendResultOfMembershipStart(result: CreditMembershipStartResult): CreditSpendResult;
|
|
189
|
+
export declare const assertCreditLotGrant: (input: unknown) => CreditLotGrant;
|
|
190
|
+
export declare const assertCreditMembershipTerms: (input: unknown) => CreditMembershipTerms;
|
|
191
|
+
export declare const assertCreditRedeemInput: (input: unknown) => CreditRedeemInput;
|
|
192
|
+
export declare const assertCreditSubscriptionEvent: (input: unknown) => CreditSubscriptionEvent;
|
|
193
|
+
export declare const assertCreditMembershipStartInput: (input: unknown) => CreditMembershipStartInput;
|
|
194
|
+
/**
|
|
195
|
+
* `assertCreditOffer` plus the wallet rules an offer must satisfy: membership
|
|
196
|
+
* terms only on a `subscription` offer, every `subscription` offer with terms,
|
|
197
|
+
* a valid positive period, and a membership priced as its terms say.
|
|
198
|
+
*/
|
|
199
|
+
export declare function assertCreditWalletOffer(input: unknown): CreditOffer;
|
|
200
|
+
export declare const creditWalletSpendEvidenceSchema: 'credit-wallet.spend.v1';
|
|
201
|
+
export interface CreditWalletSpendEvidence {
|
|
202
|
+
readonly store: StoreId;
|
|
203
|
+
readonly titleId: string;
|
|
204
|
+
/** The wallet's own id for the settled spend (its entitlement id); not a backend ledger entry. */
|
|
205
|
+
readonly entitlementId: string;
|
|
206
|
+
readonly amount: number;
|
|
207
|
+
readonly debits: readonly CreditDebit[];
|
|
208
|
+
}
|
|
209
|
+
/** The `adapter-settled` evidence of a wallet spend; `debits` is JSON because envelope payloads are flat. */
|
|
210
|
+
export declare function createCreditWalletSpendEvidence(evidence: CreditWalletSpendEvidence): PlatformEvidenceEnvelope;
|
|
211
|
+
/** Reads a `credit-wallet.spend.v1` envelope; any other schema or a malformed payload is `undefined`. */
|
|
212
|
+
export declare function readCreditWalletSpendEvidence(envelope: PlatformEvidenceEnvelope): CreditWalletSpendEvidence | undefined;
|
|
213
|
+
export interface CreditCommerceCapabilityOverrides {
|
|
214
|
+
readonly purchase?: Partial<CommercePurchaseCapabilities>;
|
|
215
|
+
readonly catalog?: Partial<CommerceCatalogCapabilities>;
|
|
216
|
+
readonly lifecycle?: Partial<CommerceLifecycleCapabilities>;
|
|
217
|
+
readonly authority?: Partial<CommerceAuthorityCapabilities>;
|
|
218
|
+
readonly availability?: PlatformProviderAvailability;
|
|
219
|
+
}
|
|
220
|
+
export interface CreateCreditCommerceProviderOptions {
|
|
221
|
+
readonly titleId: string;
|
|
222
|
+
readonly billingAuthority: CommerceBillingAuthority;
|
|
223
|
+
/**
|
|
224
|
+
* The catalog's declared currencies. An offer priced in another currency is
|
|
225
|
+
* a configuration error (RFC "Catalog currencies"); omitted, no check runs.
|
|
226
|
+
*/
|
|
227
|
+
readonly currencies?: readonly string[];
|
|
228
|
+
/**
|
|
229
|
+
* Overrides on the RFC wallet profile. `purchase.subscription` is forced
|
|
230
|
+
* `false` where the billing authority is `store` or the client cannot
|
|
231
|
+
* report active subscriptions, whatever the override.
|
|
232
|
+
*/
|
|
233
|
+
readonly capabilities?: CreditCommerceCapabilityOverrides;
|
|
234
|
+
/** Clock for `purchasedAt` when the wallet reports no settlement time; defaults to the system clock. */
|
|
235
|
+
readonly now?: () => string;
|
|
236
|
+
}
|
|
237
|
+
/** A `CommerceProvider` over a wallet client that also releases its client subscription. */
|
|
238
|
+
export interface CreditCommerceProvider extends CommerceProvider {
|
|
239
|
+
/** Unsubscribes from the client; events after this are no longer forwarded. */
|
|
240
|
+
dispose(): void;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* The RFC profile row of a project-owned wallet, before overrides.
|
|
244
|
+
* `purchase.subscription` is true only where the billing authority is `host`
|
|
245
|
+
* and the caller states that the client reports active subscriptions
|
|
246
|
+
* (`client.subscriptions: true`); with no client description it is `false`.
|
|
247
|
+
*/
|
|
248
|
+
export declare function createCreditCommerceCapabilities(billingAuthority: CommerceBillingAuthority, overrides?: CreditCommerceCapabilityOverrides, client?: {
|
|
249
|
+
readonly subscriptions?: boolean;
|
|
250
|
+
}): CommerceCapabilities;
|
|
251
|
+
/**
|
|
252
|
+
* `CommerceProvider` over a project-owned `CreditWalletClient` (RFC "Credit
|
|
253
|
+
* wallet"): `fetchProducts` lists the wallet's offers (memberships omitted
|
|
254
|
+
* where the billing authority is `store`), `requestPurchase` spends the offer
|
|
255
|
+
* price times the quantity under the game's idempotency key and answers
|
|
256
|
+
* `purchased` with `adapter-settled` evidence (`credit-wallet.spend.v1`)
|
|
257
|
+
* once the wallet's debits add up to that price, without a `settlement`
|
|
258
|
+
* pointer: the backend ledger entry exists only after the reconciler verifies
|
|
259
|
+
* that evidence, so there is nothing to point at yet,
|
|
260
|
+
* `getAvailablePurchases` lists the title's unredeemed entitlements,
|
|
261
|
+
* `finishTransaction` redeems one with the ledger entry id of its grant and
|
|
262
|
+
* refuses to run without it, `restorePurchases` re-reads the unredeemed
|
|
263
|
+
* entitlements as `purchaseUpdated` events, and the client's own events pass
|
|
264
|
+
* through the standard pre-listener buffer. Every client answer is
|
|
265
|
+
* validated; a malformed one is `INVALID_RESPONSE`. The provider never
|
|
266
|
+
* grants and never credits: lots are credited by the wallet owner from
|
|
267
|
+
* ledger grants, and memberships renew, lapse, and expire on the wallet
|
|
268
|
+
* service alone.
|
|
269
|
+
*/
|
|
270
|
+
export declare function createCreditCommerceProvider(client: CreditWalletClient, options: CreateCreditCommerceProviderOptions): CreditCommerceProvider;
|
|
271
|
+
/** Periods one `renewDue` tick charges per membership before it yields to the next tick. */
|
|
272
|
+
export declare const defaultMaxRenewalsPerTick = 12;
|
|
273
|
+
export interface CreateInMemoryCreditWalletInput {
|
|
274
|
+
readonly store: StoreId;
|
|
275
|
+
/** Currencies the wallet keeps balances in; a lot or spend in another currency is refused. */
|
|
276
|
+
readonly currencies: readonly string[];
|
|
277
|
+
/** Clock for lot eligibility, entitlements, and periods; defaults to the system clock. */
|
|
278
|
+
readonly now?: () => string;
|
|
279
|
+
/** Offers the wallet prices spends against; a `spend` of a membership offer starts the membership. */
|
|
280
|
+
readonly offers?: readonly CreditOffer[];
|
|
281
|
+
readonly creditScope?: CreditScopeRegistry;
|
|
282
|
+
/** Cap on the periods a single `renewDue` tick charges per membership; defaults to 12. */
|
|
283
|
+
readonly maxRenewalsPerTick?: number;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* The reference wallet: the client surface plus the owner-side operations a
|
|
287
|
+
* wallet service runs (credit a lot from a ledger grant, register offers,
|
|
288
|
+
* start a membership, run the renewal scheduler) and the observations the
|
|
289
|
+
* conformance vectors assert. The owner-side operations are not on
|
|
290
|
+
* `CreditWalletClient`; a game client gets only that interface.
|
|
291
|
+
*/
|
|
292
|
+
export interface InMemoryCreditWallet extends CreditWalletClient {
|
|
293
|
+
readonly lots: readonly CreditLot[];
|
|
294
|
+
/** Every debit of every processed spend, in order; replays add nothing. */
|
|
295
|
+
readonly debits: readonly CreditScheduledDebit[];
|
|
296
|
+
readonly entitlements: readonly CreditEntitlement[];
|
|
297
|
+
readonly subscriptionEvents: readonly CreditSubscriptionEvent[];
|
|
298
|
+
readonly offers: readonly CreditOffer[];
|
|
299
|
+
/** Registers or replaces offers by logical id. */
|
|
300
|
+
addOffers(offers: readonly CreditOffer[]): void;
|
|
301
|
+
/** Credits a lot whose id is the ledger entry id; a replayed grant returns the existing lot. */
|
|
302
|
+
creditFromGrant(grant: CreditLotGrant, options?: DeriveCreditLotSpendScopeOptions): CreditLot;
|
|
303
|
+
/** Starts a membership by debiting period 0; an id already started with the same terms answers with its original debits. */
|
|
304
|
+
startMembership(input: CreditMembershipStartInput): Promise<CreditMembershipStartResult>;
|
|
305
|
+
/** Runs the renewal scheduler for memberships whose paid period has ended at `now` (default: the wallet clock). */
|
|
306
|
+
renewDue(now?: string): Promise<void>;
|
|
307
|
+
getActiveSubscriptions(input?: {
|
|
308
|
+
readonly titleId?: string;
|
|
309
|
+
}): Promise<readonly ActiveSubscription[]>;
|
|
310
|
+
/** With `input.titleId`, a title-scoped membership's events reach only that title's listeners. */
|
|
311
|
+
subscribe(listener: (event: CommerceEvent) => void, input?: CreditWalletSubscribeInput): () => void;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Reference in-memory wallet implementing the RFC "Credit lots" and "Billing
|
|
315
|
+
* authority and memberships" rules on the pure rule functions above: lot ids
|
|
316
|
+
* equal ledger entry ids, spend scope derives from the lot origin, spends
|
|
317
|
+
* consume eligible lots in the fixed order, are idempotent by key, are priced
|
|
318
|
+
* by the wallet's own offers, and debit nothing on `INSUFFICIENT_BALANCE`;
|
|
319
|
+
* memberships debit `membership:<subscriptionId>:<periodIndex>` per paid
|
|
320
|
+
* period with lot eligibility judged at the period boundary, a
|
|
321
|
+
* platform-scoped membership debits `cross-title` lots only, and a membership
|
|
322
|
+
* lapses at period end when the eligible balance runs out.
|
|
323
|
+
*/
|
|
324
|
+
export declare function createInMemoryCreditWallet(input: CreateInMemoryCreditWalletInput): InMemoryCreditWallet;
|