@playmos/sdk 0.3.12 → 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/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to `@playmos/sdk`. This project adheres to [Semantic Version
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## [0.3.13] — 2026-09-11
8
+
9
+ ### Docs
10
+ - Same-studio key rule (`payment not found`). `payoutAddress` at mint or `POST /v1/studio/payout`. Browser `pay()` + MetaMask catch. Webhook register: `POST /v1/webhook_endpoints` (no signing secret in the response).
11
+ - npm README + package description name the live prepare → sign → register path (**flat 1%**). Types include `bytecode` / `unsignedTx`.
12
+
7
13
  ## [0.3.12] — 2026-08-27
8
14
 
9
15
  ### Added
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Playmos Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  **🧪 Beta — Playmos SDK.** Runs on Base Sepolia **testnet**. The value-movement primitives (escrow / marketplace / transfer) are proven on-chain but **not yet production-hardened**, and nothing is on mainnet. Build and integrate freely against the sandbox; don't route real user funds yet.
4
4
 
5
- Stablecoin payments for games on Base. One SDK for in-app purchases (**1%** Playmos — you keep 99%), **first-party** skill contests (**60/30/10**), and **in-game economies** (player · NPC · agent commerce via `transfer()`). Independent studio contests: Playmos take is **1%** and **cannot be changed**; default studio-side split is **60/30/9** **not live yet**. Live sandbox skill entry still uses the first-party 60/30/10 shape. USD in, USDC on-chain — no crypto UX for your players.
5
+ Stablecoin payments for games on Base. **One default path:** `pay()` `verify()` → a real `pay_…` id with status `confirmed` (1% Playmos — you keep 99%). No game required. Contests, economies, and timers are **optional**. Skill contests are **flat 1%** on **your** pool. If `rounds.open` is refused, that is expected until you prepare sign register your own contest pool. USD in, USDC on-chain — no crypto UX for your players.
6
6
 
7
7
  **Changelog:** see [`CHANGELOG.md`](./CHANGELOG.md) (shipped in the npm tarball from the next publish). **Breaking in 0.3.8:** player-wallet `enterRound` requires `identity` — no silent invent.
8
8
 
@@ -25,9 +25,9 @@ The sandbox API also sends CORS headers so browser `pay()` / `enterRound()` work
25
25
 
26
26
  The public sandbox key `pk_test_playmos_sandbox` runs against a real Playmos test service on Base Sepolia. **You don't need a wallet:** on a `pk_test` key with no `wallet` configured, the SDK routes to a server-settle path where Playmos signs and submits the on-chain transaction for you. You still get a real, confirmed `txHash` — just signed by the service. No wallet, no gas, no crypto.
27
27
 
28
- The key comes wired to two demo games: `game_sandbox_iap` (IAP) and `game_sandbox_skill` (prize pool).
28
+ The public key is wired to `game_sandbox_iap`. Skill entry (`game_sandbox_skill`) is an optional later path — not the first-hour default.
29
29
 
30
- ### In-app purchase — `pay()`
30
+ ### In-app purchase — `pay()` (the front door)
31
31
 
32
32
  <!-- snippet:pay -->
33
33
  ```ts
@@ -38,15 +38,22 @@ import { Playmos } from "@playmos/sdk";
38
38
  const playmos = new Playmos({ apiKey: "pk_test_playmos_sandbox" });
39
39
 
40
40
  const payment = await playmos.pay({
41
- gameId: "game_sandbox_iap", // public sandbox IAP game include it (this key spans IAP + skill)
41
+ gameId: "game_sandbox_iap", // required for the public sandbox key
42
42
  amount: "0.99", // USD string — sandbox server-settle cap $1.00/request
43
43
  sku: "gems_500", // your product id
44
- playerId: "player_abc", // your opaque user id
44
+ playerId: "player_" + Date.now(),
45
45
  });
46
46
 
47
- payment.id; // "pay_…" — real, server-issued (ULID)
48
- payment.status; // "confirmed" — real, on Base Sepolia
49
- payment.txHash; // 0x… — open on sepolia.basescan.org/tx/{txHash}
47
+ let result = await playmos.verify(payment.id);
48
+ let tries = 30;
49
+ while (result.status !== "confirmed" && tries !== 0) {
50
+ await new Promise((r) => setTimeout(r, 500));
51
+ result = await playmos.verify(payment.id);
52
+ tries -= 1;
53
+ }
54
+
55
+ console.log({ id: payment.id, status: result.status, tx: payment.txHash });
56
+ // You won: pay_… + confirmed on Base Sepolia
50
57
  ```
51
58
 
52
59
  ### Verify before you grant
@@ -68,7 +75,7 @@ if (result.status === "confirmed") {
68
75
  }
69
76
  ```
70
77
 
71
- ### Skill-game entry `enterRound()`
78
+ ### Optional later — skill-game entry (`enterRound()`)
72
79
 
73
80
  ```ts
74
81
  const entry = await playmos.enterRound({
@@ -77,10 +84,21 @@ const entry = await playmos.enterRound({
77
84
  amount: "1.00", // grows this round's pool
78
85
  playerId: "player_abc",
79
86
  });
80
- // entry.status === "confirmed"; entry.split is a first-party 60/30/10 *projection*
81
- // (sandbox / Playmos Lab not a studio 60/30/9+1% split, not a chain read)
87
+ // entry.status === "confirmed". Public sandbox skill is a shared Playmos pool — not your contest.
88
+ // Your 1% contest is live only after you register your own pool (next section).
82
89
  ```
83
90
 
91
+ ### Your own contest pool — `epochs.preparePool` (you sign)
92
+
93
+ `@playmos/sdk` **0.3.13** ships `epochs.preparePool` with `bytecode` / `unsignedTx` on the typed response. It calls the live API. Playmos sets `broadcast: false` and does **not** send the transaction.
94
+
95
+ 1. Fund your studio wallet on Base Sepolia (ETH + test USDC). Playmos has no faucet — use [Coinbase's faucet docs](https://docs.cdp.coinbase.com/faucets/introduction/welcome).
96
+ 2. Call `epochs.preparePool({ studioWallet })` or `POST /v1/epochs/pools/prepare`. Use `feeSink` from that response (`0xD84c190085aa59c48a9B478Ea333D50B8DF4aD42`).
97
+ 3. Sign `unsignedTx` in your wallet and send it.
98
+ 4. `epochs.registerPool` with `walletProof`, then open / enter **your** game — not the shared sandbox game.
99
+
100
+ Full steps: https://playmos-docs-public.vercel.app/docs#studio-pool-prepare
101
+
84
102
  ### Move USDC between wallets — `transfer()`
85
103
 
86
104
  The base value-movement primitive: move USDC from one wallet to another with a configurable per-call fee. The **game logic is the authority** — you already decided the move is valid — so this is a direct, unconditional push (reach for `escrow`/`marketplace` when a trust boundary needs fair exchange). Settled through the on-chain `PlaymosTransfer` contract; the split is verifiable on BaseScan.
@@ -281,8 +299,8 @@ The escrow/marketplace resolve endpoints (release/refund/confirm) return a deter
281
299
 
282
300
  ## Docs
283
301
 
284
- Full developer docs (install, IAP `pay()`, skill `enterRound()`, agents, webhooks, REST) — **public, no login**:
302
+ Full developer docs (install, IAP `pay()`, skill `enterRound()`, your own contest pool, agents, webhooks, REST) — **public, no login**:
285
303
 
286
- **https://playmos-docs-public.vercel.app/docs**
304
+ **https://playmos-docs-public.vercel.app/docs** · contest pool: **https://playmos-docs-public.vercel.app/docs#studio-pool-prepare**
287
305
 
288
306
  That is the third-party / stranger surface while we stress-test. Production **`playmos.io/docs`** comes after Founder promote (gate still holds for production only).
package/dist/index.cjs CHANGED
@@ -1118,7 +1118,8 @@ function mockVerifyResult(payment) {
1118
1118
  }
1119
1119
 
1120
1120
  // src/epochs.ts
1121
- var PLAYMOS_FEE_SINK_DEFAULT = "0x1b8031e20ed96131a849a52290b4d640f286998d";
1121
+ var PLAYMOS_FEE_SINK_DEFAULT = "0xd84c190085aa59c48a9b478ea333d50b8df4ad42";
1122
+ var RETIRED_PLAYMOS_FEE_SINK = "0x1b8031e20ed96131a849a52290b4d640f286998d";
1122
1123
  var EPOCH_POOL_CONSTRUCTOR_TYPES = [
1123
1124
  { type: "address" },
1124
1125
  { type: "address" },
@@ -1305,13 +1306,17 @@ function sameAddr(a, b) {
1305
1306
  }
1306
1307
  function prepareStudioPoolLocal(input, playmosFeeSink, token, playmosAddresses = []) {
1307
1308
  const studio = requireAddr(input.studioWallet, "studioWallet");
1308
- const sink = playmosFeeSink.toLowerCase();
1309
+ const locked = PLAYMOS_FEE_SINK_DEFAULT;
1310
+ if (playmosFeeSink && !sameAddr(playmosFeeSink, locked)) {
1311
+ throw new ConfigError("feeSink must equal the Playmos Sepolia treasury; refused before broadcast");
1312
+ }
1313
+ const sink = locked;
1309
1314
  const forbidden = [sink, ...playmosAddresses.map((a) => a.toLowerCase())];
1310
1315
  if (forbidden.some((a) => sameAddr(a, studio))) {
1311
1316
  throw new ConfigError("studioWallet must not be a Playmos address (Playmos never holds studio keys)");
1312
1317
  }
1313
1318
  if (input.feeSink && !sameAddr(input.feeSink, sink)) {
1314
- throw new ConfigError("feeSink must equal the Playmos sink; refused before broadcast");
1319
+ throw new ConfigError("feeSink must equal the Playmos Sepolia treasury; refused before broadcast");
1315
1320
  }
1316
1321
  if (input.admin && !sameAddr(input.admin, studio)) {
1317
1322
  throw new ConfigError("admin must be the studio wallet from block one");
@@ -1342,6 +1347,7 @@ function prepareStudioPoolLocal(input, playmosFeeSink, token, playmosAddresses =
1342
1347
  feeSink: sink,
1343
1348
  refundTimeout
1344
1349
  }),
1350
+ broadcast: false,
1345
1351
  constructor: "EpochPrizePool",
1346
1352
  studioHoldsAdmin: true,
1347
1353
  studioHoldsOperator: true,
@@ -1546,8 +1552,11 @@ function createEpochsApi(deps) {
1546
1552
  async preparePool(input) {
1547
1553
  const studioWallet = requireAddr(input?.studioWallet, "studioWallet");
1548
1554
  const cfg = deps.config();
1549
- const sink = (input.playmosFeeSink ?? PLAYMOS_FEE_SINK_DEFAULT).toLowerCase();
1555
+ const sink = PLAYMOS_FEE_SINK_DEFAULT;
1550
1556
  const token = (input.token ?? cfg.contracts?.usdc ?? "0x036cbd53842c5426634e7929541ec2318f3dcf7e").toLowerCase();
1557
+ if (input.playmosFeeSink && !sameAddr(input.playmosFeeSink, sink)) {
1558
+ throw new ConfigError("feeSink must equal the Playmos Sepolia treasury; refused before broadcast");
1559
+ }
1551
1560
  if (cfg.mock) {
1552
1561
  return prepareStudioPoolLocal({ ...input, studioWallet }, sink, token);
1553
1562
  }
@@ -4216,6 +4225,7 @@ exports.PaymentFailedError = PaymentFailedError;
4216
4225
  exports.PayoutError = PayoutError;
4217
4226
  exports.Playmos = Playmos;
4218
4227
  exports.PlaymosError = PlaymosError;
4228
+ exports.RETIRED_PLAYMOS_FEE_SINK = RETIRED_PLAYMOS_FEE_SINK;
4219
4229
  exports.USDC_ADDRESS = USDC_ADDRESS;
4220
4230
  exports.USDC_DECIMALS = USDC_DECIMALS;
4221
4231
  exports.WalletConnectionError = WalletConnectionError;
package/dist/index.d.cts CHANGED
@@ -100,8 +100,10 @@ declare function buildEpochWithdrawCall(epochPrizePool: `0x${string}`): Call;
100
100
  * `terminal`. Live `rounds.*` / `enterRound` are a different pool and stay unchanged.
101
101
  */
102
102
 
103
- /** Playmos Base Sepolia feeSink (PlaymosPay / PrizePool). Service pins this. */
104
- declare const PLAYMOS_FEE_SINK_DEFAULT: "0x1b8031e20ed96131a849a52290b4d640f286998d";
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";
105
107
  declare function encodeEpochPoolConstructorArgs(args: {
106
108
  token: `0x${string}`;
107
109
  admin: `0x${string}`;
@@ -258,6 +260,16 @@ interface EpochPreparedPool {
258
260
  feeSink: `0x${string}`;
259
261
  refundTimeout: string;
260
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;
261
273
  constructor: "EpochPrizePool";
262
274
  studioHoldsAdmin: true;
263
275
  studioHoldsOperator: true;
@@ -1575,4 +1587,4 @@ declare function ulid(seedTime?: number): string;
1575
1587
  /** `${prefix}_${ulid()}` — e.g. `pay_01J…`, `entry_01J…`, `idem_01J…`. */
1576
1588
  declare function prefixedId(prefix: string): string;
1577
1589
 
1578
- 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, 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 };
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 };
package/dist/index.d.ts CHANGED
@@ -100,8 +100,10 @@ declare function buildEpochWithdrawCall(epochPrizePool: `0x${string}`): Call;
100
100
  * `terminal`. Live `rounds.*` / `enterRound` are a different pool and stay unchanged.
101
101
  */
102
102
 
103
- /** Playmos Base Sepolia feeSink (PlaymosPay / PrizePool). Service pins this. */
104
- declare const PLAYMOS_FEE_SINK_DEFAULT: "0x1b8031e20ed96131a849a52290b4d640f286998d";
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";
105
107
  declare function encodeEpochPoolConstructorArgs(args: {
106
108
  token: `0x${string}`;
107
109
  admin: `0x${string}`;
@@ -258,6 +260,16 @@ interface EpochPreparedPool {
258
260
  feeSink: `0x${string}`;
259
261
  refundTimeout: string;
260
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;
261
273
  constructor: "EpochPrizePool";
262
274
  studioHoldsAdmin: true;
263
275
  studioHoldsOperator: true;
@@ -1575,4 +1587,4 @@ declare function ulid(seedTime?: number): string;
1575
1587
  /** `${prefix}_${ulid()}` — e.g. `pay_01J…`, `entry_01J…`, `idem_01J…`. */
1576
1588
  declare function prefixedId(prefix: string): string;
1577
1589
 
1578
- 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, 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 };
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 };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { AuthError, InvalidAmountError, epochPrizePoolEnterAbi, seriesToBytes32, identityToBytes32, encodeApprove, epochPrizePoolRefundAbi, ConfigError, MissingFieldError, buildEpochExecuteSettlementCall, PaymentFailedError, epochPrizePoolViewAbi, ApiError, assertEnoughGas, sendCalls, waitForCalls, NothingToWithdrawError, buildWithdrawCall, WalletTimeoutError, buildIapCalls, buildEntryCalls, prizePoolAbi, WalletConnectionError, AlreadyEnteredError } from './chunk-2CW4U5YB.js';
2
- export { AlreadyEnteredError, ApiError, AuthError, ConfigError, InsufficientGasError, InvalidAmountError, MissingFieldError, NothingToWithdrawError, PaymentFailedError, PlaymosError, WalletConnectionError, WalletTimeoutError, buildEpochExecuteSettlementCall, identityToBytes32, seriesToBytes32 } from './chunk-2CW4U5YB.js';
1
+ import { AuthError, InvalidAmountError, epochPrizePoolEnterAbi, seriesToBytes32, identityToBytes32, encodeApprove, epochPrizePoolRefundAbi, ConfigError, MissingFieldError, buildEpochExecuteSettlementCall, PaymentFailedError, epochPrizePoolViewAbi, ApiError, assertEnoughGas, sendCalls, waitForCalls, NothingToWithdrawError, buildWithdrawCall, WalletTimeoutError, buildIapCalls, buildEntryCalls, prizePoolAbi, WalletConnectionError, AlreadyEnteredError } from './chunk-TZFGZNXV.js';
2
+ export { AlreadyEnteredError, ApiError, AuthError, ConfigError, InsufficientGasError, InvalidAmountError, MissingFieldError, NothingToWithdrawError, PaymentFailedError, PlaymosError, WalletConnectionError, WalletTimeoutError, buildEpochExecuteSettlementCall, identityToBytes32, seriesToBytes32 } from './chunk-TZFGZNXV.js';
3
3
  import { encodeFunctionData, encodeAbiParameters, decodeFunctionResult } from 'viem';
4
4
 
5
5
  // src/config.ts
@@ -674,7 +674,8 @@ function mockVerifyResult(payment) {
674
674
  }
675
675
 
676
676
  // src/epochs.ts
677
- var PLAYMOS_FEE_SINK_DEFAULT = "0x1b8031e20ed96131a849a52290b4d640f286998d";
677
+ var PLAYMOS_FEE_SINK_DEFAULT = "0xd84c190085aa59c48a9b478ea333d50b8df4ad42";
678
+ var RETIRED_PLAYMOS_FEE_SINK = "0x1b8031e20ed96131a849a52290b4d640f286998d";
678
679
  var EPOCH_POOL_CONSTRUCTOR_TYPES = [
679
680
  { type: "address" },
680
681
  { type: "address" },
@@ -861,13 +862,17 @@ function sameAddr(a, b) {
861
862
  }
862
863
  function prepareStudioPoolLocal(input, playmosFeeSink, token, playmosAddresses = []) {
863
864
  const studio = requireAddr(input.studioWallet, "studioWallet");
864
- const sink = playmosFeeSink.toLowerCase();
865
+ const locked = PLAYMOS_FEE_SINK_DEFAULT;
866
+ if (playmosFeeSink && !sameAddr(playmosFeeSink, locked)) {
867
+ throw new ConfigError("feeSink must equal the Playmos Sepolia treasury; refused before broadcast");
868
+ }
869
+ const sink = locked;
865
870
  const forbidden = [sink, ...playmosAddresses.map((a) => a.toLowerCase())];
866
871
  if (forbidden.some((a) => sameAddr(a, studio))) {
867
872
  throw new ConfigError("studioWallet must not be a Playmos address (Playmos never holds studio keys)");
868
873
  }
869
874
  if (input.feeSink && !sameAddr(input.feeSink, sink)) {
870
- throw new ConfigError("feeSink must equal the Playmos sink; refused before broadcast");
875
+ throw new ConfigError("feeSink must equal the Playmos Sepolia treasury; refused before broadcast");
871
876
  }
872
877
  if (input.admin && !sameAddr(input.admin, studio)) {
873
878
  throw new ConfigError("admin must be the studio wallet from block one");
@@ -898,6 +903,7 @@ function prepareStudioPoolLocal(input, playmosFeeSink, token, playmosAddresses =
898
903
  feeSink: sink,
899
904
  refundTimeout
900
905
  }),
906
+ broadcast: false,
901
907
  constructor: "EpochPrizePool",
902
908
  studioHoldsAdmin: true,
903
909
  studioHoldsOperator: true,
@@ -1102,8 +1108,11 @@ function createEpochsApi(deps) {
1102
1108
  async preparePool(input) {
1103
1109
  const studioWallet = requireAddr(input?.studioWallet, "studioWallet");
1104
1110
  const cfg = deps.config();
1105
- const sink = (input.playmosFeeSink ?? PLAYMOS_FEE_SINK_DEFAULT).toLowerCase();
1111
+ const sink = PLAYMOS_FEE_SINK_DEFAULT;
1106
1112
  const token = (input.token ?? cfg.contracts?.usdc ?? "0x036cbd53842c5426634e7929541ec2318f3dcf7e").toLowerCase();
1113
+ if (input.playmosFeeSink && !sameAddr(input.playmosFeeSink, sink)) {
1114
+ throw new ConfigError("feeSink must equal the Playmos Sepolia treasury; refused before broadcast");
1115
+ }
1107
1116
  if (cfg.mock) {
1108
1117
  return prepareStudioPoolLocal({ ...input, studioWallet }, sink, token);
1109
1118
  }
@@ -3755,4 +3764,4 @@ function isX402PayloadAuthorization(auth) {
3755
3764
  return auth.kind === "x402-payload";
3756
3765
  }
3757
3766
 
3758
- export { C1_ENTER_SPLIT_MICRO, CHAIN_ID, DEFAULT_API_BASE_URL, MICRO_PER_USDC, PLAYMOS_FEE_SINK_DEFAULT, PayoutError, Playmos, USDC_ADDRESS, USDC_DECIMALS, buildEpochClaimRefundCall, buildEpochEntryCalls, buildEpochWithdrawCall, clientRuntimeSignals, computeIapSplit, computePayout, computePoolSplit, createEpochsApi, createPaymentRequirement, createX402Challenge, decodePaymentHeader, derivedEpochId, encodeEpochPoolConstructorArgs, encodePaymentHeader, epochPayableMicro, epochPoolProofMessage, formatMicroToUsd, isClientRuntime, isWalletSignatureAuthorization, isX402PayloadAuthorization, networkToCaip2, parsePaymentRequirement, parseUsdToMicro, prefixedId, prepareStudioPoolLocal, previewEscrowFee, previewIapSplit, previewMarketplaceSplit, previewPoolSplit, previewTransferSplit, resolveEnv, serializePaymentRequirement, settlementTypedData, toX402PaymentRequired, ulid, validateX402ChallengeInput };
3767
+ export { C1_ENTER_SPLIT_MICRO, CHAIN_ID, DEFAULT_API_BASE_URL, MICRO_PER_USDC, PLAYMOS_FEE_SINK_DEFAULT, PayoutError, Playmos, RETIRED_PLAYMOS_FEE_SINK, USDC_ADDRESS, USDC_DECIMALS, buildEpochClaimRefundCall, buildEpochEntryCalls, buildEpochWithdrawCall, clientRuntimeSignals, computeIapSplit, computePayout, computePoolSplit, createEpochsApi, createPaymentRequirement, createX402Challenge, decodePaymentHeader, derivedEpochId, encodeEpochPoolConstructorArgs, encodePaymentHeader, epochPayableMicro, epochPoolProofMessage, formatMicroToUsd, isClientRuntime, isWalletSignatureAuthorization, isX402PayloadAuthorization, networkToCaip2, parsePaymentRequirement, parseUsdToMicro, prefixedId, prepareStudioPoolLocal, previewEscrowFee, previewIapSplit, previewMarketplaceSplit, previewPoolSplit, previewTransferSplit, resolveEnv, serializePaymentRequirement, settlementTypedData, toX402PaymentRequired, ulid, validateX402ChallengeInput };
package/dist/server.js CHANGED
@@ -1,5 +1,5 @@
1
- import { PlaymosError, ApiError, toBytes32 } from './chunk-2CW4U5YB.js';
2
- export { toBytes32 as enterPathToBytes32 } from './chunk-2CW4U5YB.js';
1
+ import { PlaymosError, ApiError, toBytes32 } from './chunk-TZFGZNXV.js';
2
+ export { toBytes32 as enterPathToBytes32 } from './chunk-TZFGZNXV.js';
3
3
  import { timingSafeEqual, createHmac } from 'crypto';
4
4
  import { encodeFunctionData, decodeFunctionResult } from 'viem';
5
5
 
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@playmos/sdk",
3
- "version": "0.3.12",
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.",
5
- "license": "UNLICENSED",
3
+ "version": "0.3.13",
4
+ "description": "Playmos SDK — stablecoin payments for games on Base. IAP and skill contests are flat 1%. USD in, USDC on-chain, no crypto UX for players.",
5
+ "license": "MIT",
6
6
  "private": false,
7
7
  "homepage": "https://playmos-docs-public.vercel.app/",
8
8
  "bugs": {
@@ -34,6 +34,7 @@
34
34
  "!dist/**/*.map",
35
35
  "README.md",
36
36
  "CHANGELOG.md",
37
+ "LICENSE",
37
38
  "package.json"
38
39
  ],
39
40
  "scripts": {
File without changes