@playmos/sdk 0.3.11 → 0.3.13

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/dist/index.d.ts CHANGED
@@ -1,5 +1,637 @@
1
- import { N as Network, P as PlaymosConfig, W as WebhookEvent, R as RoundOpenInput, a as RoundState, b as RoundSettleInput, S as SettleRoundResult, c as RoundCancelInput, C as CancelRoundResult, d as RoundGetResult, A as ActiveSeriesRound, e as PrizeBalance, f as WithdrawResult, g as AgentWallet, h as AgentFundResult, T as TransferResult, E as EscrowHoldInput, i as EscrowHoldResult, j as EscrowResolveResult, M as MarketplaceListInput, L as Listing, k as MarketplaceSaleResult, l as MarketplaceGetResult, m as PayInput, n as Payment, o as EnterRoundInput, p as TransferReconcile, q as WaitOptions, r as TransferInput, s as TransferConfirmOptions, V as VerifyResult, t as PayoutRule } from './errors-Dpeesyop.js';
2
- export { u as ActiveForSeriesResult, v as AgentEconomyConfig, w as AlreadyEnteredError, x as ApiError, y as AuthError, z as ConfigError, B as ContractConfig, D as Eip1193Provider, G as GasConfig, F as GasMode, I as InsufficientGasError, H as InvalidAmountError, J as ListingStatus, K as MarketplaceItem, O as MarketplaceSale, Q as MissingFieldError, U as NothingToWithdrawError, X as PaymentFailedError, Y as PaymentStatus, Z as PlaymosError, _ as PlaymosErrorCode, $ as RetryOptions, a0 as RoundGetVia, a1 as RoundStatus, a2 as WalletConfig, a3 as WalletConnectionError, a4 as WalletConnector, a5 as WalletTimeoutError, a6 as WebhookEventType } from './errors-Dpeesyop.js';
1
+ import { C as Call, P as PlaymosConfig, O as OnchainStatus, N as Network, W as WebhookEvent, R as RoundOpenInput, a as RoundState, b as RoundSettleInput, S as SettleRoundResult, c as RoundCancelInput, d as CancelRoundResult, e as RoundGetResult, A as ActiveSeriesRound, f as PayoutNoticesResult, g as PrizeBalance, h as WithdrawResult, i as AgentWallet, j as AgentFundResult, T as TransferResult, E as EscrowHoldInput, k as EscrowHoldResult, l as EscrowResolveResult, M as MarketplaceListInput, L as Listing, m as MarketplaceSaleResult, n as MarketplaceGetResult, o as PayInput, p as Payment, q as EnterRoundInput, r as TransferReconcile, s as WaitOptions, t as TransferInput, u as TransferConfirmOptions, V as VerifyResult, v as PayoutRule } from './errors-CYKgt2VU.js';
2
+ export { w as ActiveForSeriesResult, x as AgentEconomyConfig, y as AlreadyEnteredError, z as ApiError, B as AuthError, D as ConfigError, F as ContractConfig, G as Eip1193Provider, H as GasConfig, I as GasMode, J as InsufficientGasError, K as InvalidAmountError, Q as ListingStatus, U as MarketplaceItem, X as MarketplaceSale, Y as MissingFieldError, Z as NothingToWithdrawError, _ as PaymentFailedError, $ as PaymentStatus, a0 as PayoutNotice, a1 as PayoutNoticeStatus, a2 as PlaymosError, a3 as PlaymosErrorCode, a4 as RetryOptions, a5 as RoundGetVia, a6 as RoundStatus, a7 as WalletConfig, a8 as WalletConnectionError, a9 as WalletConnector, aa as WalletTimeoutError, ab as WebhookEventType, ac as buildEpochExecuteSettlementCall } from './errors-CYKgt2VU.js';
3
+
4
+ /**
5
+ * Thin REST client for the Playmos service. Every SDK method that touches the
6
+ * backend (create intent, verify, payouts, agents) goes through here. `verify()`
7
+ * hits `GET /payments/:id`, which the service resolves by READING THE CHAIN — so
8
+ * the SDK never trusts a client claim or a mutable counter (#337 root fix).
9
+ *
10
+ * Automatic backoff/retry (#50 + BB-GATEB-002):
11
+ * - HTTP **429** (rate limit): always retried with exponential backoff + jitter
12
+ * (honors `Retry-After` when present).
13
+ * - HTTP **502 / 503 / 504** (gateway / DO via_upstream HTML): GET always retried;
14
+ * POST only when an `idempotency-key` is present so a retried write never
15
+ * double-broadcasts. Opt out: `retry: false` or `retry: { maxRetries: 0 }`.
16
+ */
17
+
18
+ /** Options for {@link HttpClient.post}. */
19
+ interface HttpPostOptions {
20
+ idempotencyKey?: string;
21
+ /**
22
+ * HTTP statuses to treat as success in addition to 2xx.
23
+ * Used by x402 challenge mint, which correctly returns **402 Payment Required**.
24
+ */
25
+ acceptStatuses?: number[];
26
+ }
27
+ interface HttpClient {
28
+ post<T>(path: string, body: unknown, opts?: HttpPostOptions): Promise<T>;
29
+ get<T>(path: string): Promise<T>;
30
+ }
31
+
32
+ /**
33
+ * Series string → bytes32. Shared by SDK S1 reads and the service reader.
34
+ *
35
+ * Pass-through when already `0x`+64 hex; otherwise keccak of UTF-8
36
+ * (`keccak256(toHex(s))` == `ethers.id` / C1). Do not use `toBytes(s)` —
37
+ * viem hex-decodes address-shaped strings and drifts from the chain.
38
+ */
39
+ declare function seriesToBytes32(series: string): `0x${string}`;
40
+ /**
41
+ * Identity string → bytes32 (sdk#633). Deliberately the SAME function object as
42
+ * {@link seriesToBytes32}, not a copy: an identity that hashes differently from
43
+ * the chain records a paid entry against an id nobody scores. A second
44
+ * implementation could drift; an alias cannot.
45
+ */
46
+ declare const identityToBytes32: typeof seriesToBytes32;
47
+
48
+ /**
49
+ * Epoch entry calls (sdk#635 / S2).
50
+ *
51
+ * Deliberately NOT in `calls.ts`: that file's `toBytes32` is
52
+ * `keccak256(toBytes(s))`, which viem hex-decodes for hex-shaped input and
53
+ * therefore disagrees with the chain (sdk#633). It stays as-is because the
54
+ * legacy PrizePool's live paid entries were written with it. The epoch path
55
+ * uses the shared `seriesToBytes32` / `identityToBytes32` instead.
56
+ */
57
+
58
+ interface EpochEntryCallsArgs {
59
+ usdc: `0x${string}`;
60
+ epochPrizePool: `0x${string}`;
61
+ /** Plain series string, or an already-derived 0x+64 bytes32. */
62
+ series: string;
63
+ /** Plain identity string, or an already-derived 0x+64 bytes32. */
64
+ identity: string;
65
+ /** The series' `entry` price in micro-USDC, read from the chain. */
66
+ entryMicro: bigint;
67
+ }
68
+ /** approve USDC → EpochPrizePool, then EpochPrizePool.enter(). One atomic batch. */
69
+ declare function buildEpochEntryCalls(args: EpochEntryCallsArgs): Call[];
70
+ interface EpochClaimRefundCallArgs {
71
+ epochPrizePool: `0x${string}`;
72
+ series: string;
73
+ epochId: bigint;
74
+ /** The address that paid — credit always lands here, never on the caller. */
75
+ payer: `0x${string}`;
76
+ }
77
+ /** EpochPrizePool.claimRefund(series, epochId, payer). Permissionless; credit → payer. */
78
+ declare function buildEpochClaimRefundCall(args: EpochClaimRefundCallArgs): Call;
79
+ /** EpochPrizePool.withdraw() — payer wallet pulls USDC. Not PrizePool.withdraw. */
80
+ declare function buildEpochWithdrawCall(epochPrizePool: `0x${string}`): Call;
81
+
82
+ /**
83
+ * Rolling-epoch reads (sdk#629 / S1), `enter` (sdk#635 / S2), D14 studio
84
+ * pool create (sdk#643), operator settle (sdk#639 / S3), and the C3 refund
85
+ * pull (sdk#634): `claimableRefund` / `claimRefund` / `withdraw`.
86
+ *
87
+ * `epochs.currentId` and `epochs.prize` — chain-backed via the service.
88
+ * `epochs.enter` — pay into whatever window the clock says is current; no open
89
+ * gate. `epochs.preparePool` / `registerPool` / `createPool` — studio wallet
90
+ * deploys the existing EpochPrizePool constructor; Playmos is feeSink only.
91
+ * `epochs.settle` — secret key, operator wallet, broadcast + 202. Passes the
92
+ * roster through; does not build a hub roster (R7b).
93
+ * `epochs.claimableRefund` / `claimRefund` / `withdraw` — wallet-direct on
94
+ * EpochPrizePool. No service hop. `withdraw` reports the credited balance it
95
+ * read before pulling, or no figure at all — never a placeholder zero beside a
96
+ * confirmed pull. Live `rounds.withdraw` stays on PrizePool.
97
+ * `epochs.getAttestation` / `executeSettlement` / `settlementTypedData` — E1b
98
+ * public board + permissionless relay of an operator-signed podium. The SDK
99
+ * never authors winners. `settled` is only reported from a chain read of
100
+ * `terminal`. Live `rounds.*` / `enterRound` are a different pool and stay unchanged.
101
+ */
102
+
103
+ /** Founder-locked Playmos Base Sepolia treasury (Object 3). Prepare pins this. */
104
+ declare const PLAYMOS_FEE_SINK_DEFAULT: "0xd84c190085aa59c48a9b478ea333d50b8df4ad42";
105
+ /** Retired constructor sink — prepare must never hand this out. */
106
+ declare const RETIRED_PLAYMOS_FEE_SINK: "0x1b8031e20ed96131a849a52290b4d640f286998d";
107
+ declare function encodeEpochPoolConstructorArgs(args: {
108
+ token: `0x${string}`;
109
+ admin: `0x${string}`;
110
+ operator: `0x${string}`;
111
+ feeSink: `0x${string}`;
112
+ refundTimeout: bigint;
113
+ }): `0x${string}`;
114
+
115
+ type EpochTerminal = "none" | "settled" | "refunded" | "rolled";
116
+ type EpochReadVia = "service" | "mock" | "chain";
117
+ interface EpochCurrentId {
118
+ series: string;
119
+ epochId: string;
120
+ via: EpochReadVia;
121
+ epochPrizePool?: `0x${string}` | null;
122
+ mock?: true;
123
+ }
124
+ interface EpochPrize {
125
+ series: string;
126
+ epochId: string;
127
+ /** This epoch's 60% bucket (USD). */
128
+ pool: string;
129
+ /** Inherited seed already sitting on this epoch (USD). */
130
+ incomingSeed: string;
131
+ /** This epoch's 30% — released only at settle (USD). */
132
+ outgoingSeed: string;
133
+ /** Settle payable = incomingSeed + pool (USD). */
134
+ payable: string;
135
+ poolMicro: string;
136
+ incomingSeedMicro: string;
137
+ outgoingSeedMicro: string;
138
+ payableMicro: string;
139
+ via: EpochReadVia;
140
+ epochPrizePool?: `0x${string}` | null;
141
+ mock?: true;
142
+ }
143
+ interface EpochView {
144
+ series: string;
145
+ epochId: string;
146
+ pool: string;
147
+ outgoingSeed: string;
148
+ incomingSeed: string;
149
+ payable: string;
150
+ poolMicro: string;
151
+ outgoingSeedMicro: string;
152
+ incomingSeedMicro: string;
153
+ payableMicro: string;
154
+ entryCount: string;
155
+ terminal: EpochTerminal;
156
+ via: EpochReadVia;
157
+ epochPrizePool?: `0x${string}` | null;
158
+ mock?: true;
159
+ }
160
+ interface EpochSeriesView {
161
+ series: string;
162
+ created: boolean;
163
+ genesis: string;
164
+ epochDuration: string;
165
+ entry: string;
166
+ feeBps: number;
167
+ poolBps: number;
168
+ seedBps: number;
169
+ via: EpochReadVia;
170
+ epochPrizePool?: `0x${string}` | null;
171
+ mock?: true;
172
+ }
173
+ interface EpochCurrentIdInput {
174
+ series: string;
175
+ epochPrizePool?: `0x${string}`;
176
+ /** Mock only — series genesis (unix seconds). */
177
+ genesis?: number | string;
178
+ /** Mock only — epoch duration (seconds). */
179
+ epochDuration?: number | string;
180
+ /** Mock only — clock to derive against (unix seconds). */
181
+ at?: number | string;
182
+ }
183
+ interface EpochPrizeInput {
184
+ series: string;
185
+ /** Omit to read the live epoch (`/epochs/current/prize`). */
186
+ epochId?: number | string;
187
+ epochPrizePool?: `0x${string}`;
188
+ }
189
+ interface EpochGetInput {
190
+ series: string;
191
+ epochId?: number | string;
192
+ epochPrizePool?: `0x${string}`;
193
+ }
194
+ interface EpochGetSeriesInput {
195
+ series: string;
196
+ epochPrizePool?: `0x${string}`;
197
+ }
198
+ /** Real status union — never a `"mocked"` status (P0 invariant #2). */
199
+ type EpochEntryStatus = "created" | "pending" | "confirmed" | "failed";
200
+ interface EpochEnterInput {
201
+ series: string;
202
+ /**
203
+ * The on-chain id this paid attempt is scored under. Required — never
204
+ * invented for you, because an invented identity means the player pays and
205
+ * their score is looked up somewhere else (#374 / #466).
206
+ */
207
+ identity: string;
208
+ epochPrizePool?: `0x${string}`;
209
+ /** Mock only — series genesis (unix seconds). */
210
+ genesis?: number | string;
211
+ /** Mock only — epoch duration (seconds). */
212
+ epochDuration?: number | string;
213
+ /** Mock only — clock to derive the window against (unix seconds). */
214
+ at?: number | string;
215
+ }
216
+ interface EpochEntry {
217
+ series: string;
218
+ identity: string;
219
+ /** The window this entry belongs to. */
220
+ epochId: string;
221
+ /**
222
+ * Where `epochId` came from. `chain-event` is the window the chain actually
223
+ * recorded (read back from the `Entered` log). `chain-clock` is the window
224
+ * that was current when the call was built — correct unless the tx mines on
225
+ * the far side of a boundary, which is why a confirmed entry always reports
226
+ * `chain-event`.
227
+ */
228
+ epochIdSource: "chain-event" | "chain-clock" | "mock";
229
+ seriesBytes32: `0x${string}`;
230
+ identityBytes32: `0x${string}`;
231
+ /** Entry price (USD) — the series' immutable `entry`, read from chain. */
232
+ entry: string;
233
+ entryMicro: string;
234
+ status: EpochEntryStatus;
235
+ txHash?: `0x${string}`;
236
+ /**
237
+ * How many paid entries this identity now has in this window (D9). A second
238
+ * entry reads `2` — re-entry is the product, not an error.
239
+ */
240
+ identityEntryCount?: string;
241
+ epochPrizePool?: `0x${string}` | null;
242
+ usdc?: `0x${string}` | null;
243
+ via: EpochReadVia;
244
+ mock?: true;
245
+ }
246
+ interface EpochPreparePoolInput {
247
+ studioWallet: `0x${string}`;
248
+ /** Must equal the Playmos sink if set; any other address is refused before broadcast. */
249
+ feeSink?: `0x${string}`;
250
+ admin?: `0x${string}`;
251
+ operator?: `0x${string}`;
252
+ refundTimeout?: number | string;
253
+ playmosFeeSink?: `0x${string}`;
254
+ token?: `0x${string}`;
255
+ }
256
+ interface EpochPreparedPool {
257
+ token: `0x${string}`;
258
+ admin: `0x${string}`;
259
+ operator: `0x${string}`;
260
+ feeSink: `0x${string}`;
261
+ refundTimeout: string;
262
+ constructorArgs: `0x${string}`;
263
+ /** Creation bytecode from the service prepare path. Absent on mock. */
264
+ bytecode?: `0x${string}`;
265
+ unsignedTx?: {
266
+ chainId: number;
267
+ to: null;
268
+ value: "0";
269
+ data: `0x${string}`;
270
+ };
271
+ /** Playmos never broadcasts. Studio wallet sends. */
272
+ broadcast: false;
273
+ constructor: "EpochPrizePool";
274
+ studioHoldsAdmin: true;
275
+ studioHoldsOperator: true;
276
+ playmosIsAdmin: false;
277
+ playmosIsOperator: false;
278
+ via: EpochReadVia;
279
+ mock?: true;
280
+ }
281
+ /**
282
+ * The studio wallet's EIP-191 signature over `EpochStudioPool.proof.message`.
283
+ * Without it the pool is verified on chain but ownership is left unrecorded —
284
+ * a wallet you do not hold the key to can never be registered as yours.
285
+ */
286
+ interface EpochPoolWalletProof {
287
+ signature: `0x${string}`;
288
+ }
289
+ interface EpochRegisterPoolInput {
290
+ studioWallet: `0x${string}`;
291
+ poolAddress: `0x${string}`;
292
+ feeSink?: `0x${string}`;
293
+ admin?: `0x${string}`;
294
+ operator?: `0x${string}`;
295
+ txHash?: string;
296
+ walletProof?: EpochPoolWalletProof;
297
+ }
298
+ /** `pending` = chain-verified, owner NOT recorded (no wallet proof supplied). */
299
+ type EpochPoolOwnership = "pending" | "confirmed";
300
+ interface EpochStudioPool {
301
+ poolAddress: `0x${string}`;
302
+ studioId?: string | null;
303
+ studioWallet: `0x${string}`;
304
+ feeSink: `0x${string}`;
305
+ admin: `0x${string}`;
306
+ operator: `0x${string}`;
307
+ studioHoldsAdmin: true;
308
+ studioHoldsOperator: true;
309
+ playmosIsAdmin: false;
310
+ playmosIsOperator: false;
311
+ ownership?: EpochPoolOwnership;
312
+ owner?: string | null;
313
+ /** Present while `ownership` is `pending` — sign `message` and re-register. */
314
+ proof?: {
315
+ scheme: "eip191-personal-sign";
316
+ wallet: `0x${string}`;
317
+ message: string;
318
+ };
319
+ via: EpochReadVia;
320
+ mock?: true;
321
+ }
322
+ interface EpochCreatePoolInput extends EpochPreparePoolInput {
323
+ /** After the studio wallet submitted the constructor; omitted in mock. */
324
+ poolAddress?: `0x${string}`;
325
+ txHash?: string;
326
+ walletProof?: EpochPoolWalletProof;
327
+ }
328
+ type EpochWinnerIn = `0x${string}` | {
329
+ wallet: `0x${string}`;
330
+ amount?: string;
331
+ amountMicro?: string;
332
+ };
333
+ interface EpochSettleInput {
334
+ series: string;
335
+ epochId: number | string;
336
+ /** Empty array is a legal D11 roll. */
337
+ winners: EpochWinnerIn[];
338
+ epochPrizePool?: `0x${string}`;
339
+ }
340
+ type EpochSettleStatus = "settling" | "settled" | "rolled" | "refunded";
341
+ interface EpochSettleWinner {
342
+ wallet: `0x${string}`;
343
+ /**
344
+ * USD decimal. Present only when the seat's share is known — a wallet-only
345
+ * roster carries no amounts, and absent ≠ `"0.00"` (sdk#660).
346
+ */
347
+ amount?: string;
348
+ /** Integer micro-USDC (6dp) for the same figure as {@link amount}. */
349
+ amountMicro?: string;
350
+ /** Present only after a chain read-back (never inferred from the podium). */
351
+ withdrawableMicro?: string;
352
+ }
353
+ interface EpochSettleResult {
354
+ series: string;
355
+ epochId: string;
356
+ status: EpochSettleStatus;
357
+ txHash: `0x${string}` | null;
358
+ winners: EpochSettleWinner[];
359
+ /**
360
+ * USDC the podium was paid. Present when the SDK knows it (mock: sum of
361
+ * winner amounts; live: the service figure). ABSENT when unknown — a
362
+ * wallet-only roster has no amounts to add. Never a placeholder `"0"` /
363
+ * `"0.00"` standing in for unknown (sdk#660 / same class as #659 withdraw).
364
+ */
365
+ payable?: string;
366
+ payableMicro?: string;
367
+ terminal?: EpochTerminal;
368
+ via: EpochReadVia;
369
+ epochPrizePool?: `0x${string}` | null;
370
+ mock?: true;
371
+ }
372
+ interface EpochClaimableRefundInput {
373
+ series: string;
374
+ epochId: number | string;
375
+ /** The wallet that paid — the address `claimRefund` will credit. */
376
+ payer: `0x${string}`;
377
+ epochPrizePool?: `0x${string}`;
378
+ }
379
+ interface EpochClaimableRefund {
380
+ series: string;
381
+ epochId: string;
382
+ payer: `0x${string}`;
383
+ claimable: string;
384
+ claimableMicro: string;
385
+ seriesBytes32: `0x${string}`;
386
+ epochPrizePool?: `0x${string}` | null;
387
+ via: EpochReadVia;
388
+ mock?: true;
389
+ }
390
+ interface EpochClaimRefundInput {
391
+ series: string;
392
+ epochId: number | string;
393
+ /** Credit always lands here, even if another wallet signs the tx. */
394
+ payer: `0x${string}`;
395
+ epochPrizePool?: `0x${string}`;
396
+ }
397
+ /**
398
+ * No money figure here on purpose. `claimRefund` returns the credited amount
399
+ * on chain, but a wallet batch hands back a receipt, not that return value —
400
+ * so the SDK does not know it. The figure stays readable on both sides of this
401
+ * call (`claimableRefund` before, `withdraw`'s `amountMicro` after), so there
402
+ * is nothing to guess and nothing to publish as a zero.
403
+ */
404
+ interface EpochClaimRefundResult {
405
+ series: string;
406
+ epochId: string;
407
+ payer: `0x${string}`;
408
+ txHash?: `0x${string}`;
409
+ status: "confirmed" | "pending" | "failed";
410
+ epochPrizePool?: `0x${string}` | null;
411
+ via: EpochReadVia;
412
+ mock?: true;
413
+ }
414
+ interface EpochWithdrawInput {
415
+ epochPrizePool?: `0x${string}`;
416
+ }
417
+ interface EpochWithdrawResult {
418
+ epochPrizePool: `0x${string}`;
419
+ /**
420
+ * The USDC this pull moves, read from `withdrawable[wallet]` on chain
421
+ * immediately before the call — `withdraw()` transfers the whole credited
422
+ * balance, so this is the sum that leaves the pool.
423
+ *
424
+ * ABSENT means the SDK could not read that balance (no reader wired, or the
425
+ * read failed). Absent is not zero: the withdrawal is still broadcast and
426
+ * `txHash` still describes it. Never render a missing amount as `$0.00` —
427
+ * a player who pulled $0.90 must never be shown $0.00.
428
+ */
429
+ amount?: string;
430
+ amountMicro?: string;
431
+ txHash?: `0x${string}`;
432
+ status: "confirmed" | "pending" | "failed";
433
+ via: EpochReadVia;
434
+ mock?: true;
435
+ }
436
+ interface EpochGetAttestationInput {
437
+ series: string;
438
+ epochId: number | string;
439
+ epochPrizePool?: `0x${string}`;
440
+ /** Mock only — fixture the board would have served. */
441
+ winners?: `0x${string}`[];
442
+ /** Mock only — micro-USDC strings. */
443
+ amountsMicro?: string[];
444
+ /** Mock only. */
445
+ signature?: `0x${string}`;
446
+ }
447
+ interface EpochAttestation {
448
+ series: string;
449
+ epochId: string;
450
+ winners: `0x${string}`[];
451
+ amountsMicro: string[];
452
+ signature: `0x${string}`;
453
+ epochPrizePool: `0x${string}`;
454
+ terminal?: EpochTerminal;
455
+ dueAt?: string;
456
+ via: EpochReadVia;
457
+ mock?: true;
458
+ }
459
+ interface EpochExecuteSettlementInput {
460
+ series: string;
461
+ epochId: number | string;
462
+ winners: `0x${string}`[];
463
+ /** Integer micro-USDC strings — never USD. */
464
+ amounts: string[];
465
+ signature: `0x${string}`;
466
+ epochPrizePool?: `0x${string}`;
467
+ }
468
+ interface EpochExecuteSettlementResult {
469
+ series: string;
470
+ epochId: string;
471
+ winners: `0x${string}`[];
472
+ amountsMicro: string[];
473
+ signature: `0x${string}`;
474
+ txHash?: `0x${string}`;
475
+ status: "confirmed" | "pending" | "failed";
476
+ /**
477
+ * Only present after a successful chain read of `getEpoch.terminal`.
478
+ * Absent means the read failed — never inferred from broadcast.
479
+ */
480
+ settled?: boolean;
481
+ terminal?: EpochTerminal;
482
+ epochPrizePool?: `0x${string}` | null;
483
+ via: EpochReadVia;
484
+ mock?: true;
485
+ }
486
+ interface SettlementTypedDataInput {
487
+ pool: `0x${string}`;
488
+ chainId: number;
489
+ series: string;
490
+ epochId: number | string;
491
+ winners: `0x${string}`[];
492
+ amounts: string[];
493
+ }
494
+ interface SettlementTypedData {
495
+ domain: {
496
+ name: "EpochPrizePool";
497
+ version: "1";
498
+ chainId: number;
499
+ verifyingContract: `0x${string}`;
500
+ };
501
+ types: {
502
+ Settlement: [
503
+ {
504
+ name: "series";
505
+ type: "bytes32";
506
+ },
507
+ {
508
+ name: "epochId";
509
+ type: "uint256";
510
+ },
511
+ {
512
+ name: "winners";
513
+ type: "address[]";
514
+ },
515
+ {
516
+ name: "amounts";
517
+ type: "uint256[]";
518
+ }
519
+ ];
520
+ };
521
+ primaryType: "Settlement";
522
+ message: {
523
+ series: `0x${string}`;
524
+ epochId: bigint;
525
+ winners: `0x${string}`[];
526
+ amounts: bigint[];
527
+ };
528
+ }
529
+ interface EpochsApi {
530
+ currentId(input: EpochCurrentIdInput): Promise<EpochCurrentId>;
531
+ prize(input: EpochPrizeInput): Promise<EpochPrize>;
532
+ get(input: EpochGetInput): Promise<EpochView>;
533
+ getSeries(input: EpochGetSeriesInput): Promise<EpochSeriesView>;
534
+ preparePool(input: EpochPreparePoolInput): Promise<EpochPreparedPool>;
535
+ registerPool(input: EpochRegisterPoolInput): Promise<EpochStudioPool>;
536
+ createPool(input: EpochCreatePoolInput): Promise<EpochStudioPool>;
537
+ settle(input: EpochSettleInput): Promise<EpochSettleResult>;
538
+ /**
539
+ * Read EpochPrizePool.claimableRefund — micro-USDC still sitting in
540
+ * refundOwed for this payer on a Refunded window (sdk#634).
541
+ */
542
+ claimableRefund(input: EpochClaimableRefundInput): Promise<EpochClaimableRefund>;
543
+ /**
544
+ * Permissionless: move this payer's refund share into withdrawable[payer].
545
+ * The credit never lands on the caller.
546
+ */
547
+ claimRefund(input: EpochClaimRefundInput): Promise<EpochClaimRefundResult>;
548
+ /**
549
+ * Payer wallet pulls USDC from EpochPrizePool.withdrawable[msg.sender].
550
+ * Not live PrizePool `rounds.withdraw`.
551
+ */
552
+ withdraw(input?: EpochWithdrawInput): Promise<EpochWithdrawResult>;
553
+ /**
554
+ * Fetch a posted signed podium from the service board. Any authenticated
555
+ * key — the board is public. Amounts stay micro-USDC strings.
556
+ */
557
+ getAttestation(input: EpochGetAttestationInput): Promise<EpochAttestation>;
558
+ /**
559
+ * Wallet-direct executeSignedSettlement. Relays the fetched podium
560
+ * byte-exact. `settled` only from a chain read of `terminal`.
561
+ */
562
+ executeSettlement(input: EpochExecuteSettlementInput): Promise<EpochExecuteSettlementResult>;
563
+ /**
564
+ * Pay into whatever window is current right now. No open gate (sdk#635).
565
+ *
566
+ * Once the wallet batch mines this never rejects: an entry carrying a
567
+ * `txHash` comes back even if the confirm read fails, because that hash is
568
+ * the only handle on money that has already moved. Such an entry is
569
+ * `pending` / `chain-clock` — treat it as paid-but-not-read-back, not as a
570
+ * failure to retry.
571
+ */
572
+ enter(input: EpochEnterInput): Promise<EpochEntry>;
573
+ }
574
+ interface EpochsDeps {
575
+ http: () => HttpClient;
576
+ config: () => PlaymosConfig;
577
+ assertSecretKey?: (surface: string) => void;
578
+ /**
579
+ * Send the atomic approve+enter batch from the player's wallet. Supplied by
580
+ * the client so this module stays wallet-agnostic (and so the browser bundle
581
+ * keeps its own wallet funnel). Absent → `enter` refuses rather than
582
+ * pretending (P0 invariant #1).
583
+ */
584
+ sendEntry?: (calls: Call[], opts: {
585
+ paymasterUrl?: string;
586
+ }) => Promise<{
587
+ status: OnchainStatus;
588
+ txHash?: `0x${string}`;
589
+ }>;
590
+ /**
591
+ * Wallet-or-RPC `eth_call`. Used by the refund rail so a player can read
592
+ * `claimableRefund` without a service route (sdk#634; service is a parallel slice).
593
+ */
594
+ readView?: (to: `0x${string}`, data: `0x${string}`) => Promise<`0x${string}`>;
595
+ /**
596
+ * The connected wallet address — the account `withdraw()` pulls to. Needed
597
+ * to read `withdrawable[account]` before the pull, so the result can report
598
+ * the money that actually moves instead of a placeholder.
599
+ */
600
+ walletAddress?: () => Promise<`0x${string}`>;
601
+ }
602
+ /** Derived epochId — same formula as EpochPrizePool._epochIdAt. */
603
+ declare function derivedEpochId(genesis: bigint, epochDuration: bigint, at: bigint): bigint;
604
+ /** Settle payable is inherited seed + this epoch's pool (not outgoingSeed). */
605
+ declare function epochPayableMicro(incomingSeed: bigint, pool: bigint): bigint;
606
+ /** Client-side pin — same refusals as the service, so a bad sink never reaches broadcast. */
607
+ declare function prepareStudioPoolLocal(input: EpochPreparePoolInput, playmosFeeSink: `0x${string}`, token: `0x${string}`, playmosAddresses?: `0x${string}`[]): EpochPreparedPool;
608
+ /**
609
+ * The exact message the studio wallet signs to claim ownership of a pool.
610
+ * Byte-identical to the service's `epochPoolProofMessage` — one byte of drift
611
+ * and a legitimate studio is refused, so keep the two in lockstep.
612
+ */
613
+ declare function epochPoolProofMessage(terms: {
614
+ studioId: string;
615
+ poolAddress: `0x${string}`;
616
+ studioWallet: `0x${string}`;
617
+ chainId: number;
618
+ }): string;
619
+ /**
620
+ * The one EIP-712 derivation E1c and every test must share.
621
+ * Domain: EpochPrizePool / 1 / chainId / pool.
622
+ * Type: Settlement(bytes32 series,uint256 epochId,address[] winners,uint256[] amounts).
623
+ * Amounts are micro-USDC integer strings — never USD. The SDK never signs this.
624
+ */
625
+ declare function settlementTypedData(input: SettlementTypedDataInput): SettlementTypedData;
626
+ declare function createEpochsApi(deps: EpochsDeps): EpochsApi;
627
+ /** Test helper — known C1 1 USDC enter split (fee 10% then 60/30 of remainder). */
628
+ declare const C1_ENTER_SPLIT_MICRO: {
629
+ readonly entry: 1000000n;
630
+ readonly fee: 100000n;
631
+ readonly pool: 600000n;
632
+ readonly outgoingSeed: 300000n;
633
+ readonly incomingSeed: 0n;
634
+ };
3
635
 
