@playmos/sdk 0.3.4 → 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.
@@ -486,6 +486,11 @@ interface RoundState {
486
486
  roundId: string;
487
487
  gameId: string;
488
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;
489
494
  status: RoundStatus;
490
495
  entryAmount: string;
491
496
  /** Payable pool in USD from chain after reconcile; **`null` until reconciled** (never a fabricated "0.00"). Issue #42. */
@@ -505,6 +510,28 @@ interface RoundState {
505
510
  */
506
511
  prizePoolAddress?: `0x${string}` | null;
507
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
+ }
508
535
  /** Result of `playmos.rounds.cancel` — may be async 202 cancelling (#346). */
509
536
  interface CancelRoundResult {
510
537
  roundId: string;
@@ -623,4 +650,4 @@ declare class NothingToWithdrawError extends PlaymosError {
623
650
  constructor(detail?: Record<string, unknown>);
624
651
  }
625
652
 
626
- export { type WebhookEventType as $, type AgentWallet as A, type MarketplaceItem as B, type CancelRoundResult as C, type MarketplaceSale as D, type EscrowHoldInput as E, MissingFieldError as F, type GasConfig as G, NothingToWithdrawError as H, InsufficientGasError as I, PaymentFailedError as J, type PaymentStatus as K, type Listing as L, type MarketplaceListInput as M, type Network as N, PlaymosError as O, type PlaymosConfig as P, type PlaymosErrorCode as Q, type RoundOpenInput as R, type SettleRoundResult as S, type TransferResult as T, type RetryOptions as U, type VerifyResult as V, type WebhookEvent as W, type RoundStatus as X, type WalletConfig as Y, WalletConnectionError as Z, type WalletConnector 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 PayoutRule as q, type AgentEconomyConfig as r, ApiError as s, AuthError as t, ConfigError as u, type ContractConfig as v, type Eip1193Provider as w, type GasMode as x, InvalidAmountError as y, type ListingStatus 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 };
@@ -486,6 +486,11 @@ interface RoundState {
486
486
  roundId: string;
487
487
  gameId: string;
488
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;
489
494
  status: RoundStatus;
490
495
  entryAmount: string;
491
496
  /** Payable pool in USD from chain after reconcile; **`null` until reconciled** (never a fabricated "0.00"). Issue #42. */
@@ -505,6 +510,28 @@ interface RoundState {
505
510
  */
506
511
  prizePoolAddress?: `0x${string}` | null;
507
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
+ }
508
535
  /** Result of `playmos.rounds.cancel` — may be async 202 cancelling (#346). */
509
536
  interface CancelRoundResult {
510
537
  roundId: string;
@@ -623,4 +650,4 @@ declare class NothingToWithdrawError extends PlaymosError {
623
650
  constructor(detail?: Record<string, unknown>);
624
651
  }
625
652
 
626
- export { type WebhookEventType as $, type AgentWallet as A, type MarketplaceItem as B, type CancelRoundResult as C, type MarketplaceSale as D, type EscrowHoldInput as E, MissingFieldError as F, type GasConfig as G, NothingToWithdrawError as H, InsufficientGasError as I, PaymentFailedError as J, type PaymentStatus as K, type Listing as L, type MarketplaceListInput as M, type Network as N, PlaymosError as O, type PlaymosConfig as P, type PlaymosErrorCode as Q, type RoundOpenInput as R, type SettleRoundResult as S, type TransferResult as T, type RetryOptions as U, type VerifyResult as V, type WebhookEvent as W, type RoundStatus as X, type WalletConfig as Y, WalletConnectionError as Z, type WalletConnector 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 PayoutRule as q, type AgentEconomyConfig as r, ApiError as s, AuthError as t, ConfigError as u, type ContractConfig as v, type Eip1193Provider as w, type GasMode as x, InvalidAmountError as y, type ListingStatus 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 };
package/dist/index.cjs CHANGED
@@ -1005,6 +1005,8 @@ var Playmos = class {
1005
1005
  roundId: input.roundId,
1006
1006
  gameId: input.gameId,
1007
1007
  roundKey,
1008
+ // #351 — must persist seriesKey so activeForSeries mock is authoritative
1009
+ seriesKey: input.seriesKey ?? input.gameId,
1008
1010
  status: "open",
1009
1011
  entryAmount: input.entryAmount,
1010
1012
  pool: null,
@@ -1201,6 +1203,58 @@ var Playmos = class {
1201
1203
  );
1202
1204
  return round;
1203
1205
  },
1206
+ /**
1207
+ * Authoritative series latch (#351) — `null` means **proven free**.
1208
+ * `GET /v1/series/:seriesKey/active?gameId=…` — not a candidate probe.
1209
+ */
1210
+ activeForSeries: async (input) => {
1211
+ requireField(input?.seriesKey, "seriesKey");
1212
+ requireField(input?.gameId, "gameId");
1213
+ if (this.config.mock) {
1214
+ for (const r of this.mockRounds.values()) {
1215
+ if (r.gameId !== input.gameId) continue;
1216
+ const sk = r.seriesKey ?? r.gameId;
1217
+ if (sk !== input.seriesKey) continue;
1218
+ if (r.status === "open" || r.status === "locked" || r.status === "opening" || r.status === "cancelling") {
1219
+ return {
1220
+ roundId: r.roundId,
1221
+ roundKey: r.roundKey,
1222
+ roundIdHash: "0x" + "m".repeat(64),
1223
+ status: r.status,
1224
+ entrants: r.entrants,
1225
+ pool: r.pool,
1226
+ openTxHash: r.openTxHash ?? null,
1227
+ cancelTxHash: r.cancelTxHash ?? null,
1228
+ prizePoolAddress: r.prizePoolAddress ?? "0x0000000000000000000000000000000000000002"
1229
+ };
1230
+ }
1231
+ }
1232
+ return null;
1233
+ }
1234
+ const body = await this.http.get(
1235
+ `/series/${encodeURIComponent(input.seriesKey)}/active?gameId=${encodeURIComponent(input.gameId)}`
1236
+ );
1237
+ if (body == null || typeof body !== "object") {
1238
+ throw new ApiError("activeForSeries: malformed response (expected object body)", {
1239
+ code: "invalid_response",
1240
+ status: 502
1241
+ });
1242
+ }
1243
+ if (!("active" in body)) {
1244
+ throw new ApiError("activeForSeries: malformed response (missing active field)", {
1245
+ code: "invalid_response",
1246
+ status: 502
1247
+ });
1248
+ }
1249
+ if (body.active === null) return null;
1250
+ if (body.active == null || typeof body.active !== "object") {
1251
+ throw new ApiError("activeForSeries: malformed response (active must be object or null)", {
1252
+ code: "invalid_response",
1253
+ status: 502
1254
+ });
1255
+ }
1256
+ return body.active;
1257
+ },
1204
1258
  /**
1205
1259
  * Read a wallet's **claimable** prize balance for a round (issue #41).
1206
1260
  * Prefers the service chain read (`GET /v1/rounds/:id/prize?wallet=`); falls
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
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 CancelRoundResult, c as PrizeBalance, d as WithdrawResult, A as AgentWallet, e as AgentFundResult, T as TransferResult, E as EscrowHoldInput, f as EscrowHoldResult, g as EscrowResolveResult, M as MarketplaceListInput, L as Listing, h as MarketplaceSaleResult, i as MarketplaceGetResult, j as PayInput, k as Payment, l as EnterRoundInput, m as TransferReconcile, n as WaitOptions, o as TransferInput, p as TransferConfirmOptions, V as VerifyResult, q as PayoutRule } from './errors-B_AqyZQE.cjs';
2
- export { r as AgentEconomyConfig, s as ApiError, t as AuthError, u as ConfigError, v as ContractConfig, w as Eip1193Provider, G as GasConfig, x as GasMode, I as InsufficientGasError, y as InvalidAmountError, z as ListingStatus, B as MarketplaceItem, D as MarketplaceSale, F as MissingFieldError, H as NothingToWithdrawError, J as PaymentFailedError, K as PaymentStatus, O as PlaymosError, Q as PlaymosErrorCode, U as RetryOptions, X as RoundStatus, Y as WalletConfig, Z as WalletConnectionError, _ as WalletConnector, $ as WebhookEventType } from './errors-B_AqyZQE.cjs';
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 CancelRoundResult, A as ActiveSeriesRound, c as PrizeBalance, d as WithdrawResult, e as AgentWallet, f as AgentFundResult, T as TransferResult, E as EscrowHoldInput, g as EscrowHoldResult, h as EscrowResolveResult, M as MarketplaceListInput, L as Listing, i as MarketplaceSaleResult, j as MarketplaceGetResult, k as PayInput, l as Payment, m as EnterRoundInput, n as TransferReconcile, o as WaitOptions, p as TransferInput, q as TransferConfirmOptions, V as VerifyResult, r as PayoutRule } from './errors-CdVzHuhY.cjs';
2
+ export { s as ActiveForSeriesResult, t as AgentEconomyConfig, u as ApiError, v as AuthError, w as ConfigError, x as ContractConfig, y as Eip1193Provider, G as GasConfig, z as GasMode, I as InsufficientGasError, B as InvalidAmountError, D as ListingStatus, F as MarketplaceItem, H as MarketplaceSale, J as MissingFieldError, K as NothingToWithdrawError, O as PaymentFailedError, Q as PaymentStatus, U as PlaymosError, X as PlaymosErrorCode, Y as RetryOptions, Z as RoundStatus, _ as WalletConfig, $ as WalletConnectionError, a0 as WalletConnector, a1 as WebhookEventType } from './errors-CdVzHuhY.cjs';
3
3
 
4
4
  /**
5
5
  * Environment resolution + the canonical address book.
@@ -487,6 +487,14 @@ declare class Playmos {
487
487
  get: (input: {
488
488
  roundId: string;
489
489
  }) => Promise<RoundState>;
490
+ /**
491
+ * Authoritative series latch (#351) — `null` means **proven free**.
492
+ * `GET /v1/series/:seriesKey/active?gameId=…` — not a candidate probe.
493
+ */
494
+ activeForSeries: (input: {
495
+ seriesKey: string;
496
+ gameId: string;
497
+ }) => Promise<ActiveSeriesRound | null>;
490
498
  /**
491
499
  * Read a wallet's **claimable** prize balance for a round (issue #41).
492
500
  * Prefers the service chain read (`GET /v1/rounds/:id/prize?wallet=`); falls
@@ -840,4 +848,4 @@ declare function ulid(seedTime?: number): string;
840
848
  /** `${prefix}_${ulid()}` — e.g. `pay_01J…`, `entry_01J…`, `idem_01J…`. */
841
849
  declare function prefixedId(prefix: string): string;
842
850
 
843
- export { 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, 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 };
851
+ 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, 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 };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
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 CancelRoundResult, c as PrizeBalance, d as WithdrawResult, A as AgentWallet, e as AgentFundResult, T as TransferResult, E as EscrowHoldInput, f as EscrowHoldResult, g as EscrowResolveResult, M as MarketplaceListInput, L as Listing, h as MarketplaceSaleResult, i as MarketplaceGetResult, j as PayInput, k as Payment, l as EnterRoundInput, m as TransferReconcile, n as WaitOptions, o as TransferInput, p as TransferConfirmOptions, V as VerifyResult, q as PayoutRule } from './errors-B_AqyZQE.js';
2
- export { r as AgentEconomyConfig, s as ApiError, t as AuthError, u as ConfigError, v as ContractConfig, w as Eip1193Provider, G as GasConfig, x as GasMode, I as InsufficientGasError, y as InvalidAmountError, z as ListingStatus, B as MarketplaceItem, D as MarketplaceSale, F as MissingFieldError, H as NothingToWithdrawError, J as PaymentFailedError, K as PaymentStatus, O as PlaymosError, Q as PlaymosErrorCode, U as RetryOptions, X as RoundStatus, Y as WalletConfig, Z as WalletConnectionError, _ as WalletConnector, $ as WebhookEventType } from './errors-B_AqyZQE.js';
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 CancelRoundResult, A as ActiveSeriesRound, c as PrizeBalance, d as WithdrawResult, e as AgentWallet, f as AgentFundResult, T as TransferResult, E as EscrowHoldInput, g as EscrowHoldResult, h as EscrowResolveResult, M as MarketplaceListInput, L as Listing, i as MarketplaceSaleResult, j as MarketplaceGetResult, k as PayInput, l as Payment, m as EnterRoundInput, n as TransferReconcile, o as WaitOptions, p as TransferInput, q as TransferConfirmOptions, V as VerifyResult, r as PayoutRule } from './errors-CdVzHuhY.js';
2
+ export { s as ActiveForSeriesResult, t as AgentEconomyConfig, u as ApiError, v as AuthError, w as ConfigError, x as ContractConfig, y as Eip1193Provider, G as GasConfig, z as GasMode, I as InsufficientGasError, B as InvalidAmountError, D as ListingStatus, F as MarketplaceItem, H as MarketplaceSale, J as MissingFieldError, K as NothingToWithdrawError, O as PaymentFailedError, Q as PaymentStatus, U as PlaymosError, X as PlaymosErrorCode, Y as RetryOptions, Z as RoundStatus, _ as WalletConfig, $ as WalletConnectionError, a0 as WalletConnector, a1 as WebhookEventType } from './errors-CdVzHuhY.js';
3
3
 
4
4
  /**
5
5
  * Environment resolution + the canonical address book.
@@ -487,6 +487,14 @@ declare class Playmos {
487
487
  get: (input: {
488
488
  roundId: string;
489
489
  }) => Promise<RoundState>;
490
+ /**
491
+ * Authoritative series latch (#351) — `null` means **proven free**.
492
+ * `GET /v1/series/:seriesKey/active?gameId=…` — not a candidate probe.
493
+ */
494
+ activeForSeries: (input: {
495
+ seriesKey: string;
496
+ gameId: string;
497
+ }) => Promise<ActiveSeriesRound | null>;
490
498
  /**
491
499
  * Read a wallet's **claimable** prize balance for a round (issue #41).
492
500
  * Prefers the service chain read (`GET /v1/rounds/:id/prize?wallet=`); falls
@@ -840,4 +848,4 @@ declare function ulid(seedTime?: number): string;
840
848
  /** `${prefix}_${ulid()}` — e.g. `pay_01J…`, `entry_01J…`, `idem_01J…`. */
841
849
  declare function prefixedId(prefix: string): string;
842
850
 
843
- export { 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, 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 };
851
+ 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, 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 };
package/dist/index.js CHANGED
@@ -935,6 +935,8 @@ var Playmos = class {
935
935
  roundId: input.roundId,
936
936
  gameId: input.gameId,
937
937
  roundKey,
938
+ // #351 — must persist seriesKey so activeForSeries mock is authoritative
939
+ seriesKey: input.seriesKey ?? input.gameId,
938
940
  status: "open",
939
941
  entryAmount: input.entryAmount,
940
942
  pool: null,
@@ -1131,6 +1133,58 @@ var Playmos = class {
1131
1133
  );
1132
1134
  return round;
1133
1135
  },
