@playmos/sdk 0.1.6 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -0
- package/dist/errors-CjL85YKR.d.cts +502 -0
- package/dist/errors-CjL85YKR.d.ts +502 -0
- package/dist/index.cjs +602 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +327 -17
- package/dist/index.d.ts +327 -17
- package/dist/index.js +593 -14
- package/dist/index.js.map +1 -1
- package/dist/server.d.cts +1 -1
- package/dist/server.d.ts +1 -1
- package/package.json +3 -3
- package/dist/errors-B-85VYMv.d.cts +0 -224
- package/dist/errors-B-85VYMv.d.ts +0 -224
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public types — pruned to WIRED capability only (fixes #344/I and #335/E).
|
|
3
|
+
*
|
|
4
|
+
* The old vendored surface advertised four wallet connectors that silently
|
|
5
|
+
* returned {connected:false} and config fields the code never read. Here the
|
|
6
|
+
* types expose exactly what V1 does: two connectors, the fields `pay()` /
|
|
7
|
+
* `enterRound()` actually use, and no more.
|
|
8
|
+
*/
|
|
9
|
+
type Network = "base" | "base-sepolia";
|
|
10
|
+
/** Only the connectors that are actually implemented. */
|
|
11
|
+
type WalletConnector = "base-account" | "injected";
|
|
12
|
+
type GasMode = "sponsored" | "player";
|
|
13
|
+
type PaymentStatus = "created" | "pending" | "confirmed" | "failed";
|
|
14
|
+
/** Minimal EIP-1193 provider shape (what the wallet must expose). */
|
|
15
|
+
interface Eip1193Provider {
|
|
16
|
+
request(args: {
|
|
17
|
+
method: string;
|
|
18
|
+
params?: unknown[] | object;
|
|
19
|
+
}): Promise<unknown>;
|
|
20
|
+
}
|
|
21
|
+
interface GasConfig {
|
|
22
|
+
mode?: GasMode;
|
|
23
|
+
/** CDP paymaster URL — required only for `mode: "sponsored"`. */
|
|
24
|
+
paymasterUrl?: string;
|
|
25
|
+
}
|
|
26
|
+
interface WalletConfig {
|
|
27
|
+
connector?: WalletConnector;
|
|
28
|
+
/**
|
|
29
|
+
* Pre-built EIP-1193 provider. If omitted, `injected` uses globalThis.ethereum
|
|
30
|
+
* and `base-account` expects a provider supplied by the Base Account SDK host.
|
|
31
|
+
*/
|
|
32
|
+
provider?: Eip1193Provider;
|
|
33
|
+
}
|
|
34
|
+
/** Per-game contract addresses. On testnet these come from the service intent,
|
|
35
|
+
* but a studio may pin them explicitly (matches the dogfood adapter). */
|
|
36
|
+
interface ContractConfig {
|
|
37
|
+
usdc?: `0x${string}`;
|
|
38
|
+
playmosPay?: `0x${string}`;
|
|
39
|
+
prizePool?: `0x${string}`;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* @deprecated Unused — agent routes are enabled server-side (SERVICE_MASTER_SECRET +
|
|
43
|
+
* transfer contracts). Prefer `sk_test_` + `agents.createWallet`; do not set this.
|
|
44
|
+
* Kept optional so old clients don't type-error (issue #23).
|
|
45
|
+
*/
|
|
46
|
+
interface AgentEconomyConfig {
|
|
47
|
+
enabled?: boolean;
|
|
48
|
+
}
|
|
49
|
+
interface PlaymosConfig {
|
|
50
|
+
/** pk_test_* / sk_test_* (sandbox / Base Sepolia) or pk_live_* / sk_live_* (mainnet).
|
|
51
|
+
* Agents require **sk_test_** (secret studio key), not the public pk_test_ sandbox key. */
|
|
52
|
+
apiKey: string;
|
|
53
|
+
/** Override the network derived from the key. Explicit value wins. */
|
|
54
|
+
network?: Network;
|
|
55
|
+
wallet?: WalletConfig;
|
|
56
|
+
gas?: GasConfig;
|
|
57
|
+
/** @deprecated No-op. Server enables agents; use sk_test_ + agents.* (issue #23). */
|
|
58
|
+
agentEconomy?: AgentEconomyConfig;
|
|
59
|
+
contracts?: ContractConfig;
|
|
60
|
+
/** Escape hatch; defaults to the right env's base URL. */
|
|
61
|
+
apiBaseUrl?: string;
|
|
62
|
+
/**
|
|
63
|
+
* Explicit, clearly-labeled offline unit-test helper — instant, deterministic,
|
|
64
|
+
* NO network, NO chain. Never the default, never conflated with sandbox. Note:
|
|
65
|
+
* even mock results use the REAL status union (never a synthetic "mocked").
|
|
66
|
+
*/
|
|
67
|
+
mock?: boolean;
|
|
68
|
+
}
|
|
69
|
+
interface PayInput {
|
|
70
|
+
/** USD decimal string ("4.99"). Rejected: ≤ 0, non-numeric, > 2 dp. */
|
|
71
|
+
amount: string;
|
|
72
|
+
/** Your product id, echoed on the receipt + webhook. */
|
|
73
|
+
sku: string;
|
|
74
|
+
/** Your opaque user id. */
|
|
75
|
+
playerId: string;
|
|
76
|
+
/**
|
|
77
|
+
* The game this IAP belongs to. Optional: when your API key maps to exactly
|
|
78
|
+
* one game the service resolves it for you (the quickstart). Supply it
|
|
79
|
+
* explicitly when your key spans multiple games.
|
|
80
|
+
*/
|
|
81
|
+
gameId?: string;
|
|
82
|
+
/** The studio wallet that receives the 99%. Falls back to the service default. */
|
|
83
|
+
studio?: `0x${string}`;
|
|
84
|
+
/** Supply your own to make retries safe; omit and the SDK generates a ULID. */
|
|
85
|
+
idempotencyKey?: string;
|
|
86
|
+
metadata?: Record<string, string>;
|
|
87
|
+
}
|
|
88
|
+
interface EnterRoundInput {
|
|
89
|
+
/** The game — selects its prize-pool contract. */
|
|
90
|
+
gameId: string;
|
|
91
|
+
/** The round being entered. */
|
|
92
|
+
roundId: string;
|
|
93
|
+
/** USD entry — grows this round's pool. */
|
|
94
|
+
amount: string;
|
|
95
|
+
playerId: string;
|
|
96
|
+
idempotencyKey?: string;
|
|
97
|
+
metadata?: Record<string, string>;
|
|
98
|
+
/**
|
|
99
|
+
* Advanced (games that manage their own on-chain rounds, e.g. the Playmos
|
|
100
|
+
* game-hub kit): the EXACT on-chain round key to enter — overrides the default
|
|
101
|
+
* `${gameId}:${roundId}` derivation. Set it to the value your game's server
|
|
102
|
+
* verifies `hasEntered` against (e.g. "bjtest:T1").
|
|
103
|
+
*/
|
|
104
|
+
roundKey?: string;
|
|
105
|
+
/**
|
|
106
|
+
* Advanced: the EXACT on-chain identity for this paid attempt (e.g.
|
|
107
|
+
* "0xWallet#nonce"). Overrides the server-generated identity so the on-chain
|
|
108
|
+
* entry and your server's `hasEntered` check line up. One entry per identity.
|
|
109
|
+
*/
|
|
110
|
+
identity?: string;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Input to `playmos.transfer(...)` — the value-movement `transfer` primitive (Phase 1a): move USDC
|
|
114
|
+
* from one wallet to another, with a configurable per-call fee. The game logic is the authority; the
|
|
115
|
+
* SDK just moves the money and proves it on-chain.
|
|
116
|
+
*/
|
|
117
|
+
interface TransferInput {
|
|
118
|
+
/**
|
|
119
|
+
* The payer — either a **game NPC id** you assigned a wallet to (`playmos.agents.createWallet`, e.g.
|
|
120
|
+
* `"npc_miner"`) OR a raw `0x` wallet address. OMIT it in the sandbox and the service defaults `from` to
|
|
121
|
+
* its server-held treasury signer (the untaxed-faucet path). Transferring FROM an NPC requires a secret
|
|
122
|
+
* test key (`sk_test_`) and settles gaslessly (the NPC signs; Playmos relays + pays gas).
|
|
123
|
+
*/
|
|
124
|
+
from?: string;
|
|
125
|
+
/** The payee — a game NPC id you assigned a wallet to, OR a raw `0x` address (player or NPC). */
|
|
126
|
+
to: string;
|
|
127
|
+
/** USD decimal string ("5.00"). Rejected: ≤ 0, non-numeric, > 2 dp. */
|
|
128
|
+
amount: string;
|
|
129
|
+
/** Optional note, echoed on the receipt (carried as the requirement's `terms`). */
|
|
130
|
+
memo?: string;
|
|
131
|
+
/**
|
|
132
|
+
* Per-call Playmos fee in bps of `amount`, 0–10000. Defaults to 0.
|
|
133
|
+
* 0 → an UNTAXED reward/faucet transfer (no fee taken; `feeSink` not needed).
|
|
134
|
+
* 500 → 5% (e.g. Playmos-Town P2P: 95% to payee, 5% to `feeSink`).
|
|
135
|
+
* 10000 → 100% (e.g. a first-party shop sale: all of it to `feeSink`).
|
|
136
|
+
*/
|
|
137
|
+
feeBps?: number;
|
|
138
|
+
/** Fee destination. REQUIRED when `feeBps > 0`; ignored when `feeBps === 0`. */
|
|
139
|
+
feeSink?: `0x${string}`;
|
|
140
|
+
/** Supply your own to make retries safe (anchors idempotency on the same requirement); omit and the SDK generates one. */
|
|
141
|
+
idempotencyKey?: string;
|
|
142
|
+
}
|
|
143
|
+
/** A wallet the SDK assigned to one of your game's NPCs (by your own id). Keys are never returned. */
|
|
144
|
+
interface AgentWallet {
|
|
145
|
+
agentId: string;
|
|
146
|
+
address: `0x${string}`;
|
|
147
|
+
chain: string;
|
|
148
|
+
}
|
|
149
|
+
/** What `agents.fund(...)` resolves to (sandbox faucet: treasury → NPC). */
|
|
150
|
+
interface AgentFundResult {
|
|
151
|
+
agent: AgentWallet;
|
|
152
|
+
funding: {
|
|
153
|
+
amount: string;
|
|
154
|
+
status: string;
|
|
155
|
+
txHash: string | null;
|
|
156
|
+
idempotentReplay: boolean;
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/** What `playmos.transfer(...)` resolves to — the settled result from the settlement core. */
|
|
160
|
+
interface TransferResult {
|
|
161
|
+
/** The requirement id this transfer settled (the idempotency anchor). */
|
|
162
|
+
id: string;
|
|
163
|
+
/** "settled" (on-chain confirmed) · "failed" (mined revert) · "settling" (reserved, confirmation pending). */
|
|
164
|
+
status: "settled" | "failed" | "settling";
|
|
165
|
+
/** The on-chain settlement tx (openable on BaseScan). */
|
|
166
|
+
txHash?: `0x${string}`;
|
|
167
|
+
/** Resolved payer address — omitted when it's the redacted server treasury signer. */
|
|
168
|
+
from?: `0x${string}`;
|
|
169
|
+
to: `0x${string}`;
|
|
170
|
+
/** Gross amount moved (USD). */
|
|
171
|
+
amount: string;
|
|
172
|
+
/** Fee skimmed to `feeSink` (USD). */
|
|
173
|
+
fee: string;
|
|
174
|
+
/** Amount the payee received (USD) = amount − fee. */
|
|
175
|
+
net: string;
|
|
176
|
+
feeBps: number;
|
|
177
|
+
feeSink?: `0x${string}` | null;
|
|
178
|
+
memo?: string | null;
|
|
179
|
+
/** True when a prior settle for this id was replayed instead of broadcasting again (double-spend safety). */
|
|
180
|
+
idempotentReplay: boolean;
|
|
181
|
+
}
|
|
182
|
+
/** Input to `playmos.escrow.hold(...)` — open a fair-exchange deal by locking the payer's USDC on-chain. */
|
|
183
|
+
interface EscrowHoldInput {
|
|
184
|
+
/**
|
|
185
|
+
* Payer wallet whose USDC is locked. OPTIONAL in the sandbox: omit it and the service defaults `payer`
|
|
186
|
+
* to its server-held signer wallet (Phase 2a's only payer), like `transfer.from`.
|
|
187
|
+
*/
|
|
188
|
+
payer?: `0x${string}`;
|
|
189
|
+
/** Payee wallet — where a `release` sends the funds (any identity: player or NPC). */
|
|
190
|
+
payee: `0x${string}`;
|
|
191
|
+
/** USD decimal string ("12.50"). Rejected: ≤ 0, non-numeric, > 2 dp. */
|
|
192
|
+
amount: string;
|
|
193
|
+
/**
|
|
194
|
+
* Per-call Playmos fee in bps, 0–10000, taken ONLY at `release` (a `refund` is always 100%, untaxed).
|
|
195
|
+
* Defaults to 0. Frozen at hold — the fee a deal will pay can't change once funds are locked.
|
|
196
|
+
*/
|
|
197
|
+
feeBps?: number;
|
|
198
|
+
/** Fee destination. REQUIRED when `feeBps > 0`; ignored when `feeBps === 0`. */
|
|
199
|
+
feeSink?: `0x${string}`;
|
|
200
|
+
/**
|
|
201
|
+
* The authority allowed to `release`/`refund` this deal. Defaults to the payer. This is YOUR game
|
|
202
|
+
* server's address in the common case — it verifies the deal condition off-chain, then calls release.
|
|
203
|
+
*/
|
|
204
|
+
resolver?: `0x${string}`;
|
|
205
|
+
/**
|
|
206
|
+
* On-chain auto-refund deadline as a relative duration — "30s" | "15m" | "1h" | "7d" (max 30 days).
|
|
207
|
+
* At/after it, ANYONE can trigger the refund (funds never get stuck). Defaults to "1h". This is the
|
|
208
|
+
* DEAL's life; it is distinct from the short off-chain window the hold authorization itself is valid for.
|
|
209
|
+
*/
|
|
210
|
+
expiresIn?: string;
|
|
211
|
+
/** Absolute on-chain deadline as a unix-seconds timestamp. Overrides `expiresIn` when set. */
|
|
212
|
+
deadline?: number;
|
|
213
|
+
/** Optional note, echoed on the receipt. */
|
|
214
|
+
memo?: string;
|
|
215
|
+
/** Supply your own to make retries safe (anchors idempotency on the same deal); omit and the SDK generates one. */
|
|
216
|
+
idempotencyKey?: string;
|
|
217
|
+
}
|
|
218
|
+
/** What `playmos.escrow.hold(...)` resolves to. `id` is the holdId — pass it to `release`/`refund`/`get`. */
|
|
219
|
+
interface EscrowHoldResult {
|
|
220
|
+
/** The deal id (holdId) — the reserve-before-broadcast anchor and the handle for release/refund/get. */
|
|
221
|
+
id: string;
|
|
222
|
+
/** "settled" (funds locked on-chain) · "failed" (mined revert) · "settling" (reserved, confirmation pending). */
|
|
223
|
+
status: "settled" | "failed" | "settling";
|
|
224
|
+
txHash?: `0x${string}`;
|
|
225
|
+
payee: `0x${string}`;
|
|
226
|
+
/** Gross amount locked (USD). */
|
|
227
|
+
amount: string;
|
|
228
|
+
feeBps: number;
|
|
229
|
+
feeSink?: `0x${string}` | null;
|
|
230
|
+
/** The resolver recorded for the deal; null means it defaulted to the payer. */
|
|
231
|
+
resolver?: `0x${string}` | null;
|
|
232
|
+
/** On-chain auto-refund deadline (unix seconds). */
|
|
233
|
+
deadline: number;
|
|
234
|
+
/** Fee that WOULD be skimmed on release (USD) — preview; a refund takes none. */
|
|
235
|
+
feeAtRelease: string;
|
|
236
|
+
/** Amount the payee WOULD receive on release (USD) = amount − feeAtRelease. */
|
|
237
|
+
netAtRelease: string;
|
|
238
|
+
memo?: string | null;
|
|
239
|
+
idempotentReplay: boolean;
|
|
240
|
+
}
|
|
241
|
+
/** What `release`/`refund`/`get` resolve to. */
|
|
242
|
+
interface EscrowResolveResult {
|
|
243
|
+
/** The deal id (holdId). */
|
|
244
|
+
id: string;
|
|
245
|
+
/** Which resolution this was (absent on `get`). */
|
|
246
|
+
leg?: "release" | "refund";
|
|
247
|
+
/** For release/refund: the leg's settlement status. For `get`: the HOLD's on-chain-verified state. */
|
|
248
|
+
status: string;
|
|
249
|
+
txHash?: `0x${string}` | null;
|
|
250
|
+
idempotentReplay?: boolean;
|
|
251
|
+
/** How the status was derived — chain truth, honest cache, or not-yet-configured. */
|
|
252
|
+
verifiedVia?: "chain" | "cache" | "degraded";
|
|
253
|
+
}
|
|
254
|
+
/** An item for sale. Off-chain (game DB inventory) is Phase 3a; on-chain (token) is Phase 3b. */
|
|
255
|
+
type MarketplaceItem = {
|
|
256
|
+
kind: "offchain";
|
|
257
|
+
sku: string;
|
|
258
|
+
metadata?: Record<string, unknown>;
|
|
259
|
+
} | {
|
|
260
|
+
kind: "onchain";
|
|
261
|
+
token: `0x${string}`;
|
|
262
|
+
tokenId: string;
|
|
263
|
+
};
|
|
264
|
+
interface MarketplaceListInput {
|
|
265
|
+
/** Seller wallet (the payee, paid on sale). REQUIRED — it's never defaulted to the server signer.
|
|
266
|
+
* (The buyer/payer is what defaults to the signer in the sandbox; the seller is a real counterparty.) */
|
|
267
|
+
seller: `0x${string}`;
|
|
268
|
+
/** The item being sold. Phase 3a settles `{ kind: "offchain", sku }`; on-chain items are Phase 3b. */
|
|
269
|
+
item: MarketplaceItem;
|
|
270
|
+
/** USD decimal string ("12.50"). */
|
|
271
|
+
price: string;
|
|
272
|
+
/** Per-sale Playmos take in bps, 0–10000, taken at settle (on the sale). Defaults to the service's config. */
|
|
273
|
+
feeBps?: number;
|
|
274
|
+
/** Fee destination; required when `feeBps > 0` and no service default is set. */
|
|
275
|
+
feeSink?: `0x${string}`;
|
|
276
|
+
/** On-sale delivery/escrow deadline as a duration — "30s"|"15m"|"1h"|"7d" (max 30d). Default "1h". */
|
|
277
|
+
deliveryWindow?: string;
|
|
278
|
+
/** Optional listing shelf-life — after this, the listing can't be bought (lazy `expired`). */
|
|
279
|
+
expiresIn?: string;
|
|
280
|
+
gameId?: string;
|
|
281
|
+
/** Supply your own for a deterministic listing id (retried list() never double-lists). */
|
|
282
|
+
idempotencyKey?: string;
|
|
283
|
+
}
|
|
284
|
+
type ListingStatus = "active" | "sold_pending_delivery" | "sold" | "refunded" | "cancelled" | "expired";
|
|
285
|
+
/** A marketplace listing (as the service returns it). */
|
|
286
|
+
interface Listing {
|
|
287
|
+
id: string;
|
|
288
|
+
status: ListingStatus;
|
|
289
|
+
seller: `0x${string}`;
|
|
290
|
+
buyer?: `0x${string}` | null;
|
|
291
|
+
item: MarketplaceItem;
|
|
292
|
+
price: string;
|
|
293
|
+
feeBps: number;
|
|
294
|
+
feeSink?: `0x${string}` | null;
|
|
295
|
+
/** Fee that WOULD be skimmed on a completed sale (USD). */
|
|
296
|
+
feeAtSale: string;
|
|
297
|
+
/** Amount the seller WOULD receive on a completed sale (USD) = price − feeAtSale. */
|
|
298
|
+
netAtSale: string;
|
|
299
|
+
deliveryWindowSec: number;
|
|
300
|
+
expiresAt?: string | null;
|
|
301
|
+
createdAt: string;
|
|
302
|
+
updatedAt: string;
|
|
303
|
+
}
|
|
304
|
+
/** The escrow-backed sale attached to a listing after buy/confirm/refund/get. */
|
|
305
|
+
interface MarketplaceSale {
|
|
306
|
+
/** The sale's settlement id (`<listingId>:sale`). */
|
|
307
|
+
id: string;
|
|
308
|
+
leg?: "confirm" | "refund";
|
|
309
|
+
/** "settled" (funds moved) · "settling" · "failed" — or the hold's verified state on `get`. */
|
|
310
|
+
status: string;
|
|
311
|
+
txHash?: `0x${string}` | null;
|
|
312
|
+
idempotentReplay?: boolean;
|
|
313
|
+
verifiedVia?: "chain" | "cache" | "degraded";
|
|
314
|
+
}
|
|
315
|
+
interface MarketplaceSaleResult {
|
|
316
|
+
listing: Listing;
|
|
317
|
+
sale: MarketplaceSale;
|
|
318
|
+
}
|
|
319
|
+
interface MarketplaceGetResult {
|
|
320
|
+
listing: Listing;
|
|
321
|
+
sale: MarketplaceSale | null;
|
|
322
|
+
}
|
|
323
|
+
interface Payment {
|
|
324
|
+
/** `pay_…` (IAP) or `entry_…` (prize-pool) — ULID, server-issued, unique. */
|
|
325
|
+
id: string;
|
|
326
|
+
status: PaymentStatus;
|
|
327
|
+
/** "iap" (1% external) or "entry" (60/30/10 prize-pool). */
|
|
328
|
+
kind: "iap" | "entry";
|
|
329
|
+
amount: string;
|
|
330
|
+
fee: string;
|
|
331
|
+
net: string;
|
|
332
|
+
/** Present for prize-pool entries: the 60/30/10 breakdown in USD. */
|
|
333
|
+
split?: {
|
|
334
|
+
pool: string;
|
|
335
|
+
seed: string;
|
|
336
|
+
rake: string;
|
|
337
|
+
};
|
|
338
|
+
sku?: string;
|
|
339
|
+
roundId?: string;
|
|
340
|
+
gameId?: string;
|
|
341
|
+
playerId: string;
|
|
342
|
+
txHash?: `0x${string}`;
|
|
343
|
+
chain: Network;
|
|
344
|
+
createdAt: string;
|
|
345
|
+
metadata?: Record<string, string>;
|
|
346
|
+
/**
|
|
347
|
+
* The on-chain identity used for a prize-pool entry (echo of
|
|
348
|
+
* `EnterRoundInput.identity` or the SDK-derived value) — reconcile against your
|
|
349
|
+
* server's `hasEntered`.
|
|
350
|
+
*/
|
|
351
|
+
identity?: string;
|
|
352
|
+
/** True only when produced by the labeled `mock: true` helper. */
|
|
353
|
+
mock?: boolean;
|
|
354
|
+
}
|
|
355
|
+
/** What `verify()` resolves to (server reads the chain). */
|
|
356
|
+
interface VerifyResult {
|
|
357
|
+
id: string;
|
|
358
|
+
status: PaymentStatus;
|
|
359
|
+
amount: string;
|
|
360
|
+
fee: string;
|
|
361
|
+
net: string;
|
|
362
|
+
txHash?: `0x${string}`;
|
|
363
|
+
playerId: string;
|
|
364
|
+
sku?: string;
|
|
365
|
+
roundId?: string;
|
|
366
|
+
chain: Network;
|
|
367
|
+
/** How the service derived this status: an on-chain read, the honest cache, or
|
|
368
|
+
* degraded (chain reads not configured). Lets the SDK stop polling when the
|
|
369
|
+
* service can never confirm on-chain. */
|
|
370
|
+
verifiedVia?: "chain" | "cache" | "degraded";
|
|
371
|
+
chainReads?: "enabled" | "degraded";
|
|
372
|
+
}
|
|
373
|
+
type WebhookEventType = "payment.confirmed" | "payment.failed" | "payout.settled" | "refund.processed";
|
|
374
|
+
interface WebhookEvent {
|
|
375
|
+
id: string;
|
|
376
|
+
type: WebhookEventType;
|
|
377
|
+
createdAt: string;
|
|
378
|
+
data: {
|
|
379
|
+
id: string;
|
|
380
|
+
status: PaymentStatus;
|
|
381
|
+
amount: string;
|
|
382
|
+
fee: string;
|
|
383
|
+
net: string;
|
|
384
|
+
playerId: string;
|
|
385
|
+
sku?: string;
|
|
386
|
+
txHash?: `0x${string}`;
|
|
387
|
+
chain: Network;
|
|
388
|
+
metadata?: Record<string, string>;
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
/** How the payable pool is split among ranked wallets (best-first). Never a score. */
|
|
392
|
+
type PayoutRule = {
|
|
393
|
+
kind: "winner-take-all";
|
|
394
|
+
} | {
|
|
395
|
+
kind: "top-n";
|
|
396
|
+
splitsBps: number[];
|
|
397
|
+
} | {
|
|
398
|
+
kind: "custom";
|
|
399
|
+
amounts: string[];
|
|
400
|
+
};
|
|
401
|
+
type RoundStatus = "open" | "locked" | "settled" | "cancelled" | "none";
|
|
402
|
+
interface RoundOpenInput {
|
|
403
|
+
gameId: string;
|
|
404
|
+
/** Studio-facing round id (also used as the on-chain round key unless roundKey set). */
|
|
405
|
+
roundId: string;
|
|
406
|
+
/** USD entry amount ("0.25"). Fixed for the round once opened. */
|
|
407
|
+
entryAmount: string;
|
|
408
|
+
/** Studio payout rule stored for settle-from-ranking. */
|
|
409
|
+
payout: PayoutRule;
|
|
410
|
+
/** Optional ISO-8601 when the studio intends to close entries (off-chain advisory). */
|
|
411
|
+
closeAt?: string;
|
|
412
|
+
/** Optional series key for the 60/30/10 seed flywheel; defaults to gameId. */
|
|
413
|
+
seriesKey?: string;
|
|
414
|
+
/** Advanced: exact on-chain round key string (default = roundId). */
|
|
415
|
+
roundKey?: string;
|
|
416
|
+
}
|
|
417
|
+
interface RoundState {
|
|
418
|
+
roundId: string;
|
|
419
|
+
gameId: string;
|
|
420
|
+
roundKey: string;
|
|
421
|
+
status: RoundStatus;
|
|
422
|
+
entryAmount: string;
|
|
423
|
+
/** Payable pool in USD (from chain after lock); may be "0.00" while open. */
|
|
424
|
+
pool: string;
|
|
425
|
+
entrants: number;
|
|
426
|
+
payout: PayoutRule;
|
|
427
|
+
closeAt?: string;
|
|
428
|
+
openTxHash?: `0x${string}`;
|
|
429
|
+
lockTxHash?: `0x${string}`;
|
|
430
|
+
settleTxHash?: `0x${string}`;
|
|
431
|
+
}
|
|
432
|
+
interface RoundSettleInput {
|
|
433
|
+
roundId: string;
|
|
434
|
+
gameId?: string;
|
|
435
|
+
results: {
|
|
436
|
+
ranking: `0x${string}`[];
|
|
437
|
+
} | {
|
|
438
|
+
winners: {
|
|
439
|
+
wallet: `0x${string}`;
|
|
440
|
+
amount: string;
|
|
441
|
+
}[];
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
interface SettleRoundResult {
|
|
445
|
+
roundId: string;
|
|
446
|
+
txHash: `0x${string}`;
|
|
447
|
+
poolPaid: string;
|
|
448
|
+
winners: {
|
|
449
|
+
wallet: `0x${string}`;
|
|
450
|
+
amount: string;
|
|
451
|
+
}[];
|
|
452
|
+
status: "settled";
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Typed, actionable errors — the Stripe bar (spec §11).
|
|
457
|
+
*
|
|
458
|
+
* Every error carries a stable machine-readable `code` and is thrown at the
|
|
459
|
+
* EARLIEST possible layer: input errors fire client-side before any network or
|
|
460
|
+
* chain call, so a studio never pays gas to discover a typo.
|
|
461
|
+
*/
|
|
462
|
+
type PlaymosErrorCode = "invalid_amount" | "missing_field" | "insufficient_gas" | "wallet_connection" | "payment_failed" | "auth" | "api_error" | "config";
|
|
463
|
+
declare class PlaymosError extends Error {
|
|
464
|
+
readonly code: PlaymosErrorCode;
|
|
465
|
+
/** Optional machine context (e.g. the offending field, the http status). */
|
|
466
|
+
readonly detail?: Record<string, unknown>;
|
|
467
|
+
constructor(code: PlaymosErrorCode, message: string, detail?: Record<string, unknown>);
|
|
468
|
+
}
|
|
469
|
+
/** amount ≤ 0, non-numeric, empty, or more than 2 decimal places. */
|
|
470
|
+
declare class InvalidAmountError extends PlaymosError {
|
|
471
|
+
constructor(amount: unknown);
|
|
472
|
+
}
|
|
473
|
+
/** A required field (sku, playerId, gameId, roundId, agentId…) was empty. */
|
|
474
|
+
declare class MissingFieldError extends PlaymosError {
|
|
475
|
+
constructor(field: string);
|
|
476
|
+
}
|
|
477
|
+
/** gas mode "player" and the player's ETH is too low to cover gas (pre-check, §7). */
|
|
478
|
+
declare class InsufficientGasError extends PlaymosError {
|
|
479
|
+
constructor(detail?: Record<string, unknown>);
|
|
480
|
+
}
|
|
481
|
+
/** The player closed or failed the wallet sheet, or no provider is available. */
|
|
482
|
+
declare class WalletConnectionError extends PlaymosError {
|
|
483
|
+
constructor(message?: string, detail?: Record<string, unknown>);
|
|
484
|
+
}
|
|
485
|
+
/** The on-chain settlement reverted, was cancelled, or timed out. */
|
|
486
|
+
declare class PaymentFailedError extends PlaymosError {
|
|
487
|
+
constructor(message?: string, detail?: Record<string, unknown>);
|
|
488
|
+
}
|
|
489
|
+
/** Bad, missing, or wrong-environment API key (e.g. a pk_test_ key on a live route). */
|
|
490
|
+
declare class AuthError extends PlaymosError {
|
|
491
|
+
constructor(message?: string, detail?: Record<string, unknown>);
|
|
492
|
+
}
|
|
493
|
+
/** The Playmos service returned a non-2xx we don't have a more specific error for. */
|
|
494
|
+
declare class ApiError extends PlaymosError {
|
|
495
|
+
constructor(message: string, detail?: Record<string, unknown>);
|
|
496
|
+
}
|
|
497
|
+
/** SDK misconfiguration (e.g. a missing contract address for on-chain mode). */
|
|
498
|
+
declare class ConfigError extends PlaymosError {
|
|
499
|
+
constructor(message: string, detail?: Record<string, unknown>);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
export { type AgentWallet as A, type PlaymosErrorCode as B, ConfigError as C, type RoundStatus as D, type EscrowHoldInput as E, type WalletConfig as F, type GasConfig as G, WalletConnectionError as H, InsufficientGasError as I, type WalletConnector as J, type WebhookEventType as K, type Listing as L, type MarketplaceListInput as M, type Network as N, type PlaymosConfig as P, type RoundOpenInput as R, type SettleRoundResult as S, type TransferResult as T, type VerifyResult as V, type WebhookEvent as W, type RoundState as a, type RoundSettleInput as b, type AgentFundResult as c, type EscrowHoldResult as d, type EscrowResolveResult as e, type MarketplaceSaleResult as f, type MarketplaceGetResult as g, type PayInput as h, type Payment as i, type EnterRoundInput as j, type TransferInput as k, type AgentEconomyConfig as l, ApiError as m, AuthError as n, type ContractConfig as o, type Eip1193Provider as p, type GasMode as q, InvalidAmountError as r, type ListingStatus as s, type MarketplaceItem as t, type MarketplaceSale as u, MissingFieldError as v, PaymentFailedError as w, type PaymentStatus as x, type PayoutRule as y, PlaymosError as z };
|