@voltro/plugin-economy 0.0.0-stage → 0.88.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.
Files changed (177) hide show
  1. package/CHANGELOG.md +24492 -0
  2. package/LICENSE +61 -0
  3. package/README.md +2719 -2
  4. package/SECURITY.md +56 -0
  5. package/THIRD-PARTY-NOTICES.md +9841 -0
  6. package/dist/amount.js +20 -0
  7. package/dist/appleIap.server.js +262 -0
  8. package/dist/appleIapNotifications.server.js +162 -0
  9. package/dist/appleIapTrust.server.js +30 -0
  10. package/dist/bundleValue.server.js +112 -0
  11. package/dist/canonicalDataJson.js +10 -0
  12. package/dist/capture.js +53 -0
  13. package/dist/codePort.fixture.js +123 -0
  14. package/dist/codeStore.server.js +439 -0
  15. package/dist/codeTables.entity.js +43 -0
  16. package/dist/codes.d.ts +150 -0
  17. package/dist/codes.js +82 -0
  18. package/dist/components.d.ts +397 -0
  19. package/dist/components.js +283 -0
  20. package/dist/consistency.server.js +115 -0
  21. package/dist/containerStore.server.js +687 -0
  22. package/dist/containerStore.testFixtures.js +75 -0
  23. package/dist/containerTables.entity.js +45 -0
  24. package/dist/containers.d.ts +311 -0
  25. package/dist/containers.fixture.js +128 -0
  26. package/dist/containers.js +214 -0
  27. package/dist/containers.server.js +39 -0
  28. package/dist/containersPort.fixture.js +74 -0
  29. package/dist/currency.js +32 -0
  30. package/dist/declarationFixtures.js +61 -0
  31. package/dist/economy-app/events/economy.refundReversed.event.ts +1 -0
  32. package/dist/economy-app/events/economy.refunded.event.ts +1 -0
  33. package/dist/economyPort.fixture.js +124 -0
  34. package/dist/errors.d.ts +14 -0
  35. package/dist/errors.js +21 -0
  36. package/dist/events.d.ts +46 -0
  37. package/dist/events.js +1 -0
  38. package/dist/googleIap.server.js +391 -0
  39. package/dist/googleIapNotifications.server.js +130 -0
  40. package/dist/googleIapSubscription.server.js +183 -0
  41. package/dist/iap.d.ts +309 -0
  42. package/dist/iap.js +303 -0
  43. package/dist/iap.testFixtures.js +144 -0
  44. package/dist/iapAccountTables.entity.js +39 -0
  45. package/dist/iapAccounts.server.js +200 -0
  46. package/dist/iapBinding.server.js +523 -0
  47. package/dist/iapCheckout.server.js +97 -0
  48. package/dist/iapCompletion.server.js +55 -0
  49. package/dist/iapCurrentState.server.js +107 -0
  50. package/dist/iapCurrentState.testFixtures.js +22 -0
  51. package/dist/iapCurrentStatePort.fixture.js +63 -0
  52. package/dist/iapEntitlements.d.ts +79 -0
  53. package/dist/iapEntitlements.js +57 -0
  54. package/dist/iapEntitlements.server.js +48 -0
  55. package/dist/iapEntitlementsBinding.server.js +105 -0
  56. package/dist/iapEntitlementsPort.fixture.js +80 -0
  57. package/dist/iapInstalledEntitlements.testFixtures.js +75 -0
  58. package/dist/iapInstalledNotifications.testFixtures.js +93 -0
  59. package/dist/iapInventoryRefunds.server.js +261 -0
  60. package/dist/iapNotificationCustodyPort.fixture.js +67 -0
  61. package/dist/iapNotificationPort.fixture.js +73 -0
  62. package/dist/iapNotificationProcessor.server.js +134 -0
  63. package/dist/iapNotificationProcessor.testFixtures.js +63 -0
  64. package/dist/iapNotificationProcessorPort.fixture.js +55 -0
  65. package/dist/iapNotificationSchedule.server.js +69 -0
  66. package/dist/iapNotificationStore.server.js +352 -0
  67. package/dist/iapNotificationStore.testFixtures.js +31 -0
  68. package/dist/iapNotificationTables.entity.js +48 -0
  69. package/dist/iapNotificationTarget.server.js +36 -0
  70. package/dist/iapNotificationTarget.testFixtures.js +29 -0
  71. package/dist/iapNotifications.d.ts +644 -0
  72. package/dist/iapNotifications.js +6 -0
  73. package/dist/iapNotifications.server.js +95 -0
  74. package/dist/iapNotificationsBinding.server.js +232 -0
  75. package/dist/iapNotificationsSystemPort.fixture.js +50 -0
  76. package/dist/iapPlugin.testFixtures.js +59 -0
  77. package/dist/iapPort.fixture.js +74 -0
  78. package/dist/iapProviderCapture.server.js +17 -0
  79. package/dist/iapRecovery.d.ts +146 -0
  80. package/dist/iapRecovery.js +89 -0
  81. package/dist/iapRefundEventDelivery.server.js +82 -0
  82. package/dist/iapRefundEvents.js +44 -0
  83. package/dist/iapRefundEventsPort.fixture.js +59 -0
  84. package/dist/iapRefundPort.fixture.js +54 -0
  85. package/dist/iapRefundTables.entity.js +55 -0
  86. package/dist/iapRefunds.d.ts +755 -0
  87. package/dist/iapRefunds.js +6 -0
  88. package/dist/iapRefunds.server.js +553 -0
  89. package/dist/iapRefunds.testFixtures.js +64 -0
  90. package/dist/iapSpendAdmission.server.js +98 -0
  91. package/dist/iapStore.server.js +740 -0
  92. package/dist/iapStore.testFixtures.js +127 -0
  93. package/dist/iapTables.entity.js +80 -0
  94. package/dist/iapVerification.server.js +120 -0
  95. package/dist/index.d.ts +2984 -0
  96. package/dist/index.js +15 -0
  97. package/dist/intentionRecovery.js +133 -0
  98. package/dist/ledger.js +77 -0
  99. package/dist/loyalty.d.ts +274 -0
  100. package/dist/loyalty.fixture.js +92 -0
  101. package/dist/loyalty.js +311 -0
  102. package/dist/loyaltyBinding.server.js +203 -0
  103. package/dist/loyaltyPort.fixture.js +86 -0
  104. package/dist/loyaltyShopSource.server.js +90 -0
  105. package/dist/loyaltyStore.server.js +552 -0
  106. package/dist/loyaltyStore.testFixtures.js +82 -0
  107. package/dist/loyaltyTables.entity.js +49 -0
  108. package/dist/offerMerchandising.fixture.js +114 -0
  109. package/dist/offerMerchandising.js +282 -0
  110. package/dist/offerPolicies.d.ts +441 -0
  111. package/dist/offerPolicies.fixture.js +53 -0
  112. package/dist/offerPolicies.js +267 -0
  113. package/dist/piggyBanks.d.ts +272 -0
  114. package/dist/piggyBanks.fixture.js +70 -0
  115. package/dist/piggyBanks.js +200 -0
  116. package/dist/piggyBinding.server.js +204 -0
  117. package/dist/piggyPort.fixture.js +72 -0
  118. package/dist/piggyStore.server.js +610 -0
  119. package/dist/piggyStore.testFixtures.js +97 -0
  120. package/dist/piggyTables.entity.js +40 -0
  121. package/dist/plugin.js +1047 -0
  122. package/dist/port.js +12 -0
  123. package/dist/price.d.ts +99 -0
  124. package/dist/price.js +143 -0
  125. package/dist/purchaseRecovery.js +55 -0
  126. package/dist/reports.server.js +114 -0
  127. package/dist/rpc.d.ts +3201 -0
  128. package/dist/rpc.js +1200 -0
  129. package/dist/sanctionsTradeAuthority.server.js +79 -0
  130. package/dist/server.d.ts +3856 -0
  131. package/dist/server.js +43 -0
  132. package/dist/shop.d.ts +279 -0
  133. package/dist/shop.js +195 -0
  134. package/dist/shop.testFixtures.js +113 -0
  135. package/dist/shopPort.fixture.js +71 -0
  136. package/dist/shopPresentation.js +67 -0
  137. package/dist/shopStore.server.js +623 -0
  138. package/dist/shopTables.entity.js +62 -0
  139. package/dist/shopUiCopy.js +56 -0
  140. package/dist/spendLimits.d.ts +140 -0
  141. package/dist/spendLimits.fixture.js +52 -0
  142. package/dist/spendLimits.js +154 -0
  143. package/dist/spendLimitsPort.fixture.js +119 -0
  144. package/dist/subscriptionBinding.server.js +210 -0
  145. package/dist/subscriptionStore.server.js +642 -0
  146. package/dist/subscriptionStore.testFixtures.js +71 -0
  147. package/dist/subscriptionTables.entity.js +36 -0
  148. package/dist/subscriptions.d.ts +394 -0
  149. package/dist/subscriptions.fixture.js +96 -0
  150. package/dist/subscriptions.js +212 -0
  151. package/dist/subscriptionsPort.fixture.js +75 -0
  152. package/dist/systemFixtures.js +88 -0
  153. package/dist/tables.entity.js +82 -0
  154. package/dist/testing.d.ts +4615 -0
  155. package/dist/testing.js +29 -0
  156. package/dist/tradeAuthority.server.js +171 -0
  157. package/dist/tradeBinding.server.js +200 -0
  158. package/dist/tradeComponents.js +341 -0
  159. package/dist/tradeEscrow.server.js +231 -0
  160. package/dist/tradeEscrow.testFixtures.js +132 -0
  161. package/dist/tradeExpiry.server.js +42 -0
  162. package/dist/tradeRecovery.js +47 -0
  163. package/dist/tradeStore.server.js +749 -0
  164. package/dist/tradeStore.testFixtures.js +72 -0
  165. package/dist/tradeTables.entity.js +65 -0
  166. package/dist/tradeUiCopy.js +78 -0
  167. package/dist/trades.d.ts +246 -0
  168. package/dist/trades.fixture.js +102 -0
  169. package/dist/trades.js +288 -0
  170. package/dist/tradesPort.fixture.js +93 -0
  171. package/dist/walletEscrow.js +105 -0
  172. package/dist/walletEscrow.server.js +375 -0
  173. package/dist/walletKeys.server.js +4 -0
  174. package/dist/walletStore.js +570 -0
  175. package/dist/web.d.ts +2257 -0
  176. package/dist/web.js +8 -0
  177. package/package.json +161 -4
