@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.
- package/CHANGELOG.md +24492 -0
- package/LICENSE +61 -0
- package/README.md +2719 -2
- package/SECURITY.md +56 -0
- package/THIRD-PARTY-NOTICES.md +9841 -0
- package/dist/amount.js +20 -0
- package/dist/appleIap.server.js +262 -0
- package/dist/appleIapNotifications.server.js +162 -0
- package/dist/appleIapTrust.server.js +30 -0
- package/dist/bundleValue.server.js +112 -0
- package/dist/canonicalDataJson.js +10 -0
- package/dist/capture.js +53 -0
- package/dist/codePort.fixture.js +123 -0
- package/dist/codeStore.server.js +439 -0
- package/dist/codeTables.entity.js +43 -0
- package/dist/codes.d.ts +150 -0
- package/dist/codes.js +82 -0
- package/dist/components.d.ts +397 -0
- package/dist/components.js +283 -0
- package/dist/consistency.server.js +115 -0
- package/dist/containerStore.server.js +687 -0
- package/dist/containerStore.testFixtures.js +75 -0
- package/dist/containerTables.entity.js +45 -0
- package/dist/containers.d.ts +311 -0
- package/dist/containers.fixture.js +128 -0
- package/dist/containers.js +214 -0
- package/dist/containers.server.js +39 -0
- package/dist/containersPort.fixture.js +74 -0
- package/dist/currency.js +32 -0
- package/dist/declarationFixtures.js +61 -0
- package/dist/economy-app/events/economy.refundReversed.event.ts +1 -0
- package/dist/economy-app/events/economy.refunded.event.ts +1 -0
- package/dist/economyPort.fixture.js +124 -0
- package/dist/errors.d.ts +14 -0
- package/dist/errors.js +21 -0
- package/dist/events.d.ts +46 -0
- package/dist/events.js +1 -0
- package/dist/googleIap.server.js +391 -0
- package/dist/googleIapNotifications.server.js +130 -0
- package/dist/googleIapSubscription.server.js +183 -0
- package/dist/iap.d.ts +309 -0
- package/dist/iap.js +303 -0
- package/dist/iap.testFixtures.js +144 -0
- package/dist/iapAccountTables.entity.js +39 -0
- package/dist/iapAccounts.server.js +200 -0
- package/dist/iapBinding.server.js +523 -0
- package/dist/iapCheckout.server.js +97 -0
- package/dist/iapCompletion.server.js +55 -0
- package/dist/iapCurrentState.server.js +107 -0
- package/dist/iapCurrentState.testFixtures.js +22 -0
- package/dist/iapCurrentStatePort.fixture.js +63 -0
- package/dist/iapEntitlements.d.ts +79 -0
- package/dist/iapEntitlements.js +57 -0
- package/dist/iapEntitlements.server.js +48 -0
- package/dist/iapEntitlementsBinding.server.js +105 -0
- package/dist/iapEntitlementsPort.fixture.js +80 -0
- package/dist/iapInstalledEntitlements.testFixtures.js +75 -0
- package/dist/iapInstalledNotifications.testFixtures.js +93 -0
- package/dist/iapInventoryRefunds.server.js +261 -0
- package/dist/iapNotificationCustodyPort.fixture.js +67 -0
- package/dist/iapNotificationPort.fixture.js +73 -0
- package/dist/iapNotificationProcessor.server.js +134 -0
- package/dist/iapNotificationProcessor.testFixtures.js +63 -0
- package/dist/iapNotificationProcessorPort.fixture.js +55 -0
- package/dist/iapNotificationSchedule.server.js +69 -0
- package/dist/iapNotificationStore.server.js +352 -0
- package/dist/iapNotificationStore.testFixtures.js +31 -0
- package/dist/iapNotificationTables.entity.js +48 -0
- package/dist/iapNotificationTarget.server.js +36 -0
- package/dist/iapNotificationTarget.testFixtures.js +29 -0
- package/dist/iapNotifications.d.ts +644 -0
- package/dist/iapNotifications.js +6 -0
- package/dist/iapNotifications.server.js +95 -0
- package/dist/iapNotificationsBinding.server.js +232 -0
- package/dist/iapNotificationsSystemPort.fixture.js +50 -0
- package/dist/iapPlugin.testFixtures.js +59 -0
- package/dist/iapPort.fixture.js +74 -0
- package/dist/iapProviderCapture.server.js +17 -0
- package/dist/iapRecovery.d.ts +146 -0
- package/dist/iapRecovery.js +89 -0
- package/dist/iapRefundEventDelivery.server.js +82 -0
- package/dist/iapRefundEvents.js +44 -0
- package/dist/iapRefundEventsPort.fixture.js +59 -0
- package/dist/iapRefundPort.fixture.js +54 -0
- package/dist/iapRefundTables.entity.js +55 -0
- package/dist/iapRefunds.d.ts +755 -0
- package/dist/iapRefunds.js +6 -0
- package/dist/iapRefunds.server.js +553 -0
- package/dist/iapRefunds.testFixtures.js +64 -0
- package/dist/iapSpendAdmission.server.js +98 -0
- package/dist/iapStore.server.js +740 -0
- package/dist/iapStore.testFixtures.js +127 -0
- package/dist/iapTables.entity.js +80 -0
- package/dist/iapVerification.server.js +120 -0
- package/dist/index.d.ts +2984 -0
- package/dist/index.js +15 -0
- package/dist/intentionRecovery.js +133 -0
- package/dist/ledger.js +77 -0
- package/dist/loyalty.d.ts +274 -0
- package/dist/loyalty.fixture.js +92 -0
- package/dist/loyalty.js +311 -0
- package/dist/loyaltyBinding.server.js +203 -0
- package/dist/loyaltyPort.fixture.js +86 -0
- package/dist/loyaltyShopSource.server.js +90 -0
- package/dist/loyaltyStore.server.js +552 -0
- package/dist/loyaltyStore.testFixtures.js +82 -0
- package/dist/loyaltyTables.entity.js +49 -0
- package/dist/offerMerchandising.fixture.js +114 -0
- package/dist/offerMerchandising.js +282 -0
- package/dist/offerPolicies.d.ts +441 -0
- package/dist/offerPolicies.fixture.js +53 -0
- package/dist/offerPolicies.js +267 -0
- package/dist/piggyBanks.d.ts +272 -0
- package/dist/piggyBanks.fixture.js +70 -0
- package/dist/piggyBanks.js +200 -0
- package/dist/piggyBinding.server.js +204 -0
- package/dist/piggyPort.fixture.js +72 -0
- package/dist/piggyStore.server.js +610 -0
- package/dist/piggyStore.testFixtures.js +97 -0
- package/dist/piggyTables.entity.js +40 -0
- package/dist/plugin.js +1047 -0
- package/dist/port.js +12 -0
- package/dist/price.d.ts +99 -0
- package/dist/price.js +143 -0
- package/dist/purchaseRecovery.js +55 -0
- package/dist/reports.server.js +114 -0
- package/dist/rpc.d.ts +3201 -0
- package/dist/rpc.js +1200 -0
- package/dist/sanctionsTradeAuthority.server.js +79 -0
- package/dist/server.d.ts +3856 -0
- package/dist/server.js +43 -0
- package/dist/shop.d.ts +279 -0
- package/dist/shop.js +195 -0
- package/dist/shop.testFixtures.js +113 -0
- package/dist/shopPort.fixture.js +71 -0
- package/dist/shopPresentation.js +67 -0
- package/dist/shopStore.server.js +623 -0
- package/dist/shopTables.entity.js +62 -0
- package/dist/shopUiCopy.js +56 -0
- package/dist/spendLimits.d.ts +140 -0
- package/dist/spendLimits.fixture.js +52 -0
- package/dist/spendLimits.js +154 -0
- package/dist/spendLimitsPort.fixture.js +119 -0
- package/dist/subscriptionBinding.server.js +210 -0
- package/dist/subscriptionStore.server.js +642 -0
- package/dist/subscriptionStore.testFixtures.js +71 -0
- package/dist/subscriptionTables.entity.js +36 -0
- package/dist/subscriptions.d.ts +394 -0
- package/dist/subscriptions.fixture.js +96 -0
- package/dist/subscriptions.js +212 -0
- package/dist/subscriptionsPort.fixture.js +75 -0
- package/dist/systemFixtures.js +88 -0
- package/dist/tables.entity.js +82 -0
- package/dist/testing.d.ts +4615 -0
- package/dist/testing.js +29 -0
- package/dist/tradeAuthority.server.js +171 -0
- package/dist/tradeBinding.server.js +200 -0
- package/dist/tradeComponents.js +341 -0
- package/dist/tradeEscrow.server.js +231 -0
- package/dist/tradeEscrow.testFixtures.js +132 -0
- package/dist/tradeExpiry.server.js +42 -0
- package/dist/tradeRecovery.js +47 -0
- package/dist/tradeStore.server.js +749 -0
- package/dist/tradeStore.testFixtures.js +72 -0
- package/dist/tradeTables.entity.js +65 -0
- package/dist/tradeUiCopy.js +78 -0
- package/dist/trades.d.ts +246 -0
- package/dist/trades.fixture.js +102 -0
- package/dist/trades.js +288 -0
- package/dist/tradesPort.fixture.js +93 -0
- package/dist/walletEscrow.js +105 -0
- package/dist/walletEscrow.server.js +375 -0
- package/dist/walletKeys.server.js +4 -0
- package/dist/walletStore.js +570 -0
- package/dist/web.d.ts +2257 -0
- package/dist/web.js +8 -0
- package/package.json +161 -4
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { economyError as e } from "./errors.js";
|
|
2
|
+
import { tradeTables as t } from "./tradeTables.entity.js";
|
|
3
|
+
import { dataStoreTrades as n } from "./tradeStore.server.js";
|
|
4
|
+
import { tradeEscrowAt as r, tradeEscrowFixture as i, tradeEscrowMachine as a } from "./tradeEscrow.testFixtures.js";
|
|
5
|
+
import { Effect as o } from "effect";
|
|
6
|
+
import { and as s, ensureTableRegistered as c, eq as l, queryFor as u } from "@voltro/database";
|
|
7
|
+
import { prepareSqlMutation as d } from "@voltro/database/sql";
|
|
8
|
+
import { inventoryItemsTable as f, inventorySubjectsTable as p } from "@voltro/plugin-inventory/server";
|
|
9
|
+
// src/tradeStore.testFixtures.ts
|
|
10
|
+
var m = async (m, h = "tenant") => {
|
|
11
|
+
t.forEach(c);
|
|
12
|
+
let g = await i(m, h), _ = {
|
|
13
|
+
read: (t) => o.gen(function* () {
|
|
14
|
+
let e = yield* g.inventory.mine(g.user(t.ownerId)), n = yield* g.inventory.reservationEvidence(a, {
|
|
15
|
+
tenantId: t.tenantId,
|
|
16
|
+
owner: {
|
|
17
|
+
ownerKind: "player",
|
|
18
|
+
ownerId: t.ownerId
|
|
19
|
+
},
|
|
20
|
+
reservationId: t.tradeId
|
|
21
|
+
});
|
|
22
|
+
return {
|
|
23
|
+
tenantId: t.tenantId,
|
|
24
|
+
ownerId: t.ownerId,
|
|
25
|
+
allowed: !0,
|
|
26
|
+
trustScore: 10,
|
|
27
|
+
items: e.map((e) => ({
|
|
28
|
+
instanceId: e.id,
|
|
29
|
+
itemId: e.itemId,
|
|
30
|
+
qty: e.qty,
|
|
31
|
+
tradable: g.item.tradable,
|
|
32
|
+
locked: e.locked,
|
|
33
|
+
reservationId: n.state === "reserved" && n.items.some((t) => t.instance.id === e.id) ? t.tradeId : null,
|
|
34
|
+
expiresAt: e.expiresAt
|
|
35
|
+
}))
|
|
36
|
+
};
|
|
37
|
+
}).pipe(o.mapError(() => e("unavailable"))),
|
|
38
|
+
prepare: (t) => o.sync(() => d(g.store, async (n) => {
|
|
39
|
+
for (let r of [...t.participants].sort((e, t) => e.ownerId < t.ownerId ? -1 : 1)) {
|
|
40
|
+
if (await n.updateMany(p.tableName, { admission: 0 }, { where: s(l("tenantId", t.tenantId), l("ownerId", r.ownerId), l("erased", !1)) }) !== 1) throw e("erased");
|
|
41
|
+
let i = await n.query(u(f).where(s(l("tenantId", t.tenantId), l("ownerId", r.ownerId))).descriptor);
|
|
42
|
+
if (i.length !== r.items.length || r.items.some((e) => {
|
|
43
|
+
let t = i.find((t) => t.id === e.instanceId);
|
|
44
|
+
return !t || t.qty !== e.qty || t.locked !== e.locked || t.itemId !== e.itemId;
|
|
45
|
+
})) throw e("conflict");
|
|
46
|
+
}
|
|
47
|
+
}))
|
|
48
|
+
}, v = {
|
|
49
|
+
...g.options,
|
|
50
|
+
authority: _,
|
|
51
|
+
inventory: g.inventory,
|
|
52
|
+
now: () => r
|
|
53
|
+
}, y = n(g.store, v), b = {
|
|
54
|
+
toId: "b",
|
|
55
|
+
offered: g.terms.offered,
|
|
56
|
+
requested: g.terms.requested,
|
|
57
|
+
durationMs: 500,
|
|
58
|
+
requestId: "proposal"
|
|
59
|
+
}, x = (e, t = "accept") => ({
|
|
60
|
+
tradeId: e.trade.tradeId,
|
|
61
|
+
tradeDigest: e.trade.tradeDigest,
|
|
62
|
+
requestId: t
|
|
63
|
+
});
|
|
64
|
+
return {
|
|
65
|
+
...g,
|
|
66
|
+
options: v,
|
|
67
|
+
service: y,
|
|
68
|
+
proposed: b,
|
|
69
|
+
accept: x
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
export { m as tradeStoreFixture };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { boolean as e, id as t, integer as n, json as r, table as i, text as a, timestamp as o } from "@voltro/database";
|
|
2
|
+
// src/tradeTables.entity.ts
|
|
3
|
+
var s = () => a().maxLength(120).externalId().sensitive("pii"), c = i("_voltro_eco_trade_tenants", {
|
|
4
|
+
id: t({ prefix: "ett" }),
|
|
5
|
+
tenantId: s(),
|
|
6
|
+
admission: n().serverOnly(),
|
|
7
|
+
tradesCount: n().serverOnly()
|
|
8
|
+
}).index(["tenantId"]), l = i("_voltro_eco_trade_subjects", {
|
|
9
|
+
id: t({ prefix: "ets" }),
|
|
10
|
+
tenantId: s(),
|
|
11
|
+
ownerId: a().maxLength(120).nullable().externalId().sensitive("pii"),
|
|
12
|
+
erased: e().serverOnly(),
|
|
13
|
+
admission: n().serverOnly(),
|
|
14
|
+
operationsCount: n().serverOnly()
|
|
15
|
+
}).index(["tenantId", "ownerId"]), u = i("_voltro_eco_trades", {
|
|
16
|
+
id: t({ prefix: "etd" }),
|
|
17
|
+
tenantId: s(),
|
|
18
|
+
proposerKey: a().maxLength(64).serverOnly(),
|
|
19
|
+
targetKey: a().maxLength(64).nullable().serverOnly(),
|
|
20
|
+
accepterKey: a().maxLength(64).nullable().serverOnly(),
|
|
21
|
+
accepted: e().serverOnly(),
|
|
22
|
+
state: a().maxLength(16).oneOf([
|
|
23
|
+
"pending",
|
|
24
|
+
"proposed",
|
|
25
|
+
"accepted",
|
|
26
|
+
"cancelled",
|
|
27
|
+
"expired",
|
|
28
|
+
"erased"
|
|
29
|
+
]).serverOnly(),
|
|
30
|
+
admission: n().serverOnly(),
|
|
31
|
+
digest: a().maxLength(64).nullable().serverOnly(),
|
|
32
|
+
proposal: r().nullable().serverOnly(),
|
|
33
|
+
closing: r().nullable().serverOnly(),
|
|
34
|
+
createdAt: o().nullable().serverOnly(),
|
|
35
|
+
expiresAt: o().nullable().serverOnly()
|
|
36
|
+
}).index(["tenantId", "proposerKey"]).index(["tenantId", "targetKey"]).index(["tenantId", "accepterKey"]), d = i("_voltro_eco_trade_operations", {
|
|
37
|
+
id: t({ prefix: "eto" }),
|
|
38
|
+
tenantId: s(),
|
|
39
|
+
ownerKey: a().maxLength(64).serverOnly(),
|
|
40
|
+
ownerId: a().maxLength(120).nullable().externalId().sensitive("pii"),
|
|
41
|
+
tradeId: a().maxLength(64).nullable().serverOnly(),
|
|
42
|
+
kind: a().maxLength(16).oneOf([
|
|
43
|
+
"propose",
|
|
44
|
+
"accept",
|
|
45
|
+
"cancel",
|
|
46
|
+
"expire"
|
|
47
|
+
]).serverOnly(),
|
|
48
|
+
state: a().maxLength(16).oneOf([
|
|
49
|
+
"pending",
|
|
50
|
+
"fulfilled",
|
|
51
|
+
"erased"
|
|
52
|
+
]).serverOnly(),
|
|
53
|
+
admission: n().serverOnly(),
|
|
54
|
+
sequence: n().nullable().serverOnly(),
|
|
55
|
+
digest: a().maxLength(64).nullable().serverOnly(),
|
|
56
|
+
request: r().nullable().serverOnly(),
|
|
57
|
+
receipt: r().nullable().serverOnly(),
|
|
58
|
+
at: o().nullable().serverOnly()
|
|
59
|
+
}).index(["tenantId", "ownerKey"]).index(["tenantId", "tradeId"]), f = [
|
|
60
|
+
c,
|
|
61
|
+
l,
|
|
62
|
+
u,
|
|
63
|
+
d
|
|
64
|
+
];
|
|
65
|
+
export { d as tradeOperationsTable, l as tradeSubjectsTable, f as tradeTables, c as tradeTenantsTable, u as tradesTable };
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// src/tradeUiCopy.ts
|
|
2
|
+
var e = Object.freeze({
|
|
3
|
+
en: Object.freeze({
|
|
4
|
+
title: "Trades",
|
|
5
|
+
loading: "Loading trades…",
|
|
6
|
+
unavailable: "Trades could not be refreshed. Check the connection and refresh.",
|
|
7
|
+
invalid: "These trade details could not be verified. Refresh before continuing.",
|
|
8
|
+
empty: "No trades to show.",
|
|
9
|
+
offered: "Proposer offers",
|
|
10
|
+
requested: "Counterparty offers",
|
|
11
|
+
emptyLeg: "No items or currency selected.",
|
|
12
|
+
accept: "Review trade",
|
|
13
|
+
cancel: "Cancel trade",
|
|
14
|
+
close: "Close",
|
|
15
|
+
confirm: "Accept these terms",
|
|
16
|
+
confirmation: "Confirm trade",
|
|
17
|
+
confirmationHelp: "Review both sides and the tax deduction. Acceptance uses these original terms; the server checks availability and permission again.",
|
|
18
|
+
expired: "This trade has expired. Refresh to check its final outcome.",
|
|
19
|
+
sending: "Checking the original outcome…",
|
|
20
|
+
complete: "Trade accepted.",
|
|
21
|
+
recovery: "Unresolved trade request",
|
|
22
|
+
uncertain: "The outcome is not confirmed. Check the receipt or retry the saved request.",
|
|
23
|
+
retry: "Retry saved request",
|
|
24
|
+
checkReceipt: "Check receipt",
|
|
25
|
+
reference: "Recovery reference",
|
|
26
|
+
operation: Object.freeze({
|
|
27
|
+
propose: "Propose trade",
|
|
28
|
+
accept: "Accept trade",
|
|
29
|
+
cancel: "Cancel trade"
|
|
30
|
+
}),
|
|
31
|
+
status: Object.freeze({
|
|
32
|
+
proposed: "Awaiting acceptance",
|
|
33
|
+
accepted: "Accepted",
|
|
34
|
+
cancelled: "Cancelled",
|
|
35
|
+
expired: "Expired"
|
|
36
|
+
}),
|
|
37
|
+
expires: (e) => `Expires ${e}`,
|
|
38
|
+
payment: (e, t, n, r) => `${e} ${r} offered · ${t} received · ${n} tax`
|
|
39
|
+
}),
|
|
40
|
+
de: Object.freeze({
|
|
41
|
+
title: "Handel",
|
|
42
|
+
loading: "Handel wird geladen…",
|
|
43
|
+
unavailable: "Der Handel konnte nicht aktualisiert werden. Verbindung prüfen und neu laden.",
|
|
44
|
+
invalid: "Diese Handelsdetails konnten nicht geprüft werden. Vor dem Fortfahren neu laden.",
|
|
45
|
+
empty: "Keine Handelsvorgänge vorhanden.",
|
|
46
|
+
offered: "Angebot des Vorschlagenden",
|
|
47
|
+
requested: "Angebot der Gegenseite",
|
|
48
|
+
emptyLeg: "Keine Items oder Währung gewählt.",
|
|
49
|
+
accept: "Handel prüfen",
|
|
50
|
+
cancel: "Handel abbrechen",
|
|
51
|
+
close: "Schließen",
|
|
52
|
+
confirm: "Diese Bedingungen annehmen",
|
|
53
|
+
confirmation: "Handel bestätigen",
|
|
54
|
+
confirmationHelp: "Beide Seiten und den Steuerabzug prüfen. Die Annahme verwendet diese Originalbedingungen; der Server prüft Verfügbarkeit und Berechtigung erneut.",
|
|
55
|
+
expired: "Dieser Handel ist abgelaufen. Neu laden, um das endgültige Ergebnis zu prüfen.",
|
|
56
|
+
sending: "Das Originalergebnis wird geprüft…",
|
|
57
|
+
complete: "Handel angenommen.",
|
|
58
|
+
recovery: "Ungelöste Handelsanfrage",
|
|
59
|
+
uncertain: "Das Ergebnis ist nicht bestätigt. Beleg prüfen oder die gespeicherte Anfrage erneut senden.",
|
|
60
|
+
retry: "Gespeicherte Anfrage erneut senden",
|
|
61
|
+
checkReceipt: "Beleg prüfen",
|
|
62
|
+
reference: "Recovery-Referenz",
|
|
63
|
+
operation: Object.freeze({
|
|
64
|
+
propose: "Handel vorschlagen",
|
|
65
|
+
accept: "Handel annehmen",
|
|
66
|
+
cancel: "Handel abbrechen"
|
|
67
|
+
}),
|
|
68
|
+
status: Object.freeze({
|
|
69
|
+
proposed: "Annahme ausstehend",
|
|
70
|
+
accepted: "Angenommen",
|
|
71
|
+
cancelled: "Abgebrochen",
|
|
72
|
+
expired: "Abgelaufen"
|
|
73
|
+
}),
|
|
74
|
+
expires: (e) => `Läuft ab: ${e}`,
|
|
75
|
+
payment: (e, t, n, r) => `${e} ${r} angeboten · ${t} empfangen · ${n} Steuer`
|
|
76
|
+
})
|
|
77
|
+
});
|
|
78
|
+
export { e as tradeUiCopy };
|
package/dist/trades.d.ts
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { Context } from 'effect';
|
|
2
|
+
import { Effect } from 'effect';
|
|
3
|
+
import { PluginPrivacyTarget } from '@voltro/protocol';
|
|
4
|
+
import { Schema } from 'effect';
|
|
5
|
+
import { Subject } from '@voltro/protocol';
|
|
6
|
+
import { YieldableError } from 'effect/Cause';
|
|
7
|
+
|
|
8
|
+
export declare const captureTradeLeg: (input: TradeLegDefinition | TradeLeg, declarations: readonly CurrencyDefinition[]) => TradeLeg;
|
|
9
|
+
|
|
10
|
+
export declare const captureTradeObservation: (input: unknown) => TradeObservation;
|
|
11
|
+
|
|
12
|
+
export declare const captureTradeParticipantAuthority: (value: unknown, tenantId: string, expectedOwner: string) => TradeParticipantAuthority;
|
|
13
|
+
|
|
14
|
+
/** Pure detached wire shape only. New admission must still validate actual
|
|
15
|
+
* currencies and rules; originals compare before current declarations. */
|
|
16
|
+
export declare const captureTradeProposeIntention: (input: TradeProposeInput) => Readonly<{
|
|
17
|
+
toId: string | null;
|
|
18
|
+
offered: TradeLeg;
|
|
19
|
+
requested: TradeLeg;
|
|
20
|
+
durationMs: number;
|
|
21
|
+
requestId: string;
|
|
22
|
+
}>;
|
|
23
|
+
|
|
24
|
+
export declare const captureTradeReceipt: (input: unknown) => TradeReceipt;
|
|
25
|
+
|
|
26
|
+
export declare const captureTradesService: (input: TradesService) => TradesService;
|
|
27
|
+
|
|
28
|
+
/** Browser-safe detached receipt shape, never a substitute for server custody/permission proof. */
|
|
29
|
+
export declare const captureTradeView: (input: unknown) => TradeView;
|
|
30
|
+
|
|
31
|
+
declare interface CurrencyDefinition {
|
|
32
|
+
readonly id: string;
|
|
33
|
+
readonly kind: 'soft' | 'hard';
|
|
34
|
+
readonly cap?: EconomyAmountInput;
|
|
35
|
+
readonly premium?: boolean;
|
|
36
|
+
readonly display?: {
|
|
37
|
+
readonly nameKey: string;
|
|
38
|
+
} | null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export declare const defaultTradeEligibilityPolicy: TradeEligibilityPolicy;
|
|
42
|
+
|
|
43
|
+
/** Seller deduction, rounded upward; gross = net + tax exactly. No real-money
|
|
44
|
+
* channel or minted treasury value is part of a tax projection. */
|
|
45
|
+
export declare const defaultTradeTaxPolicy: TradeTaxPolicy;
|
|
46
|
+
|
|
47
|
+
export declare const defineTradeRules: (input: TradeRulesDefinition | TradeRules) => TradeRules;
|
|
48
|
+
|
|
49
|
+
declare type EconomyAmountInput = string | number | bigint;
|
|
50
|
+
|
|
51
|
+
/** Redacted codes; never carries owners, amounts or provider payloads. */
|
|
52
|
+
declare class EconomyError extends EconomyError_base {
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
declare const EconomyError_base: Schema.Class<EconomyError, Schema.TaggedStruct<"EconomyError", {
|
|
56
|
+
readonly code: Schema.Literals<readonly ["invalid_currency", "invalid_amount", "overflow", "invalid_price", "real_money_disabled", "invalid_input", "invalid_record", "currency_cap_reached", "insufficient_funds", "conflict", "forbidden", "unavailable", "not_found", "erased", "limit_exceeded", "already_redeemed"]>;
|
|
57
|
+
}>, YieldableError>;
|
|
58
|
+
|
|
59
|
+
export declare const resolveTradeEligibility: (input: TradeEligibilityContext, policy?: TradeEligibilityPolicy) => boolean;
|
|
60
|
+
|
|
61
|
+
export declare const resolveTradeTax: (input: TradeTaxContext, policy?: TradeTaxPolicy) => Readonly<{
|
|
62
|
+
currency: string;
|
|
63
|
+
gross: string;
|
|
64
|
+
net: string;
|
|
65
|
+
tax: string;
|
|
66
|
+
}>;
|
|
67
|
+
|
|
68
|
+
export declare interface TradeAcceptInput {
|
|
69
|
+
readonly tradeId: string;
|
|
70
|
+
readonly tradeDigest: string;
|
|
71
|
+
readonly requestId: string;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export declare const tradeAcceptIntent: (input: TradeAcceptInput) => TradeAcceptInput;
|
|
75
|
+
|
|
76
|
+
export declare const tradeCancelIntent: (input: {
|
|
77
|
+
readonly tradeId: string;
|
|
78
|
+
readonly requestId: string;
|
|
79
|
+
}) => Readonly<{
|
|
80
|
+
tradeId: string;
|
|
81
|
+
requestId: string;
|
|
82
|
+
}>;
|
|
83
|
+
|
|
84
|
+
export declare interface TradeCurrencyIntention {
|
|
85
|
+
readonly currency: string;
|
|
86
|
+
readonly amount: EconomyAmountInput;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export declare interface TradeEligibilityContext {
|
|
90
|
+
readonly tenantId: string;
|
|
91
|
+
readonly proposerId: string;
|
|
92
|
+
readonly accepterId: string;
|
|
93
|
+
readonly tradeId: string;
|
|
94
|
+
readonly proposedToId: string | null;
|
|
95
|
+
readonly createdAt: number;
|
|
96
|
+
readonly at: number;
|
|
97
|
+
readonly expiresAt: number;
|
|
98
|
+
readonly rules: TradeRules;
|
|
99
|
+
readonly currencies: readonly CurrencyDefinition[];
|
|
100
|
+
readonly offered: TradeLeg;
|
|
101
|
+
readonly requested: TradeLeg;
|
|
102
|
+
readonly proposer: TradeParticipantAuthority;
|
|
103
|
+
readonly accepter: TradeParticipantAuthority;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export declare type TradeEligibilityPolicy = (input: TradeEligibilityContext) => boolean;
|
|
107
|
+
|
|
108
|
+
export declare interface TradeItemAuthority {
|
|
109
|
+
readonly instanceId: string;
|
|
110
|
+
readonly itemId: string;
|
|
111
|
+
readonly qty: number;
|
|
112
|
+
readonly tradable: boolean;
|
|
113
|
+
readonly locked: boolean;
|
|
114
|
+
readonly reservationId: string | null;
|
|
115
|
+
readonly expiresAt: number | null;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export declare interface TradeItemIntention {
|
|
119
|
+
readonly instanceId: string;
|
|
120
|
+
readonly qty: number;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export declare interface TradeLeg {
|
|
124
|
+
readonly items: readonly TradeItemIntention[];
|
|
125
|
+
readonly currencies: readonly {
|
|
126
|
+
readonly currency: string;
|
|
127
|
+
readonly amount: string;
|
|
128
|
+
}[];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export declare interface TradeLegDefinition {
|
|
132
|
+
readonly items: readonly TradeItemIntention[];
|
|
133
|
+
readonly currencies: readonly TradeCurrencyIntention[];
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export declare type TradeObservation = {
|
|
137
|
+
readonly requestId: string;
|
|
138
|
+
readonly state: 'not-observed';
|
|
139
|
+
} | {
|
|
140
|
+
readonly requestId: string;
|
|
141
|
+
readonly state: 'fulfilled';
|
|
142
|
+
readonly receipt: TradeReceipt;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
export declare interface TradeParticipantAuthority {
|
|
146
|
+
readonly tenantId: string;
|
|
147
|
+
readonly ownerId: string;
|
|
148
|
+
readonly allowed: boolean;
|
|
149
|
+
readonly trustScore: number;
|
|
150
|
+
readonly items: readonly TradeItemAuthority[];
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export declare interface TradeProposeInput {
|
|
154
|
+
readonly toId: string | null;
|
|
155
|
+
readonly offered: TradeLegDefinition;
|
|
156
|
+
readonly requested: TradeLegDefinition;
|
|
157
|
+
readonly durationMs: number;
|
|
158
|
+
readonly requestId: string;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export declare const tradeProposeIntent: (input: TradeProposeInput, currencies: readonly CurrencyDefinition[], rulesInput: TradeRulesDefinition) => Readonly<{
|
|
162
|
+
offered: TradeLeg;
|
|
163
|
+
requested: TradeLeg;
|
|
164
|
+
durationMs: number;
|
|
165
|
+
toId: string | null;
|
|
166
|
+
requestId: string;
|
|
167
|
+
}>;
|
|
168
|
+
|
|
169
|
+
export declare interface TradeReceipt {
|
|
170
|
+
readonly operationId: string;
|
|
171
|
+
readonly requestId: string;
|
|
172
|
+
readonly trade: TradeView;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export declare interface TradeRules {
|
|
176
|
+
readonly version: string;
|
|
177
|
+
readonly taxBps: number;
|
|
178
|
+
readonly maxDurationMs: number;
|
|
179
|
+
readonly minTrustScore: number;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export declare interface TradeRulesDefinition {
|
|
183
|
+
readonly version: string;
|
|
184
|
+
readonly taxBps?: number;
|
|
185
|
+
readonly maxDurationMs?: number;
|
|
186
|
+
readonly minTrustScore?: number;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export declare class TradesPort extends TradesPort_base {
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
declare const TradesPort_base: Context.ServiceClass<TradesPort, "@voltro/TradesPort", TradesService>;
|
|
193
|
+
|
|
194
|
+
/** Full owning service; no default implementation or escrow installation is
|
|
195
|
+
* inferred from a Tag. SQL reservation/transfer/expiry/privacy own acceptance. */
|
|
196
|
+
export declare interface TradesService {
|
|
197
|
+
readonly propose: (subject: Subject, input: TradeProposeInput) => Effect.Effect<TradeReceipt, EconomyError>;
|
|
198
|
+
readonly accept: (subject: Subject, input: TradeAcceptInput) => Effect.Effect<TradeReceipt, EconomyError>;
|
|
199
|
+
readonly cancel: (subject: Subject, input: {
|
|
200
|
+
readonly tradeId: string;
|
|
201
|
+
readonly requestId: string;
|
|
202
|
+
}) => Effect.Effect<TradeReceipt, EconomyError>;
|
|
203
|
+
readonly mine: (subject: Subject) => Effect.Effect<readonly TradeView[], EconomyError>;
|
|
204
|
+
readonly receipt: (subject: Subject, input: {
|
|
205
|
+
readonly requestId: string;
|
|
206
|
+
}) => Effect.Effect<TradeObservation, EconomyError>;
|
|
207
|
+
readonly rebuild: (subject: Subject, input: {
|
|
208
|
+
readonly tenantId: string;
|
|
209
|
+
readonly tradeId: string;
|
|
210
|
+
}) => Effect.Effect<TradeView, EconomyError>;
|
|
211
|
+
readonly exportSubject: (target: PluginPrivacyTarget) => Effect.Effect<unknown, EconomyError>;
|
|
212
|
+
readonly eraseSubject: (target: PluginPrivacyTarget) => Effect.Effect<void, EconomyError>;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export declare interface TradeTaxContext {
|
|
216
|
+
readonly currency: string;
|
|
217
|
+
readonly amount: EconomyAmountInput;
|
|
218
|
+
readonly rules: TradeRules;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export declare type TradeTaxPolicy = (input: TradeTaxContext) => EconomyAmountInput;
|
|
222
|
+
|
|
223
|
+
export declare interface TradeTaxView {
|
|
224
|
+
readonly leg: 'offered' | 'requested';
|
|
225
|
+
readonly currency: string;
|
|
226
|
+
readonly gross: string;
|
|
227
|
+
readonly net: string;
|
|
228
|
+
readonly tax: string;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export declare interface TradeView {
|
|
232
|
+
readonly tradeId: string;
|
|
233
|
+
readonly tradeDigest: string;
|
|
234
|
+
readonly proposerId: string;
|
|
235
|
+
readonly toId: string | null;
|
|
236
|
+
readonly offered: TradeLeg;
|
|
237
|
+
readonly requested: TradeLeg;
|
|
238
|
+
readonly createdAt: number;
|
|
239
|
+
readonly expiresAt: number;
|
|
240
|
+
readonly state: 'proposed' | 'accepted' | 'cancelled' | 'expired';
|
|
241
|
+
readonly accepterId: string | null;
|
|
242
|
+
readonly rulesVersion: string;
|
|
243
|
+
readonly taxes: readonly TradeTaxView[];
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export { }
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { captureTradeLeg as e, defaultTradeEligibilityPolicy as t, defaultTradeTaxPolicy as n, defineTradeRules as r, resolveTradeEligibility as i, resolveTradeTax as a } from "./trades.js";
|
|
2
|
+
import { Effect as o } from "effect";
|
|
3
|
+
// src/trades.fixture.ts
|
|
4
|
+
var s = () => {
|
|
5
|
+
let t = [{
|
|
6
|
+
id: "test.gold",
|
|
7
|
+
kind: "soft"
|
|
8
|
+
}], n = r({
|
|
9
|
+
version: "fixture.trade.v1",
|
|
10
|
+
taxBps: 500,
|
|
11
|
+
minTrustScore: 50
|
|
12
|
+
}), i = e({
|
|
13
|
+
items: [{
|
|
14
|
+
instanceId: "instance.a",
|
|
15
|
+
qty: 2
|
|
16
|
+
}],
|
|
17
|
+
currencies: []
|
|
18
|
+
}, t), a = e({
|
|
19
|
+
items: [],
|
|
20
|
+
currencies: [{
|
|
21
|
+
currency: "test.gold",
|
|
22
|
+
amount: "10"
|
|
23
|
+
}]
|
|
24
|
+
}, t);
|
|
25
|
+
return Object.freeze({
|
|
26
|
+
currencies: t,
|
|
27
|
+
rules: n,
|
|
28
|
+
tenantId: "fixture",
|
|
29
|
+
tradeId: "trade.a",
|
|
30
|
+
proposerId: "a",
|
|
31
|
+
accepterId: "b",
|
|
32
|
+
proposedToId: "b",
|
|
33
|
+
createdAt: 0,
|
|
34
|
+
at: 100,
|
|
35
|
+
expiresAt: 1e3,
|
|
36
|
+
offered: i,
|
|
37
|
+
requested: a,
|
|
38
|
+
proposer: {
|
|
39
|
+
tenantId: "fixture",
|
|
40
|
+
ownerId: "a",
|
|
41
|
+
allowed: !0,
|
|
42
|
+
trustScore: 80,
|
|
43
|
+
items: [{
|
|
44
|
+
instanceId: "instance.a",
|
|
45
|
+
itemId: "test.potion",
|
|
46
|
+
qty: 3,
|
|
47
|
+
tradable: !0,
|
|
48
|
+
locked: !0,
|
|
49
|
+
reservationId: "trade.a",
|
|
50
|
+
expiresAt: 5e3
|
|
51
|
+
}]
|
|
52
|
+
},
|
|
53
|
+
accepter: {
|
|
54
|
+
tenantId: "fixture",
|
|
55
|
+
ownerId: "b",
|
|
56
|
+
allowed: !0,
|
|
57
|
+
trustScore: 60,
|
|
58
|
+
items: []
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}, c = s(), l = Object.freeze({
|
|
62
|
+
kind: "slot",
|
|
63
|
+
defaultImplementation: n,
|
|
64
|
+
defaultProbe: {
|
|
65
|
+
run: () => o.sync(() => a({
|
|
66
|
+
currency: "test.gold",
|
|
67
|
+
amount: "100",
|
|
68
|
+
rules: c.rules
|
|
69
|
+
})),
|
|
70
|
+
expected: {
|
|
71
|
+
currency: "test.gold",
|
|
72
|
+
gross: "100",
|
|
73
|
+
net: "95",
|
|
74
|
+
tax: "5"
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
overrideProbe: {
|
|
78
|
+
run: () => o.sync(() => a({
|
|
79
|
+
currency: "test.gold",
|
|
80
|
+
amount: "100",
|
|
81
|
+
rules: c.rules
|
|
82
|
+
}, () => "2")),
|
|
83
|
+
expected: {
|
|
84
|
+
currency: "test.gold",
|
|
85
|
+
gross: "100",
|
|
86
|
+
net: "98",
|
|
87
|
+
tax: "2"
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}), u = Object.freeze({
|
|
91
|
+
kind: "slot",
|
|
92
|
+
defaultImplementation: t,
|
|
93
|
+
defaultProbe: {
|
|
94
|
+
run: () => o.sync(() => i(c)),
|
|
95
|
+
expected: !0
|
|
96
|
+
},
|
|
97
|
+
overrideProbe: {
|
|
98
|
+
run: () => o.sync(() => i(c, () => !1)),
|
|
99
|
+
expected: !1
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
export { u as tradeEligibilitySystemFixture, s as tradeFixture, l as tradeTaxSystemFixture };
|