@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 CHANGED
@@ -999,6 +999,8 @@ var Playmos = class {
999
999
  *
1000
1000
  * Operator txs are signed by the Playmos service (OPERATOR_ROLE key).
1001
1001
  */
1002
+ /** Offline mock store for rounds.open/lock/settle/get when `mock: true` (3-game dogfood). */
1003
+ this.mockRounds = /* @__PURE__ */ new Map();
1002
1004
  this.rounds = {
1003
1005
  open: async (input) => {
1004
1006
  requireField(input?.gameId, "gameId");
@@ -1008,6 +1010,34 @@ var Playmos = class {
1008
1010
  throw new ConfigError("payout rule is required (winner-take-all | top-n | custom)");
1009
1011
  }
1010
1012
  validateAmount(input.entryAmount);
1013
+ if (this.config.mock) {
1014
+ const roundKey = input.roundKey ?? input.roundId;
1015
+ const existing = this.mockRounds.get(input.roundId);
1016
+ if (existing?.status === "open" || existing?.status === "locked") {
1017
+ return existing;
1018
+ }
1019
+ if (existing?.status === "settled") {
1020
+ throw new ApiError(`round ${input.roundId} already settled`, {
1021
+ status: 409,
1022
+ code: "conflict"
1023
+ });
1024
+ }
1025
+ const round2 = {
1026
+ roundId: input.roundId,
1027
+ gameId: input.gameId,
1028
+ roundKey,
1029
+ status: "open",
1030
+ entryAmount: input.entryAmount,
1031
+ pool: null,
1032
+ entrants: 0,
1033
+ payout: input.payout,
1034
+ closeAt: input.closeAt,
1035
+ openTxHash: "0x000000000000000000000000000000000000000000000000000000000000mock",
1036
+ prizePoolAddress: this.config.contracts?.prizePool ?? "0x0000000000000000000000000000000000000002"
1037
+ };
1038
+ this.mockRounds.set(input.roundId, round2);
1039
+ return round2;
1040
+ }
1011
1041
  const { round } = await this.http.post("/rounds", {
1012
1042
  gameId: input.gameId,
1013
1043
  roundId: input.roundId,
@@ -1021,6 +1051,29 @@ var Playmos = class {
1021
1051
  },
1022
1052
  lock: async (input) => {
1023
1053
  requireField(input?.roundId, "roundId");
1054
+ if (this.config.mock) {
1055
+ const existing = this.mockRounds.get(input.roundId);
1056
+ if (!existing) {
1057
+ throw new ApiError(`unknown round: ${input.roundId}`, { status: 404, code: "not_found" });
1058
+ }
1059
+ if (existing.status === "locked" || existing.status === "settled") return existing;
1060
+ if (existing.status !== "open") {
1061
+ throw new ApiError(`round ${input.roundId} is not open (status=${existing.status})`, {
1062
+ status: 409,
1063
+ code: "conflict"
1064
+ });
1065
+ }
1066
+ const locked = {
1067
+ ...existing,
1068
+ status: "locked",
1069
+ // Mock payable pool ≈ 60% of entry × max(1, entrants) for shape only — not money truth.
1070
+ pool: existing.pool ?? existing.entryAmount,
1071
+ entrants: existing.entrants ?? 0,
1072
+ lockTxHash: "0x000000000000000000000000000000000000000000000000000000000000loc1"
1073
+ };
1074
+ this.mockRounds.set(input.roundId, locked);
1075
+ return locked;
1076
+ }
1024
1077
  const { round } = await this.http.post(
1025
1078
  `/rounds/${encodeURIComponent(input.roundId)}/lock`,
1026
1079
  { gameId: input.gameId }
@@ -1030,6 +1083,51 @@ var Playmos = class {
1030
1083
  settle: async (input) => {
1031
1084
  requireField(input?.roundId, "roundId");
1032
1085
  if (!input?.results) throw new ConfigError("results are required (ranking or winners)");
1086
+ if (this.config.mock) {
1087
+ const existing = this.mockRounds.get(input.roundId);
1088
+ if (!existing) {
1089
+ throw new ApiError(`unknown round: ${input.roundId}`, { status: 404, code: "not_found" });
1090
+ }
1091
+ if (existing.status === "settled" && existing.settleTxHash) {
1092
+ return {
1093
+ roundId: input.roundId,
1094
+ txHash: existing.settleTxHash,
1095
+ poolPaid: existing.pool ?? "0",
1096
+ winners: "winners" in input.results ? input.results.winners : input.results.ranking.map((wallet) => ({
1097
+ wallet,
1098
+ amount: existing.pool ?? existing.entryAmount
1099
+ })),
1100
+ status: "settled"
1101
+ };
1102
+ }
1103
+ if (existing.status !== "locked" && existing.status !== "open") {
1104
+ throw new ApiError(`round ${input.roundId} cannot settle (status=${existing.status})`, {
1105
+ status: 409,
1106
+ code: "conflict"
1107
+ });
1108
+ }
1109
+ const winners = "winners" in input.results ? input.results.winners : input.results.ranking.map((wallet, i) => ({
1110
+ wallet,
1111
+ // Winner-take-all mock shape when ranking only.
1112
+ amount: i === 0 ? existing.pool ?? existing.entryAmount : "0"
1113
+ }));
1114
+ const settleTxHash = "0x000000000000000000000000000000000000000000000000000000000000set1";
1115
+ const poolPaid = existing.pool ?? existing.entryAmount;
1116
+ const settled = {
1117
+ ...existing,
1118
+ status: "settled",
1119
+ settleTxHash,
1120
+ pool: poolPaid
1121
+ };
1122
+ this.mockRounds.set(input.roundId, settled);
1123
+ return {
1124
+ roundId: input.roundId,
1125
+ txHash: settleTxHash,
1126
+ poolPaid,
1127
+ winners,
1128
+ status: "settled"
1129
+ };
1130
+ }
1033
1131
  const { settle } = await this.http.post(
1034
1132
  `/rounds/${encodeURIComponent(input.roundId)}/settle`,
1035
1133
  { gameId: input.gameId, results: input.results }
@@ -1038,6 +1136,13 @@ var Playmos = class {
1038
1136
  },
1039
1137
  get: async (input) => {
1040
1138
  requireField(input?.roundId, "roundId");
1139
+ if (this.config.mock) {
1140
+ const existing = this.mockRounds.get(input.roundId);
1141
+ if (!existing) {
1142
+ throw new ApiError(`unknown round: ${input.roundId}`, { status: 404, code: "not_found" });
1143
+ }
1144
+ return existing;
1145
+ }
1041
1146
  const { round } = await this.http.get(
1042
1147
  `/rounds/${encodeURIComponent(input.roundId)}`
1043
1148
  );
@@ -1402,12 +1507,13 @@ var Playmos = class {
1402
1507
  amount: formatMicroToUsd(req.entryUnits),
1403
1508
  playerId: req.wallet
1404
1509
  });
1405
- const status = entry.status === "confirmed" ? "CONFIRMED" : entry.status === "failed" ? "FAILED" : "PENDING";
1510
+ const raw = String(entry.status ?? "pending").toLowerCase();
1511
+ const status = raw === "confirmed" ? "confirmed" : raw === "failed" ? "failed" : "pending";
1406
1512
  const onchain = !entry.mock;
1407
1513
  return {
1408
1514
  paymentId: entry.id,
1409
1515
  status,
1410
- txHash: entry.txHash,
1516
+ ...entry.txHash ? { txHash: entry.txHash } : {},
1411
1517
  onchain,
1412
1518
  identity: entry.identity ?? req.identity
1413
1519
  };