@playmos/sdk 0.3.2 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +108 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +108 -2
- package/dist/index.js.map +1 -1
- package/package.json +6 -4
package/dist/index.d.cts
CHANGED
|
@@ -437,6 +437,8 @@ declare class Playmos {
|
|
|
437
437
|
*
|
|
438
438
|
* Operator txs are signed by the Playmos service (OPERATOR_ROLE key).
|
|
439
439
|
*/
|
|
440
|
+
/** Offline mock store for rounds.open/lock/settle/get when `mock: true` (3-game dogfood). */
|
|
441
|
+
private readonly mockRounds;
|
|
440
442
|
readonly rounds: {
|
|
441
443
|
open: (input: RoundOpenInput) => Promise<RoundState>;
|
|
442
444
|
lock: (input: {
|
|
@@ -579,7 +581,8 @@ declare class Playmos {
|
|
|
579
581
|
entryUnits: bigint;
|
|
580
582
|
}): Promise<{
|
|
581
583
|
paymentId: string;
|
|
582
|
-
status
|
|
584
|
+
/** Lowercase product status (matches Payment.status) — 0.3.3+; kits should compare case-insensitively. */
|
|
585
|
+
status: "confirmed" | "failed" | "pending";
|
|
583
586
|
txHash?: string;
|
|
584
587
|
onchain: boolean;
|
|
585
588
|
/** The on-chain identity actually entered — reconcile with `hasEntered`. */
|
package/dist/index.d.ts
CHANGED
|
@@ -437,6 +437,8 @@ declare class Playmos {
|
|
|
437
437
|
*
|
|
438
438
|
* Operator txs are signed by the Playmos service (OPERATOR_ROLE key).
|
|
439
439
|
*/
|
|
440
|
+
/** Offline mock store for rounds.open/lock/settle/get when `mock: true` (3-game dogfood). */
|
|
441
|
+
private readonly mockRounds;
|
|
440
442
|
readonly rounds: {
|
|
441
443
|
open: (input: RoundOpenInput) => Promise<RoundState>;
|
|
442
444
|
lock: (input: {
|
|
@@ -579,7 +581,8 @@ declare class Playmos {
|
|
|
579
581
|
entryUnits: bigint;
|
|
580
582
|
}): Promise<{
|
|
581
583
|
paymentId: string;
|
|
582
|
-
status
|
|
584
|
+
/** Lowercase product status (matches Payment.status) — 0.3.3+; kits should compare case-insensitively. */
|
|
585
|
+
status: "confirmed" | "failed" | "pending";
|
|
583
586
|
txHash?: string;
|
|
584
587
|
onchain: boolean;
|
|
585
588
|
/** The on-chain identity actually entered — reconcile with `hasEntered`. */
|
package/dist/index.js
CHANGED
|
@@ -929,6 +929,8 @@ var Playmos = class {
|
|
|
929
929
|
*
|
|
930
930
|
* Operator txs are signed by the Playmos service (OPERATOR_ROLE key).
|
|
931
931
|
*/
|
|
932
|
+
/** Offline mock store for rounds.open/lock/settle/get when `mock: true` (3-game dogfood). */
|
|
933
|
+
this.mockRounds = /* @__PURE__ */ new Map();
|
|
932
934
|
this.rounds = {
|
|
933
935
|
open: async (input) => {
|
|
934
936
|
requireField(input?.gameId, "gameId");
|
|
@@ -938,6 +940,34 @@ var Playmos = class {
|
|
|
938
940
|
throw new ConfigError("payout rule is required (winner-take-all | top-n | custom)");
|
|
939
941
|
}
|
|
940
942
|
validateAmount(input.entryAmount);
|
|
943
|
+
if (this.config.mock) {
|
|
944
|
+
const roundKey = input.roundKey ?? input.roundId;
|
|
945
|
+
const existing = this.mockRounds.get(input.roundId);
|
|
946
|
+
if (existing?.status === "open" || existing?.status === "locked") {
|
|
947
|
+
return existing;
|
|
948
|
+
}
|
|
949
|
+
if (existing?.status === "settled") {
|
|
950
|
+
throw new ApiError(`round ${input.roundId} already settled`, {
|
|
951
|
+
status: 409,
|
|
952
|
+
code: "conflict"
|
|
953
|
+
});
|
|
954
|
+
}
|
|
955
|
+
const round2 = {
|
|
956
|
+
roundId: input.roundId,
|
|
957
|
+
gameId: input.gameId,
|
|
958
|
+
roundKey,
|
|
959
|
+
status: "open",
|
|
960
|
+
entryAmount: input.entryAmount,
|
|
961
|
+
pool: null,
|
|
962
|
+
entrants: 0,
|
|
963
|
+
payout: input.payout,
|
|
964
|
+
closeAt: input.closeAt,
|
|
965
|
+
openTxHash: "0x000000000000000000000000000000000000000000000000000000000000mock",
|
|
966
|
+
prizePoolAddress: this.config.contracts?.prizePool ?? "0x0000000000000000000000000000000000000002"
|
|
967
|
+
};
|
|
968
|
+
this.mockRounds.set(input.roundId, round2);
|
|
969
|
+
return round2;
|
|
970
|
+
}
|
|
941
971
|
const { round } = await this.http.post("/rounds", {
|
|
942
972
|
gameId: input.gameId,
|
|
943
973
|
roundId: input.roundId,
|
|
@@ -951,6 +981,29 @@ var Playmos = class {
|
|
|
951
981
|
},
|
|
952
982
|
lock: async (input) => {
|
|
953
983
|
requireField(input?.roundId, "roundId");
|
|
984
|
+
if (this.config.mock) {
|
|
985
|
+
const existing = this.mockRounds.get(input.roundId);
|
|
986
|
+
if (!existing) {
|
|
987
|
+
throw new ApiError(`unknown round: ${input.roundId}`, { status: 404, code: "not_found" });
|
|
988
|
+
}
|
|
989
|
+
if (existing.status === "locked" || existing.status === "settled") return existing;
|
|
990
|
+
if (existing.status !== "open") {
|
|
991
|
+
throw new ApiError(`round ${input.roundId} is not open (status=${existing.status})`, {
|
|
992
|
+
status: 409,
|
|
993
|
+
code: "conflict"
|
|
994
|
+
});
|
|
995
|
+
}
|
|
996
|
+
const locked = {
|
|
997
|
+
...existing,
|
|
998
|
+
status: "locked",
|
|
999
|
+
// Mock payable pool ≈ 60% of entry × max(1, entrants) for shape only — not money truth.
|
|
1000
|
+
pool: existing.pool ?? existing.entryAmount,
|
|
1001
|
+
entrants: existing.entrants ?? 0,
|
|
1002
|
+
lockTxHash: "0x000000000000000000000000000000000000000000000000000000000000loc1"
|
|
1003
|
+
};
|
|
1004
|
+
this.mockRounds.set(input.roundId, locked);
|
|
1005
|
+
return locked;
|
|
1006
|
+
}
|
|
954
1007
|
const { round } = await this.http.post(
|
|
955
1008
|
`/rounds/${encodeURIComponent(input.roundId)}/lock`,
|
|
956
1009
|
{ gameId: input.gameId }
|
|
@@ -960,6 +1013,51 @@ var Playmos = class {
|
|
|
960
1013
|
settle: async (input) => {
|
|
961
1014
|
requireField(input?.roundId, "roundId");
|
|
962
1015
|
if (!input?.results) throw new ConfigError("results are required (ranking or winners)");
|
|
1016
|
+
if (this.config.mock) {
|
|
1017
|
+
const existing = this.mockRounds.get(input.roundId);
|
|
1018
|
+
if (!existing) {
|
|
1019
|
+
throw new ApiError(`unknown round: ${input.roundId}`, { status: 404, code: "not_found" });
|
|
1020
|
+
}
|
|
1021
|
+
if (existing.status === "settled" && existing.settleTxHash) {
|
|
1022
|
+
return {
|
|
1023
|
+
roundId: input.roundId,
|
|
1024
|
+
txHash: existing.settleTxHash,
|
|
1025
|
+
poolPaid: existing.pool ?? "0",
|
|
1026
|
+
winners: "winners" in input.results ? input.results.winners : input.results.ranking.map((wallet) => ({
|
|
1027
|
+
wallet,
|
|
1028
|
+
amount: existing.pool ?? existing.entryAmount
|
|
1029
|
+
})),
|
|
1030
|
+
status: "settled"
|
|
1031
|
+
};
|
|
1032
|
+
}
|
|
1033
|
+
if (existing.status !== "locked" && existing.status !== "open") {
|
|
1034
|
+
throw new ApiError(`round ${input.roundId} cannot settle (status=${existing.status})`, {
|
|
1035
|
+
status: 409,
|
|
1036
|
+
code: "conflict"
|
|
1037
|
+
});
|
|
1038
|
+
}
|
|
1039
|
+
const winners = "winners" in input.results ? input.results.winners : input.results.ranking.map((wallet, i) => ({
|
|
1040
|
+
wallet,
|
|
1041
|
+
// Winner-take-all mock shape when ranking only.
|
|
1042
|
+
amount: i === 0 ? existing.pool ?? existing.entryAmount : "0"
|
|
1043
|
+
}));
|
|
1044
|
+
const settleTxHash = "0x000000000000000000000000000000000000000000000000000000000000set1";
|
|
1045
|
+
const poolPaid = existing.pool ?? existing.entryAmount;
|
|
1046
|
+
const settled = {
|
|
1047
|
+
...existing,
|
|
1048
|
+
status: "settled",
|
|
1049
|
+
settleTxHash,
|
|
1050
|
+
pool: poolPaid
|
|
1051
|
+
};
|
|
1052
|
+
this.mockRounds.set(input.roundId, settled);
|
|
1053
|
+
return {
|
|
1054
|
+
roundId: input.roundId,
|
|
1055
|
+
txHash: settleTxHash,
|
|
1056
|
+
poolPaid,
|
|
1057
|
+
winners,
|
|
1058
|
+
status: "settled"
|
|
1059
|
+
};
|
|
1060
|
+
}
|
|
963
1061
|
const { settle } = await this.http.post(
|
|
964
1062
|
`/rounds/${encodeURIComponent(input.roundId)}/settle`,
|
|
965
1063
|
{ gameId: input.gameId, results: input.results }
|
|
@@ -968,6 +1066,13 @@ var Playmos = class {
|
|
|
968
1066
|
},
|
|
969
1067
|
get: async (input) => {
|
|
970
1068
|
requireField(input?.roundId, "roundId");
|
|
1069
|
+
if (this.config.mock) {
|
|
1070
|
+
const existing = this.mockRounds.get(input.roundId);
|
|
1071
|
+
if (!existing) {
|
|
1072
|
+
throw new ApiError(`unknown round: ${input.roundId}`, { status: 404, code: "not_found" });
|
|
1073
|
+
}
|
|
1074
|
+
return existing;
|
|
1075
|
+
}
|
|
971
1076
|
const { round } = await this.http.get(
|
|
972
1077
|
`/rounds/${encodeURIComponent(input.roundId)}`
|
|
973
1078
|
);
|
|
@@ -1332,12 +1437,13 @@ var Playmos = class {
|
|
|
1332
1437
|
amount: formatMicroToUsd(req.entryUnits),
|
|
1333
1438
|
playerId: req.wallet
|
|
1334
1439
|
});
|
|
1335
|
-
const
|
|
1440
|
+
const raw = String(entry.status ?? "pending").toLowerCase();
|
|
1441
|
+
const status = raw === "confirmed" ? "confirmed" : raw === "failed" ? "failed" : "pending";
|
|
1336
1442
|
const onchain = !entry.mock;
|
|
1337
1443
|
return {
|
|
1338
1444
|
paymentId: entry.id,
|
|
1339
1445
|
status,
|
|
1340
|
-
txHash: entry.txHash,
|
|
1446
|
+
...entry.txHash ? { txHash: entry.txHash } : {},
|
|
1341
1447
|
onchain,
|
|
1342
1448
|
identity: entry.identity ?? req.identity
|
|
1343
1449
|
};
|