@mpgd/game-services 0.21.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/README.md +30 -0
- package/dist/admob-ssv-conformance.js +3 -1
- package/dist/app-store-recovery.js +5 -0
- package/dist/client.d.ts +39 -1
- package/dist/client.js +198 -0
- package/dist/commerce-evidence-registry.d.ts +406 -0
- package/dist/commerce-evidence-registry.js +773 -0
- package/dist/commerce-ledger.d.ts +64 -0
- package/dist/commerce-ledger.js +146 -0
- package/dist/commerce-reconciler.d.ts +191 -0
- package/dist/commerce-reconciler.js +1251 -0
- package/dist/contract.d.ts +4 -1
- package/dist/contract.js +8 -0
- package/dist/evidence-verification.d.ts +14 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/monetization-operation-store.d.ts +20 -0
- package/dist/monetization-operation-store.js +80 -0
- package/dist/monetization-recovery.d.ts +57 -2
- package/dist/monetization-recovery.js +102 -8
- package/dist/operation-results.d.ts +14 -0
- package/dist/operations.d.ts +2 -1
- package/dist/platform-order.d.ts +47 -0
- package/dist/platform-order.js +86 -0
- package/dist/runtime.js +12 -1
- package/dist/server.d.ts +43 -1
- package/dist/server.js +305 -7
- package/dist/types.d.ts +79 -3
- package/dist/types.js +97 -6
- package/package.json +18 -6
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
import type { ProductCatalog } from '@mpgd/catalog';
|
|
2
|
+
import type { CommerceCapabilities, CommerceFinishOwner, PlatformEvidenceEnvelope } from '@mpgd/platform';
|
|
3
|
+
import { type CommerceServiceCapabilities, type CommerceServiceStoreCapabilities, type StoreId } from '@mpgd/platform/commerce';
|
|
4
|
+
import type { EvidenceVerificationDecision, GameServicesEvidenceVerifier, GameServicesPurchaseGrantFinalizer, VerifyPurchaseEvidenceInput } from './evidence-verification.js';
|
|
5
|
+
import type { GameServicesStore } from './server.js';
|
|
6
|
+
import { type EntitlementLedgerGrant, type EntitlementLedgerPayload, type ProductGrantTransaction, type VerifyPurchaseRequest } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Commerce v2 evidence registry (RFC "Server: commerce service protocol").
|
|
9
|
+
* The game composes one registry from the reference entries below and its
|
|
10
|
+
* own; the backend routes every verify request by `evidence.schema` to the
|
|
11
|
+
* entry that claims it, publishes the stores it accepts through the
|
|
12
|
+
* capabilities endpoint, and finalizes server-finish grants through the
|
|
13
|
+
* entry's finalizer. Nothing here grants: an entry's verifier decides, and
|
|
14
|
+
* the backend writes the ledger.
|
|
15
|
+
*/
|
|
16
|
+
/** Stable rejection reasons the registry answers before any verifier runs. */
|
|
17
|
+
export type CommerceEvidenceRegistryErrorCode = 'EVIDENCE_SCHEMA_UNSUPPORTED' | 'EVIDENCE_SCHEMA_STORE_MISMATCH' | 'EVIDENCE_SCHEMA_TARGET_MISMATCH';
|
|
18
|
+
/** The purchase kinds a store sells, as the capabilities endpoint publishes them. */
|
|
19
|
+
export type CommerceServicePurchaseCapabilities = CommerceServiceStoreCapabilities['purchase'];
|
|
20
|
+
export interface CommerceEvidenceRegistryEntry {
|
|
21
|
+
/** The evidence schema this entry verifies, for example `google-play.product-purchase.v2`. */
|
|
22
|
+
readonly schema: string;
|
|
23
|
+
readonly store: StoreId;
|
|
24
|
+
readonly verifier: Pick<GameServicesEvidenceVerifier, 'verifyPurchase'>;
|
|
25
|
+
/** Required when `finish` is `server`; registry construction fails otherwise. */
|
|
26
|
+
readonly finalizer?: GameServicesPurchaseGrantFinalizer;
|
|
27
|
+
readonly finish: CommerceFinishOwner;
|
|
28
|
+
/** Spend scope of credit lots bought through this store. Default 'title'. */
|
|
29
|
+
readonly creditScope?: 'title' | 'cross-title';
|
|
30
|
+
/**
|
|
31
|
+
* Route a request of this store that carries no evidence envelope to this
|
|
32
|
+
* entry (the App Store verifier keeps its Server API lookup for one). At
|
|
33
|
+
* most one entry per store may declare it.
|
|
34
|
+
*/
|
|
35
|
+
readonly acceptsMissingEvidence?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Route a request of this store whose schema no entry claims to this entry
|
|
38
|
+
* as well (a verifier binding that keeps its own schema list). At most one
|
|
39
|
+
* entry per store may declare it; without one such a request is rejected.
|
|
40
|
+
*/
|
|
41
|
+
readonly acceptsUnclaimedSchemas?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* The ledger targets a request of this store may name (`request.target`).
|
|
44
|
+
* A request naming another target is rejected with
|
|
45
|
+
* `EVIDENCE_SCHEMA_TARGET_MISMATCH`; absent, any target is accepted.
|
|
46
|
+
*/
|
|
47
|
+
readonly targets?: readonly string[];
|
|
48
|
+
/**
|
|
49
|
+
* What the store sells, published by the capabilities endpoint. Defaults to
|
|
50
|
+
* consumable and durable one-time products; every entry of one store is
|
|
51
|
+
* merged.
|
|
52
|
+
*/
|
|
53
|
+
readonly purchase?: CommerceServicePurchaseCapabilities;
|
|
54
|
+
}
|
|
55
|
+
/** A store the `unregistered` fallback verifier serves, published by the capabilities endpoint. */
|
|
56
|
+
export interface CommerceEvidenceFallbackStore {
|
|
57
|
+
readonly store: StoreId;
|
|
58
|
+
readonly finish: CommerceFinishOwner;
|
|
59
|
+
readonly purchase?: CommerceServicePurchaseCapabilities;
|
|
60
|
+
readonly targets?: readonly string[];
|
|
61
|
+
}
|
|
62
|
+
export interface CreateCommerceEvidenceRegistryOptions {
|
|
63
|
+
/**
|
|
64
|
+
* A deployment's v1 verifier (and finalizer) for requests whose schema no
|
|
65
|
+
* entry claims, so a registry can be introduced next to an existing
|
|
66
|
+
* aggregate verifier. Without it such a request is rejected with
|
|
67
|
+
* `EVIDENCE_SCHEMA_UNSUPPORTED`. A schema an entry claims never reaches it.
|
|
68
|
+
*/
|
|
69
|
+
readonly unregistered?: {
|
|
70
|
+
readonly verifier: Pick<GameServicesEvidenceVerifier, 'verifyPurchase'>;
|
|
71
|
+
readonly finalizer?: GameServicesPurchaseGrantFinalizer;
|
|
72
|
+
/**
|
|
73
|
+
* The stores the fallback publishes through the capabilities endpoint
|
|
74
|
+
* (with no schemas), so a client of such a store is not told
|
|
75
|
+
* `configuration-required`. Absent, nothing is published for the
|
|
76
|
+
* fallback.
|
|
77
|
+
*/
|
|
78
|
+
readonly stores?: readonly CommerceEvidenceFallbackStore[];
|
|
79
|
+
/**
|
|
80
|
+
* Whether the fallback also serves stores it did not declare (a v1
|
|
81
|
+
* aggregate verifier that served every target). Defaults to true when
|
|
82
|
+
* `stores` is absent and to false when it is given: a declared list is
|
|
83
|
+
* then also the list of served stores, and any other store is rejected.
|
|
84
|
+
*/
|
|
85
|
+
readonly servesUndeclaredStores?: boolean;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
export type CommerceEvidenceRoute = {
|
|
89
|
+
readonly status: 'routed';
|
|
90
|
+
readonly store: StoreId;
|
|
91
|
+
readonly entry: CommerceEvidenceRegistryEntry;
|
|
92
|
+
} | {
|
|
93
|
+
/** No entry claims the request's schema (or its missing envelope). */
|
|
94
|
+
readonly status: 'unregistered';
|
|
95
|
+
readonly store: StoreId;
|
|
96
|
+
} | {
|
|
97
|
+
readonly status: 'rejected';
|
|
98
|
+
readonly store: StoreId;
|
|
99
|
+
readonly reason: CommerceEvidenceRegistryErrorCode;
|
|
100
|
+
};
|
|
101
|
+
export interface CommerceEvidenceRegistry {
|
|
102
|
+
readonly entries: readonly CommerceEvidenceRegistryEntry[];
|
|
103
|
+
/** Every store the registry serves: the entries' stores and the fallback's declared ones. */
|
|
104
|
+
readonly stores: ReadonlySet<StoreId>;
|
|
105
|
+
/**
|
|
106
|
+
* Whether a request is served at all: a served store, or (with
|
|
107
|
+
* `servesUndeclaredStores`) an undeclared store whose target's v1 store is
|
|
108
|
+
* not itself served. The backend answers a 400 otherwise.
|
|
109
|
+
*/
|
|
110
|
+
serves(request: Pick<VerifyPurchaseRequest, 'target' | 'store'>): boolean;
|
|
111
|
+
/** Whether the fallback serves stores it did not declare. */
|
|
112
|
+
readonly servesUndeclaredStores: boolean;
|
|
113
|
+
/**
|
|
114
|
+
* The ledger targets requests of a served store may name: the union of the
|
|
115
|
+
* store's entries' `targets` (or the declared fallback store's), or
|
|
116
|
+
* undefined when any target is accepted or the store is not served.
|
|
117
|
+
*/
|
|
118
|
+
allowedTargets(store: StoreId): ReadonlySet<string> | undefined;
|
|
119
|
+
/** The store a request names: `store`, or the v1 mapping of its `target`. */
|
|
120
|
+
resolveStore(request: Pick<VerifyPurchaseRequest, 'target' | 'store'>): StoreId;
|
|
121
|
+
/** Where a request's evidence is routed, without running a verifier. */
|
|
122
|
+
route(request: Pick<VerifyPurchaseRequest, 'target' | 'store' | 'evidence'>): CommerceEvidenceRoute;
|
|
123
|
+
/** Routes the request and runs the entry's verifier; a `GameServicesEvidenceVerifier.verifyPurchase`. */
|
|
124
|
+
verifyPurchase(input: VerifyPurchaseEvidenceInput): Promise<EvidenceVerificationDecision>;
|
|
125
|
+
/** Routes a grant to the entry's finalizer; a `GameServicesPurchaseGrantFinalizer`. */
|
|
126
|
+
readonly finalizer: GameServicesPurchaseGrantFinalizer;
|
|
127
|
+
/** What the backend accepts, for the provider capabilities endpoint. */
|
|
128
|
+
getCapabilities(): CommerceServiceCapabilities;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* The v1 request mapping (RFC "Open store ids"): a request without `store`
|
|
132
|
+
* names its store through its deployment target. `android` is `google-play`,
|
|
133
|
+
* `ios` is `app-store`, `ait` is `apps-in-toss`, `reddit` is `devvit`, and
|
|
134
|
+
* every other target is its own store id (`microsoft-store`, `verse8`,
|
|
135
|
+
* `oneplay`, or a project store that reuses its target name).
|
|
136
|
+
*/
|
|
137
|
+
export declare function resolveLegacyCommerceStoreId(target: string): StoreId;
|
|
138
|
+
/** The store a verify request names: its `store`, or the v1 mapping of its `target`. */
|
|
139
|
+
export declare function resolveCommerceStoreId(request: Pick<VerifyPurchaseRequest, 'target' | 'store'>): StoreId;
|
|
140
|
+
/**
|
|
141
|
+
* Builds the registry. Construction fails when two entries claim one schema,
|
|
142
|
+
* when a `finish: 'server'` entry has no finalizer, when two entries of one
|
|
143
|
+
* store disagree on `finish`, or when more than one entry of a store accepts
|
|
144
|
+
* a missing envelope.
|
|
145
|
+
*/
|
|
146
|
+
export declare function createCommerceEvidenceRegistry(entries: readonly CommerceEvidenceRegistryEntry[], options?: CreateCommerceEvidenceRegistryOptions): CommerceEvidenceRegistry;
|
|
147
|
+
/** The ledger target each reference store's verify requests name (RFC "Open store ids"). */
|
|
148
|
+
export declare const referenceCommerceLedgerTargets: Readonly<{
|
|
149
|
+
'google-play': readonly string[];
|
|
150
|
+
'app-store': readonly string[];
|
|
151
|
+
'microsoft-store': readonly string[];
|
|
152
|
+
'apps-in-toss': readonly string[];
|
|
153
|
+
devvit: readonly string[];
|
|
154
|
+
verse8: readonly string[];
|
|
155
|
+
}>;
|
|
156
|
+
/** The RFC profile purchase flags of the reference stores. */
|
|
157
|
+
export declare const referenceCommercePurchaseCapabilities: Readonly<{
|
|
158
|
+
'google-play': Readonly<{
|
|
159
|
+
consumable: true;
|
|
160
|
+
durable: true;
|
|
161
|
+
subscription: false;
|
|
162
|
+
}>;
|
|
163
|
+
'app-store': Readonly<{
|
|
164
|
+
consumable: true;
|
|
165
|
+
durable: true;
|
|
166
|
+
subscription: false;
|
|
167
|
+
}>;
|
|
168
|
+
'microsoft-store': Readonly<{
|
|
169
|
+
consumable: true;
|
|
170
|
+
durable: false;
|
|
171
|
+
subscription: false;
|
|
172
|
+
}>;
|
|
173
|
+
'apps-in-toss': Readonly<{
|
|
174
|
+
consumable: true;
|
|
175
|
+
durable: true;
|
|
176
|
+
subscription: false;
|
|
177
|
+
}>;
|
|
178
|
+
devvit: Readonly<{
|
|
179
|
+
consumable: true;
|
|
180
|
+
durable: true;
|
|
181
|
+
subscription: false;
|
|
182
|
+
}>;
|
|
183
|
+
verse8: Readonly<{
|
|
184
|
+
consumable: true;
|
|
185
|
+
durable: true;
|
|
186
|
+
subscription: false;
|
|
187
|
+
}>;
|
|
188
|
+
}>;
|
|
189
|
+
export declare const googlePlayCommerceStoreId: 'google-play';
|
|
190
|
+
export declare const appStoreCommerceStoreId: 'app-store';
|
|
191
|
+
export declare const microsoftStoreCommerceStoreId: 'microsoft-store';
|
|
192
|
+
export declare const appsInTossCommerceStoreId: 'apps-in-toss';
|
|
193
|
+
export declare const devvitCommerceStoreId: 'devvit';
|
|
194
|
+
export declare const verse8CommerceStoreId: 'verse8';
|
|
195
|
+
export declare const googlePlayCommerceEvidenceSchema: 'google-play.product-purchase.v2';
|
|
196
|
+
export declare const appStoreCommerceEvidenceSchema: 'app-store.signed-transaction.v1';
|
|
197
|
+
export declare const microsoftStoreCommerceEvidenceSchema: 'mpgd.microsoft-store.digital-goods.v1';
|
|
198
|
+
export declare const appsInTossCommerceEvidenceSchema: 'apps-in-toss.iap.callback.v1';
|
|
199
|
+
export declare const devvitPaymentOrderEvidenceSchema: 'devvit.payment-order.v1';
|
|
200
|
+
export declare const devvitOrderEvidenceSchema: 'devvit.order.v1';
|
|
201
|
+
export declare const verse8Agent8EventEvidenceSchema: 'verse8.agent8-event.v1';
|
|
202
|
+
/**
|
|
203
|
+
* `google-play.product-purchase.v2`: the Play boundary verifies the purchase
|
|
204
|
+
* token and, after the ledger grant, acknowledges or consumes it
|
|
205
|
+
* (`finish: 'server'`). Pass `createGooglePlayProductPurchaseBoundary(...)`,
|
|
206
|
+
* or a verifier binding plus a separate finalizer.
|
|
207
|
+
*/
|
|
208
|
+
export declare function createGooglePlayCommerceEvidenceEntry(input: {
|
|
209
|
+
readonly verifier: Pick<GameServicesEvidenceVerifier, 'verifyPurchase'>;
|
|
210
|
+
/** Required for `finish: 'server'` (the default). */
|
|
211
|
+
readonly finalizer?: GameServicesPurchaseGrantFinalizer;
|
|
212
|
+
/** Route a token-less request to the verifier too; the Play boundary rejects one itself. */
|
|
213
|
+
readonly acceptsMissingEvidence?: boolean;
|
|
214
|
+
/** Route any schema of the store to the verifier (a binding that keeps its own list). */
|
|
215
|
+
readonly acceptsUnclaimedSchemas?: boolean;
|
|
216
|
+
/** Who finishes; `client` only for a verifier that acknowledges the purchase itself. */
|
|
217
|
+
readonly finish?: Extract<CommerceFinishOwner, 'server' | 'client'>;
|
|
218
|
+
readonly targets?: readonly string[];
|
|
219
|
+
}): CommerceEvidenceRegistryEntry;
|
|
220
|
+
/**
|
|
221
|
+
* `app-store.signed-transaction.v1`: the App Store verifier checks the
|
|
222
|
+
* StoreKit JWS offline and decides on the Server API status; a request
|
|
223
|
+
* without the envelope keeps the `Get Transaction Info` lookup, so the entry
|
|
224
|
+
* accepts a missing envelope. The client finishes after the ledger grant.
|
|
225
|
+
*/
|
|
226
|
+
export declare function createAppStoreCommerceEvidenceEntry(input: {
|
|
227
|
+
readonly verifier: Pick<GameServicesEvidenceVerifier, 'verifyPurchase'>;
|
|
228
|
+
/** Defaults to true: a request without the JWS keeps the Server API lookup. */
|
|
229
|
+
readonly acceptsMissingEvidence?: boolean;
|
|
230
|
+
readonly acceptsUnclaimedSchemas?: boolean;
|
|
231
|
+
readonly targets?: readonly string[];
|
|
232
|
+
}): CommerceEvidenceRegistryEntry;
|
|
233
|
+
/**
|
|
234
|
+
* `mpgd.microsoft-store.digital-goods.v1`: the Collections verifier before
|
|
235
|
+
* the grant and the consume finalizer after it (`finish: 'server'`), always
|
|
236
|
+
* configured together.
|
|
237
|
+
*/
|
|
238
|
+
export declare function createMicrosoftStoreCommerceEvidenceEntry(input: {
|
|
239
|
+
readonly verifier: Pick<GameServicesEvidenceVerifier, 'verifyPurchase'>;
|
|
240
|
+
readonly finalizer: GameServicesPurchaseGrantFinalizer;
|
|
241
|
+
readonly acceptsMissingEvidence?: boolean;
|
|
242
|
+
readonly acceptsUnclaimedSchemas?: boolean;
|
|
243
|
+
readonly targets?: readonly string[];
|
|
244
|
+
}): CommerceEvidenceRegistryEntry;
|
|
245
|
+
/**
|
|
246
|
+
* `apps-in-toss.iap.callback.v1`: the production evidence verifier binds the
|
|
247
|
+
* order through the partner API; the host finishes (`completeProductGrant`)
|
|
248
|
+
* after the ledger grant.
|
|
249
|
+
*/
|
|
250
|
+
export declare function createAppsInTossCommerceEvidenceEntry(input: {
|
|
251
|
+
readonly verifier: Pick<GameServicesEvidenceVerifier, 'verifyPurchase'>;
|
|
252
|
+
readonly acceptsMissingEvidence?: boolean;
|
|
253
|
+
readonly acceptsUnclaimedSchemas?: boolean;
|
|
254
|
+
readonly targets?: readonly string[];
|
|
255
|
+
}): CommerceEvidenceRegistryEntry;
|
|
256
|
+
export interface DevvitPaymentOrderAuthorityInput {
|
|
257
|
+
readonly orderId: string;
|
|
258
|
+
readonly playerId: string;
|
|
259
|
+
readonly platformSku: string;
|
|
260
|
+
readonly signal: AbortSignal;
|
|
261
|
+
}
|
|
262
|
+
/** A Reddit order as the deployment's payments authority reports it. */
|
|
263
|
+
export interface DevvitPaymentOrderRecord {
|
|
264
|
+
readonly orderId: string;
|
|
265
|
+
/** The purchasing Reddit account as the payments authority knows it. */
|
|
266
|
+
readonly playerId: string;
|
|
267
|
+
readonly sku: string;
|
|
268
|
+
readonly status: 'PAID' | 'DELIVERED' | 'REVERTED' | string;
|
|
269
|
+
/** ISO timestamp of the status change. */
|
|
270
|
+
readonly occurredAt?: string;
|
|
271
|
+
}
|
|
272
|
+
export type DevvitPaymentOrderAuthorityResult = {
|
|
273
|
+
readonly decision: 'resolved';
|
|
274
|
+
readonly order: DevvitPaymentOrderRecord;
|
|
275
|
+
} | {
|
|
276
|
+
readonly decision: 'pending';
|
|
277
|
+
readonly reason?: string;
|
|
278
|
+
} | {
|
|
279
|
+
readonly decision: 'rejected';
|
|
280
|
+
readonly reason: string;
|
|
281
|
+
};
|
|
282
|
+
/**
|
|
283
|
+
* Game-owned port the `devvit.payment-order.v1` verifier binds an order
|
|
284
|
+
* through: the Devvit `payments` plugin's order read on the Devvit server, or
|
|
285
|
+
* the fulfillment handler's own order when the backend runs in that process.
|
|
286
|
+
* It is the authority; the envelope only names the order.
|
|
287
|
+
*/
|
|
288
|
+
export interface DevvitPaymentOrderAuthority {
|
|
289
|
+
getOrder(input: DevvitPaymentOrderAuthorityInput): Promise<DevvitPaymentOrderAuthorityResult>;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* The `devvit.payment-order.v1` verifier: the envelope
|
|
293
|
+
* `normalizeDevvitFulfillmentOrder` produced names the order, and the grant
|
|
294
|
+
* is decided by the deployment's payments authority (`PAID` or `DELIVERED`
|
|
295
|
+
* for the requesting player and SKU). Replay identity is the order id, so a
|
|
296
|
+
* second fulfillment of one order meets the first grant.
|
|
297
|
+
*/
|
|
298
|
+
export declare function createDevvitPaymentOrderEvidenceVerifier(input: {
|
|
299
|
+
readonly authority: DevvitPaymentOrderAuthority;
|
|
300
|
+
readonly now?: () => string;
|
|
301
|
+
}): Pick<GameServicesEvidenceVerifier, 'verifyPurchase'>;
|
|
302
|
+
/** `devvit.payment-order.v1`: the fulfillment handler's own record, bound through the payments authority. */
|
|
303
|
+
export declare function createDevvitPaymentOrderCommerceEvidenceEntry(input: {
|
|
304
|
+
readonly authority: DevvitPaymentOrderAuthority;
|
|
305
|
+
readonly now?: () => string;
|
|
306
|
+
readonly targets?: readonly string[];
|
|
307
|
+
}): CommerceEvidenceRegistryEntry;
|
|
308
|
+
export interface CreateCommerceLedgerLookupVerifierInput {
|
|
309
|
+
readonly schema: string;
|
|
310
|
+
readonly store: StoreId;
|
|
311
|
+
/** The ledger the host's fulfillment path writes. */
|
|
312
|
+
readonly ledger: GameServicesStore;
|
|
313
|
+
/** The store transaction id the envelope names; `undefined` rejects the envelope. */
|
|
314
|
+
readonly readTransactionId: (payload: EntitlementLedgerPayload) => string | undefined;
|
|
315
|
+
/** The store SKU the envelope names, compared with the catalog's platform product id when present. */
|
|
316
|
+
readonly readStoreSku?: (payload: EntitlementLedgerPayload) => string | undefined;
|
|
317
|
+
/** The ledger target the fulfillment path wrote the grant under; defaults to the request's target. */
|
|
318
|
+
readonly ledgerTarget?: string;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* A server-push lookup verifier (RFC "Evidence registry"): it never grants
|
|
322
|
+
* from the client envelope. It answers `settled` with the ledger entry the
|
|
323
|
+
* host's fulfillment path already wrote for the same store and transaction
|
|
324
|
+
* id, when that entry belongs to the requesting player and product and is
|
|
325
|
+
* not reversed; `pending` while no such entry exists; and `rejected` when the
|
|
326
|
+
* envelope names another transaction or product than the request, or the
|
|
327
|
+
* entry belongs to someone else.
|
|
328
|
+
*/
|
|
329
|
+
export declare function createCommerceLedgerLookupVerifier(input: CreateCommerceLedgerLookupVerifierInput): Pick<GameServicesEvidenceVerifier, 'verifyPurchase'>;
|
|
330
|
+
/** The purchase grant written under a ledger target and store transaction id, through the store's index or a list scan. */
|
|
331
|
+
export declare function findPurchaseGrantByPlatformEvidence(ledger: GameServicesStore, identity: {
|
|
332
|
+
readonly target: string;
|
|
333
|
+
readonly platformEvidenceId: string;
|
|
334
|
+
}): Promise<ProductGrantTransaction | undefined>;
|
|
335
|
+
/**
|
|
336
|
+
* `devvit.order.v1`: the client's order envelope (a checkout result or the
|
|
337
|
+
* paid-order list) looked up against the ledger the fulfillment handler
|
|
338
|
+
* wrote under target `reddit` (`createPlatformOrderLedgerGrant`).
|
|
339
|
+
*/
|
|
340
|
+
export declare function createDevvitOrderLookupCommerceEvidenceEntry(input: {
|
|
341
|
+
readonly ledger: GameServicesStore;
|
|
342
|
+
/** Defaults to the request target, which `targets` pins to `reddit`. */
|
|
343
|
+
readonly ledgerTarget?: string;
|
|
344
|
+
readonly targets?: readonly string[];
|
|
345
|
+
}): CommerceEvidenceRegistryEntry;
|
|
346
|
+
/**
|
|
347
|
+
* `verse8.agent8-event.v1`: the client's Agent8 purchase envelope looked up
|
|
348
|
+
* against the ledger the `$onItemPurchased` event wrote under target `verse8`
|
|
349
|
+
* (`createServerPushLedgerGrant`; the Agent8 commerce service writes it when
|
|
350
|
+
* given a ledger).
|
|
351
|
+
*/
|
|
352
|
+
export declare function createVerse8Agent8EventLookupCommerceEvidenceEntry(input: {
|
|
353
|
+
readonly ledger: GameServicesStore;
|
|
354
|
+
readonly ledgerTarget?: string;
|
|
355
|
+
readonly targets?: readonly string[];
|
|
356
|
+
}): CommerceEvidenceRegistryEntry;
|
|
357
|
+
export interface CreateServerPushLedgerGrantInput {
|
|
358
|
+
readonly store: StoreId;
|
|
359
|
+
/** The ledger target the lookup verifier reads under (`reddit`, `verse8`). */
|
|
360
|
+
readonly target: string;
|
|
361
|
+
readonly deploymentTarget?: string;
|
|
362
|
+
readonly playerId: string;
|
|
363
|
+
readonly product: ProductCatalog['products'][number];
|
|
364
|
+
readonly platformProductId: string;
|
|
365
|
+
/** The store transaction id (a Reddit order id, an Agent8 purchase id). */
|
|
366
|
+
readonly transactionId: string;
|
|
367
|
+
/** Units bought in one transaction; a currency or resource grant is scaled by it. Default 1. */
|
|
368
|
+
readonly quantity?: number;
|
|
369
|
+
readonly purchasedAt: string;
|
|
370
|
+
readonly grantedAt: string;
|
|
371
|
+
/** The host's own evidence (`devvit.payment-order.v1`, `verse8.agent8-event.v1`). */
|
|
372
|
+
readonly evidence: PlatformEvidenceEnvelope;
|
|
373
|
+
/** Defaults to the reconciler's derived key `store:<store>:<transactionId>`. */
|
|
374
|
+
readonly idempotencyKey?: string;
|
|
375
|
+
/** Defaults to `<store>:<schema>:<transactionId>`. */
|
|
376
|
+
readonly evidenceVerificationId?: string;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* The ledger grant a host's fulfillment path writes for a server-push
|
|
380
|
+
* purchase, in the shape the lookup verifiers read: `payload.target`,
|
|
381
|
+
* `payload.store`, and `payload.platformTransactionId` identify it, and the
|
|
382
|
+
* platform-evidence unique index keeps a second write of the same transaction
|
|
383
|
+
* out. Write it with `GameServicesStore.recordEntitlementGrant`.
|
|
384
|
+
*/
|
|
385
|
+
export declare function createServerPushLedgerGrant(input: CreateServerPushLedgerGrantInput): EntitlementLedgerGrant;
|
|
386
|
+
export type CommerceServiceAlignment = {
|
|
387
|
+
readonly status: 'aligned';
|
|
388
|
+
readonly store: StoreId;
|
|
389
|
+
} | {
|
|
390
|
+
readonly status: 'configuration-required';
|
|
391
|
+
readonly store: StoreId;
|
|
392
|
+
readonly reason: 'STORE_NOT_ACCEPTED' | 'FINISH_OWNER_MISMATCH' | 'PROTOCOL_VERSION_MISMATCH';
|
|
393
|
+
readonly message: string;
|
|
394
|
+
};
|
|
395
|
+
/**
|
|
396
|
+
* Compares a provider's capability block with the backend's published
|
|
397
|
+
* capabilities (RFC "Provider capabilities endpoint"): a store the backend
|
|
398
|
+
* does not accept, a finish owner that disagrees, or another protocol major
|
|
399
|
+
* version sets the provider's availability to `configuration-required`
|
|
400
|
+
* before any purchase UI opens. The reconciler applies it at start.
|
|
401
|
+
*/
|
|
402
|
+
export declare function compareCommerceServiceCapabilities(input: {
|
|
403
|
+
readonly store: StoreId;
|
|
404
|
+
readonly provider: Pick<CommerceCapabilities, 'lifecycle'>;
|
|
405
|
+
readonly service: CommerceServiceCapabilities;
|
|
406
|
+
}): CommerceServiceAlignment;
|