4
636
  /**
5
637
  * Environment resolution + the canonical address book.
@@ -373,15 +1005,6 @@ declare function validateX402ChallengeInput(input: X402ChallengeInput): {
373
1005
  id?: string;
374
1006
  };
375
1007
 
376
- /**
377
- * The Playmos client — `new Playmos({ apiKey })` → `pay()`, `enterRound()`,
378
- * `verify()`, `webhooks`, `payouts`, `agents`.
379
- *
380
- * Real behavior, no `"mocked"` status anywhere. The chain calls use the proven
381
- * EIP-5792 approve+call batch; `verify()` resolves by the service's on-chain
382
- * read; ids are ULIDs; inputs are validated client-side; idempotency is honored.
383
- */
384
-
385
1008
  declare class Playmos {
386
1009
  readonly config: PlaymosConfig;
387
1010
  readonly env: ResolvedEnv;
@@ -401,6 +1024,16 @@ declare class Playmos {
401
1024
  */
402
1025
  verify: (_rawBody: string | Buffer, _signatureHeader: string | string[] | undefined, _secret: string) => WebhookEvent;
403
1026
  };
1027
+ /**
1028
+ * Rolling epochs — `currentId` / `prize` / `get` / `getSeries` (sdk#629),
1029
+ * `enter` (sdk#635 / S2), operator `settle` (sdk#639 / S3), the C3
1030
+ * refund pull (sdk#634), and E1b `getAttestation` / `executeSettlement`
1031
+ * (wallet-direct via the same `walletProvider()` funnel as `rounds.withdraw`).
1032
+ * Reads/settle go through the service. Refund claim, withdraw, and signed
1033
+ * execute are wallet-direct on EpochPrizePool — not PrizePool.
1034
+ * Nothing here opens a round.
1035
+ */
1036
+ readonly epochs: EpochsApi;
404
1037
  readonly payouts: {
405
1038
  /** Choose how the studio is paid: "usdc" (default) or "fiat" (Bridge). Secret key only (#264). */
406
1039
  setMode: (mode: "usdc" | "fiat") => Promise<{
@@ -479,6 +1112,8 @@ declare class Playmos {
479
1112
  private readonly mockPotMicro;
480
1113
  /** Persisted settle winners for re-settle replay (#490 C2) — never re-invent pool-to-everyone. */
481
1114
  private readonly mockSettleWinners;
1115
+ /** L34 notices after mock settle — funded only with a push txHash. */
1116
+ private readonly mockPayoutNotices;
482
1117
  /**
483
1118
  * Resolve mock round by roundId **or** roundKey (kit `entryProvider` keys by roundKey, #490 C3).
484
1119
  */
@@ -542,6 +1177,28 @@ declare class Playmos {
542
1177
  seriesKey: string;
543
1178
  gameId: string;
544
1179
  }) => Promise<ActiveSeriesRound | null>;
1180
+ /**
1181
+ * L34 / sdk#610 — notifications for a settled round.
1182
+ * Each win is `funded` (push txHash) or `claimable` (withdraw fallback).
1183
+ * Never returns `funded` without a transfer txHash.
1184
+ */
1185
+ payoutNotices: (input: {
1186
+ roundId: string;
1187
+ wallet?: string;
1188
+ }) => Promise<PayoutNoticesResult>;
1189
+ /**
1190
+ * Operator push-attempt after settle (L34). Mock: mark a winner funded only
1191
+ * when a real-shaped txHash is supplied; otherwise that row stays claimable.
1192
+ */
1193
+ pushWinnings: (input: {
1194
+ roundId: string;
1195
+ /** Per-wallet push result. Missing / failed → claimable. */
1196
+ pushes?: Array<{
1197
+ wallet: string;
1198
+ txHash?: string;
1199
+ failed?: boolean;
1200
+ }>;
1201
+ }) => Promise<PayoutNoticesResult>;
545
1202
  /**
546
1203
  * Read a wallet's **claimable** prize balance for a round (issue #41).
547
1204
  * Prefers the service chain read (`GET /v1/rounds/:id/prize?wallet=`); falls
@@ -709,7 +1366,7 @@ declare class Playmos {
709
1366
  private mockIdemReplayOrThrow;
710
1367
  /** External-studio IAP (1%). Returns a real confirmed Payment with a txHash. */
711
1368
  pay(input: PayInput): Promise<Payment>;
712
- /** Playmos-owned skill-game entry (10%, 60/30/10 prize pool). Closes #343. */
1369
+ /** Skill-game prize-pool entry. Live sandbox / Playmos Lab uses 60/30/10. Studio contest take is 1% (not a live separate pool yet). Closes #343. */
713
1370
  enterRound(input: EnterRoundInput): Promise<Payment>;
714
1371
  /**
715
1372
  * `transfers` — read-back / confirmation for a prior `transfer()` (issues #27, #47).
@@ -905,9 +1562,10 @@ declare function computeIapSplit(amountMicro: bigint, feeBps: number): {
905
1562
  netMicro: bigint;
906
1563
  };
907
1564
  /**
908
- * Skill-game prize-pool split (60/30/10 by default). Floor-matches the on-chain
909
- * `EconomyConfig`. Any 1–2 micro rounding remainder is assigned to the pool so
910
- * the three parts sum EXACTLY to the entry (invariant asserted below).
1565
+ * First-party skill-game prize-pool split (60/30/10 by default). Floor-matches
1566
+ * the on-chain first-party `EconomyConfig`. Not the studio contest take (1%
1567
+ * Playmos / default 60/30/9 not live). Any 1–2 micro rounding remainder is
1568
+ * assigned to the pool so the three parts sum EXACTLY to the entry.
911
1569
  */
912
1570
  declare function computePoolSplit(amountMicro: bigint, poolBps: number, seedBps: number, rakeBps: number): {
913
1571
  poolMicro: bigint;
@@ -929,4 +1587,4 @@ declare function ulid(seedTime?: number): string;
929
1587
  /** `${prefix}_${ulid()}` — e.g. `pay_01J…`, `entry_01J…`, `idem_01J…`. */
930
1588
  declare function prefixedId(prefix: string): string;
931
1589
 
932
- export { ActiveSeriesRound, AgentFundResult, AgentWallet, type Authorization, CHAIN_ID, CancelRoundResult, type CreatePaymentRequirementInput, DEFAULT_API_BASE_URL, EnterRoundInput, EscrowHoldInput, EscrowHoldResult, EscrowResolveResult, Listing, MICRO_PER_USDC, MarketplaceGetResult, MarketplaceListInput, MarketplaceSaleResult, Network, PayInput, Payment, type PaymentRequirement, PayoutError, PayoutRule, PayoutRule as PayoutRuleCompute, Playmos, PlaymosConfig, PrizeBalance, RoundCancelInput, RoundGetResult, RoundOpenInput, RoundSettleInput, RoundState, SettleRoundResult, type SettlementAsset, TransferConfirmOptions, TransferInput, TransferReconcile, TransferResult, USDC_ADDRESS, USDC_DECIMALS, VerifyResult, WaitOptions, type WalletSignatureAuthorization, WebhookEvent, WithdrawResult, type X402ChallengeInput, type X402ChallengeResult, type X402FulfillAuthorization, type X402PayInput, type X402PayloadAuthorization, type X402PayloadMode, type X402PaymentRequired, type X402SettleResult, clientRuntimeSignals, computeIapSplit, computePayout, computePoolSplit, createPaymentRequirement, createX402Challenge, decodePaymentHeader, encodePaymentHeader, formatMicroToUsd, isClientRuntime, isWalletSignatureAuthorization, isX402PayloadAuthorization, networkToCaip2, parsePaymentRequirement, parseUsdToMicro, prefixedId, previewEscrowFee, previewIapSplit, previewMarketplaceSplit, previewPoolSplit, previewTransferSplit, resolveEnv, serializePaymentRequirement, toX402PaymentRequired, ulid, validateX402ChallengeInput };
1590
+ export { ActiveSeriesRound, AgentFundResult, AgentWallet, type Authorization, C1_ENTER_SPLIT_MICRO, CHAIN_ID, CancelRoundResult, type CreatePaymentRequirementInput, DEFAULT_API_BASE_URL, EnterRoundInput, type EpochAttestation, type EpochClaimRefundInput, type EpochClaimRefundResult, type EpochClaimableRefund, type EpochClaimableRefundInput, type EpochCreatePoolInput, type EpochCurrentId, type EpochCurrentIdInput, type EpochEnterInput, type EpochEntry, type EpochEntryStatus, type EpochExecuteSettlementInput, type EpochExecuteSettlementResult, type EpochGetAttestationInput, type EpochGetInput, type EpochGetSeriesInput, type EpochPoolOwnership, type EpochPoolWalletProof, type EpochPreparePoolInput, type EpochPreparedPool, type EpochPrize, type EpochPrizeInput, type EpochReadVia, type EpochRegisterPoolInput, type EpochSeriesView, type EpochSettleInput, type EpochSettleResult, type EpochSettleStatus, type EpochSettleWinner, type EpochStudioPool, type EpochTerminal, type EpochView, type EpochWinnerIn, type EpochWithdrawInput, type EpochWithdrawResult, type EpochsApi, EscrowHoldInput, EscrowHoldResult, EscrowResolveResult, Listing, MICRO_PER_USDC, MarketplaceGetResult, MarketplaceListInput, MarketplaceSaleResult, Network, PLAYMOS_FEE_SINK_DEFAULT, PayInput, Payment, type PaymentRequirement, PayoutError, PayoutNoticesResult, PayoutRule, PayoutRule as PayoutRuleCompute, Playmos, PlaymosConfig, PrizeBalance, RETIRED_PLAYMOS_FEE_SINK, RoundCancelInput, RoundGetResult, RoundOpenInput, RoundSettleInput, RoundState, SettleRoundResult, type SettlementAsset, type SettlementTypedData, type SettlementTypedDataInput, TransferConfirmOptions, TransferInput, TransferReconcile, TransferResult, USDC_ADDRESS, USDC_DECIMALS, VerifyResult, WaitOptions, type WalletSignatureAuthorization, WebhookEvent, WithdrawResult, type X402ChallengeInput, type X402ChallengeResult, type X402FulfillAuthorization, type X402PayInput, type X402PayloadAuthorization, type X402PayloadMode, type X402PaymentRequired, type X402SettleResult, buildEpochClaimRefundCall, buildEpochEntryCalls, buildEpochWithdrawCall, clientRuntimeSignals, computeIapSplit, computePayout, computePoolSplit, createEpochsApi, createPaymentRequirement, createX402Challenge, decodePaymentHeader, derivedEpochId, encodeEpochPoolConstructorArgs, encodePaymentHeader, epochPayableMicro, epochPoolProofMessage, formatMicroToUsd, identityToBytes32, isClientRuntime, isWalletSignatureAuthorization, isX402PayloadAuthorization, networkToCaip2, parsePaymentRequirement, parseUsdToMicro, prefixedId, prepareStudioPoolLocal, previewEscrowFee, previewIapSplit, previewMarketplaceSplit, previewPoolSplit, previewTransferSplit, resolveEnv, serializePaymentRequirement, seriesToBytes32, settlementTypedData, toX402PaymentRequired, ulid, validateX402ChallengeInput };