@tinyburg/treasury-sdk 0.0.0-stage → 0.2.1
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/LICENSE +674 -0
- package/README.md +4 -2
- package/dist/Scopes.d.ts +53 -0
- package/dist/Scopes.d.ts.map +1 -0
- package/dist/Scopes.js +54 -0
- package/dist/Scopes.js.map +1 -0
- package/dist/Sdk.d.ts +1264 -0
- package/dist/Sdk.d.ts.map +1 -0
- package/dist/Sdk.js +328 -0
- package/dist/Sdk.js.map +1 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/package.json +55 -3
- package/src/Scopes.ts +70 -0
- package/src/Sdk.ts +387 -0
- package/src/index.ts +52 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Sdk.d.ts","sourceRoot":"","sources":["../src/Sdk.ts"],"names":[],"mappings":"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"}
|
package/dist/Sdk.js
ADDED
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The api the treasury serves: player-to-player trades, escrowed.
|
|
3
|
+
*
|
|
4
|
+
* Nimblebit has no hold primitive, so the treasury makes one out of the gift
|
|
5
|
+
* channel: each side's item is sent to a treasury-owned vault tower, where it
|
|
6
|
+
* sits as an *unreceived* gift - a native escrow slot - until both deposits
|
|
7
|
+
* are verified, and only then is each item forwarded to the other side. A
|
|
8
|
+
* save-splice trade instead rewrites both saves directly, which is why it
|
|
9
|
+
* requires an explicit confirmation from both parties before anything runs.
|
|
10
|
+
*
|
|
11
|
+
* Every endpoint but the public stats is bearer authenticated with a JWT
|
|
12
|
+
* access token the Tinyburg OAuth server issued for the Tinyburg api
|
|
13
|
+
* (`<site>/v1`), and guarded by a leaf of the `treasury` scope area in
|
|
14
|
+
* `Scopes`. The treasury lives behind tinyburg.app: the paths here are
|
|
15
|
+
* reached at `<site>/v1/treasury/*`, which tinyburg.app forwards verbatim,
|
|
16
|
+
* `Authorization` header included. The first-party app gets its token from
|
|
17
|
+
* tinyburg.app's `/auth/token`; any other application uses the one it was
|
|
18
|
+
* issued.
|
|
19
|
+
*
|
|
20
|
+
* A token without the endpoint's scope is refused with `403` and an
|
|
21
|
+
* `insufficient_scope` challenge. Any other `403` from a trade endpoint
|
|
22
|
+
* means the treasury holds no usable grant for the caller's towers;
|
|
23
|
+
* `GrantStatus` says so explicitly and carries the url that starts the
|
|
24
|
+
* connect flow.
|
|
25
|
+
*
|
|
26
|
+
* @since 1.0.0
|
|
27
|
+
*/
|
|
28
|
+
import { HttpApi, HttpApiEndpoint, HttpApiError, HttpApiGroup } from "effect/http-api";
|
|
29
|
+
import * as Schema from "effect/Schema";
|
|
30
|
+
import * as NimblebitConfig from "@tinyburg/nimblebit-sdk/NimblebitConfig";
|
|
31
|
+
import * as NimblebitScopes from "@tinyburg/nimblebit-sdk/NimblebitScopes";
|
|
32
|
+
import * as SyncItemType from "@tinyburg/tinytower-sdk/SyncItemType";
|
|
33
|
+
import * as OAuthScope from "@yielded/auth/OAuthScope";
|
|
34
|
+
import * as Scopes from "./Scopes.js";
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// Schemas
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
/**
|
|
39
|
+
* How a trade moves its items. `gift` rides Nimblebit's gift channel through
|
|
40
|
+
* the vault; `splice` rewrites both saves and can carry what the gift channel
|
|
41
|
+
* cannot (costumes, pets, coins, bux).
|
|
42
|
+
*
|
|
43
|
+
* @since 1.0.0
|
|
44
|
+
* @category Schemas
|
|
45
|
+
*/
|
|
46
|
+
export const TradeMechanism = /*#__PURE__*/Schema.Literals(["gift", "splice"]);
|
|
47
|
+
/**
|
|
48
|
+
* The games the treasury trades in. TinyTower only, until the tinyburg api
|
|
49
|
+
* serves more.
|
|
50
|
+
*
|
|
51
|
+
* @since 1.0.0
|
|
52
|
+
* @category Schemas
|
|
53
|
+
*/
|
|
54
|
+
export const TradeGame = /*#__PURE__*/Schema.Literals(["tinytower"]);
|
|
55
|
+
/**
|
|
56
|
+
* Where a trade is in its life. The happy path is `proposed` → `accepted` →
|
|
57
|
+
* (`awaiting_confirmation`, splice only) → `escrowing` → `escrowed` →
|
|
58
|
+
* `releasing` (gift) or `executing` (splice) → `settled`; everything else is
|
|
59
|
+
* one of the ways out.
|
|
60
|
+
*
|
|
61
|
+
* @since 1.0.0
|
|
62
|
+
* @category Schemas
|
|
63
|
+
*/
|
|
64
|
+
export const TradeState = /*#__PURE__*/Schema.Literals(["proposed", "accepted", "awaiting_confirmation", "escrowing", "escrowed", "releasing", "executing", "settled", "cancelled", "refunding", "refunded", "expired", "failed"]);
|
|
65
|
+
/**
|
|
66
|
+
* One side of a gift trade's journey through the vault: `pending` → `sent`
|
|
67
|
+
* (deposit dispatched) → `verified` (seen in the vault's gift queue) →
|
|
68
|
+
* `released` (forwarded to the counterparty) → `settled` (vault slot
|
|
69
|
+
* claimed); refunds run `refund_sent` → `refunded`, and `lost` is a deposit
|
|
70
|
+
* that never arrived.
|
|
71
|
+
*
|
|
72
|
+
* @since 1.0.0
|
|
73
|
+
* @category Schemas
|
|
74
|
+
*/
|
|
75
|
+
export const LegState = /*#__PURE__*/Schema.Literals(["pending", "sent", "verified", "released", "settled", "refund_sent", "refunded", "lost"]);
|
|
76
|
+
/**
|
|
77
|
+
* @since 1.0.0
|
|
78
|
+
* @category Schemas
|
|
79
|
+
*/
|
|
80
|
+
export const TradeRole = /*#__PURE__*/Schema.Literals(["proposer", "counterparty"]);
|
|
81
|
+
/**
|
|
82
|
+
* One item offered over the gift channel, in the encoded form the game
|
|
83
|
+
* exchanges items in - the same string `SendItem` carries.
|
|
84
|
+
*
|
|
85
|
+
* @since 1.0.0
|
|
86
|
+
* @category Schemas
|
|
87
|
+
*/
|
|
88
|
+
export const GiftItem = /*#__PURE__*/Schema.Struct({
|
|
89
|
+
_tag: /*#__PURE__*/Schema.tag("GiftItem"),
|
|
90
|
+
itemType: /*#__PURE__*/Schema.Enum(SyncItemType.SyncItemType),
|
|
91
|
+
item: Schema.String
|
|
92
|
+
});
|
|
93
|
+
/**
|
|
94
|
+
* One item offered by splice. Bitizens, costumes and pets carry the encoded
|
|
95
|
+
* string a save stores them as; coins and bux carry an amount instead.
|
|
96
|
+
*
|
|
97
|
+
* @since 1.0.0
|
|
98
|
+
* @category Schemas
|
|
99
|
+
*/
|
|
100
|
+
export const SpliceItem = /*#__PURE__*/Schema.Struct({
|
|
101
|
+
kind: /*#__PURE__*/Schema.Literals(["bitizen", "costume", "pet", "coins", "bux"]),
|
|
102
|
+
item: /*#__PURE__*/Schema.optional(Schema.String),
|
|
103
|
+
amount: /*#__PURE__*/Schema.optional(Schema.Int)
|
|
104
|
+
});
|
|
105
|
+
/**
|
|
106
|
+
* @since 1.0.0
|
|
107
|
+
* @category Schemas
|
|
108
|
+
*/
|
|
109
|
+
export const SpliceItems = /*#__PURE__*/Schema.Struct({
|
|
110
|
+
_tag: /*#__PURE__*/Schema.tag("SpliceItems"),
|
|
111
|
+
items: /*#__PURE__*/Schema.Array(SpliceItem)
|
|
112
|
+
});
|
|
113
|
+
/**
|
|
114
|
+
* What one side of a trade puts in: a gift-channel item or a list of splice
|
|
115
|
+
* items, matching the trade's mechanism.
|
|
116
|
+
*
|
|
117
|
+
* @since 1.0.0
|
|
118
|
+
* @category Schemas
|
|
119
|
+
*/
|
|
120
|
+
export const ItemSpec = /*#__PURE__*/Schema.Union([GiftItem, SpliceItems]);
|
|
121
|
+
/**
|
|
122
|
+
* A trade as the api describes it. `gives` and `wants` are always from the
|
|
123
|
+
* proposer's point of view; `role` is which side the caller is on, absent for
|
|
124
|
+
* an open offer the caller could accept.
|
|
125
|
+
*
|
|
126
|
+
* @since 1.0.0
|
|
127
|
+
* @category Schemas
|
|
128
|
+
*/
|
|
129
|
+
export const Trade = /*#__PURE__*/Schema.Struct({
|
|
130
|
+
id: Schema.String,
|
|
131
|
+
mechanism: TradeMechanism,
|
|
132
|
+
game: TradeGame,
|
|
133
|
+
state: TradeState,
|
|
134
|
+
proposerPlayerId: NimblebitConfig.PlayerIdSchema,
|
|
135
|
+
counterpartyPlayerId: /*#__PURE__*/Schema.optional(NimblebitConfig.PlayerIdSchema),
|
|
136
|
+
gives: ItemSpec,
|
|
137
|
+
wants: ItemSpec,
|
|
138
|
+
role: /*#__PURE__*/Schema.optional(TradeRole),
|
|
139
|
+
proposerConfirmedAt: /*#__PURE__*/Schema.optional(Schema.DateTimeUtcFromString),
|
|
140
|
+
counterpartyConfirmedAt: /*#__PURE__*/Schema.optional(Schema.DateTimeUtcFromString),
|
|
141
|
+
createdAt: Schema.DateTimeUtcFromString,
|
|
142
|
+
expiresAt: Schema.DateTimeUtcFromString,
|
|
143
|
+
failureReason: /*#__PURE__*/Schema.optional(Schema.String)
|
|
144
|
+
});
|
|
145
|
+
/**
|
|
146
|
+
* @since 1.0.0
|
|
147
|
+
* @category Schemas
|
|
148
|
+
*/
|
|
149
|
+
export const TradeLeg = /*#__PURE__*/Schema.Struct({
|
|
150
|
+
role: TradeRole,
|
|
151
|
+
fromPlayerId: NimblebitConfig.PlayerIdSchema,
|
|
152
|
+
toPlayerId: NimblebitConfig.PlayerIdSchema,
|
|
153
|
+
state: LegState,
|
|
154
|
+
itemType: /*#__PURE__*/Schema.Enum(SyncItemType.SyncItemType),
|
|
155
|
+
item: Schema.String
|
|
156
|
+
});
|
|
157
|
+
/**
|
|
158
|
+
* One entry of a trade's append-only history, as shown on its timeline.
|
|
159
|
+
*
|
|
160
|
+
* @since 1.0.0
|
|
161
|
+
* @category Schemas
|
|
162
|
+
*/
|
|
163
|
+
export const LedgerEvent = /*#__PURE__*/Schema.Struct({
|
|
164
|
+
event: Schema.String,
|
|
165
|
+
at: Schema.DateTimeUtcFromString
|
|
166
|
+
});
|
|
167
|
+
/**
|
|
168
|
+
* A trade with its legs and its history, for the participants only.
|
|
169
|
+
*
|
|
170
|
+
* @since 1.0.0
|
|
171
|
+
* @category Schemas
|
|
172
|
+
*/
|
|
173
|
+
export const TradeDetail = /*#__PURE__*/Schema.Struct({
|
|
174
|
+
trade: Trade,
|
|
175
|
+
legs: /*#__PURE__*/Schema.Array(TradeLeg),
|
|
176
|
+
ledger: /*#__PURE__*/Schema.Array(LedgerEvent)
|
|
177
|
+
});
|
|
178
|
+
/**
|
|
179
|
+
* Whether the treasury can currently act on the caller's towers, and where
|
|
180
|
+
* to go to make it so. The url is built server-side so the browser stays
|
|
181
|
+
* configuration-free.
|
|
182
|
+
*
|
|
183
|
+
* @since 1.0.0
|
|
184
|
+
* @category Schemas
|
|
185
|
+
*/
|
|
186
|
+
export const GrantStatus = /*#__PURE__*/Schema.Struct({
|
|
187
|
+
connected: Schema.Boolean,
|
|
188
|
+
scope: /*#__PURE__*/Schema.optional(Schema.String),
|
|
189
|
+
connectUrl: Schema.String
|
|
190
|
+
});
|
|
191
|
+
/**
|
|
192
|
+
* What a tower could put into a trade, read out of its save. Bitizens are the
|
|
193
|
+
* encoded strings the gift channel carries; costumes and pets are the strings
|
|
194
|
+
* the save stores.
|
|
195
|
+
*
|
|
196
|
+
* @since 1.0.0
|
|
197
|
+
* @category Schemas
|
|
198
|
+
*/
|
|
199
|
+
export const Inventory = /*#__PURE__*/Schema.Struct({
|
|
200
|
+
playerId: NimblebitConfig.PlayerIdSchema,
|
|
201
|
+
bitizens: /*#__PURE__*/Schema.Array(Schema.String),
|
|
202
|
+
costumes: /*#__PURE__*/Schema.Array(Schema.String),
|
|
203
|
+
pets: /*#__PURE__*/Schema.Array(Schema.String),
|
|
204
|
+
coins: Schema.Int,
|
|
205
|
+
bux: Schema.Int
|
|
206
|
+
});
|
|
207
|
+
/**
|
|
208
|
+
* The treasury's public counters, for the home page's stat tiles. Counts
|
|
209
|
+
* only, cached server-side, and deliberately free of anything per-user.
|
|
210
|
+
*
|
|
211
|
+
* @since 1.0.0
|
|
212
|
+
* @category Schemas
|
|
213
|
+
*/
|
|
214
|
+
export const TreasuryStats = /*#__PURE__*/Schema.Struct({
|
|
215
|
+
activeTraders: Schema.Int,
|
|
216
|
+
settledTrades: Schema.Int,
|
|
217
|
+
itemsMoved: Schema.Int
|
|
218
|
+
});
|
|
219
|
+
/**
|
|
220
|
+
* @since 1.0.0
|
|
221
|
+
* @category Schemas
|
|
222
|
+
*/
|
|
223
|
+
export const TradeProposal = /*#__PURE__*/Schema.Struct({
|
|
224
|
+
mechanism: TradeMechanism,
|
|
225
|
+
game: TradeGame,
|
|
226
|
+
proposerPlayerId: NimblebitConfig.PlayerIdSchema,
|
|
227
|
+
/** Absent for an open offer, which whoever accepts first gets. */
|
|
228
|
+
counterpartyPlayerId: /*#__PURE__*/Schema.optional(NimblebitConfig.PlayerIdSchema),
|
|
229
|
+
gives: ItemSpec,
|
|
230
|
+
wants: ItemSpec,
|
|
231
|
+
ttlHours: /*#__PURE__*/Schema.Int.check(/*#__PURE__*/Schema.isBetween({
|
|
232
|
+
minimum: 1,
|
|
233
|
+
maximum: 168
|
|
234
|
+
}))
|
|
235
|
+
});
|
|
236
|
+
// ---------------------------------------------------------------------------
|
|
237
|
+
// Endpoints
|
|
238
|
+
// ---------------------------------------------------------------------------
|
|
239
|
+
const tradeId = Schema.String;
|
|
240
|
+
const playerId = NimblebitConfig.PlayerIdSchema;
|
|
241
|
+
/**
|
|
242
|
+
* What acting on a trade can fail with: it does not exist or the caller is
|
|
243
|
+
* not a participant (`404`, and the api never confirms a trade exists to a
|
|
244
|
+
* stranger), it is not in a state the action applies to (`409`), the
|
|
245
|
+
* treasury holds no usable grant for the caller (`403`), or the world
|
|
246
|
+
* beyond - tinyburg.app, Nimblebit - did not cooperate (`503`).
|
|
247
|
+
*/
|
|
248
|
+
const TradeErrors = [HttpApiError.NotFound, HttpApiError.Conflict, HttpApiError.Forbidden, HttpApiError.ServiceUnavailable];
|
|
249
|
+
const GetGrantStatus = /*#__PURE__*/HttpApiEndpoint.get("GrantStatus", "/v1/treasury/grant", {
|
|
250
|
+
success: GrantStatus
|
|
251
|
+
}).annotate(OAuthScope.Required, Scopes.Treasury.read.grant_status.required);
|
|
252
|
+
const ListTrades = /*#__PURE__*/HttpApiEndpoint.get("ListTrades", "/v1/treasury/trades", {
|
|
253
|
+
success: Schema.Array(Trade)
|
|
254
|
+
}).annotate(OAuthScope.Required, Scopes.Treasury.read.list_trades.required);
|
|
255
|
+
const GetTrade = /*#__PURE__*/HttpApiEndpoint.get("GetTrade", "/v1/treasury/trades/:tradeId", {
|
|
256
|
+
params: {
|
|
257
|
+
tradeId
|
|
258
|
+
},
|
|
259
|
+
error: HttpApiError.NotFound,
|
|
260
|
+
success: TradeDetail
|
|
261
|
+
}).annotate(OAuthScope.Required, Scopes.Treasury.read.get_trade.required);
|
|
262
|
+
const ProposeTrade = /*#__PURE__*/HttpApiEndpoint.post("ProposeTrade", "/v1/treasury/trades", {
|
|
263
|
+
payload: TradeProposal,
|
|
264
|
+
error: [HttpApiError.BadRequest, HttpApiError.Forbidden, HttpApiError.ServiceUnavailable],
|
|
265
|
+
success: Trade
|
|
266
|
+
}).annotate(OAuthScope.Required, Scopes.Treasury.write.propose.required);
|
|
267
|
+
const AcceptTrade = /*#__PURE__*/HttpApiEndpoint.post("AcceptTrade", "/v1/treasury/trades/:tradeId/accept", {
|
|
268
|
+
params: {
|
|
269
|
+
tradeId
|
|
270
|
+
},
|
|
271
|
+
payload: Schema.Struct({
|
|
272
|
+
playerId
|
|
273
|
+
}),
|
|
274
|
+
error: TradeErrors,
|
|
275
|
+
success: Trade
|
|
276
|
+
}).annotate(OAuthScope.Required, Scopes.Treasury.write.accept.required);
|
|
277
|
+
const CancelTrade = /*#__PURE__*/HttpApiEndpoint.post("CancelTrade", "/v1/treasury/trades/:tradeId/cancel", {
|
|
278
|
+
params: {
|
|
279
|
+
tradeId
|
|
280
|
+
},
|
|
281
|
+
error: [HttpApiError.NotFound, HttpApiError.Conflict],
|
|
282
|
+
success: Trade
|
|
283
|
+
}).annotate(OAuthScope.Required, Scopes.Treasury.write.cancel.required);
|
|
284
|
+
const ConfirmSplice = /*#__PURE__*/HttpApiEndpoint.post("ConfirmSplice", "/v1/treasury/trades/:tradeId/confirm", {
|
|
285
|
+
params: {
|
|
286
|
+
tradeId
|
|
287
|
+
},
|
|
288
|
+
error: [HttpApiError.NotFound, HttpApiError.Conflict],
|
|
289
|
+
success: Trade
|
|
290
|
+
}).annotate(OAuthScope.Required, Scopes.Treasury.write.confirm_splice.required);
|
|
291
|
+
const ListInventory = /*#__PURE__*/HttpApiEndpoint.get("ListInventory", "/v1/treasury/inventory/:playerId", {
|
|
292
|
+
params: {
|
|
293
|
+
playerId
|
|
294
|
+
},
|
|
295
|
+
error: [HttpApiError.NotFound, HttpApiError.Forbidden, HttpApiError.ServiceUnavailable],
|
|
296
|
+
success: Inventory
|
|
297
|
+
}).annotate(OAuthScope.Required, Scopes.Treasury.read.list_inventory.required);
|
|
298
|
+
const GetStats = /*#__PURE__*/HttpApiEndpoint.get("Stats", "/v1/treasury/stats", {
|
|
299
|
+
success: TreasuryStats
|
|
300
|
+
});
|
|
301
|
+
// ---------------------------------------------------------------------------
|
|
302
|
+
// Groups
|
|
303
|
+
// ---------------------------------------------------------------------------
|
|
304
|
+
/**
|
|
305
|
+
* Everything the treasury serves. The group annotation is the floor: an
|
|
306
|
+
* endpoint added later without its own leaf accepts only the whole
|
|
307
|
+
* `treasury` scope, so nothing defaults to a weaker permission.
|
|
308
|
+
*
|
|
309
|
+
* @since 1.0.0
|
|
310
|
+
* @category Groups
|
|
311
|
+
*/
|
|
312
|
+
export const TreasuryGroup = /*#__PURE__*/HttpApiGroup.make("TreasuryGroup").add(GetGrantStatus).add(ListTrades).add(GetTrade).add(ProposeTrade).add(AcceptTrade).add(CancelTrade).add(ConfirmSplice).add(ListInventory).annotate(OAuthScope.Required, NimblebitScopes.requiredBy(Scopes.Treasury)).middleware(OAuthScope.RequireAccess);
|
|
313
|
+
/**
|
|
314
|
+
* What the treasury tells anyone at all: the stat counters the home page
|
|
315
|
+
* shows. The one group without `RequireAccess` or a scope requirement, and
|
|
316
|
+
* it must stay that way - the home page is public, so this rides
|
|
317
|
+
* tinyburg.app's proxy without a token behind it.
|
|
318
|
+
*
|
|
319
|
+
* @since 1.0.0
|
|
320
|
+
* @category Groups
|
|
321
|
+
*/
|
|
322
|
+
export const TreasuryPublicGroup = /*#__PURE__*/HttpApiGroup.make("TreasuryPublicGroup").add(GetStats);
|
|
323
|
+
/**
|
|
324
|
+
* @since 1.0.0
|
|
325
|
+
* @category Api
|
|
326
|
+
*/
|
|
327
|
+
export const Api = /*#__PURE__*/HttpApi.make("TreasurySdk").add(TreasuryGroup).add(TreasuryPublicGroup);
|
|
328
|
+
//# sourceMappingURL=Sdk.js.map
|
package/dist/Sdk.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Sdk.js","names":[],"sources":["../src/Sdk.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since 1.0.0
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* The scopes the treasury api is guarded by, as one `treasury` area.
|
|
6
|
+
*
|
|
7
|
+
* These guard the treasury's own api - proposing, accepting and watching
|
|
8
|
+
* trades - not the towers the trades move items between. Acting on a tower
|
|
9
|
+
* (depositing an item into escrow, splicing a save) happens through the
|
|
10
|
+
* tinyburg api under that game's own scopes, with a grant the player gives the
|
|
11
|
+
* treasury separately on the consent screen. Splitting the two means "let the
|
|
12
|
+
* treasury manage my trades" and "let the treasury touch my tower" are
|
|
13
|
+
* distinct questions with distinct answers.
|
|
14
|
+
*
|
|
15
|
+
* The area is built with the same `defineArea` every game's scopes are, so
|
|
16
|
+
* `Treasury.read.list_trades` is the leaf named `treasury:list_trades`, and
|
|
17
|
+
* `Treasury.read.list_trades.required` is what goes on the endpoint.
|
|
18
|
+
*
|
|
19
|
+
* @since 1.0.0
|
|
20
|
+
* @category Scopes
|
|
21
|
+
*/
|
|
22
|
+
export * as Scopes from "./Scopes.ts";
|
|
23
|
+
/**
|
|
24
|
+
* The api the treasury serves: player-to-player trades, escrowed.
|
|
25
|
+
*
|
|
26
|
+
* Nimblebit has no hold primitive, so the treasury makes one out of the gift
|
|
27
|
+
* channel: each side's item is sent to a treasury-owned vault tower, where it
|
|
28
|
+
* sits as an *unreceived* gift - a native escrow slot - until both deposits
|
|
29
|
+
* are verified, and only then is each item forwarded to the other side. A
|
|
30
|
+
* save-splice trade instead rewrites both saves directly, which is why it
|
|
31
|
+
* requires an explicit confirmation from both parties before anything runs.
|
|
32
|
+
*
|
|
33
|
+
* Every endpoint but the public stats is bearer authenticated with a JWT
|
|
34
|
+
* access token the Tinyburg OAuth server issued for the Tinyburg api
|
|
35
|
+
* (`<site>/v1`), and guarded by a leaf of the `treasury` scope area in
|
|
36
|
+
* `Scopes`. The treasury lives behind tinyburg.app: the paths here are
|
|
37
|
+
* reached at `<site>/v1/treasury/*`, which tinyburg.app forwards verbatim,
|
|
38
|
+
* `Authorization` header included. The first-party app gets its token from
|
|
39
|
+
* tinyburg.app's `/auth/token`; any other application uses the one it was
|
|
40
|
+
* issued.
|
|
41
|
+
*
|
|
42
|
+
* A token without the endpoint's scope is refused with `403` and an
|
|
43
|
+
* `insufficient_scope` challenge. Any other `403` from a trade endpoint
|
|
44
|
+
* means the treasury holds no usable grant for the caller's towers;
|
|
45
|
+
* `GrantStatus` says so explicitly and carries the url that starts the
|
|
46
|
+
* connect flow.
|
|
47
|
+
*
|
|
48
|
+
* @since 1.0.0
|
|
49
|
+
*/
|
|
50
|
+
export * as Sdk from "./Sdk.ts";
|
|
51
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since 1.0.0
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* The scopes the treasury api is guarded by, as one `treasury` area.
|
|
6
|
+
*
|
|
7
|
+
* These guard the treasury's own api - proposing, accepting and watching
|
|
8
|
+
* trades - not the towers the trades move items between. Acting on a tower
|
|
9
|
+
* (depositing an item into escrow, splicing a save) happens through the
|
|
10
|
+
* tinyburg api under that game's own scopes, with a grant the player gives the
|
|
11
|
+
* treasury separately on the consent screen. Splitting the two means "let the
|
|
12
|
+
* treasury manage my trades" and "let the treasury touch my tower" are
|
|
13
|
+
* distinct questions with distinct answers.
|
|
14
|
+
*
|
|
15
|
+
* The area is built with the same `defineArea` every game's scopes are, so
|
|
16
|
+
* `Treasury.read.list_trades` is the leaf named `treasury:list_trades`, and
|
|
17
|
+
* `Treasury.read.list_trades.required` is what goes on the endpoint.
|
|
18
|
+
*
|
|
19
|
+
* @since 1.0.0
|
|
20
|
+
* @category Scopes
|
|
21
|
+
*/
|
|
22
|
+
export * as Scopes from "./Scopes.js";
|
|
23
|
+
/**
|
|
24
|
+
* The api the treasury serves: player-to-player trades, escrowed.
|
|
25
|
+
*
|
|
26
|
+
* Nimblebit has no hold primitive, so the treasury makes one out of the gift
|
|
27
|
+
* channel: each side's item is sent to a treasury-owned vault tower, where it
|
|
28
|
+
* sits as an *unreceived* gift - a native escrow slot - until both deposits
|
|
29
|
+
* are verified, and only then is each item forwarded to the other side. A
|
|
30
|
+
* save-splice trade instead rewrites both saves directly, which is why it
|
|
31
|
+
* requires an explicit confirmation from both parties before anything runs.
|
|
32
|
+
*
|
|
33
|
+
* Every endpoint but the public stats is bearer authenticated with a JWT
|
|
34
|
+
* access token the Tinyburg OAuth server issued for the Tinyburg api
|
|
35
|
+
* (`<site>/v1`), and guarded by a leaf of the `treasury` scope area in
|
|
36
|
+
* `Scopes`. The treasury lives behind tinyburg.app: the paths here are
|
|
37
|
+
* reached at `<site>/v1/treasury/*`, which tinyburg.app forwards verbatim,
|
|
38
|
+
* `Authorization` header included. The first-party app gets its token from
|
|
39
|
+
* tinyburg.app's `/auth/token`; any other application uses the one it was
|
|
40
|
+
* issued.
|
|
41
|
+
*
|
|
42
|
+
* A token without the endpoint's scope is refused with `403` and an
|
|
43
|
+
* `insufficient_scope` challenge. Any other `403` from a trade endpoint
|
|
44
|
+
* means the treasury holds no usable grant for the caller's towers;
|
|
45
|
+
* `GrantStatus` says so explicitly and carries the url that starts the
|
|
46
|
+
* connect flow.
|
|
47
|
+
*
|
|
48
|
+
* @since 1.0.0
|
|
49
|
+
*/
|
|
50
|
+
export * as Sdk from "./Sdk.js";
|
|
51
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA;;;AAIA;;;;;;;;;;;;;;;;;;AAkBA,OAAO,KAAK,MAAM,MAAM,aAAa;AAErC;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,OAAO,KAAK,GAAG,MAAM,UAAU","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,58 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tinyburg/treasury-sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "treasury (trade escrow) sdk for tinyburg.app",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"nimblebit",
|
|
7
|
+
"tinytower",
|
|
8
|
+
"tinytowers"
|
|
9
|
+
],
|
|
10
|
+
"homepage": "https://github.com/leonitousconforti/tinyburg",
|
|
11
|
+
"license": "GPL-3.0-only",
|
|
12
|
+
"author": "Leo Conforti <leo@leoconforti.us> (https://leoconforti.us)",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/leonitousconforti/tinyburg.git",
|
|
16
|
+
"directory": "packages/treasury-sdk"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"src/**/*.ts",
|
|
20
|
+
"dist/**/*.js",
|
|
21
|
+
"dist/**/*.js.map",
|
|
22
|
+
"dist/**/*.d.ts",
|
|
23
|
+
"dist/**/*.d.ts.map"
|
|
24
|
+
],
|
|
25
|
+
"type": "module",
|
|
26
|
+
"sideEffects": false,
|
|
27
|
+
"exports": {
|
|
28
|
+
"./package.json": "./package.json",
|
|
29
|
+
".": "./dist/index.js",
|
|
30
|
+
"./*": "./dist/*.js",
|
|
31
|
+
"./internal/*": null
|
|
32
|
+
},
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@tinyburg/nimblebit-sdk": "^0.2.1",
|
|
38
|
+
"@tinyburg/tinytower-sdk": "^0.2.1"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@yielded/auth": "0.1.0-beta.47",
|
|
42
|
+
"effect": "4.1.1"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"@yielded/auth": "0.1.0-beta.47",
|
|
46
|
+
"effect": "4.1.1"
|
|
47
|
+
},
|
|
48
|
+
"tags": [
|
|
49
|
+
"nimblebit",
|
|
50
|
+
"tinytower",
|
|
51
|
+
"tinytowers"
|
|
52
|
+
],
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "tsc -b tsconfig.build.json && babel dist --plugins annotate-pure-calls --out-dir dist --source-maps",
|
|
55
|
+
"check": "tsc -b tsconfig.json",
|
|
56
|
+
"codegen": "build-utils prepare-v4"
|
|
57
|
+
}
|
|
6
58
|
}
|
package/src/Scopes.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The scopes the treasury api is guarded by, as one `treasury` area.
|
|
3
|
+
*
|
|
4
|
+
* These guard the treasury's own api - proposing, accepting and watching
|
|
5
|
+
* trades - not the towers the trades move items between. Acting on a tower
|
|
6
|
+
* (depositing an item into escrow, splicing a save) happens through the
|
|
7
|
+
* tinyburg api under that game's own scopes, with a grant the player gives the
|
|
8
|
+
* treasury separately on the consent screen. Splitting the two means "let the
|
|
9
|
+
* treasury manage my trades" and "let the treasury touch my tower" are
|
|
10
|
+
* distinct questions with distinct answers.
|
|
11
|
+
*
|
|
12
|
+
* The area is built with the same `defineArea` every game's scopes are, so
|
|
13
|
+
* `Treasury.read.list_trades` is the leaf named `treasury:list_trades`, and
|
|
14
|
+
* `Treasury.read.list_trades.required` is what goes on the endpoint.
|
|
15
|
+
*
|
|
16
|
+
* @since 1.0.0
|
|
17
|
+
* @category Scopes
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { type ScopeDescription, defineArea } from "@tinyburg/nimblebit-sdk/NimblebitScopes";
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @since 1.0.0
|
|
24
|
+
* @category Areas
|
|
25
|
+
*/
|
|
26
|
+
export const Treasury = defineArea({
|
|
27
|
+
name: "treasury",
|
|
28
|
+
description: "Trades escrowed by the Tinyburg treasury",
|
|
29
|
+
read: {
|
|
30
|
+
description: "See your trades and what could go into them, without changing anything",
|
|
31
|
+
leaves: {
|
|
32
|
+
grant_status: "Check whether the treasury can act on your towers",
|
|
33
|
+
list_trades: "List your trades and the open offers you could accept",
|
|
34
|
+
get_trade: "See one trade's full state and history",
|
|
35
|
+
list_inventory: "See which of a tower's items could be traded",
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
write: {
|
|
39
|
+
description: "Propose, accept, cancel and confirm trades",
|
|
40
|
+
leaves: {
|
|
41
|
+
propose: "Propose a trade with another player",
|
|
42
|
+
accept: "Accept a trade proposed to you",
|
|
43
|
+
cancel: "Cancel a trade you are part of",
|
|
44
|
+
confirm_splice: "Confirm a save-splice trade for execution",
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The shape of the treasury's area, for code that takes it as a value.
|
|
51
|
+
*
|
|
52
|
+
* @since 1.0.0
|
|
53
|
+
* @category Areas
|
|
54
|
+
*/
|
|
55
|
+
export type TreasuryArea = typeof Treasury;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Every scope in the tree, the area first, then each branch, then its
|
|
59
|
+
* leaves. The order a consent screen lists them in.
|
|
60
|
+
*
|
|
61
|
+
* @since 1.0.0
|
|
62
|
+
* @category Tree
|
|
63
|
+
*/
|
|
64
|
+
export const all = (): ReadonlyArray<ScopeDescription> => [
|
|
65
|
+
Treasury,
|
|
66
|
+
Treasury.read,
|
|
67
|
+
...Treasury.read.children,
|
|
68
|
+
Treasury.write,
|
|
69
|
+
...Treasury.write.children,
|
|
70
|
+
];
|