@playmos/sdk 0.3.13 → 0.3.15
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 +13 -0
- package/README.md +15 -7
- package/dist/{chunk-TZFGZNXV.js → chunk-ROWX6HVU.js} +18 -1
- package/dist/{errors-CYKgt2VU.d.cts → errors-WcDNfb4q.d.cts} +7 -0
- package/dist/{errors-CYKgt2VU.d.ts → errors-WcDNfb4q.d.ts} +7 -0
- package/dist/index.cjs +152 -5
- package/dist/index.d.cts +52 -3
- package/dist/index.d.ts +52 -3
- package/dist/index.js +134 -8
- package/dist/server.d.cts +2 -2
- package/dist/server.d.ts +2 -2
- package/dist/server.js +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,19 @@ All notable changes to `@playmos/sdk`. This project adheres to [Semantic Version
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## [0.3.15] — 2026-09-11
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- **`epochs.prepareSeries`** / `POST /v1/epochs/series/prepare` — after register, one call returns an unsigned `createSeries` tx (`broadcast: false`, default `feeBps` 100). The studio EOA signs. Playmos never broadcasts. (#742 / #739)
|
|
11
|
+
|
|
12
|
+
### Fixed (service)
|
|
13
|
+
- Studio-operated pool `POST /v1/epochs/:epochId/settle` returns 4xx naming `settleEpoch` / `executeSignedSettlement`, not a product 502/504. (#741 / #736)
|
|
14
|
+
|
|
15
|
+
## [0.3.14] — 2026-09-11
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- **`settle: "server"`** on `new Playmos({ ... })` — explicit sandbox no-wallet path. `pay()` / `enterRound()` server-settle even when MetaMask is installed. Live keys throw. Default without the ask is unchanged (wallet present → player signs).
|
|
19
|
+
|
|
7
20
|
## [0.3.13] — 2026-09-11
|
|
8
21
|
|
|
9
22
|
### Docs
|
package/README.md
CHANGED
|
@@ -16,14 +16,14 @@ Requires **Node 18 / 20 / 22 LTS** for local development and CI toolchains. Full
|
|
|
16
16
|
|
|
17
17
|
## Browser vs server entry
|
|
18
18
|
|
|
19
|
-
- **Games (browser / Vite / Phaser):** `import { Playmos } from "@playmos/sdk"` — this entry is browser-safe and does **not** import Node `crypto` (issue #9).
|
|
19
|
+
- **Games (browser / Vite / Phaser):** `import { Playmos } from "@playmos/sdk"` — this entry is browser-safe and does **not** import Node `crypto` (issue #9). The package depends on **viem**; the named import tree-shakes, but a default Vite single chunk can still exceed 500 kB gzip-warn.
|
|
20
20
|
- **Your backend (webhook receivers):** `import { verifyWebhook } from "@playmos/sdk/server"` — HMAC verification uses Node crypto and must stay off the client bundle.
|
|
21
21
|
|
|
22
22
|
The sandbox API also sends CORS headers so browser `pay()` / `enterRound()` work without a same-origin proxy (issue #10).
|
|
23
23
|
|
|
24
24
|
## Quickstart — the no-wallet sandbox
|
|
25
25
|
|
|
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:**
|
|
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:** set `settle: "server"` (the quickstart does). The SDK then server-settles even if MetaMask is installed. You still get a real, confirmed `txHash` — signed by the service. No wallet, no gas, no crypto. Omit `settle` only when you want the player to sign.
|
|
27
27
|
|
|
28
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
|
|
|
@@ -35,7 +35,7 @@ import { Playmos } from "@playmos/sdk";
|
|
|
35
35
|
|
|
36
36
|
// Public sandbox key — client-safe, like Stripe's pk_test_.
|
|
37
37
|
// No wallet needed: Playmos server-settles the test payment for you.
|
|
38
|
-
const playmos = new Playmos({ apiKey: "pk_test_playmos_sandbox" });
|
|
38
|
+
const playmos = new Playmos({ apiKey: "pk_test_playmos_sandbox", settle: "server" });
|
|
39
39
|
|
|
40
40
|
const payment = await playmos.pay({
|
|
41
41
|
gameId: "game_sandbox_iap", // required for the public sandbox key
|
|
@@ -51,6 +51,9 @@ while (result.status !== "confirmed" && tries !== 0) {
|
|
|
51
51
|
result = await playmos.verify(payment.id);
|
|
52
52
|
tries -= 1;
|
|
53
53
|
}
|
|
54
|
+
if (result.status !== "confirmed") {
|
|
55
|
+
throw new Error(`not confirmed yet: ${result.status}`);
|
|
56
|
+
}
|
|
54
57
|
|
|
55
58
|
console.log({ id: payment.id, status: result.status, tx: payment.txHash });
|
|
56
59
|
// You won: pay_… + confirmed on Base Sepolia
|
|
@@ -78,24 +81,29 @@ if (result.status === "confirmed") {
|
|
|
78
81
|
### Optional later — skill-game entry (`enterRound()`)
|
|
79
82
|
|
|
80
83
|
```ts
|
|
84
|
+
const idempotencyKey = "entry-player_abc"; // persist BEFORE enterRound
|
|
81
85
|
const entry = await playmos.enterRound({
|
|
82
86
|
gameId: "game_sandbox_skill",
|
|
83
87
|
roundId: "5m-5944009",
|
|
84
88
|
amount: "1.00", // grows this round's pool
|
|
85
89
|
playerId: "player_abc",
|
|
90
|
+
idempotencyKey,
|
|
86
91
|
});
|
|
87
|
-
// entry.status === "confirmed". Public sandbox skill is a shared Playmos pool —
|
|
88
|
-
//
|
|
92
|
+
// entry.status === "confirmed". Public sandbox skill is a shared Playmos pool —
|
|
93
|
+
// not your contest and not your published take. Persist entry.identity
|
|
94
|
+
// (sandbox#entry_…) when there is no wallet. Same $1.00/request cap as pay().
|
|
95
|
+
// Your 1% is IAP pay() and your own registered pool (next section).
|
|
89
96
|
```
|
|
90
97
|
|
|
91
98
|
### Your own contest pool — `epochs.preparePool` (you sign)
|
|
92
99
|
|
|
93
|
-
`@playmos/sdk` **0.3.
|
|
100
|
+
`@playmos/sdk` **0.3.15** ships `epochs.preparePool` and `epochs.prepareSeries` with `unsignedTx` on the typed response. It calls the live API. Playmos sets `broadcast: false` and does **not** send the transaction.
|
|
94
101
|
|
|
95
102
|
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
103
|
2. Call `epochs.preparePool({ studioWallet })` or `POST /v1/epochs/pools/prepare`. Use `feeSink` from that response (`0xD84c190085aa59c48a9B478Ea333D50B8DF4aD42`).
|
|
97
104
|
3. Sign `unsignedTx` in your wallet and send it.
|
|
98
|
-
4. `epochs.registerPool` with `walletProof
|
|
105
|
+
4. `epochs.registerPool` with `walletProof`.
|
|
106
|
+
5. `epochs.prepareSeries` — one returned `unsignedTx`, you sign in the same EOA. Then `GET /v1/epochs/series` until `created=true`, then enter **your** game — not the shared sandbox game.
|
|
99
107
|
|
|
100
108
|
Full steps: https://playmos-docs-public.vercel.app/docs#studio-pool-prepare
|
|
101
109
|
|
|
@@ -345,6 +345,23 @@ var epochPrizePoolViewAbi = [
|
|
|
345
345
|
outputs: [{ type: "uint256" }]
|
|
346
346
|
}
|
|
347
347
|
];
|
|
348
|
+
var epochPrizePoolCreateSeriesAbi = [
|
|
349
|
+
{
|
|
350
|
+
type: "function",
|
|
351
|
+
name: "createSeries",
|
|
352
|
+
stateMutability: "nonpayable",
|
|
353
|
+
inputs: [
|
|
354
|
+
{ name: "series", type: "bytes32" },
|
|
355
|
+
{ name: "genesis", type: "uint256" },
|
|
356
|
+
{ name: "epochDuration", type: "uint256" },
|
|
357
|
+
{ name: "entry", type: "uint256" },
|
|
358
|
+
{ name: "feeBps", type: "uint16" },
|
|
359
|
+
{ name: "poolBps", type: "uint16" },
|
|
360
|
+
{ name: "seedBps", type: "uint16" }
|
|
361
|
+
],
|
|
362
|
+
outputs: []
|
|
363
|
+
}
|
|
364
|
+
];
|
|
348
365
|
var epochPrizePoolEnterAbi = [
|
|
349
366
|
{
|
|
350
367
|
type: "function",
|
|
@@ -442,4 +459,4 @@ function buildEpochExecuteSettlementCall(args) {
|
|
|
442
459
|
};
|
|
443
460
|
}
|
|
444
461
|
|
|
445
|
-
export { AlreadyEnteredError, ApiError, AuthError, ConfigError, InsufficientGasError, InvalidAmountError, MissingFieldError, NothingToWithdrawError, PaymentFailedError, PlaymosError, WalletConnectionError, WalletTimeoutError, assertEnoughGas, buildEntryCalls, buildEpochExecuteSettlementCall, buildIapCalls, buildWithdrawCall, encodeApprove, epochPrizePoolEnterAbi, epochPrizePoolRefundAbi, epochPrizePoolViewAbi, identityToBytes32, prizePoolAbi, sendCalls, seriesToBytes32, toBytes32, waitForCalls };
|
|
462
|
+
export { AlreadyEnteredError, ApiError, AuthError, ConfigError, InsufficientGasError, InvalidAmountError, MissingFieldError, NothingToWithdrawError, PaymentFailedError, PlaymosError, WalletConnectionError, WalletTimeoutError, assertEnoughGas, buildEntryCalls, buildEpochExecuteSettlementCall, buildIapCalls, buildWithdrawCall, encodeApprove, epochPrizePoolCreateSeriesAbi, epochPrizePoolEnterAbi, epochPrizePoolRefundAbi, epochPrizePoolViewAbi, identityToBytes32, prizePoolAbi, sendCalls, seriesToBytes32, toBytes32, waitForCalls };
|
|
@@ -76,6 +76,13 @@ interface PlaymosConfig {
|
|
|
76
76
|
* even mock results use the REAL status union (never a synthetic "mocked").
|
|
77
77
|
*/
|
|
78
78
|
mock?: boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Explicit sandbox no-wallet path. On a test key, `pay()` / `enterRound()`
|
|
81
|
+
* server-settle even if MetaMask (or another injected wallet) is installed.
|
|
82
|
+
* Live keys (`pk_live_` / `sk_live_`) throw — never server-settle real money.
|
|
83
|
+
* Omit to keep today's default: server-settle only when no wallet is present.
|
|
84
|
+
*/
|
|
85
|
+
settle?: "server";
|
|
79
86
|
/**
|
|
80
87
|
* Automatic backoff/retry on HTTP 429 (throttling). Default ON (up to 2 retries,
|
|
81
88
|
* honoring a `Retry-After` header). Retries are safe — reads are idempotent and
|
|
@@ -76,6 +76,13 @@ interface PlaymosConfig {
|
|
|
76
76
|
* even mock results use the REAL status union (never a synthetic "mocked").
|
|
77
77
|
*/
|
|
78
78
|
mock?: boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Explicit sandbox no-wallet path. On a test key, `pay()` / `enterRound()`
|
|
81
|
+
* server-settle even if MetaMask (or another injected wallet) is installed.
|
|
82
|
+
* Live keys (`pk_live_` / `sk_live_`) throw — never server-settle real money.
|
|
83
|
+
* Omit to keep today's default: server-settle only when no wallet is present.
|
|
84
|
+
*/
|
|
85
|
+
settle?: "server";
|
|
79
86
|
/**
|
|
80
87
|
* Automatic backoff/retry on HTTP 429 (throttling). Default ON (up to 2 retries,
|
|
81
88
|
* honoring a `Retry-After` header). Retries are safe — reads are idempotent and
|
package/dist/index.cjs
CHANGED
|
@@ -929,6 +929,23 @@ var epochPrizePoolViewAbi = [
|
|
|
929
929
|
outputs: [{ type: "uint256" }]
|
|
930
930
|
}
|
|
931
931
|
];
|
|
932
|
+
var epochPrizePoolCreateSeriesAbi = [
|
|
933
|
+
{
|
|
934
|
+
type: "function",
|
|
935
|
+
name: "createSeries",
|
|
936
|
+
stateMutability: "nonpayable",
|
|
937
|
+
inputs: [
|
|
938
|
+
{ name: "series", type: "bytes32" },
|
|
939
|
+
{ name: "genesis", type: "uint256" },
|
|
940
|
+
{ name: "epochDuration", type: "uint256" },
|
|
941
|
+
{ name: "entry", type: "uint256" },
|
|
942
|
+
{ name: "feeBps", type: "uint16" },
|
|
943
|
+
{ name: "poolBps", type: "uint16" },
|
|
944
|
+
{ name: "seedBps", type: "uint16" }
|
|
945
|
+
],
|
|
946
|
+
outputs: []
|
|
947
|
+
}
|
|
948
|
+
];
|
|
932
949
|
var epochPrizePoolEnterAbi = [
|
|
933
950
|
{
|
|
934
951
|
type: "function",
|
|
@@ -1136,6 +1153,9 @@ function encodeEpochPoolConstructorArgs(args) {
|
|
|
1136
1153
|
args.refundTimeout
|
|
1137
1154
|
]);
|
|
1138
1155
|
}
|
|
1156
|
+
var LOCKED_SERIES_FEE_BPS = 100;
|
|
1157
|
+
var DEFAULT_SERIES_POOL_BPS = 7900;
|
|
1158
|
+
var DEFAULT_SERIES_SEED_BPS = 2e3;
|
|
1139
1159
|
function derivedEpochId(genesis, epochDuration, at) {
|
|
1140
1160
|
if (epochDuration === 0n) {
|
|
1141
1161
|
throw new ConfigError("epochDuration must be > 0");
|
|
@@ -1304,6 +1324,66 @@ function walletStatus(status) {
|
|
|
1304
1324
|
function sameAddr(a, b) {
|
|
1305
1325
|
return a.toLowerCase() === b.toLowerCase();
|
|
1306
1326
|
}
|
|
1327
|
+
function parseSeriesBps(raw, field) {
|
|
1328
|
+
if (raw === void 0) return void 0;
|
|
1329
|
+
if (!Number.isInteger(raw) || raw < 0) {
|
|
1330
|
+
throw new ConfigError(`${field} must be a non-negative integer`);
|
|
1331
|
+
}
|
|
1332
|
+
return raw;
|
|
1333
|
+
}
|
|
1334
|
+
function prepareSeriesLocal(input, chainId) {
|
|
1335
|
+
const pool = requireAddr(input.epochPrizePool, "epochPrizePool");
|
|
1336
|
+
const series = requireSeries(input.series);
|
|
1337
|
+
const feeBps = parseSeriesBps(input.feeBps, "feeBps");
|
|
1338
|
+
if (feeBps !== void 0 && feeBps !== LOCKED_SERIES_FEE_BPS) {
|
|
1339
|
+
throw new ConfigError(
|
|
1340
|
+
"feeBps must be 100 (the locked 1% Playmos take); refused before anything signable"
|
|
1341
|
+
);
|
|
1342
|
+
}
|
|
1343
|
+
const poolBps = parseSeriesBps(input.poolBps, "poolBps") ?? DEFAULT_SERIES_POOL_BPS;
|
|
1344
|
+
const seedBps = parseSeriesBps(input.seedBps, "seedBps") ?? DEFAULT_SERIES_SEED_BPS;
|
|
1345
|
+
if (LOCKED_SERIES_FEE_BPS + poolBps + seedBps !== 1e4) {
|
|
1346
|
+
throw new ConfigError("feeBps + poolBps + seedBps must sum to 10000 (fee is 100)");
|
|
1347
|
+
}
|
|
1348
|
+
const epochDuration = toBig(input.epochDuration, 0n);
|
|
1349
|
+
const entry = toBig(input.entry, 0n);
|
|
1350
|
+
if (epochDuration <= 0n) throw new ConfigError("epochDuration must be greater than 0");
|
|
1351
|
+
if (entry <= 0n) throw new ConfigError("entry must be greater than 0");
|
|
1352
|
+
const genesis = toBig(input.genesis, BigInt(Math.floor(Date.now() / 1e3)));
|
|
1353
|
+
if (genesis <= 0n) throw new ConfigError("genesis must be greater than 0");
|
|
1354
|
+
const data = viem.encodeFunctionData({
|
|
1355
|
+
abi: epochPrizePoolCreateSeriesAbi,
|
|
1356
|
+
functionName: "createSeries",
|
|
1357
|
+
args: [
|
|
1358
|
+
seriesToBytes32(series),
|
|
1359
|
+
genesis,
|
|
1360
|
+
epochDuration,
|
|
1361
|
+
entry,
|
|
1362
|
+
LOCKED_SERIES_FEE_BPS,
|
|
1363
|
+
poolBps,
|
|
1364
|
+
seedBps
|
|
1365
|
+
]
|
|
1366
|
+
});
|
|
1367
|
+
return {
|
|
1368
|
+
series,
|
|
1369
|
+
epochPrizePool: pool,
|
|
1370
|
+
genesis: genesis.toString(),
|
|
1371
|
+
epochDuration: epochDuration.toString(),
|
|
1372
|
+
entry: entry.toString(),
|
|
1373
|
+
feeBps: 100,
|
|
1374
|
+
poolBps,
|
|
1375
|
+
seedBps,
|
|
1376
|
+
unsignedTx: {
|
|
1377
|
+
chainId,
|
|
1378
|
+
to: pool,
|
|
1379
|
+
value: "0",
|
|
1380
|
+
data
|
|
1381
|
+
},
|
|
1382
|
+
broadcast: false,
|
|
1383
|
+
via: "mock",
|
|
1384
|
+
mock: true
|
|
1385
|
+
};
|
|
1386
|
+
}
|
|
1307
1387
|
function prepareStudioPoolLocal(input, playmosFeeSink, token, playmosAddresses = []) {
|
|
1308
1388
|
const studio = requireAddr(input.studioWallet, "studioWallet");
|
|
1309
1389
|
const locked = PLAYMOS_FEE_SINK_DEFAULT;
|
|
@@ -1452,6 +1532,7 @@ async function readEpochTerminal(deps, pool, series, epochId) {
|
|
|
1452
1532
|
}
|
|
1453
1533
|
}
|
|
1454
1534
|
function createEpochsApi(deps) {
|
|
1535
|
+
const mockPreparedSeries = /* @__PURE__ */ new Map();
|
|
1455
1536
|
return {
|
|
1456
1537
|
async currentId(input) {
|
|
1457
1538
|
const series = requireSeries(input?.series);
|
|
@@ -1529,6 +1610,9 @@ function createEpochsApi(deps) {
|
|
|
1529
1610
|
const series = requireSeries(input?.series);
|
|
1530
1611
|
const cfg = deps.config();
|
|
1531
1612
|
if (cfg.mock) {
|
|
1613
|
+
const pool = (input.epochPrizePool ?? cfg.contracts?.epochPrizePool ?? "").toLowerCase();
|
|
1614
|
+
const prepared = mockPreparedSeries.get(`${pool}:${series}`);
|
|
1615
|
+
if (prepared) return prepared;
|
|
1532
1616
|
return {
|
|
1533
1617
|
series,
|
|
1534
1618
|
created: true,
|
|
@@ -1549,6 +1633,42 @@ function createEpochsApi(deps) {
|
|
|
1549
1633
|
})}`;
|
|
1550
1634
|
return deps.http().get(path);
|
|
1551
1635
|
},
|
|
1636
|
+
async prepareSeries(input) {
|
|
1637
|
+
const feeBps = input?.feeBps;
|
|
1638
|
+
if (feeBps !== void 0 && feeBps !== LOCKED_SERIES_FEE_BPS) {
|
|
1639
|
+
throw new ConfigError(
|
|
1640
|
+
"feeBps must be 100 (the locked 1% Playmos take); refused before anything signable"
|
|
1641
|
+
);
|
|
1642
|
+
}
|
|
1643
|
+
const cfg = deps.config();
|
|
1644
|
+
if (cfg.mock) {
|
|
1645
|
+
const prepared = prepareSeriesLocal(input, CHAIN_ID["base-sepolia"]);
|
|
1646
|
+
mockPreparedSeries.set(`${prepared.epochPrizePool}:${prepared.series}`, {
|
|
1647
|
+
series: prepared.series,
|
|
1648
|
+
created: true,
|
|
1649
|
+
genesis: prepared.genesis,
|
|
1650
|
+
epochDuration: prepared.epochDuration,
|
|
1651
|
+
entry: prepared.entry,
|
|
1652
|
+
feeBps: prepared.feeBps,
|
|
1653
|
+
poolBps: prepared.poolBps,
|
|
1654
|
+
seedBps: prepared.seedBps,
|
|
1655
|
+
via: "mock",
|
|
1656
|
+
epochPrizePool: prepared.epochPrizePool,
|
|
1657
|
+
mock: true
|
|
1658
|
+
});
|
|
1659
|
+
return prepared;
|
|
1660
|
+
}
|
|
1661
|
+
return deps.http().post("/epochs/series/prepare", {
|
|
1662
|
+
epochPrizePool: requireAddr(input?.epochPrizePool, "epochPrizePool"),
|
|
1663
|
+
series: requireSeries(input?.series),
|
|
1664
|
+
epochDuration: input.epochDuration,
|
|
1665
|
+
entry: input.entry,
|
|
1666
|
+
genesis: input.genesis,
|
|
1667
|
+
feeBps: input.feeBps,
|
|
1668
|
+
poolBps: input.poolBps,
|
|
1669
|
+
seedBps: input.seedBps
|
|
1670
|
+
});
|
|
1671
|
+
},
|
|
1552
1672
|
async preparePool(input) {
|
|
1553
1673
|
const studioWallet = requireAddr(input?.studioWallet, "studioWallet");
|
|
1554
1674
|
const cfg = deps.config();
|
|
@@ -2262,7 +2382,7 @@ var Playmos = class {
|
|
|
2262
2382
|
},
|
|
2263
2383
|
walletAddress: async () => getAccount(this.walletProvider()),
|
|
2264
2384
|
readView: async (to, data) => {
|
|
2265
|
-
if (await walletAvailable(this.config.wallet, this.walletTimeoutPolicy())) {
|
|
2385
|
+
if (!await this.shouldServerSettle() && await walletAvailable(this.config.wallet, this.walletTimeoutPolicy())) {
|
|
2266
2386
|
const provider = this.walletProvider();
|
|
2267
2387
|
return await provider.request({
|
|
2268
2388
|
method: "eth_call",
|
|
@@ -3363,8 +3483,14 @@ var Playmos = class {
|
|
|
3363
3483
|
);
|
|
3364
3484
|
}
|
|
3365
3485
|
}
|
|
3486
|
+
if (config.settle === "server" && !this.env.isTest) {
|
|
3487
|
+
throw new ConfigError(
|
|
3488
|
+
'settle: "server" is sandbox-only. Live keys must use a player wallet \u2014 never server-settle real money.',
|
|
3489
|
+
{ field: "settle" }
|
|
3490
|
+
);
|
|
3491
|
+
}
|
|
3366
3492
|
this.http = createHttpClient(this.env.apiBaseUrl, config.apiKey, config.retry);
|
|
3367
|
-
if (!config.mock) {
|
|
3493
|
+
if (!config.mock && config.settle !== "server") {
|
|
3368
3494
|
try {
|
|
3369
3495
|
resolveProvider(config.wallet, this.walletTimeoutPolicy());
|
|
3370
3496
|
} catch {
|
|
@@ -3434,6 +3560,23 @@ var Playmos = class {
|
|
|
3434
3560
|
return 0n;
|
|
3435
3561
|
}
|
|
3436
3562
|
}
|
|
3563
|
+
/**
|
|
3564
|
+
* Sandbox server-settle when the developer asked (`settle: "server"`) or when
|
|
3565
|
+
* a test key has no wallet. Never calls walletAvailable if the ask is set —
|
|
3566
|
+
* that is the MetaMask-hijack delete (Moonhop leftover Slice 1).
|
|
3567
|
+
*/
|
|
3568
|
+
async shouldServerSettle() {
|
|
3569
|
+
if (this.config.settle === "server") {
|
|
3570
|
+
if (!this.env.isTest) {
|
|
3571
|
+
throw new ConfigError(
|
|
3572
|
+
'settle: "server" is sandbox-only. Live keys must use a player wallet \u2014 never server-settle real money.',
|
|
3573
|
+
{ field: "settle" }
|
|
3574
|
+
);
|
|
3575
|
+
}
|
|
3576
|
+
return true;
|
|
3577
|
+
}
|
|
3578
|
+
return this.env.isTest && !await walletAvailable(this.config.wallet, this.walletTimeoutPolicy());
|
|
3579
|
+
}
|
|
3437
3580
|
/**
|
|
3438
3581
|
* Wallet timeout policy (#462 / PR #463 residual).
|
|
3439
3582
|
* - connectTimeoutMs → eth_requestAccounts only
|
|
@@ -3561,7 +3704,7 @@ var Playmos = class {
|
|
|
3561
3704
|
heldIdem ? { key: heldIdem, terms } : void 0
|
|
3562
3705
|
);
|
|
3563
3706
|
}
|
|
3564
|
-
if (
|
|
3707
|
+
if (await this.shouldServerSettle()) {
|
|
3565
3708
|
const res = await this.http.post(
|
|
3566
3709
|
"/payments",
|
|
3567
3710
|
{
|
|
@@ -3666,7 +3809,7 @@ var Playmos = class {
|
|
|
3666
3809
|
heldIdem ? { key: heldIdem, terms } : void 0
|
|
3667
3810
|
);
|
|
3668
3811
|
}
|
|
3669
|
-
const serverSettleNoWallet =
|
|
3812
|
+
const serverSettleNoWallet = await this.shouldServerSettle();
|
|
3670
3813
|
if (!serverSettleNoWallet) {
|
|
3671
3814
|
const pinned = typeof input.identity === "string" ? input.identity.trim() : "";
|
|
3672
3815
|
if (!pinned) {
|
|
@@ -3996,7 +4139,7 @@ var Playmos = class {
|
|
|
3996
4139
|
});
|
|
3997
4140
|
let raw;
|
|
3998
4141
|
try {
|
|
3999
|
-
if (await walletAvailable(this.config.wallet, this.walletTimeoutPolicy())) {
|
|
4142
|
+
if (!await this.shouldServerSettle() && await walletAvailable(this.config.wallet, this.walletTimeoutPolicy())) {
|
|
4000
4143
|
const provider = this.walletProvider();
|
|
4001
4144
|
raw = await provider.request({
|
|
4002
4145
|
method: "eth_call",
|
|
@@ -4215,8 +4358,11 @@ exports.C1_ENTER_SPLIT_MICRO = C1_ENTER_SPLIT_MICRO;
|
|
|
4215
4358
|
exports.CHAIN_ID = CHAIN_ID;
|
|
4216
4359
|
exports.ConfigError = ConfigError;
|
|
4217
4360
|
exports.DEFAULT_API_BASE_URL = DEFAULT_API_BASE_URL;
|
|
4361
|
+
exports.DEFAULT_SERIES_POOL_BPS = DEFAULT_SERIES_POOL_BPS;
|
|
4362
|
+
exports.DEFAULT_SERIES_SEED_BPS = DEFAULT_SERIES_SEED_BPS;
|
|
4218
4363
|
exports.InsufficientGasError = InsufficientGasError;
|
|
4219
4364
|
exports.InvalidAmountError = InvalidAmountError;
|
|
4365
|
+
exports.LOCKED_SERIES_FEE_BPS = LOCKED_SERIES_FEE_BPS;
|
|
4220
4366
|
exports.MICRO_PER_USDC = MICRO_PER_USDC;
|
|
4221
4367
|
exports.MissingFieldError = MissingFieldError;
|
|
4222
4368
|
exports.NothingToWithdrawError = NothingToWithdrawError;
|
|
@@ -4256,6 +4402,7 @@ exports.networkToCaip2 = networkToCaip2;
|
|
|
4256
4402
|
exports.parsePaymentRequirement = parsePaymentRequirement;
|
|
4257
4403
|
exports.parseUsdToMicro = parseUsdToMicro;
|
|
4258
4404
|
exports.prefixedId = prefixedId;
|
|
4405
|
+
exports.prepareSeriesLocal = prepareSeriesLocal;
|
|
4259
4406
|
exports.prepareStudioPoolLocal = prepareStudioPoolLocal;
|
|
4260
4407
|
exports.previewEscrowFee = previewEscrowFee;
|
|
4261
4408
|
exports.previewIapSplit = previewIapSplit;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
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-
|
|
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-
|
|
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-WcDNfb4q.cjs';
|
|
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-WcDNfb4q.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Thin REST client for the Playmos service. Every SDK method that touches the
|
|
@@ -88,6 +88,8 @@ declare function buildEpochWithdrawCall(epochPrizePool: `0x${string}`): Call;
|
|
|
88
88
|
* `epochs.enter` — pay into whatever window the clock says is current; no open
|
|
89
89
|
* gate. `epochs.preparePool` / `registerPool` / `createPool` — studio wallet
|
|
90
90
|
* deploys the existing EpochPrizePool constructor; Playmos is feeSink only.
|
|
91
|
+
* `epochs.prepareSeries` — unsigned createSeries tx; studio EOA signs; Playmos
|
|
92
|
+
* never broadcasts (sdk#739).
|
|
91
93
|
* `epochs.settle` — secret key, operator wallet, broadcast + 202. Passes the
|
|
92
94
|
* roster through; does not build a hub roster (R7b).
|
|
93
95
|
* `epochs.claimableRefund` / `claimRefund` / `withdraw` — wallet-direct on
|
|
@@ -243,6 +245,44 @@ interface EpochEntry {
|
|
|
243
245
|
via: EpochReadVia;
|
|
244
246
|
mock?: true;
|
|
245
247
|
}
|
|
248
|
+
/** Locked 1% Playmos take on a studio series. Any other fee is refused before signable bytes. */
|
|
249
|
+
declare const LOCKED_SERIES_FEE_BPS = 100;
|
|
250
|
+
/** Default prize-bucket bps when the studio does not type a split (fee 100 + seed 2000 = 10000). */
|
|
251
|
+
declare const DEFAULT_SERIES_POOL_BPS = 7900;
|
|
252
|
+
/** Default next-window seed bps when the studio does not type a split. */
|
|
253
|
+
declare const DEFAULT_SERIES_SEED_BPS = 2000;
|
|
254
|
+
interface EpochPrepareSeriesInput {
|
|
255
|
+
epochPrizePool: `0x${string}`;
|
|
256
|
+
series: string;
|
|
257
|
+
epochDuration: number | string;
|
|
258
|
+
/** Integer micro-USDC. */
|
|
259
|
+
entry: number | string;
|
|
260
|
+
genesis?: number | string;
|
|
261
|
+
/** Must be 100 if set — the locked 1% Playmos take. */
|
|
262
|
+
feeBps?: number;
|
|
263
|
+
poolBps?: number;
|
|
264
|
+
seedBps?: number;
|
|
265
|
+
}
|
|
266
|
+
interface EpochPreparedSeries {
|
|
267
|
+
series: string;
|
|
268
|
+
epochPrizePool: `0x${string}`;
|
|
269
|
+
genesis: string;
|
|
270
|
+
epochDuration: string;
|
|
271
|
+
entry: string;
|
|
272
|
+
feeBps: 100;
|
|
273
|
+
poolBps: number;
|
|
274
|
+
seedBps: number;
|
|
275
|
+
unsignedTx: {
|
|
276
|
+
chainId: number;
|
|
277
|
+
to: `0x${string}`;
|
|
278
|
+
value: "0";
|
|
279
|
+
data: `0x${string}`;
|
|
280
|
+
};
|
|
281
|
+
/** Playmos never broadcasts. Studio EOA sends. */
|
|
282
|
+
broadcast: false;
|
|
283
|
+
via: EpochReadVia;
|
|
284
|
+
mock?: true;
|
|
285
|
+
}
|
|
246
286
|
interface EpochPreparePoolInput {
|
|
247
287
|
studioWallet: `0x${string}`;
|
|
248
288
|
/** Must equal the Playmos sink if set; any other address is refused before broadcast. */
|
|
@@ -531,6 +571,7 @@ interface EpochsApi {
|
|
|
531
571
|
prize(input: EpochPrizeInput): Promise<EpochPrize>;
|
|
532
572
|
get(input: EpochGetInput): Promise<EpochView>;
|
|
533
573
|
getSeries(input: EpochGetSeriesInput): Promise<EpochSeriesView>;
|
|
574
|
+
prepareSeries(input: EpochPrepareSeriesInput): Promise<EpochPreparedSeries>;
|
|
534
575
|
preparePool(input: EpochPreparePoolInput): Promise<EpochPreparedPool>;
|
|
535
576
|
registerPool(input: EpochRegisterPoolInput): Promise<EpochStudioPool>;
|
|
536
577
|
createPool(input: EpochCreatePoolInput): Promise<EpochStudioPool>;
|
|
@@ -603,6 +644,8 @@ interface EpochsDeps {
|
|
|
603
644
|
declare function derivedEpochId(genesis: bigint, epochDuration: bigint, at: bigint): bigint;
|
|
604
645
|
/** Settle payable is inherited seed + this epoch's pool (not outgoingSeed). */
|
|
605
646
|
declare function epochPayableMicro(incomingSeed: bigint, pool: bigint): bigint;
|
|
647
|
+
/** Same refuse-before-signable posture as preparePool's feeSink check. */
|
|
648
|
+
declare function prepareSeriesLocal(input: EpochPrepareSeriesInput, chainId: number): EpochPreparedSeries;
|
|
606
649
|
/** Client-side pin — same refusals as the service, so a bad sink never reaches broadcast. */
|
|
607
650
|
declare function prepareStudioPoolLocal(input: EpochPreparePoolInput, playmosFeeSink: `0x${string}`, token: `0x${string}`, playmosAddresses?: `0x${string}`[]): EpochPreparedPool;
|
|
608
651
|
/**
|
|
@@ -1323,6 +1366,12 @@ declare class Playmos {
|
|
|
1323
1366
|
*/
|
|
1324
1367
|
private readonly mockByIdempotencyKey;
|
|
1325
1368
|
constructor(config: PlaymosConfig);
|
|
1369
|
+
/**
|
|
1370
|
+
* Sandbox server-settle when the developer asked (`settle: "server"`) or when
|
|
1371
|
+
* a test key has no wallet. Never calls walletAvailable if the ask is set —
|
|
1372
|
+
* that is the MetaMask-hijack delete (Moonhop leftover Slice 1).
|
|
1373
|
+
*/
|
|
1374
|
+
private shouldServerSettle;
|
|
1326
1375
|
/**
|
|
1327
1376
|
* Wallet timeout policy (#462 / PR #463 residual).
|
|
1328
1377
|
* - connectTimeoutMs → eth_requestAccounts only
|
|
@@ -1587,4 +1636,4 @@ declare function ulid(seedTime?: number): string;
|
|
|
1587
1636
|
/** `${prefix}_${ulid()}` — e.g. `pay_01J…`, `entry_01J…`, `idem_01J…`. */
|
|
1588
1637
|
declare function prefixedId(prefix: string): string;
|
|
1589
1638
|
|
|
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 };
|
|
1639
|
+
export { ActiveSeriesRound, AgentFundResult, AgentWallet, type Authorization, C1_ENTER_SPLIT_MICRO, CHAIN_ID, CancelRoundResult, type CreatePaymentRequirementInput, DEFAULT_API_BASE_URL, DEFAULT_SERIES_POOL_BPS, DEFAULT_SERIES_SEED_BPS, 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 EpochPrepareSeriesInput, type EpochPreparedPool, type EpochPreparedSeries, 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, LOCKED_SERIES_FEE_BPS, 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, prepareSeriesLocal, prepareStudioPoolLocal, previewEscrowFee, previewIapSplit, previewMarketplaceSplit, previewPoolSplit, previewTransferSplit, resolveEnv, serializePaymentRequirement, seriesToBytes32, settlementTypedData, toX402PaymentRequired, ulid, validateX402ChallengeInput };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
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-
|
|
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-
|
|
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-WcDNfb4q.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-WcDNfb4q.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Thin REST client for the Playmos service. Every SDK method that touches the
|
|
@@ -88,6 +88,8 @@ declare function buildEpochWithdrawCall(epochPrizePool: `0x${string}`): Call;
|
|
|
88
88
|
* `epochs.enter` — pay into whatever window the clock says is current; no open
|
|
89
89
|
* gate. `epochs.preparePool` / `registerPool` / `createPool` — studio wallet
|
|
90
90
|
* deploys the existing EpochPrizePool constructor; Playmos is feeSink only.
|
|
91
|
+
* `epochs.prepareSeries` — unsigned createSeries tx; studio EOA signs; Playmos
|
|
92
|
+
* never broadcasts (sdk#739).
|
|
91
93
|
* `epochs.settle` — secret key, operator wallet, broadcast + 202. Passes the
|
|
92
94
|
* roster through; does not build a hub roster (R7b).
|
|
93
95
|
* `epochs.claimableRefund` / `claimRefund` / `withdraw` — wallet-direct on
|
|
@@ -243,6 +245,44 @@ interface EpochEntry {
|
|
|
243
245
|
via: EpochReadVia;
|
|
244
246
|
mock?: true;
|
|
245
247
|
}
|
|
248
|
+
/** Locked 1% Playmos take on a studio series. Any other fee is refused before signable bytes. */
|
|
249
|
+
declare const LOCKED_SERIES_FEE_BPS = 100;
|
|
250
|
+
/** Default prize-bucket bps when the studio does not type a split (fee 100 + seed 2000 = 10000). */
|
|
251
|
+
declare const DEFAULT_SERIES_POOL_BPS = 7900;
|
|
252
|
+
/** Default next-window seed bps when the studio does not type a split. */
|
|
253
|
+
declare const DEFAULT_SERIES_SEED_BPS = 2000;
|
|
254
|
+
interface EpochPrepareSeriesInput {
|
|
255
|
+
epochPrizePool: `0x${string}`;
|
|
256
|
+
series: string;
|
|
257
|
+
epochDuration: number | string;
|
|
258
|
+
/** Integer micro-USDC. */
|
|
259
|
+
entry: number | string;
|
|
260
|
+
genesis?: number | string;
|
|
261
|
+
/** Must be 100 if set — the locked 1% Playmos take. */
|
|
262
|
+
feeBps?: number;
|
|
263
|
+
poolBps?: number;
|
|
264
|
+
seedBps?: number;
|
|
265
|
+
}
|
|
266
|
+
interface EpochPreparedSeries {
|
|
267
|
+
series: string;
|
|
268
|
+
epochPrizePool: `0x${string}`;
|
|
269
|
+
genesis: string;
|
|
270
|
+
epochDuration: string;
|
|
271
|
+
entry: string;
|
|
272
|
+
feeBps: 100;
|
|
273
|
+
poolBps: number;
|
|
274
|
+
seedBps: number;
|
|
275
|
+
unsignedTx: {
|
|
276
|
+
chainId: number;
|
|
277
|
+
to: `0x${string}`;
|
|
278
|
+
value: "0";
|
|
279
|
+
data: `0x${string}`;
|
|
280
|
+
};
|
|
281
|
+
/** Playmos never broadcasts. Studio EOA sends. */
|
|
282
|
+
broadcast: false;
|
|
283
|
+
via: EpochReadVia;
|
|
284
|
+
mock?: true;
|
|
285
|
+
}
|
|
246
286
|
interface EpochPreparePoolInput {
|
|
247
287
|
studioWallet: `0x${string}`;
|
|
248
288
|
/** Must equal the Playmos sink if set; any other address is refused before broadcast. */
|
|
@@ -531,6 +571,7 @@ interface EpochsApi {
|
|
|
531
571
|
prize(input: EpochPrizeInput): Promise<EpochPrize>;
|
|
532
572
|
get(input: EpochGetInput): Promise<EpochView>;
|
|
533
573
|
getSeries(input: EpochGetSeriesInput): Promise<EpochSeriesView>;
|
|
574
|
+
prepareSeries(input: EpochPrepareSeriesInput): Promise<EpochPreparedSeries>;
|
|
534
575
|
preparePool(input: EpochPreparePoolInput): Promise<EpochPreparedPool>;
|
|
535
576
|
registerPool(input: EpochRegisterPoolInput): Promise<EpochStudioPool>;
|
|
536
577
|
createPool(input: EpochCreatePoolInput): Promise<EpochStudioPool>;
|
|
@@ -603,6 +644,8 @@ interface EpochsDeps {
|
|
|
603
644
|
declare function derivedEpochId(genesis: bigint, epochDuration: bigint, at: bigint): bigint;
|
|
604
645
|
/** Settle payable is inherited seed + this epoch's pool (not outgoingSeed). */
|
|
605
646
|
declare function epochPayableMicro(incomingSeed: bigint, pool: bigint): bigint;
|
|
647
|
+
/** Same refuse-before-signable posture as preparePool's feeSink check. */
|
|
648
|
+
declare function prepareSeriesLocal(input: EpochPrepareSeriesInput, chainId: number): EpochPreparedSeries;
|
|
606
649
|
/** Client-side pin — same refusals as the service, so a bad sink never reaches broadcast. */
|
|
607
650
|
declare function prepareStudioPoolLocal(input: EpochPreparePoolInput, playmosFeeSink: `0x${string}`, token: `0x${string}`, playmosAddresses?: `0x${string}`[]): EpochPreparedPool;
|
|
608
651
|
/**
|
|
@@ -1323,6 +1366,12 @@ declare class Playmos {
|
|
|
1323
1366
|
*/
|
|
1324
1367
|
private readonly mockByIdempotencyKey;
|
|
1325
1368
|
constructor(config: PlaymosConfig);
|
|
1369
|
+
/**
|
|
1370
|
+
* Sandbox server-settle when the developer asked (`settle: "server"`) or when
|
|
1371
|
+
* a test key has no wallet. Never calls walletAvailable if the ask is set —
|
|
1372
|
+
* that is the MetaMask-hijack delete (Moonhop leftover Slice 1).
|
|
1373
|
+
*/
|
|
1374
|
+
private shouldServerSettle;
|
|
1326
1375
|
/**
|
|
1327
1376
|
* Wallet timeout policy (#462 / PR #463 residual).
|
|
1328
1377
|
* - connectTimeoutMs → eth_requestAccounts only
|
|
@@ -1587,4 +1636,4 @@ declare function ulid(seedTime?: number): string;
|
|
|
1587
1636
|
/** `${prefix}_${ulid()}` — e.g. `pay_01J…`, `entry_01J…`, `idem_01J…`. */
|
|
1588
1637
|
declare function prefixedId(prefix: string): string;
|
|
1589
1638
|
|
|
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 };
|
|
1639
|
+
export { ActiveSeriesRound, AgentFundResult, AgentWallet, type Authorization, C1_ENTER_SPLIT_MICRO, CHAIN_ID, CancelRoundResult, type CreatePaymentRequirementInput, DEFAULT_API_BASE_URL, DEFAULT_SERIES_POOL_BPS, DEFAULT_SERIES_SEED_BPS, 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 EpochPrepareSeriesInput, type EpochPreparedPool, type EpochPreparedSeries, 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, LOCKED_SERIES_FEE_BPS, 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, prepareSeriesLocal, 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-
|
|
2
|
-
export { AlreadyEnteredError, ApiError, AuthError, ConfigError, InsufficientGasError, InvalidAmountError, MissingFieldError, NothingToWithdrawError, PaymentFailedError, PlaymosError, WalletConnectionError, WalletTimeoutError, buildEpochExecuteSettlementCall, identityToBytes32, seriesToBytes32 } from './chunk-
|
|
1
|
+
import { AuthError, InvalidAmountError, epochPrizePoolEnterAbi, seriesToBytes32, identityToBytes32, encodeApprove, epochPrizePoolRefundAbi, ConfigError, epochPrizePoolCreateSeriesAbi, MissingFieldError, buildEpochExecuteSettlementCall, PaymentFailedError, epochPrizePoolViewAbi, ApiError, assertEnoughGas, sendCalls, waitForCalls, NothingToWithdrawError, buildWithdrawCall, WalletTimeoutError, buildIapCalls, buildEntryCalls, prizePoolAbi, WalletConnectionError, AlreadyEnteredError } from './chunk-ROWX6HVU.js';
|
|
2
|
+
export { AlreadyEnteredError, ApiError, AuthError, ConfigError, InsufficientGasError, InvalidAmountError, MissingFieldError, NothingToWithdrawError, PaymentFailedError, PlaymosError, WalletConnectionError, WalletTimeoutError, buildEpochExecuteSettlementCall, identityToBytes32, seriesToBytes32 } from './chunk-ROWX6HVU.js';
|
|
3
3
|
import { encodeFunctionData, encodeAbiParameters, decodeFunctionResult } from 'viem';
|
|
4
4
|
|
|
5
5
|
// src/config.ts
|
|
@@ -692,6 +692,9 @@ function encodeEpochPoolConstructorArgs(args) {
|
|
|
692
692
|
args.refundTimeout
|
|
693
693
|
]);
|
|
694
694
|
}
|
|
695
|
+
var LOCKED_SERIES_FEE_BPS = 100;
|
|
696
|
+
var DEFAULT_SERIES_POOL_BPS = 7900;
|
|
697
|
+
var DEFAULT_SERIES_SEED_BPS = 2e3;
|
|
695
698
|
function derivedEpochId(genesis, epochDuration, at) {
|
|
696
699
|
if (epochDuration === 0n) {
|
|
697
700
|
throw new ConfigError("epochDuration must be > 0");
|
|
@@ -860,6 +863,66 @@ function walletStatus(status) {
|
|
|
860
863
|
function sameAddr(a, b) {
|
|
861
864
|
return a.toLowerCase() === b.toLowerCase();
|
|
862
865
|
}
|
|
866
|
+
function parseSeriesBps(raw, field) {
|
|
867
|
+
if (raw === void 0) return void 0;
|
|
868
|
+
if (!Number.isInteger(raw) || raw < 0) {
|
|
869
|
+
throw new ConfigError(`${field} must be a non-negative integer`);
|
|
870
|
+
}
|
|
871
|
+
return raw;
|
|
872
|
+
}
|
|
873
|
+
function prepareSeriesLocal(input, chainId) {
|
|
874
|
+
const pool = requireAddr(input.epochPrizePool, "epochPrizePool");
|
|
875
|
+
const series = requireSeries(input.series);
|
|
876
|
+
const feeBps = parseSeriesBps(input.feeBps, "feeBps");
|
|
877
|
+
if (feeBps !== void 0 && feeBps !== LOCKED_SERIES_FEE_BPS) {
|
|
878
|
+
throw new ConfigError(
|
|
879
|
+
"feeBps must be 100 (the locked 1% Playmos take); refused before anything signable"
|
|
880
|
+
);
|
|
881
|
+
}
|
|
882
|
+
const poolBps = parseSeriesBps(input.poolBps, "poolBps") ?? DEFAULT_SERIES_POOL_BPS;
|
|
883
|
+
const seedBps = parseSeriesBps(input.seedBps, "seedBps") ?? DEFAULT_SERIES_SEED_BPS;
|
|
884
|
+
if (LOCKED_SERIES_FEE_BPS + poolBps + seedBps !== 1e4) {
|
|
885
|
+
throw new ConfigError("feeBps + poolBps + seedBps must sum to 10000 (fee is 100)");
|
|
886
|
+
}
|
|
887
|
+
const epochDuration = toBig(input.epochDuration, 0n);
|
|
888
|
+
const entry = toBig(input.entry, 0n);
|
|
889
|
+
if (epochDuration <= 0n) throw new ConfigError("epochDuration must be greater than 0");
|
|
890
|
+
if (entry <= 0n) throw new ConfigError("entry must be greater than 0");
|
|
891
|
+
const genesis = toBig(input.genesis, BigInt(Math.floor(Date.now() / 1e3)));
|
|
892
|
+
if (genesis <= 0n) throw new ConfigError("genesis must be greater than 0");
|
|
893
|
+
const data = encodeFunctionData({
|
|
894
|
+
abi: epochPrizePoolCreateSeriesAbi,
|
|
895
|
+
functionName: "createSeries",
|
|
896
|
+
args: [
|
|
897
|
+
seriesToBytes32(series),
|
|
898
|
+
genesis,
|
|
899
|
+
epochDuration,
|
|
900
|
+
entry,
|
|
901
|
+
LOCKED_SERIES_FEE_BPS,
|
|
902
|
+
poolBps,
|
|
903
|
+
seedBps
|
|
904
|
+
]
|
|
905
|
+
});
|
|
906
|
+
return {
|
|
907
|
+
series,
|
|
908
|
+
epochPrizePool: pool,
|
|
909
|
+
genesis: genesis.toString(),
|
|
910
|
+
epochDuration: epochDuration.toString(),
|
|
911
|
+
entry: entry.toString(),
|
|
912
|
+
feeBps: 100,
|
|
913
|
+
poolBps,
|
|
914
|
+
seedBps,
|
|
915
|
+
unsignedTx: {
|
|
916
|
+
chainId,
|
|
917
|
+
to: pool,
|
|
918
|
+
value: "0",
|
|
919
|
+
data
|
|
920
|
+
},
|
|
921
|
+
broadcast: false,
|
|
922
|
+
via: "mock",
|
|
923
|
+
mock: true
|
|
924
|
+
};
|
|
925
|
+
}
|
|
863
926
|
function prepareStudioPoolLocal(input, playmosFeeSink, token, playmosAddresses = []) {
|
|
864
927
|
const studio = requireAddr(input.studioWallet, "studioWallet");
|
|
865
928
|
const locked = PLAYMOS_FEE_SINK_DEFAULT;
|
|
@@ -1008,6 +1071,7 @@ async function readEpochTerminal(deps, pool, series, epochId) {
|
|
|
1008
1071
|
}
|
|
1009
1072
|
}
|
|
1010
1073
|
function createEpochsApi(deps) {
|
|
1074
|
+
const mockPreparedSeries = /* @__PURE__ */ new Map();
|
|
1011
1075
|
return {
|
|
1012
1076
|
async currentId(input) {
|
|
1013
1077
|
const series = requireSeries(input?.series);
|
|
@@ -1085,6 +1149,9 @@ function createEpochsApi(deps) {
|
|
|
1085
1149
|
const series = requireSeries(input?.series);
|
|
1086
1150
|
const cfg = deps.config();
|
|
1087
1151
|
if (cfg.mock) {
|
|
1152
|
+
const pool = (input.epochPrizePool ?? cfg.contracts?.epochPrizePool ?? "").toLowerCase();
|
|
1153
|
+
const prepared = mockPreparedSeries.get(`${pool}:${series}`);
|
|
1154
|
+
if (prepared) return prepared;
|
|
1088
1155
|
return {
|
|
1089
1156
|
series,
|
|
1090
1157
|
created: true,
|
|
@@ -1105,6 +1172,42 @@ function createEpochsApi(deps) {
|
|
|
1105
1172
|
})}`;
|
|
1106
1173
|
return deps.http().get(path);
|
|
1107
1174
|
},
|
|
1175
|
+
async prepareSeries(input) {
|
|
1176
|
+
const feeBps = input?.feeBps;
|
|
1177
|
+
if (feeBps !== void 0 && feeBps !== LOCKED_SERIES_FEE_BPS) {
|
|
1178
|
+
throw new ConfigError(
|
|
1179
|
+
"feeBps must be 100 (the locked 1% Playmos take); refused before anything signable"
|
|
1180
|
+
);
|
|
1181
|
+
}
|
|
1182
|
+
const cfg = deps.config();
|
|
1183
|
+
if (cfg.mock) {
|
|
1184
|
+
const prepared = prepareSeriesLocal(input, CHAIN_ID["base-sepolia"]);
|
|
1185
|
+
mockPreparedSeries.set(`${prepared.epochPrizePool}:${prepared.series}`, {
|
|
1186
|
+
series: prepared.series,
|
|
1187
|
+
created: true,
|
|
1188
|
+
genesis: prepared.genesis,
|
|
1189
|
+
epochDuration: prepared.epochDuration,
|
|
1190
|
+
entry: prepared.entry,
|
|
1191
|
+
feeBps: prepared.feeBps,
|
|
1192
|
+
poolBps: prepared.poolBps,
|
|
1193
|
+
seedBps: prepared.seedBps,
|
|
1194
|
+
via: "mock",
|
|
1195
|
+
epochPrizePool: prepared.epochPrizePool,
|
|
1196
|
+
mock: true
|
|
1197
|
+
});
|
|
1198
|
+
return prepared;
|
|
1199
|
+
}
|
|
1200
|
+
return deps.http().post("/epochs/series/prepare", {
|
|
1201
|
+
epochPrizePool: requireAddr(input?.epochPrizePool, "epochPrizePool"),
|
|
1202
|
+
series: requireSeries(input?.series),
|
|
1203
|
+
epochDuration: input.epochDuration,
|
|
1204
|
+
entry: input.entry,
|
|
1205
|
+
genesis: input.genesis,
|
|
1206
|
+
feeBps: input.feeBps,
|
|
1207
|
+
poolBps: input.poolBps,
|
|
1208
|
+
seedBps: input.seedBps
|
|
1209
|
+
});
|
|
1210
|
+
},
|
|
1108
1211
|
async preparePool(input) {
|
|
1109
1212
|
const studioWallet = requireAddr(input?.studioWallet, "studioWallet");
|
|
1110
1213
|
const cfg = deps.config();
|
|
@@ -1818,7 +1921,7 @@ var Playmos = class {
|
|
|
1818
1921
|
},
|
|
1819
1922
|
walletAddress: async () => getAccount(this.walletProvider()),
|
|
1820
1923
|
readView: async (to, data) => {
|
|
1821
|
-
if (await walletAvailable(this.config.wallet, this.walletTimeoutPolicy())) {
|
|
1924
|
+
if (!await this.shouldServerSettle() && await walletAvailable(this.config.wallet, this.walletTimeoutPolicy())) {
|
|
1822
1925
|
const provider = this.walletProvider();
|
|
1823
1926
|
return await provider.request({
|
|
1824
1927
|
method: "eth_call",
|
|
@@ -2919,8 +3022,14 @@ var Playmos = class {
|
|
|
2919
3022
|
);
|
|
2920
3023
|
}
|
|
2921
3024
|
}
|
|
3025
|
+
if (config.settle === "server" && !this.env.isTest) {
|
|
3026
|
+
throw new ConfigError(
|
|
3027
|
+
'settle: "server" is sandbox-only. Live keys must use a player wallet \u2014 never server-settle real money.',
|
|
3028
|
+
{ field: "settle" }
|
|
3029
|
+
);
|
|
3030
|
+
}
|
|
2922
3031
|
this.http = createHttpClient(this.env.apiBaseUrl, config.apiKey, config.retry);
|
|
2923
|
-
if (!config.mock) {
|
|
3032
|
+
if (!config.mock && config.settle !== "server") {
|
|
2924
3033
|
try {
|
|
2925
3034
|
resolveProvider(config.wallet, this.walletTimeoutPolicy());
|
|
2926
3035
|
} catch {
|
|
@@ -2990,6 +3099,23 @@ var Playmos = class {
|
|
|
2990
3099
|
return 0n;
|
|
2991
3100
|
}
|
|
2992
3101
|
}
|
|
3102
|
+
/**
|
|
3103
|
+
* Sandbox server-settle when the developer asked (`settle: "server"`) or when
|
|
3104
|
+
* a test key has no wallet. Never calls walletAvailable if the ask is set —
|
|
3105
|
+
* that is the MetaMask-hijack delete (Moonhop leftover Slice 1).
|
|
3106
|
+
*/
|
|
3107
|
+
async shouldServerSettle() {
|
|
3108
|
+
if (this.config.settle === "server") {
|
|
3109
|
+
if (!this.env.isTest) {
|
|
3110
|
+
throw new ConfigError(
|
|
3111
|
+
'settle: "server" is sandbox-only. Live keys must use a player wallet \u2014 never server-settle real money.',
|
|
3112
|
+
{ field: "settle" }
|
|
3113
|
+
);
|
|
3114
|
+
}
|
|
3115
|
+
return true;
|
|
3116
|
+
}
|
|
3117
|
+
return this.env.isTest && !await walletAvailable(this.config.wallet, this.walletTimeoutPolicy());
|
|
3118
|
+
}
|
|
2993
3119
|
/**
|
|
2994
3120
|
* Wallet timeout policy (#462 / PR #463 residual).
|
|
2995
3121
|
* - connectTimeoutMs → eth_requestAccounts only
|
|
@@ -3117,7 +3243,7 @@ var Playmos = class {
|
|
|
3117
3243
|
heldIdem ? { key: heldIdem, terms } : void 0
|
|
3118
3244
|
);
|
|
3119
3245
|
}
|
|
3120
|
-
if (
|
|
3246
|
+
if (await this.shouldServerSettle()) {
|
|
3121
3247
|
const res = await this.http.post(
|
|
3122
3248
|
"/payments",
|
|
3123
3249
|
{
|
|
@@ -3222,7 +3348,7 @@ var Playmos = class {
|
|
|
3222
3348
|
heldIdem ? { key: heldIdem, terms } : void 0
|
|
3223
3349
|
);
|
|
3224
3350
|
}
|
|
3225
|
-
const serverSettleNoWallet =
|
|
3351
|
+
const serverSettleNoWallet = await this.shouldServerSettle();
|
|
3226
3352
|
if (!serverSettleNoWallet) {
|
|
3227
3353
|
const pinned = typeof input.identity === "string" ? input.identity.trim() : "";
|
|
3228
3354
|
if (!pinned) {
|
|
@@ -3552,7 +3678,7 @@ var Playmos = class {
|
|
|
3552
3678
|
});
|
|
3553
3679
|
let raw;
|
|
3554
3680
|
try {
|
|
3555
|
-
if (await walletAvailable(this.config.wallet, this.walletTimeoutPolicy())) {
|
|
3681
|
+
if (!await this.shouldServerSettle() && await walletAvailable(this.config.wallet, this.walletTimeoutPolicy())) {
|
|
3556
3682
|
const provider = this.walletProvider();
|
|
3557
3683
|
raw = await provider.request({
|
|
3558
3684
|
method: "eth_call",
|
|
@@ -3764,4 +3890,4 @@ function isX402PayloadAuthorization(auth) {
|
|
|
3764
3890
|
return auth.kind === "x402-payload";
|
|
3765
3891
|
}
|
|
3766
3892
|
|
|
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 };
|
|
3893
|
+
export { C1_ENTER_SPLIT_MICRO, CHAIN_ID, DEFAULT_API_BASE_URL, DEFAULT_SERIES_POOL_BPS, DEFAULT_SERIES_SEED_BPS, LOCKED_SERIES_FEE_BPS, 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, prepareSeriesLocal, prepareStudioPoolLocal, previewEscrowFee, previewIapSplit, previewMarketplaceSplit, previewPoolSplit, previewTransferSplit, resolveEnv, serializePaymentRequirement, settlementTypedData, toX402PaymentRequired, ulid, validateX402ChallengeInput };
|
package/dist/server.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a2 as PlaymosError, W as WebhookEvent } from './errors-
|
|
2
|
-
export { ad as enterPathToBytes32 } from './errors-
|
|
1
|
+
import { a2 as PlaymosError, W as WebhookEvent } from './errors-WcDNfb4q.cjs';
|
|
2
|
+
export { ad as enterPathToBytes32 } from './errors-WcDNfb4q.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Webhook signature verification (spec §6.2) — server-side only.
|
package/dist/server.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a2 as PlaymosError, W as WebhookEvent } from './errors-
|
|
2
|
-
export { ad as enterPathToBytes32 } from './errors-
|
|
1
|
+
import { a2 as PlaymosError, W as WebhookEvent } from './errors-WcDNfb4q.js';
|
|
2
|
+
export { ad as enterPathToBytes32 } from './errors-WcDNfb4q.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Webhook signature verification (spec §6.2) — server-side only.
|
package/dist/server.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { PlaymosError, ApiError, toBytes32 } from './chunk-
|
|
2
|
-
export { toBytes32 as enterPathToBytes32 } from './chunk-
|
|
1
|
+
import { PlaymosError, ApiError, toBytes32 } from './chunk-ROWX6HVU.js';
|
|
2
|
+
export { toBytes32 as enterPathToBytes32 } from './chunk-ROWX6HVU.js';
|
|
3
3
|
import { timingSafeEqual, createHmac } from 'crypto';
|
|
4
4
|
import { encodeFunctionData, decodeFunctionResult } from 'viem';
|
|
5
5
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@playmos/sdk",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.15",
|
|
4
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
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|