@@ -0,0 +1,740 @@
1
+ import { EconomyError as e, economyError as t } from "./errors.js";
2
+ import { captureBoundMethods as n, dataList as r, dataObject as i, identifier as a } from "./capture.js";
3
+ import { positiveAmount as o } from "./amount.js";
4
+ import { captureCurrencies as s } from "./currency.js";
5
+ import { defineShopOffer as c, shopInteger as l } from "./shop.js";
6
+ import { captureIapObservation as u, captureIapOrderReceipt as d, captureIapSubscriptionPeriod as f, iapChannel as p, iapReceiptIntent as m, iapReceiptReference as h, iapTimestamp as g } from "./iap.js";
7
+ import { canonicalDataJson as _ } from "./canonicalDataJson.js";
8
+ import { prepareVerifiedIapNotification as v, readVerifiedIapNotification as y, validateVerifiedIapNotification as b } from "./iapNotifications.server.js";
9
+ import { captureIapNotificationTargetOptions as x, issueAcceptedIapNotificationTarget as S } from "./iapNotificationTarget.server.js";
10
+ import { readVerifiedIapCurrentState as C } from "./iapCurrentState.server.js";
11
+ import { captureIapTransactionFacts as w, readVerifiedIapPurchase as T } from "./iapVerification.server.js";
12
+ import { iapNamespacesTable as E, iapOrdersTable as D, iapReceiptsTable as O, iapSubjectsTable as k } from "./iapTables.entity.js";
13
+ import { issueAcceptedIapCompletion as ee } from "./iapCompletion.server.js";
14
+ import { Effect as A, Result as j } from "effect";
15
+ import { systemSubject as te } from "@voltro/protocol";
16
+ import { createHash as M } from "node:crypto";
17
+ import { and as ne, eq as N, queryFor as P } from "@voltro/database";
18
+ import { executeSqlMutations as re, prepareSqlMutation as ie, prepareSqlMutationGroup as ae } from "@voltro/database/sql";
19
+ import { InventoryError as F } from "@voltro/plugin-inventory/errors";
20
+ // src/iapStore.server.ts
21
+ var I = (e) => {
22
+ let t = n(e, ["prepare"]), r = typeof e == "object" && e && "checkout" in e && e.checkout !== void 0 ? n(e, ["checkout"]).checkout : void 0;
23
+ return Object.freeze({
24
+ prepare: t.prepare,
25
+ ...r ? { checkout: r } : {}
26
+ });
27
+ }, L = (e) => M("sha256").update(_(e)).digest("hex"), R = (e, ...t) => e + L(t).slice(0, 56), z = (n) => n instanceof e ? n : n instanceof F && [
28
+ "invalid_input",
29
+ "invalid_record",
30
+ "not_found",
31
+ "erased",
32
+ "forbidden",
33
+ "conflict",
34
+ "limit_exceeded"
35
+ ].includes(n.code) ? t(n.code) : t("unavailable"), B = (e) => A.tryPromise({
36
+ try: e,
37
+ catch: z
38
+ }), V = (e) => {
39
+ try {
40
+ return e();
41
+ } catch (e) {
42
+ return A.fail(z(e));
43
+ }
44
+ }, H = async (e) => {
45
+ let t = await A.runPromise(e.pipe(A.result));
46
+ if (j.isFailure(t)) throw t.failure;
47
+ return t.success;
48
+ }, U = (e) => g(e instanceof Date ? e.getTime() : typeof e == "string" ? Date.parse(e) : NaN), W = (e) => l(e, 0, 2147483647), oe = class extends Error {
49
+ constructor() {
50
+ super("Accepted IAP original"), this.name = "IapOriginal";
51
+ }
52
+ }, se = (e) => {
53
+ let r = i(e, [
54
+ "realMoney",
55
+ "namespace",
56
+ "currencies",
57
+ "verification",
58
+ "admission",
59
+ "economy",
60
+ "inventory",
61
+ "refundDisposition",
62
+ "systemAccount",
63
+ "maxHistoryRows",
64
+ "now"
65
+ ]);
66
+ if (r.realMoney !== !0) throw t(r.realMoney === !1 ? "real_money_disabled" : "invalid_input");
67
+ let o = r.now ?? Date.now;
68
+ if (typeof o != "function") throw t("invalid_input");
69
+ return Object.freeze({
70
+ namespace: a(r.namespace),
71
+ currencies: s(r.currencies),
72
+ verification: n(r.verification, ["verify"]),
73
+ admission: I(r.admission),
74
+ economy: n(r.economy, ["prepareTransfer"]),
75
+ inventory: r.inventory === void 0 ? void 0 : n(r.inventory, ["prepareGrant"]),
76
+ refundDisposition: r.refundDisposition === void 0 ? void 0 : n(r.refundDisposition, ["read"]),
77
+ systemAccount: a(r.systemAccount),
78
+ maxHistoryRows: l(r.maxHistoryRows ?? 1e4, 1, 1e5),
79
+ now: o
80
+ });
81
+ }, G = (e, n) => {
82
+ let j = se(n), M = j.namespace, F = j.maxHistoryRows, I = R("ein_", M), z = (e, t) => R("eis_", M, e, t), G = (e, t, n) => R("eio_", M, e, t, n), K = (e) => "eir_" + e.slice(0, 56), q = () => g(j.now()), ce = te("economy.iap"), J = (e) => {
83
+ if (e.type !== "user") throw t("forbidden");
84
+ return Object.freeze({
85
+ tenantId: a(e.tenantId),
86
+ ownerId: a(e.id)
87
+ });
88
+ }, le = async (t) => {
89
+ await e.insertIgnore(E.tableName, {
90
+ id: I,
91
+ namespace: M,
92
+ admission: 0,
93
+ ordersCount: 0,
94
+ receiptsCount: 0
95
+ }, { conflictColumns: ["id"] }), await e.insertIgnore(k.tableName, {
96
+ id: z(t.tenantId, t.ownerId),
97
+ namespace: M,
98
+ tenantId: t.tenantId,
99
+ ownerId: t.ownerId,
100
+ erased: !1,
101
+ admission: 0,
102
+ ordersCount: 0
103
+ }, { conflictColumns: ["id"] });
104
+ }, Y = async (e) => {
105
+ if (await e.updateMany(E.tableName, { admission: 0 }, { where: N("id", I) }) !== 1) throw t("unavailable");
106
+ let n = (await e.query(P(E).where(N("id", I)).limit(1).descriptor))[0];
107
+ if (!n || n.namespace !== M || n.admission !== 0) throw t("invalid_record");
108
+ return W(n.ordersCount), W(n.receiptsCount), n;
109
+ }, X = async (e, n, r = !1) => {
110
+ let i = (await e.query(P(k).where(N("id", z(n.tenantId, n.ownerId))).limit(1).descriptor))[0];
111
+ if (i) {
112
+ if (i.namespace !== M || i.tenantId !== n.tenantId || i.admission !== 0 || i.erased !== !0 && i.erased !== !1 || (i.erased ? i.ownerId !== null : i.ownerId !== n.ownerId)) throw t("invalid_record");
113
+ if (W(i.ordersCount), i.erased === !0 && !r) throw t("erased");
114
+ return i;
115
+ }
116
+ }, Z = async (e, n, r = !1) => {
117
+ if (await e.updateMany(k.tableName, { admission: 0 }, { where: N("id", z(n.tenantId, n.ownerId)) }) !== 1) throw t("unavailable");
118
+ let i = await X(e, n, r);
119
+ if (!i) throw t("invalid_record");
120
+ return i;
121
+ }, ue = async (e, n, r) => {
122
+ let i = await e.query(P(n).where(r).limit(F + 1).descriptor);
123
+ if (i.length > F) throw t("limit_exceeded");
124
+ return i;
125
+ }, de = async (e, n) => {
126
+ let r = await ue(e, D, N("namespace", M)), i = await ue(e, O, N("namespace", M));
127
+ if (r.length !== W(n.ordersCount) || i.length !== W(n.receiptsCount)) throw t("invalid_record");
128
+ for (let e of r) {
129
+ if (a(e.offerId), a(e.offerVersion), p(e.channel), typeof e.configurationDigest != "string" || !/^[a-f0-9]{64}$/.test(e.configurationDigest) || e.namespace !== M || typeof e.accepted != "boolean" || ![
130
+ "pending",
131
+ "fulfilled",
132
+ "erased"
133
+ ].includes(String(e.state)) || typeof e.ownerKey != "string" || !/^eis_[a-f0-9]{56}$/.test(e.ownerKey) || (e.state === "erased" ? e.ownerId !== null || e.intentDigest !== null || e.snapshot !== null || e.receipt !== null : e.ownerKey !== z(a(e.tenantId), a(e.ownerId)))) throw t("invalid_record");
134
+ if (e.accepted) {
135
+ if (l(e.acceptedQuantity, 1, 1e3), l(e.acceptedDay, 0, 1e8), e.state === "pending" || e.fulfilledAt === null || e.acceptedDay !== Math.floor(U(e.fulfilledAt) / 864e5)) throw t("invalid_record");
136
+ } else if (e.acceptedQuantity !== null || e.acceptedDay !== null || e.fulfilledAt !== null || e.state === "fulfilled") throw t("invalid_record");
137
+ let n = i.find((t) => t.id === e.receiptKey);
138
+ if (!n || n.orderKey !== e.id || n.tenantId !== e.tenantId || n.ownerKey !== e.ownerKey || n.accepted !== e.accepted || n.state !== e.state || (e.fulfilledAt === null ? n.fulfilledAt !== null : U(e.fulfilledAt) !== U(n.fulfilledAt))) throw t("invalid_record");
139
+ }
140
+ for (let e of i) if (e.namespace !== M || typeof e.identity != "string" || !/^[a-f0-9]{64}$/.test(e.identity) || e.id !== K(e.identity) || typeof e.factsDigest != "string" || !/^[a-f0-9]{64}$/.test(e.factsDigest) || !r.some((t) => t.id === e.orderKey && t.receiptKey === e.id)) throw t("invalid_record");
141
+ return {
142
+ orders: r,
143
+ receipts: i
144
+ };
145
+ }, Q = async (e, n, r) => {
146
+ let i = (await e.query(P(D).where(N("id", r)).limit(1).descriptor))[0];
147
+ if (i && (i.namespace !== M || i.tenantId !== n.tenantId || i.ownerKey !== z(n.tenantId, n.ownerId))) throw t("invalid_record");
148
+ return i;
149
+ }, $ = async (e, n) => {
150
+ if (n.state !== "fulfilled" || n.accepted !== !0 || typeof n.ownerId != "string") throw t("invalid_record");
151
+ let u = i(n.snapshot, [
152
+ "scope",
153
+ "requestId",
154
+ "intentDigest",
155
+ "identity",
156
+ "product",
157
+ "currencies",
158
+ "facts",
159
+ "verifiedAt",
160
+ "at"
161
+ ], "invalid_record"), f = i(u.scope, ["tenantId", "ownerId"], "invalid_record"), p = i(u.product, [
162
+ "offer",
163
+ "channel",
164
+ "kind",
165
+ "storeProductId"
166
+ ], "invalid_record"), m = s(u.currencies), h = c(p.offer, m, !0, { grantless: p.kind === "subscription" }), v = w(u.facts), y = g(u.at), b = g(u.verifiedAt), x = L([
167
+ v.channel,
168
+ v.environment,
169
+ v.applicationId,
170
+ v.transactionId
171
+ ]);
172
+ if (f.tenantId !== n.tenantId || f.ownerId !== n.ownerId || n.id !== G(a(f.tenantId), a(f.ownerId), a(u.requestId)) || n.ownerKey !== z(a(f.tenantId), a(f.ownerId)) || u.intentDigest !== n.intentDigest || typeof n.intentDigest != "string" || !/^[a-f0-9]{64}$/.test(n.intentDigest) || u.identity !== x || n.receiptKey !== K(x) || p.channel !== v.channel || p.kind !== v.kind || p.storeProductId !== v.storeProductId || v.quantity > h.maxQuantity || n.offerId !== h.id || n.offerVersion !== h.version || n.channel !== v.channel || n.configurationDigest !== L([p, m]) || n.acceptedQuantity !== v.quantity || n.acceptedDay !== Math.floor(y / 864e5) || y < b || b < v.purchasedAt || y < U(n.createdAt) || y !== U(n.fulfilledAt) || (h.price.kind === "real" ? h.price : h.price.kind === "mixed" ? h.price.real : null)?.storeProductIds[v.channel] !== v.storeProductId) throw t("invalid_record");
173
+ let S = (await e.query(P(O).where(N("id", K(x))).limit(1).descriptor))[0];
174
+ if (!S || S.identity !== x || S.factsDigest !== L(v) || S.namespace !== M || S.tenantId !== n.tenantId || S.ownerKey !== n.ownerKey || S.orderKey !== n.id || S.state !== "fulfilled" || S.accepted !== !0 || U(S.fulfilledAt) !== y) throw t("invalid_record");
175
+ let C = i(n.receipt, [
176
+ "orderId",
177
+ "offerId",
178
+ "offerVersion",
179
+ "quantity",
180
+ "at",
181
+ "pricePaid",
182
+ "transfers",
183
+ "grants"
184
+ ], "invalid_record");
185
+ if (C.orderId !== n.id || C.offerId !== h.id || C.offerVersion !== h.version || C.quantity !== v.quantity || C.at !== y || _(C.pricePaid) !== _(v.paid)) throw t("invalid_record");
186
+ let T = r(C.transfers, 16, "invalid_record").map((e, n) => {
187
+ let r = i(e, [
188
+ "txId",
189
+ "currency",
190
+ "amount",
191
+ "at"
192
+ ], "invalid_record"), s = h.currencies[n];
193
+ if (!s || r.currency !== s.currency || r.amount !== (BigInt(s.amount) * BigInt(v.quantity)).toString()) throw t("invalid_record");
194
+ return Object.freeze({
195
+ txId: a(r.txId),
196
+ currency: s.currency,
197
+ amount: o(r.amount).toString(),
198
+ at: l(r.at, b, y)
199
+ });
200
+ }), E = r(C.grants, 16, "invalid_record").map((e, n) => {
201
+ let o = i(e, [
202
+ "operationId",
203
+ "kind",
204
+ "changes",
205
+ "at"
206
+ ], "invalid_record"), s = h.items[n];
207
+ if (!s || o.kind !== "grant") throw t("invalid_record");
208
+ let c = r(o.changes, F, "invalid_record").map((e) => {
209
+ let t = i(e, ["instanceId", "delta"], "invalid_record");
210
+ return Object.freeze({
211
+ instanceId: a(t.instanceId),
212
+ delta: l(t.delta, 1, 1e6)
213
+ });
214
+ });
215
+ if (c.reduce((e, t) => e + t.delta, 0) !== s.qty * v.quantity || new Set(c.map((e) => e.instanceId)).size !== c.length) throw t("invalid_record");
216
+ return Object.freeze({
217
+ operationId: a(o.operationId),
218
+ kind: "grant",
219
+ changes: Object.freeze(c),
220
+ at: l(o.at, 0, y)
221
+ });
222
+ });
223
+ if (T.length !== h.currencies.length || E.length !== h.items.length || new Set(T.map((e) => e.txId)).size !== T.length || new Set(E.map((e) => e.operationId)).size !== E.length) throw t("invalid_record");
224
+ return d({
225
+ orderId: a(n.id),
226
+ offerId: h.id,
227
+ offerVersion: h.version,
228
+ quantity: v.quantity,
229
+ at: y,
230
+ pricePaid: v.paid,
231
+ transfers: T,
232
+ grants: E
233
+ });
234
+ }, fe = async (e, n, r) => {
235
+ let o = await $(e, n), l = i(n.snapshot, [
236
+ "scope",
237
+ "requestId",
238
+ "intentDigest",
239
+ "identity",
240
+ "product",
241
+ "currencies",
242
+ "facts",
243
+ "verifiedAt",
244
+ "at"
245
+ ], "invalid_record"), u = i(l.product, [
246
+ "offer",
247
+ "channel",
248
+ "kind",
249
+ "storeProductId"
250
+ ], "invalid_record"), d = s(l.currencies);
251
+ if (n.tenantId !== r.tenantId || n.ownerId !== r.ownerId) throw t("invalid_record");
252
+ return Object.freeze({
253
+ orderId: o.orderId,
254
+ scope: r,
255
+ receipt: o,
256
+ currencies: d,
257
+ facts: w(l.facts),
258
+ product: Object.freeze({
259
+ offer: c(u.offer, d, !0, { grantless: u.kind === "subscription" }),
260
+ channel: p(u.channel),
261
+ kind: u.kind,
262
+ storeProductId: a(u.storeProductId)
263
+ })
264
+ });
265
+ }, pe = async (n, r, i) => e.transactional(async (e) => {
266
+ await Y(e), await Z(e, n);
267
+ let a = await Q(e, n, r);
268
+ if (a) {
269
+ if (a.intentDigest !== i) throw t("conflict");
270
+ if (a.state === "fulfilled") return $(e, a);
271
+ if (a.state !== "pending" || a.accepted !== !1 || a.snapshot !== null || a.receipt !== null || a.fulfilledAt !== null) throw t("invalid_record");
272
+ }
273
+ }), me = (n, r) => V(() => {
274
+ let i = J(n), a = m(r), o = G(i.tenantId, i.ownerId, a.requestId), s = L([
275
+ M,
276
+ i,
277
+ a.channel,
278
+ a.offerId,
279
+ a.offerVersion,
280
+ a.requestId,
281
+ L(a.receipt)
282
+ ]);
283
+ return B(async () => {
284
+ await le(i);
285
+ let n = await pe(i, o, s);
286
+ if (n) return n;
287
+ try {
288
+ let n = T(await H(j.verification.verify(i, a)));
289
+ if (_(n.scope) !== _(i) || n.requestId !== a.requestId || n.offerId !== a.offerId || n.offerVersion !== a.offerVersion || n.facts.channel !== a.channel || _(n.currencies) !== _(j.currencies)) throw t("forbidden");
290
+ let { product: r, facts: c, identity: u, verifiedAt: d } = n, f = r.offer, p = q(), m = K(u), h = L([r, j.currencies]), g = L(c);
291
+ if (p < d || c.expiresAt !== null && c.expiresAt <= p || f.from !== null && p < f.from || f.until !== null && p >= f.until) throw t("forbidden");
292
+ if (f.items.length && !j.inventory) throw t("unavailable");
293
+ let v = await H(n.accounts.prepareBinding(i, c.channel, c.environment, n.accountToken)), y = await H(j.admission.prepare(Object.freeze({
294
+ scope: i,
295
+ product: r,
296
+ facts: c,
297
+ at: p
298
+ })));
299
+ await e.transactional(async (e) => {
300
+ let n = await Y(e), r = await Z(e, i), a = await de(e, n), l = a.orders.filter((e) => e.ownerKey === z(i.tenantId, i.ownerId));
301
+ if (l.length !== W(r.ordersCount)) throw t("invalid_record");
302
+ if (a.orders.some((e) => e.offerId === f.id && e.offerVersion === f.version && e.channel === c.channel && e.configurationDigest !== h)) throw t("conflict");
303
+ let d = await Q(e, i, o);
304
+ if (d?.state === "fulfilled") throw await $(e, d), new oe();
305
+ if (!d) {
306
+ if (a.orders.length >= F) throw t("limit_exceeded");
307
+ await e.insert(D.tableName, {
308
+ id: o,
309
+ namespace: M,
310
+ tenantId: i.tenantId,
311
+ ownerId: i.ownerId,
312
+ ownerKey: z(i.tenantId, i.ownerId),
313
+ offerId: f.id,
314
+ offerVersion: f.version,
315
+ channel: c.channel,
316
+ configurationDigest: h,
317
+ acceptedQuantity: null,
318
+ acceptedDay: null,
319
+ state: "pending",
320
+ accepted: !1,
321
+ intentDigest: s,
322
+ receiptKey: m,
323
+ snapshot: null,
324
+ receipt: null,
325
+ createdAt: new Date(p),
326
+ fulfilledAt: null
327
+ }), await e.update(E.tableName, I, { ordersCount: a.orders.length + 1 }), await e.update(k.tableName, z(i.tenantId, i.ownerId), { ordersCount: l.length + 1 });
328
+ } else if (d.intentDigest !== s || d.receiptKey !== m || d.state !== "pending") throw t("conflict");
329
+ let _ = (await e.query(P(O).where(N("id", m)).limit(1).descriptor))[0];
330
+ if (_) {
331
+ if (_.identity !== u) throw t("invalid_record");
332
+ if (_.namespace !== M || _.tenantId !== i.tenantId || _.ownerKey !== z(i.tenantId, i.ownerId) || _.orderKey !== o || _.accepted === !0 || _.state === "erased") throw t("already_redeemed");
333
+ if (_.state !== "pending" || _.accepted !== !1 || _.fulfilledAt !== null) throw t("invalid_record");
334
+ if (_.factsDigest !== g) throw t("conflict");
335
+ } else {
336
+ if (a.receipts.length >= F) throw t("limit_exceeded");
337
+ await e.insert(O.tableName, {
338
+ id: m,
339
+ namespace: M,
340
+ tenantId: i.tenantId,
341
+ ownerKey: z(i.tenantId, i.ownerId),
342
+ orderKey: o,
343
+ identity: u,
344
+ factsDigest: g,
345
+ state: "pending",
346
+ accepted: !1,
347
+ createdAt: new Date(p),
348
+ fulfilledAt: null
349
+ }), await e.update(E.tableName, I, { receiptsCount: a.receipts.length + 1 });
350
+ }
351
+ });
352
+ let b = [
353
+ v,
354
+ y,
355
+ ie(e, async (e) => {
356
+ let n = await Y(e);
357
+ await Z(e, i);
358
+ let r = await de(e, n), a = await Q(e, i, o);
359
+ if (!a || a.intentDigest !== s || a.receiptKey !== m || a.ownerId !== i.ownerId) throw t("invalid_record");
360
+ if (a.state === "fulfilled") throw await $(e, a), new oe();
361
+ if (a.state !== "pending" || a.accepted !== !1 || c.consumption === "consumed" || c.kind !== "subscription" && c.acknowledgement === "acknowledged") throw t("forbidden");
362
+ if (await e.updateMany(O.tableName, { accepted: !1 }, { where: ne(N("id", m), N("state", "pending")) }) !== 1) throw t("already_redeemed");
363
+ let d = (await e.query(P(O).where(N("id", m)).limit(1).descriptor))[0];
364
+ if (!d || d.identity !== u || d.orderKey !== o || d.namespace !== M || d.tenantId !== i.tenantId || d.ownerKey !== a.ownerKey) throw t("already_redeemed");
365
+ if (d.factsDigest !== g || a.configurationDigest !== h) throw t("conflict");
366
+ let p = r.orders.filter((e) => e.accepted === !0 && e.offerId === f.id), _ = 0, v = 0, y = 0;
367
+ for (let t of p) {
368
+ t.state === "fulfilled" && await $(e, t);
369
+ let n = l(t.acceptedQuantity, 1, 1e3);
370
+ _ += n, t.ownerKey === a.ownerKey && (v += n, t.acceptedDay === Math.floor(x / 864e5) && (y += n));
371
+ }
372
+ if (f.limits.global !== null && _ + c.quantity > f.limits.global || f.limits.perPlayer !== null && v + c.quantity > f.limits.perPlayer || f.limits.perDay !== null && y + c.quantity > f.limits.perDay) throw t("limit_exceeded");
373
+ return null;
374
+ })
375
+ ];
376
+ for (let [e, t] of f.currencies.entries()) b.push(await H(j.economy.prepareTransfer(ce, {
377
+ tenantId: i.tenantId,
378
+ requestId: R("eik_", o, "transfer", String(e)),
379
+ currency: t.currency,
380
+ amount: (BigInt(t.amount) * BigInt(c.quantity)).toString(),
381
+ from: {
382
+ kind: "system",
383
+ id: j.systemAccount
384
+ },
385
+ to: {
386
+ kind: "wallet",
387
+ ownerKind: "player",
388
+ ownerId: i.ownerId
389
+ },
390
+ reason: "iap.fulfill",
391
+ ref: {
392
+ kind: "iap-order",
393
+ id: o
394
+ }
395
+ })));
396
+ for (let [e, t] of f.items.entries()) b.push(await H(j.inventory.prepareGrant(ce, {
397
+ tenantId: i.tenantId,
398
+ owner: {
399
+ ownerKind: "player",
400
+ ownerId: i.ownerId
401
+ },
402
+ itemId: t.itemId,
403
+ qty: t.qty * c.quantity,
404
+ requestId: R("eik_", o, "grant", String(e)),
405
+ reason: "iap.fulfill",
406
+ ref: {
407
+ kind: "iap-order",
408
+ id: o
409
+ }
410
+ })));
411
+ let x = q();
412
+ if (x < p || c.expiresAt !== null && c.expiresAt <= x || f.until !== null && x >= f.until) throw t("forbidden");
413
+ let S = ae(e, b, async (e, n) => {
414
+ let l = {
415
+ orderId: o,
416
+ offerId: f.id,
417
+ offerVersion: f.version,
418
+ quantity: c.quantity,
419
+ at: x,
420
+ pricePaid: c.paid,
421
+ transfers: n.slice(3, 3 + f.currencies.length),
422
+ grants: n.slice(3 + f.currencies.length)
423
+ };
424
+ await e.update(O.tableName, m, {
425
+ state: "fulfilled",
426
+ accepted: !0,
427
+ fulfilledAt: new Date(x)
428
+ }), await e.update(D.tableName, o, {
429
+ state: "fulfilled",
430
+ accepted: !0,
431
+ acceptedQuantity: c.quantity,
432
+ acceptedDay: Math.floor(x / 864e5),
433
+ snapshot: {
434
+ scope: i,
435
+ requestId: a.requestId,
436
+ intentDigest: s,
437
+ identity: u,
438
+ product: r,
439
+ currencies: j.currencies,
440
+ facts: c,
441
+ verifiedAt: d,
442
+ at: x
443
+ },
444
+ receipt: l,
445
+ fulfilledAt: new Date(x)
446
+ });
447
+ let p = await Q(e, i, o);
448
+ if (!p) throw t("invalid_record");
449
+ return $(e, p);
450
+ });
451
+ return (await re(e, [S]))[0];
452
+ } catch (e) {
453
+ let t = await pe(i, o, s);
454
+ if (t) return t;
455
+ throw e;
456
+ }
457
+ });
458
+ }), he = (n, r) => V(() => {
459
+ let i = J(n), a = h(r), o = G(i.tenantId, i.ownerId, a.requestId), s = L([
460
+ M,
461
+ i,
462
+ a.channel,
463
+ a.offerId,
464
+ a.offerVersion,
465
+ a.requestId,
466
+ a.receiptDigest
467
+ ]);
468
+ return B(() => e.transactional(async (e) => {
469
+ let n = await X(e, i), r = await Q(e, i, o);
470
+ if (r && !n) throw t("invalid_record");
471
+ if (!r) return Object.freeze({
472
+ requestId: a.requestId,
473
+ state: "not-observed"
474
+ });
475
+ if (r.intentDigest !== s) throw t("conflict");
476
+ if (r.state === "fulfilled") {
477
+ let t = await $(e, r);
478
+ if (!j.refundDisposition) return Object.freeze({
479
+ requestId: a.requestId,
480
+ state: "fulfilled",
481
+ receipt: t
482
+ });
483
+ let n = await fe(e, r, i), o = await j.refundDisposition.read(e, n);
484
+ return u({
485
+ requestId: a.requestId,
486
+ state: o?.state === "revoked" ? "refunded" : o?.state === "partially-refunded" ? "partially-refunded" : "fulfilled",
487
+ receipt: t,
488
+ ...o === null ? {} : { refund: o }
489
+ });
490
+ }
491
+ if (r.state !== "pending" || r.ownerId !== i.ownerId || r.accepted !== !1 || r.receipt !== null || r.snapshot !== null || r.fulfilledAt !== null) throw t("invalid_record");
492
+ return Object.freeze({
493
+ requestId: a.requestId,
494
+ state: "pending"
495
+ });
496
+ }));
497
+ }), ge = (e) => {
498
+ let n = i(e, [
499
+ "tenantId",
500
+ "subjectId",
501
+ "kind"
502
+ ]);
503
+ if (n.kind !== "user" && n.kind !== "guest") throw t("invalid_input");
504
+ return Object.freeze({
505
+ tenantId: a(n.tenantId),
506
+ ownerId: a(n.subjectId)
507
+ });
508
+ }, _e = async (e, n, r, i = !1) => {
509
+ let a = await ue(e, D, ne(N("namespace", M), N("tenantId", n.tenantId), N("ownerKey", z(n.tenantId, n.ownerId))));
510
+ if (a.length !== (r ? W(r.ordersCount) : 0)) throw t("invalid_record");
511
+ for (let n of a) if (n.state === "fulfilled") i || await $(e, n);
512
+ else if (n.state === "pending" ? n.accepted !== !1 || n.receipt !== null || n.snapshot !== null || n.fulfilledAt !== null : n.state !== "erased" || n.ownerId !== null || n.intentDigest !== null || n.receipt !== null || n.snapshot !== null || typeof n.accepted != "boolean" || n.accepted === !0 && n.fulfilledAt === null || n.accepted === !1 && n.fulfilledAt !== null) throw t("invalid_record");
513
+ return a;
514
+ };
515
+ return Object.freeze({
516
+ redeem: me,
517
+ receipt: he,
518
+ subscriptionPeriods: (n) => V(() => {
519
+ let r = J(n);
520
+ return B(() => e.transactional(async (e) => {
521
+ let n = await X(e, r), i = await _e(e, r, n), a = [];
522
+ for (let n of i) {
523
+ if (n.state !== "fulfilled") continue;
524
+ let i = await fe(e, n, r);
525
+ if (i.facts.kind !== "subscription") continue;
526
+ if (!j.refundDisposition) throw t("unavailable");
527
+ let o = await j.refundDisposition.read(e, i);
528
+ a.push(f({
529
+ orderId: i.orderId,
530
+ offerId: i.receipt.offerId,
531
+ offerVersion: i.receipt.offerVersion,
532
+ channel: i.facts.channel,
533
+ startsAt: i.facts.purchasedAt,
534
+ expiresAt: i.facts.expiresAt,
535
+ refund: o
536
+ }));
537
+ }
538
+ return Object.freeze(a.sort((e, t) => e.startsAt - t.startsAt || e.orderId.localeCompare(t.orderId)));
539
+ }));
540
+ }),
541
+ subscriptionOriginals: (t, n) => V(() => {
542
+ let r = J(t), i = p(n);
543
+ return B(() => e.transactional(async (e) => {
544
+ let t = await X(e, r), n = await _e(e, r, t), a = [];
545
+ for (let t of n) {
546
+ if (t.state !== "fulfilled") continue;
547
+ let n = await fe(e, t, r);
548
+ n.facts.kind === "subscription" && n.facts.channel === i && n.facts.originalTransactionId !== null && a.push({
549
+ id: n.facts.originalTransactionId,
550
+ at: n.facts.purchasedAt
551
+ });
552
+ }
553
+ return Object.freeze([...new Set(a.sort((e, t) => t.at - e.at).map((e) => e.id))]);
554
+ }));
555
+ }),
556
+ exportSubject: (t) => V(() => {
557
+ let n = ge(t);
558
+ return B(() => e.transactional(async (e) => {
559
+ let t = await X(e, n, !0), r = await _e(e, n, t);
560
+ return t?.erased === !0 ? { orders: [] } : { orders: r.filter((e) => e.state !== "erased").map((e) => ({
561
+ orderId: e.id,
562
+ state: e.state,
563
+ receipt: e.receipt
564
+ })) };
565
+ }));
566
+ }),
567
+ eraseSubject: (n) => V(() => {
568
+ let r = ge(n);
569
+ return B(async () => {
570
+ await le(r), await e.transactional(async (e) => {
571
+ let n = await Y(e), i = await Z(e, r, !0);
572
+ await de(e, n);
573
+ let a = await _e(e, r, i, !0);
574
+ for (let n of a) {
575
+ if (n.receiptKey !== null) {
576
+ let i = (await e.query(P(O).where(N("id", String(n.receiptKey))).limit(1).descriptor))[0];
577
+ if (!i || i.namespace !== M || i.tenantId !== r.tenantId || i.ownerKey !== n.ownerKey || i.orderKey !== n.id || i.accepted !== n.accepted) throw t("invalid_record");
578
+ await e.update(O.tableName, String(i.id), { state: "erased" });
579
+ }
580
+ await e.update(D.tableName, String(n.id), {
581
+ ownerId: null,
582
+ state: "erased",
583
+ intentDigest: null,
584
+ snapshot: null,
585
+ receipt: null
586
+ });
587
+ }
588
+ await e.update(k.tableName, z(r.tenantId, r.ownerId), {
589
+ ownerId: null,
590
+ erased: !0
591
+ });
592
+ });
593
+ });
594
+ }),
595
+ prepareCompletion: (n, r) => V(() => {
596
+ let o = J(n), l = m(r), u = G(o.tenantId, o.ownerId, l.requestId), d = L([
597
+ M,
598
+ o,
599
+ l.channel,
600
+ l.offerId,
601
+ l.offerVersion,
602
+ l.requestId,
603
+ L(l.receipt)
604
+ ]), f = () => B(() => e.transactional(async (e) => {
605
+ let n = await X(e, o), r = await Q(e, o, u);
606
+ if (!r) throw t("not_found");
607
+ if (!n) throw t("invalid_record");
608
+ if (r.intentDigest !== d) throw t("conflict");
609
+ if (r.state !== "fulfilled" || r.accepted !== !0) throw t("forbidden");
610
+ await $(e, r);
611
+ let f = i(r.snapshot, [
612
+ "scope",
613
+ "requestId",
614
+ "intentDigest",
615
+ "identity",
616
+ "product",
617
+ "currencies",
618
+ "facts",
619
+ "verifiedAt",
620
+ "at"
621
+ ], "invalid_record"), m = i(f.product, [
622
+ "offer",
623
+ "channel",
624
+ "kind",
625
+ "storeProductId"
626
+ ], "invalid_record"), h = s(f.currencies), g = Object.freeze({
627
+ offer: c(m.offer, h, !0, { grantless: m.kind === "subscription" }),
628
+ channel: p(m.channel),
629
+ kind: m.kind,
630
+ storeProductId: a(m.storeProductId)
631
+ });
632
+ return Object.freeze({
633
+ orderId: u,
634
+ scope: o,
635
+ intent: l,
636
+ product: g,
637
+ currencies: h,
638
+ facts: w(f.facts)
639
+ });
640
+ }));
641
+ return f().pipe(A.map(() => ee(u, f)));
642
+ }),
643
+ prepareNotification: (n, r) => V(() => {
644
+ let o = x(n), l = y(r), u = l.notice;
645
+ if (u.channel !== o.channel || u.applicationId !== o.applicationId || u.environment !== null && u.environment !== o.environment) throw t("forbidden");
646
+ if (u.kind === "test" || u.transactionId === null) throw t("unavailable");
647
+ let d = L([
648
+ o.channel,
649
+ o.environment,
650
+ o.applicationId,
651
+ u.transactionId
652
+ ]), f = K(d), m, h = () => b(r).pipe(A.flatMap(() => B(() => e.transactional(async (e) => {
653
+ let n = (await e.query(P(O).where(N("id", f)).limit(1).descriptor))[0];
654
+ if (!n) throw t("not_found");
655
+ if (n.identity !== d) throw t("invalid_record");
656
+ if (n.namespace !== M) throw t("forbidden");
657
+ if (n.state === "erased") throw t("erased");
658
+ if (n.state !== "fulfilled" || n.accepted !== !0) throw t("forbidden");
659
+ let h = (await e.query(P(D).where(N("id", String(n.orderKey))).limit(1).descriptor))[0];
660
+ if (!h) throw t("invalid_record");
661
+ if (h.state === "erased") throw t("erased");
662
+ let g = Object.freeze({
663
+ tenantId: a(h.tenantId),
664
+ ownerId: a(h.ownerId)
665
+ });
666
+ if (h.namespace !== M || n.tenantId !== g.tenantId || n.ownerKey !== z(g.tenantId, g.ownerId) || h.ownerKey !== n.ownerKey || h.receiptKey !== f || !await X(e, g)) throw t("invalid_record");
667
+ if (m && (h.id !== m.orderId || g.tenantId !== m.tenantId || g.ownerId !== m.ownerId)) throw t("conflict");
668
+ let _ = await $(e, h), v = i(h.snapshot, [
669
+ "scope",
670
+ "requestId",
671
+ "intentDigest",
672
+ "identity",
673
+ "product",
674
+ "currencies",
675
+ "facts",
676
+ "verifiedAt",
677
+ "at"
678
+ ], "invalid_record"), b = i(v.product, [
679
+ "offer",
680
+ "channel",
681
+ "kind",
682
+ "storeProductId"
683
+ ], "invalid_record"), x = s(v.currencies), S = w(v.facts);
684
+ if (S.channel !== o.channel || S.environment !== o.environment || S.applicationId !== o.applicationId || S.transactionId !== u.transactionId || u.originalTransactionId !== null && u.originalTransactionId !== S.originalTransactionId || u.storeProductId !== null && u.storeProductId !== S.storeProductId || u.kind === "subscription" && S.kind !== "subscription" || u.kind === "one-time" && S.kind === "subscription") throw t("forbidden");
685
+ let C = Object.freeze({
686
+ offer: c(b.offer, x, !0, { grantless: b.kind === "subscription" }),
687
+ channel: p(b.channel),
688
+ kind: b.kind,
689
+ storeProductId: a(b.storeProductId)
690
+ });
691
+ return Object.freeze({
692
+ orderId: _.orderId,
693
+ notice: u,
694
+ notification: r,
695
+ receipt: _,
696
+ scope: g,
697
+ product: C,
698
+ currencies: x,
699
+ facts: S,
700
+ fingerprint: l.fingerprint,
701
+ material: y(r).material
702
+ });
703
+ }))));
704
+ return h().pipe(A.map((e) => (m = Object.freeze({
705
+ orderId: e.orderId,
706
+ tenantId: e.scope.tenantId,
707
+ ownerId: e.scope.ownerId
708
+ }), S(e.orderId, u.noticeId, h))));
709
+ }),
710
+ prepareCurrentState: (n) => C(n).pipe(A.flatMap((n) => {
711
+ let { original: r, state: a } = n;
712
+ return A.gen(function* () {
713
+ let o = yield* n.prepareBinding(), s = yield* v(r.notification), c = ie(e, async (e) => {
714
+ q(), n.assertFresh(), await Y(e), await Z(e, r.scope);
715
+ let a = await Q(e, r.scope, r.orderId);
716
+ if (!a) throw t("not_found");
717
+ let o = await $(e, a), s = i(a.snapshot, [
718
+ "scope",
719
+ "requestId",
720
+ "intentDigest",
721
+ "identity",
722
+ "product",
723
+ "currencies",
724
+ "facts",
725
+ "verifiedAt",
726
+ "at"
727
+ ], "invalid_record");
728
+ if (_(o) !== _(r.receipt) || _(s.facts) !== _(r.facts) || _(s.product) !== _(r.product) || _(s.currencies) !== _(r.currencies)) throw t("conflict");
729
+ return null;
730
+ });
731
+ return ae(e, [
732
+ c,
733
+ o,
734
+ ...s
735
+ ], async () => (q(), n.assertFresh(), a));
736
+ });
737
+ }), A.catchDefect(() => A.fail(t("unavailable"))))
738
+ });
739
+ };
740
+ export { G as dataStoreIap, se as resolveIapStoreOptions };