1136
+ /**
1137
+ * Authoritative series latch (#351) — `null` means **proven free**.
1138
+ * `GET /v1/series/:seriesKey/active?gameId=…` — not a candidate probe.
1139
+ */
1140
+ activeForSeries: async (input) => {
1141
+ requireField(input?.seriesKey, "seriesKey");
1142
+ requireField(input?.gameId, "gameId");
1143
+ if (this.config.mock) {
1144
+ for (const r of this.mockRounds.values()) {
1145
+ if (r.gameId !== input.gameId) continue;
1146
+ const sk = r.seriesKey ?? r.gameId;
1147
+ if (sk !== input.seriesKey) continue;
1148
+ if (r.status === "open" || r.status === "locked" || r.status === "opening" || r.status === "cancelling") {
1149
+ return {
1150
+ roundId: r.roundId,
1151
+ roundKey: r.roundKey,
1152
+ roundIdHash: "0x" + "m".repeat(64),
1153
+ status: r.status,
1154
+ entrants: r.entrants,
1155
+ pool: r.pool,
1156
+ openTxHash: r.openTxHash ?? null,
1157
+ cancelTxHash: r.cancelTxHash ?? null,
1158
+ prizePoolAddress: r.prizePoolAddress ?? "0x0000000000000000000000000000000000000002"
1159
+ };
1160
+ }
1161
+ }
1162
+ return null;
1163
+ }
1164
+ const body = await this.http.get(
1165
+ `/series/${encodeURIComponent(input.seriesKey)}/active?gameId=${encodeURIComponent(input.gameId)}`
1166
+ );
1167
+ if (body == null || typeof body !== "object") {
1168
+ throw new ApiError("activeForSeries: malformed response (expected object body)", {
1169
+ code: "invalid_response",
1170
+ status: 502
1171
+ });
1172
+ }
1173
+ if (!("active" in body)) {
1174
+ throw new ApiError("activeForSeries: malformed response (missing active field)", {
1175
+ code: "invalid_response",
1176
+ status: 502
1177
+ });
1178
+ }
1179
+ if (body.active === null) return null;
1180
+ if (body.active == null || typeof body.active !== "object") {
1181
+ throw new ApiError("activeForSeries: malformed response (active must be object or null)", {
1182
+ code: "invalid_response",
1183
+ status: 502
1184
+ });
1185
+ }
1186
+ return body.active;
1187
+ },
1134
1188
  /**
1135
1189
  * Read a wallet's **claimable** prize balance for a round (issue #41).
1136
1190
  * Prefers the service chain read (`GET /v1/rounds/:id/prize?wallet=`); falls
package/dist/server.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { O as PlaymosError, W as WebhookEvent } from './errors-B_AqyZQE.cjs';
1
+ import { U as PlaymosError, W as WebhookEvent } from './errors-CdVzHuhY.cjs';
2
2
 
3
3
  /**
4
4
  * Webhook signature verification (spec §6.2) — server-side only.
package/dist/server.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { O as PlaymosError, W as WebhookEvent } from './errors-B_AqyZQE.js';
1
+ import { U as PlaymosError, W as WebhookEvent } from './errors-CdVzHuhY.js';
2
2
 
3
3
  /**
4
4
  * Webhook signature verification (spec §6.2) — server-side only.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@playmos/sdk",
3
- "version": "0.3.4",
4
- "description": "Playmos SDK stablecoin payments for games on Base. One SDK for IAP (1%), skill-game prize-pool entries (10%, 60/30/10), and agent economies. USD in, USDC on-chain, no crypto UX for players.",
3
+ "version": "0.3.5",
4
+ "description": "Playmos SDK \u2014 stablecoin payments for games on Base. One SDK for IAP (1%), skill-game prize-pool entries (10%, 60/30/10), and agent economies. USD in, USDC on-chain, no crypto UX for players.",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,
7
7
  "type": "module",