@playmos/sdk 0.3.3 → 0.3.5

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 CHANGED
@@ -4,6 +4,21 @@
4
4
 
5
5
  Stablecoin payments for games on Base. One SDK for in-app purchases (1%), skill-game prize-pool entries (10%, 60/30/10), and **in-game economies** (player · NPC · agent commerce via `transfer()`). USD in, USDC on-chain — no crypto UX for your players.
6
6
 
7
+
8
+ ## Local `file:` / monorepo install
9
+
10
+ `@playmos/sdk` ships **built `dist/`**. `prepare` / `prepack` / `prepublishOnly` run
11
+ `scripts/ensure-build.cjs`, which rebuilds `dist/` via local `tsup` or (on a cold
12
+ `file:` install with no `sdk/node_modules`) `npx --yes tsup@8.3.0`:
13
+
14
+ - `npm install` inside `sdk/`
15
+ - `npm install` of a **`file:`** / git dependency (dogfood monorepos)
16
+ - `npm publish` / pack
17
+
18
+ So wiping `dist/` then `npm i file:…/sdk` still yields a current build (#211).
19
+ CI also fails if committed `dist/` drifts from source.
20
+
21
+
7
22
  ## Install
8
23
 
9
24
  ```bash
@@ -67,5 +67,3 @@ var NothingToWithdrawError = class extends PlaymosError {
67
67
  };
68
68
 
69
69
  export { ApiError, AuthError, ConfigError, InsufficientGasError, InvalidAmountError, MissingFieldError, NothingToWithdrawError, PaymentFailedError, PlaymosError, WalletConnectionError };
70
- //# sourceMappingURL=chunk-TMBBEGIF.js.map
71
- //# sourceMappingURL=chunk-TMBBEGIF.js.map
@@ -76,7 +76,7 @@ interface PlaymosConfig {
76
76
  }
77
77
  /** Tuning for the automatic 429 retry (all optional; sane defaults). */
78
78
  interface RetryOptions {
79
- /** Max automatic retries on HTTP 429. `0` disables retrying entirely. Default 2. */
79
+ /** Max automatic retries on HTTP 429. `0` disables retrying entirely. Default 2 (→ up to 3 attempts). */
80
80
  maxRetries?: number;
81
81
  /** Base backoff in ms; the wait grows exponentially per attempt (2^n). Default 500. */
82
82
  baseDelayMs?: number;
@@ -144,10 +144,11 @@ interface EnterRoundInput {
144
144
  idempotencyKey?: string;
145
145
  metadata?: Record<string, string>;
146
146
  /**
147
- * Advanced (games that manage their own on-chain rounds, e.g. the Playmos
148
- * game-hub kit): the EXACT on-chain round key to enter — overrides the default
149
- * `${gameId}:${roundId}` derivation. Set it to the value your game's server
150
- * verifies `hasEntered` against (e.g. "bjtest:T1").
147
+ * Exact on-chain round key for Path B / entryProvider (#201 / #204 / #210).
148
+ * First-class for **fixed pins** (`bmtest:T1`, `bjtest:T1`) and **rolling**
149
+ * windows (`2026-07-15T18:00:T1`). Must match what the hub verifies via
150
+ * `hasEntered`. When set, this is sent as the payment roundId on create-intent
151
+ * and server-settle so on-chain enter + receipt agree.
151
152
  */
152
153
  roundKey?: string;
153
154
  /**
@@ -457,7 +458,11 @@ type PayoutRule = {
457
458
  kind: "custom";
458
459
  amounts: string[];
459
460
  };
460
- type RoundStatus = "open" | "locked" | "settled" | "cancelled" | "none";
461
+ /**
462
+ * `opening` = open tx broadcast (#344).
463
+ * `cancelling` = cancel tx broadcast (#346) — refunds entrants, frees series latch.
464
+ */
465
+ type RoundStatus = "opening" | "open" | "locked" | "settled" | "cancelling" | "cancelled" | "none";
461
466
  interface RoundOpenInput {
462
467
  gameId: string;
463
468
  /** Studio-facing round id (also used as the on-chain round key unless roundKey set). */
@@ -470,13 +475,22 @@ interface RoundOpenInput {
470
475
  closeAt?: string;
471
476
  /** Optional series key for the 60/30/10 seed flywheel; defaults to gameId. */
472
477
  seriesKey?: string;
473
- /** Advanced: exact on-chain round key string (default = roundId). */
478
+ /**
479
+ * Exact on-chain round key string (default = roundId).
480
+ * First-class for fixed pins (`bmtest:T1`, `bjtest:T1`) and rolling windows
481
+ * (`2026-07-15T18:00:T1`) — Path B / entryProvider (#201 / #210).
482
+ */
474
483
  roundKey?: string;
475
484
  }
476
485
  interface RoundState {
477
486
  roundId: string;
478
487
  gameId: string;
479
488
  roundKey: string;
489
+ /**
490
+ * Series latch key for the 60/30/10 flywheel (#351). Required for
491
+ * `rounds.activeForSeries` under mock — open must persist it (not discard).
492
+ */
493
+ seriesKey?: string;
480
494
  status: RoundStatus;
481
495
  entryAmount: string;
482
496
  /** Payable pool in USD from chain after reconcile; **`null` until reconciled** (never a fabricated "0.00"). Issue #42. */
@@ -488,12 +502,44 @@ interface RoundState {
488
502
  openTxHash?: `0x${string}`;
489
503
  lockTxHash?: `0x${string}`;
490
504
  settleTxHash?: `0x${string}`;
505
+ /** PrizePool.cancel broadcast hash (#346). */
506
+ cancelTxHash?: `0x${string}`;
491
507
  /**
492
508
  * PrizePool contract for this round's game (issue #41). Needed to claim winnings.
493
509
  * `null` only if the game has no contract address configured.
494
510
  */
495
511
  prizePoolAddress?: `0x${string}` | null;
496
512
  }
513
+ /**
514
+ * Active series latch from `GET /v1/series/:seriesKey/active` (#351).
515
+ * `null` from `activeForSeries` is a **proof of free**, not a failed probe.
516
+ */
517
+ interface ActiveSeriesRound {
518
+ roundId: string | null;
519
+ roundKey: string | null;
520
+ roundIdHash: `0x${string}`;
521
+ status: RoundStatus | "opening" | "cancelling";
522
+ /** null if unreconciled — never fabricate 0 */
523
+ entrants: number | null;
524
+ /** null unless Locked/Settled */
525
+ pool: string | null;
526
+ openTxHash?: string | null;
527
+ cancelTxHash?: string | null;
528
+ prizePoolAddress: `0x${string}`;
529
+ }
530
+ interface ActiveForSeriesResult {
531
+ series: string;
532
+ via: "chain" | "cache";
533
+ active: ActiveSeriesRound | null;
534
+ }
535
+ /** Result of `playmos.rounds.cancel` — may be async 202 cancelling (#346). */
536
+ interface CancelRoundResult {
537
+ roundId: string;
538
+ txHash: `0x${string}` | null;
539
+ /** `"cancelling"` = broadcast accepted; `"cancelled"` = chain Cancelled(4) finalized. */
540
+ status: "cancelling" | "cancelled";
541
+ round?: RoundState;
542
+ }
497
543
  /** What `rounds.prize({ … })` returns — claimable pull-payment balance (issue #41). */
498
544
  interface PrizeBalance {
499
545
  roundId: string;
@@ -528,15 +574,26 @@ interface RoundSettleInput {
528
574
  }[];
529
575
  };
530
576
  }
577
+ /**
578
+ * Result of `playmos.rounds.settle`.
579
+ *
580
+ * After #339 / async settle: the service may return **`status: "settling"`** with a
581
+ * broadcast `txHash` (HTTP 202) — the receipt is **not** awaited in the request.
582
+ * Treat settle as **submit-only** when `status === "settling"`; poll
583
+ * `playmos.rounds.get` / on-chain inspect until `status === "settled"` (or call
584
+ * settle again to reconcile). `status: "settled"` remains the terminal success shape.
585
+ */
531
586
  interface SettleRoundResult {
532
587
  roundId: string;
533
- txHash: `0x${string}`;
534
- poolPaid: string;
535
- winners: {
588
+ txHash: `0x${string}` | null;
589
+ /** Present when settled (or echoed from the submit body); may be omitted while settling. */
590
+ poolPaid?: string | null;
591
+ winners?: {
536
592
  wallet: `0x${string}`;
537
593
  amount: string;
538
594
  }[];
539
- status: "settled";
595
+ /** `"settling"` = broadcast accepted, confirmation pending; `"settled"` = finalized. */
596
+ status: "settled" | "settling";
540
597
  }
541
598
 
542
599
  /**
@@ -593,4 +650,4 @@ declare class NothingToWithdrawError extends PlaymosError {
593
650
  constructor(detail?: Record<string, unknown>);
594
651
  }
595
652
 
596
- export { type AgentWallet as A, MissingFieldError as B, ConfigError as C, NothingToWithdrawError as D, type EscrowHoldInput as E, PaymentFailedError as F, type GasConfig as G, type PaymentStatus as H, InsufficientGasError as I, type PayoutRule as J, PlaymosError as K, type Listing as L, type MarketplaceListInput as M, type Network as N, type PlaymosErrorCode as O, type PlaymosConfig as P, type RetryOptions as Q, type RoundOpenInput as R, type SettleRoundResult as S, type TransferResult as T, type RoundStatus as U, type VerifyResult as V, type WebhookEvent as W, type WalletConfig as X, WalletConnectionError as Y, type WalletConnector as Z, type WebhookEventType as _, type RoundState as a, type RoundSettleInput as b, type PrizeBalance as c, type WithdrawResult as d, type AgentFundResult as e, type EscrowHoldResult as f, type EscrowResolveResult as g, type MarketplaceSaleResult as h, type MarketplaceGetResult as i, type PayInput as j, type Payment as k, type EnterRoundInput as l, type TransferReconcile as m, type WaitOptions as n, type TransferInput as o, type TransferConfirmOptions as p, type AgentEconomyConfig as q, ApiError as r, AuthError as s, type ContractConfig as t, type Eip1193Provider as u, type GasMode as v, InvalidAmountError as w, type ListingStatus as x, type MarketplaceItem as y, type MarketplaceSale as z };
653
+ export { WalletConnectionError as $, type ActiveSeriesRound as A, InvalidAmountError as B, type CancelRoundResult as C, type ListingStatus as D, type EscrowHoldInput as E, type MarketplaceItem as F, type GasConfig as G, type MarketplaceSale as H, InsufficientGasError as I, MissingFieldError as J, NothingToWithdrawError as K, type Listing as L, type MarketplaceListInput as M, type Network as N, PaymentFailedError as O, type PlaymosConfig as P, type PaymentStatus as Q, type RoundOpenInput as R, type SettleRoundResult as S, type TransferResult as T, PlaymosError as U, type VerifyResult as V, type WebhookEvent as W, type PlaymosErrorCode as X, type RetryOptions as Y, type RoundStatus as Z, type WalletConfig as _, type RoundState as a, type WalletConnector as a0, type WebhookEventType as a1, type RoundSettleInput as b, type PrizeBalance as c, type WithdrawResult as d, type AgentWallet as e, type AgentFundResult as f, type EscrowHoldResult as g, type EscrowResolveResult as h, type MarketplaceSaleResult as i, type MarketplaceGetResult as j, type PayInput as k, type Payment as l, type EnterRoundInput as m, type TransferReconcile as n, type WaitOptions as o, type TransferInput as p, type TransferConfirmOptions as q, type PayoutRule as r, type ActiveForSeriesResult as s, type AgentEconomyConfig as t, ApiError as u, AuthError as v, ConfigError as w, type ContractConfig as x, type Eip1193Provider as y, type GasMode as z };
@@ -76,7 +76,7 @@ interface PlaymosConfig {
76
76
  }
77
77
  /** Tuning for the automatic 429 retry (all optional; sane defaults). */
78
78
  interface RetryOptions {
79
- /** Max automatic retries on HTTP 429. `0` disables retrying entirely. Default 2. */
79
+ /** Max automatic retries on HTTP 429. `0` disables retrying entirely. Default 2 (→ up to 3 attempts). */
80
80
  maxRetries?: number;
81
81
  /** Base backoff in ms; the wait grows exponentially per attempt (2^n). Default 500. */
82
82
  baseDelayMs?: number;
@@ -144,10 +144,11 @@ interface EnterRoundInput {
144
144
  idempotencyKey?: string;
145
145
  metadata?: Record<string, string>;
146
146
  /**
147
- * Advanced (games that manage their own on-chain rounds, e.g. the Playmos
148
- * game-hub kit): the EXACT on-chain round key to enter — overrides the default
149
- * `${gameId}:${roundId}` derivation. Set it to the value your game's server
150
- * verifies `hasEntered` against (e.g. "bjtest:T1").
147
+ * Exact on-chain round key for Path B / entryProvider (#201 / #204 / #210).
148
+ * First-class for **fixed pins** (`bmtest:T1`, `bjtest:T1`) and **rolling**
149
+ * windows (`2026-07-15T18:00:T1`). Must match what the hub verifies via
150
+ * `hasEntered`. When set, this is sent as the payment roundId on create-intent
151
+ * and server-settle so on-chain enter + receipt agree.
151
152
  */
152
153
  roundKey?: string;
153
154
  /**
@@ -457,7 +458,11 @@ type PayoutRule = {
457
458
  kind: "custom";
458
459
  amounts: string[];
459
460
  };
460
- type RoundStatus = "open" | "locked" | "settled" | "cancelled" | "none";
461
+ /**
462
+ * `opening` = open tx broadcast (#344).
463
+ * `cancelling` = cancel tx broadcast (#346) — refunds entrants, frees series latch.
464
+ */
465
+ type RoundStatus = "opening" | "open" | "locked" | "settled" | "cancelling" | "cancelled" | "none";
461
466
  interface RoundOpenInput {
462
467
  gameId: string;
463
468
  /** Studio-facing round id (also used as the on-chain round key unless roundKey set). */
@@ -470,13 +475,22 @@ interface RoundOpenInput {
470
475
  closeAt?: string;
471
476
  /** Optional series key for the 60/30/10 seed flywheel; defaults to gameId. */
472
477
  seriesKey?: string;
473
- /** Advanced: exact on-chain round key string (default = roundId). */
478
+ /**
479
+ * Exact on-chain round key string (default = roundId).
480
+ * First-class for fixed pins (`bmtest:T1`, `bjtest:T1`) and rolling windows
481
+ * (`2026-07-15T18:00:T1`) — Path B / entryProvider (#201 / #210).
482
+ */
474
483
  roundKey?: string;
475
484
  }
476
485
  interface RoundState {
477
486
  roundId: string;
478
487
  gameId: string;
479
488
  roundKey: string;
489
+ /**
490
+ * Series latch key for the 60/30/10 flywheel (#351). Required for
491
+ * `rounds.activeForSeries` under mock — open must persist it (not discard).
492
+ */
493
+ seriesKey?: string;
480
494
  status: RoundStatus;
481
495
  entryAmount: string;
482
496
  /** Payable pool in USD from chain after reconcile; **`null` until reconciled** (never a fabricated "0.00"). Issue #42. */
@@ -488,12 +502,44 @@ interface RoundState {
488
502
  openTxHash?: `0x${string}`;
489
503
  lockTxHash?: `0x${string}`;
490
504
  settleTxHash?: `0x${string}`;
505
+ /** PrizePool.cancel broadcast hash (#346). */
506
+ cancelTxHash?: `0x${string}`;
491
507
  /**
492
508
  * PrizePool contract for this round's game (issue #41). Needed to claim winnings.
493
509
  * `null` only if the game has no contract address configured.
494
510
  */
495
511
  prizePoolAddress?: `0x${string}` | null;
496
512
  }
513
+ /**
514
+ * Active series latch from `GET /v1/series/:seriesKey/active` (#351).
515
+ * `null` from `activeForSeries` is a **proof of free**, not a failed probe.
516
+ */
517
+ interface ActiveSeriesRound {
518
+ roundId: string | null;
519
+ roundKey: string | null;
520
+ roundIdHash: `0x${string}`;
521
+ status: RoundStatus | "opening" | "cancelling";
522
+ /** null if unreconciled — never fabricate 0 */
523
+ entrants: number | null;
524
+ /** null unless Locked/Settled */
525
+ pool: string | null;
526
+ openTxHash?: string | null;
527
+ cancelTxHash?: string | null;
528
+ prizePoolAddress: `0x${string}`;
529
+ }
530
+ interface ActiveForSeriesResult {
531
+ series: string;
532
+ via: "chain" | "cache";
533
+ active: ActiveSeriesRound | null;
534
+ }
535
+ /** Result of `playmos.rounds.cancel` — may be async 202 cancelling (#346). */
536
+ interface CancelRoundResult {
537
+ roundId: string;
538
+ txHash: `0x${string}` | null;
539
+ /** `"cancelling"` = broadcast accepted; `"cancelled"` = chain Cancelled(4) finalized. */
540
+ status: "cancelling" | "cancelled";
541
+ round?: RoundState;
542
+ }
497
543
  /** What `rounds.prize({ … })` returns — claimable pull-payment balance (issue #41). */
498
544
  interface PrizeBalance {
499
545
  roundId: string;
@@ -528,15 +574,26 @@ interface RoundSettleInput {
528
574
  }[];
529
575
  };
530
576
  }
577
+ /**
578
+ * Result of `playmos.rounds.settle`.
579
+ *
580
+ * After #339 / async settle: the service may return **`status: "settling"`** with a
581
+ * broadcast `txHash` (HTTP 202) — the receipt is **not** awaited in the request.
582
+ * Treat settle as **submit-only** when `status === "settling"`; poll
583
+ * `playmos.rounds.get` / on-chain inspect until `status === "settled"` (or call
584
+ * settle again to reconcile). `status: "settled"` remains the terminal success shape.
585
+ */
531
586
  interface SettleRoundResult {
532
587
  roundId: string;
533
- txHash: `0x${string}`;
534
- poolPaid: string;
535
- winners: {
588
+ txHash: `0x${string}` | null;
589
+ /** Present when settled (or echoed from the submit body); may be omitted while settling. */
590
+ poolPaid?: string | null;
591
+ winners?: {
536
592
  wallet: `0x${string}`;
537
593
  amount: string;
538
594
  }[];
539
- status: "settled";
595
+ /** `"settling"` = broadcast accepted, confirmation pending; `"settled"` = finalized. */
596
+ status: "settled" | "settling";
540
597
  }
541
598
 
542
599
  /**
@@ -593,4 +650,4 @@ declare class NothingToWithdrawError extends PlaymosError {
593
650
  constructor(detail?: Record<string, unknown>);
594
651
  }
595
652
 
596
- export { type AgentWallet as A, MissingFieldError as B, ConfigError as C, NothingToWithdrawError as D, type EscrowHoldInput as E, PaymentFailedError as F, type GasConfig as G, type PaymentStatus as H, InsufficientGasError as I, type PayoutRule as J, PlaymosError as K, type Listing as L, type MarketplaceListInput as M, type Network as N, type PlaymosErrorCode as O, type PlaymosConfig as P, type RetryOptions as Q, type RoundOpenInput as R, type SettleRoundResult as S, type TransferResult as T, type RoundStatus as U, type VerifyResult as V, type WebhookEvent as W, type WalletConfig as X, WalletConnectionError as Y, type WalletConnector as Z, type WebhookEventType as _, type RoundState as a, type RoundSettleInput as b, type PrizeBalance as c, type WithdrawResult as d, type AgentFundResult as e, type EscrowHoldResult as f, type EscrowResolveResult as g, type MarketplaceSaleResult as h, type MarketplaceGetResult as i, type PayInput as j, type Payment as k, type EnterRoundInput as l, type TransferReconcile as m, type WaitOptions as n, type TransferInput as o, type TransferConfirmOptions as p, type AgentEconomyConfig as q, ApiError as r, AuthError as s, type ContractConfig as t, type Eip1193Provider as u, type GasMode as v, InvalidAmountError as w, type ListingStatus as x, type MarketplaceItem as y, type MarketplaceSale as z };
653
+ export { WalletConnectionError as $, type ActiveSeriesRound as A, InvalidAmountError as B, type CancelRoundResult as C, type ListingStatus as D, type EscrowHoldInput as E, type MarketplaceItem as F, type GasConfig as G, type MarketplaceSale as H, InsufficientGasError as I, MissingFieldError as J, NothingToWithdrawError as K, type Listing as L, type MarketplaceListInput as M, type Network as N, PaymentFailedError as O, type PlaymosConfig as P, type PaymentStatus as Q, type RoundOpenInput as R, type SettleRoundResult as S, type TransferResult as T, PlaymosError as U, type VerifyResult as V, type WebhookEvent as W, type PlaymosErrorCode as X, type RetryOptions as Y, type RoundStatus as Z, type WalletConfig as _, type RoundState as a, type WalletConnector as a0, type WebhookEventType as a1, type RoundSettleInput as b, type PrizeBalance as c, type WithdrawResult as d, type AgentWallet as e, type AgentFundResult as f, type EscrowHoldResult as g, type EscrowResolveResult as h, type MarketplaceSaleResult as i, type MarketplaceGetResult as j, type PayInput as k, type Payment as l, type EnterRoundInput as m, type TransferReconcile as n, type WaitOptions as o, type TransferInput as p, type TransferConfirmOptions as q, type PayoutRule as r, type ActiveForSeriesResult as s, type AgentEconomyConfig as t, ApiError as u, AuthError as v, ConfigError as w, type ContractConfig as x, type Eip1193Provider as y, type GasMode as z };