gameon-sdk 1.0.0 → 1.0.2
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/LICENSE +21 -0
- package/README.md +94 -0
- package/dist/client.d.ts +116 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +251 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -5
- package/dist/index.js.map +1 -1
- package/dist/server.cjs +193 -0
- package/dist/server.d.ts +101 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +169 -0
- package/dist/server.js.map +1 -0
- package/dist/types.d.ts +93 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/package.json +37 -10
- package/dist/apis/DefaultApi.d.ts +0 -308
- package/dist/apis/DefaultApi.d.ts.map +0 -1
- package/dist/apis/DefaultApi.js +0 -569
- package/dist/apis/DefaultApi.js.map +0 -1
- package/dist/apis/index.d.ts +0 -2
- package/dist/apis/index.d.ts.map +0 -1
- package/dist/apis/index.js +0 -4
- package/dist/apis/index.js.map +0 -1
- package/dist/models/BetCurrency.d.ts +0 -27
- package/dist/models/BetCurrency.d.ts.map +0 -1
- package/dist/models/BetCurrency.js +0 -45
- package/dist/models/BetCurrency.js.map +0 -1
- package/dist/models/BetInput.d.ts +0 -35
- package/dist/models/BetInput.d.ts.map +0 -1
- package/dist/models/BetInput.js +0 -48
- package/dist/models/BetInput.js.map +0 -1
- package/dist/models/BetRecord.d.ts +0 -86
- package/dist/models/BetRecord.d.ts.map +0 -1
- package/dist/models/BetRecord.js +0 -81
- package/dist/models/BetRecord.js.map +0 -1
- package/dist/models/BiggestWin.d.ts +0 -60
- package/dist/models/BiggestWin.d.ts.map +0 -1
- package/dist/models/BiggestWin.js +0 -58
- package/dist/models/BiggestWin.js.map +0 -1
- package/dist/models/Colour.d.ts +0 -27
- package/dist/models/Colour.d.ts.map +0 -1
- package/dist/models/Colour.js +0 -45
- package/dist/models/Colour.js.map +0 -1
- package/dist/models/CreateRoomV2Request.d.ts +0 -37
- package/dist/models/CreateRoomV2Request.d.ts.map +0 -1
- package/dist/models/CreateRoomV2Request.js +0 -48
- package/dist/models/CreateRoomV2Request.js.map +0 -1
- package/dist/models/CreateRoomV2RequestPlayersInner.d.ts +0 -43
- package/dist/models/CreateRoomV2RequestPlayersInner.d.ts.map +0 -1
- package/dist/models/CreateRoomV2RequestPlayersInner.js +0 -50
- package/dist/models/CreateRoomV2RequestPlayersInner.js.map +0 -1
- package/dist/models/CreateRoomV2RequestRoom.d.ts +0 -39
- package/dist/models/CreateRoomV2RequestRoom.d.ts.map +0 -1
- package/dist/models/CreateRoomV2RequestRoom.js +0 -46
- package/dist/models/CreateRoomV2RequestRoom.js.map +0 -1
- package/dist/models/CreateRoomV2Response.d.ts +0 -45
- package/dist/models/CreateRoomV2Response.d.ts.map +0 -1
- package/dist/models/CreateRoomV2Response.js +0 -56
- package/dist/models/CreateRoomV2Response.js.map +0 -1
- package/dist/models/CreateRoomV2ResponsePayload.d.ts +0 -63
- package/dist/models/CreateRoomV2ResponsePayload.d.ts.map +0 -1
- package/dist/models/CreateRoomV2ResponsePayload.js +0 -67
- package/dist/models/CreateRoomV2ResponsePayload.js.map +0 -1
- package/dist/models/CreateRoomV2ResponseUserInfo.d.ts +0 -39
- package/dist/models/CreateRoomV2ResponseUserInfo.d.ts.map +0 -1
- package/dist/models/CreateRoomV2ResponseUserInfo.js +0 -46
- package/dist/models/CreateRoomV2ResponseUserInfo.js.map +0 -1
- package/dist/models/CurrencyTier.d.ts +0 -43
- package/dist/models/CurrencyTier.d.ts.map +0 -1
- package/dist/models/CurrencyTier.js +0 -56
- package/dist/models/CurrencyTier.js.map +0 -1
- package/dist/models/ErrorResponse.d.ts +0 -35
- package/dist/models/ErrorResponse.d.ts.map +0 -1
- package/dist/models/ErrorResponse.js +0 -46
- package/dist/models/ErrorResponse.js.map +0 -1
- package/dist/models/ExchangeLaunchTicketRequest.d.ts +0 -31
- package/dist/models/ExchangeLaunchTicketRequest.d.ts.map +0 -1
- package/dist/models/ExchangeLaunchTicketRequest.js +0 -44
- package/dist/models/ExchangeLaunchTicketRequest.js.map +0 -1
- package/dist/models/ExchangeLaunchTicketResponse.d.ts +0 -31
- package/dist/models/ExchangeLaunchTicketResponse.d.ts.map +0 -1
- package/dist/models/ExchangeLaunchTicketResponse.js +0 -44
- package/dist/models/ExchangeLaunchTicketResponse.js.map +0 -1
- package/dist/models/FxRate.d.ts +0 -39
- package/dist/models/FxRate.d.ts.map +0 -1
- package/dist/models/FxRate.js +0 -52
- package/dist/models/FxRate.js.map +0 -1
- package/dist/models/GameConfig.d.ts +0 -69
- package/dist/models/GameConfig.d.ts.map +0 -1
- package/dist/models/GameConfig.js +0 -76
- package/dist/models/GameConfig.js.map +0 -1
- package/dist/models/GameConfigCurrencies.d.ts +0 -36
- package/dist/models/GameConfigCurrencies.d.ts.map +0 -1
- package/dist/models/GameConfigCurrencies.js +0 -49
- package/dist/models/GameConfigCurrencies.js.map +0 -1
- package/dist/models/GameConfigFx.d.ts +0 -31
- package/dist/models/GameConfigFx.d.ts.map +0 -1
- package/dist/models/GameConfigFx.js +0 -44
- package/dist/models/GameConfigFx.js.map +0 -1
- package/dist/models/HealthResponse.d.ts +0 -39
- package/dist/models/HealthResponse.d.ts.map +0 -1
- package/dist/models/HealthResponse.js +0 -52
- package/dist/models/HealthResponse.js.map +0 -1
- package/dist/models/HousePoolResponse.d.ts +0 -45
- package/dist/models/HousePoolResponse.d.ts.map +0 -1
- package/dist/models/HousePoolResponse.js +0 -58
- package/dist/models/HousePoolResponse.js.map +0 -1
- package/dist/models/HousePoolStats.d.ts +0 -59
- package/dist/models/HousePoolStats.d.ts.map +0 -1
- package/dist/models/HousePoolStats.js +0 -56
- package/dist/models/HousePoolStats.js.map +0 -1
- package/dist/models/LeaderboardEntry.d.ts +0 -59
- package/dist/models/LeaderboardEntry.d.ts.map +0 -1
- package/dist/models/LeaderboardEntry.js +0 -56
- package/dist/models/LeaderboardEntry.js.map +0 -1
- package/dist/models/MyBetsResponse.d.ts +0 -49
- package/dist/models/MyBetsResponse.d.ts.map +0 -1
- package/dist/models/MyBetsResponse.js +0 -54
- package/dist/models/MyBetsResponse.js.map +0 -1
- package/dist/models/MyHistoryResponse.d.ts +0 -36
- package/dist/models/MyHistoryResponse.d.ts.map +0 -1
- package/dist/models/MyHistoryResponse.js +0 -49
- package/dist/models/MyHistoryResponse.js.map +0 -1
- package/dist/models/Phase.d.ts +0 -27
- package/dist/models/Phase.d.ts.map +0 -1
- package/dist/models/Phase.js +0 -45
- package/dist/models/Phase.js.map +0 -1
- package/dist/models/PlaceBetRequest.d.ts +0 -45
- package/dist/models/PlaceBetRequest.d.ts.map +0 -1
- package/dist/models/PlaceBetRequest.js +0 -54
- package/dist/models/PlaceBetRequest.js.map +0 -1
- package/dist/models/PlaceBetResponse.d.ts +0 -52
- package/dist/models/PlaceBetResponse.d.ts.map +0 -1
- package/dist/models/PlaceBetResponse.js +0 -65
- package/dist/models/PlaceBetResponse.js.map +0 -1
- package/dist/models/PlacedBet.d.ts +0 -59
- package/dist/models/PlacedBet.d.ts.map +0 -1
- package/dist/models/PlacedBet.js +0 -66
- package/dist/models/PlacedBet.js.map +0 -1
- package/dist/models/Round.d.ts +0 -89
- package/dist/models/Round.d.ts.map +0 -1
- package/dist/models/Round.js +0 -77
- package/dist/models/Round.js.map +0 -1
- package/dist/models/RoundHistoryEntry.d.ts +0 -65
- package/dist/models/RoundHistoryEntry.d.ts.map +0 -1
- package/dist/models/RoundHistoryEntry.js +0 -76
- package/dist/models/RoundHistoryEntry.js.map +0 -1
- package/dist/models/RoundPlayer.d.ts +0 -59
- package/dist/models/RoundPlayer.d.ts.map +0 -1
- package/dist/models/RoundPlayer.js +0 -59
- package/dist/models/RoundPlayer.js.map +0 -1
- package/dist/models/RoundState.d.ts +0 -65
- package/dist/models/RoundState.d.ts.map +0 -1
- package/dist/models/RoundState.js +0 -62
- package/dist/models/RoundState.js.map +0 -1
- package/dist/models/RoundsResponse.d.ts +0 -36
- package/dist/models/RoundsResponse.d.ts.map +0 -1
- package/dist/models/RoundsResponse.js +0 -49
- package/dist/models/RoundsResponse.js.map +0 -1
- package/dist/models/SettledBet.d.ts +0 -71
- package/dist/models/SettledBet.d.ts.map +0 -1
- package/dist/models/SettledBet.js +0 -72
- package/dist/models/SettledBet.js.map +0 -1
- package/dist/models/StatusMessageResponse.d.ts +0 -39
- package/dist/models/StatusMessageResponse.d.ts.map +0 -1
- package/dist/models/StatusMessageResponse.js +0 -48
- package/dist/models/StatusMessageResponse.js.map +0 -1
- package/dist/models/TopWinnersResponse.d.ts +0 -45
- package/dist/models/TopWinnersResponse.d.ts.map +0 -1
- package/dist/models/TopWinnersResponse.js +0 -54
- package/dist/models/TopWinnersResponse.js.map +0 -1
- package/dist/models/User.d.ts +0 -55
- package/dist/models/User.d.ts.map +0 -1
- package/dist/models/User.js +0 -61
- package/dist/models/User.js.map +0 -1
- package/dist/models/UserHistoryResponse.d.ts +0 -48
- package/dist/models/UserHistoryResponse.d.ts.map +0 -1
- package/dist/models/UserHistoryResponse.js +0 -61
- package/dist/models/UserHistoryResponse.js.map +0 -1
- package/dist/models/UserRecordResponse.d.ts +0 -36
- package/dist/models/UserRecordResponse.d.ts.map +0 -1
- package/dist/models/UserRecordResponse.js +0 -49
- package/dist/models/UserRecordResponse.js.map +0 -1
- package/dist/models/WalletBalanceResponse.d.ts +0 -43
- package/dist/models/WalletBalanceResponse.d.ts.map +0 -1
- package/dist/models/WalletBalanceResponse.js +0 -50
- package/dist/models/WalletBalanceResponse.js.map +0 -1
- package/dist/models/index.d.ts +0 -42
- package/dist/models/index.d.ts.map +0 -1
- package/dist/models/index.js +0 -44
- package/dist/models/index.js.map +0 -1
- package/dist/runtime.d.ts +0 -218
- package/dist/runtime.d.ts.map +0 -1
- package/dist/runtime.js +0 -446
- package/dist/runtime.js.map +0 -1
package/dist/server.cjs
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/server.ts
|
|
21
|
+
var server_exports = {};
|
|
22
|
+
__export(server_exports, {
|
|
23
|
+
GameOnPlatform: () => GameOnPlatform,
|
|
24
|
+
GameOnPlatformError: () => GameOnPlatformError,
|
|
25
|
+
WIN_POINTS: () => WIN_POINTS,
|
|
26
|
+
signPayload: () => signPayload
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(server_exports);
|
|
29
|
+
var import_node_crypto = require("node:crypto");
|
|
30
|
+
var WIN_POINTS = 100;
|
|
31
|
+
var GameOnPlatformError = class extends Error {
|
|
32
|
+
constructor(status, body, path) {
|
|
33
|
+
super(`GameOn ${path} failed (HTTP ${status})${body?.message ? `: ${body.message}` : ""}`);
|
|
34
|
+
this.status = status;
|
|
35
|
+
this.body = body;
|
|
36
|
+
this.name = "GameOnPlatformError";
|
|
37
|
+
}
|
|
38
|
+
/** GameOn's numeric error code, e.g. 420001 (invalid signature). */
|
|
39
|
+
get errorCode() {
|
|
40
|
+
return this.body?.error_code;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
function signPayload(payload, privateKey) {
|
|
44
|
+
const body = JSON.stringify(payload);
|
|
45
|
+
const signer = (0, import_node_crypto.createSign)("RSA-SHA256");
|
|
46
|
+
signer.update(body);
|
|
47
|
+
signer.end();
|
|
48
|
+
return { signature: signer.sign(privateKey, "base64"), body };
|
|
49
|
+
}
|
|
50
|
+
var GameOnPlatform = class {
|
|
51
|
+
constructor(options) {
|
|
52
|
+
this.options = options;
|
|
53
|
+
}
|
|
54
|
+
// --- results ---
|
|
55
|
+
/**
|
|
56
|
+
* Reports a finished game the same way for every game: tournament games go
|
|
57
|
+
* to the match result, all others to game_session_finish. A tournament with
|
|
58
|
+
* no clear winner and loser (a draw) is not reported; returns false then.
|
|
59
|
+
*/
|
|
60
|
+
async reportGameResult(result) {
|
|
61
|
+
if (result.gameType === "TOURNAMENT") {
|
|
62
|
+
const winner = result.players.find((p) => p.winState === "WON");
|
|
63
|
+
const loser = result.players.find((p) => ["DEFEATED", "DROPPED", "CRASHED"].includes(p.winState));
|
|
64
|
+
if (!winner || !loser) return false;
|
|
65
|
+
if (result.matchId == null) {
|
|
66
|
+
throw new Error(`Tournament game ${result.gameSessionUuid} has no matchId`);
|
|
67
|
+
}
|
|
68
|
+
await this.reportTournamentResult(result.matchId, {
|
|
69
|
+
winnerUuid: winner.uuid,
|
|
70
|
+
loserUuid: loser.uuid,
|
|
71
|
+
score: { [winner.name ?? winner.uuid]: WIN_POINTS, [loser.name ?? loser.uuid]: 0 },
|
|
72
|
+
gameSessionUuid: result.gameSessionUuid
|
|
73
|
+
});
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
await this.finishGameSession({
|
|
77
|
+
gameSessionUuid: result.gameSessionUuid,
|
|
78
|
+
gameStatus: result.gameStatus,
|
|
79
|
+
players: result.players.map((p) => ({
|
|
80
|
+
uuid: p.uuid,
|
|
81
|
+
points: p.winState === "WON" ? WIN_POINTS : 0,
|
|
82
|
+
userGameSessionStatus: p.winState
|
|
83
|
+
}))
|
|
84
|
+
});
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
/** POST /api/external_game/v1/game_session_finish */
|
|
88
|
+
finishGameSession(input) {
|
|
89
|
+
return this.post("/api/external_game/v1/game_session_finish", input);
|
|
90
|
+
}
|
|
91
|
+
/** POST /tounament/api/matches/{matchId}/result (the platform's path is spelled "tounament"). */
|
|
92
|
+
reportTournamentResult(matchId, input) {
|
|
93
|
+
return this.post(`/tounament/api/matches/${encodeURIComponent(matchId)}/result`, {
|
|
94
|
+
winner_uuid: input.winnerUuid,
|
|
95
|
+
loser_uuid: input.loserUuid,
|
|
96
|
+
score: input.score,
|
|
97
|
+
game_session_id: input.gameSessionUuid
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
// --- players & coins ---
|
|
101
|
+
/** The player's live coin balance (signed). */
|
|
102
|
+
async getUserCoinBalance(userUuid) {
|
|
103
|
+
const { signature } = signPayload({ userUuid }, this.requirePrivateKey());
|
|
104
|
+
const body = await this.call("GET", `/api/sdk/v1/game-session/get-user-coin-balance?userUuid=${encodeURIComponent(userUuid)}`, {
|
|
105
|
+
headers: this.signedHeaders(signature)
|
|
106
|
+
});
|
|
107
|
+
if (!body?.status || typeof body.content !== "number") {
|
|
108
|
+
throw new GameOnPlatformError(200, body, "get-user-coin-balance");
|
|
109
|
+
}
|
|
110
|
+
return body.content;
|
|
111
|
+
}
|
|
112
|
+
/** Whether a player uuid belongs to a platform bot. */
|
|
113
|
+
async isBot(uuid) {
|
|
114
|
+
const body = await this.call("GET", `/api/sdk/v1/game-session/is-bot?uuid=${encodeURIComponent(uuid)}`);
|
|
115
|
+
return body?.content === true;
|
|
116
|
+
}
|
|
117
|
+
/** Creates the player's game session and holds the stake. */
|
|
118
|
+
async createUserGameSession(input) {
|
|
119
|
+
const body = await this.post("/api/sdk/v1/game-session/create-user-game-sessionv2", {
|
|
120
|
+
sessionUuid: input.sessionUuid,
|
|
121
|
+
sessionToken: input.sessionToken,
|
|
122
|
+
gameSessionUuid: input.gameSessionUuid,
|
|
123
|
+
amount: input.amount,
|
|
124
|
+
actionType: "HOLD",
|
|
125
|
+
...input.type ? { type: input.type } : {}
|
|
126
|
+
});
|
|
127
|
+
if (!body?.status) throw new GameOnPlatformError(200, body, "create-user-game-sessionv2");
|
|
128
|
+
return body;
|
|
129
|
+
}
|
|
130
|
+
/** Moves coins for a player: RELEASE, CAPTURE or WIN (signed). Not retried - the caller decides. */
|
|
131
|
+
async updateUserCoins(input) {
|
|
132
|
+
const payload = {
|
|
133
|
+
uuid: input.uuid,
|
|
134
|
+
actionType: input.actionType,
|
|
135
|
+
amount: input.amount,
|
|
136
|
+
sessionUuid: input.sessionUuid,
|
|
137
|
+
...input.type ? { type: input.type } : {}
|
|
138
|
+
};
|
|
139
|
+
const { signature, body } = signPayload(payload, this.requirePrivateKey());
|
|
140
|
+
const response = await this.call("POST", "/api/sdk/v1/game-session/usercoin-action/update", {
|
|
141
|
+
headers: { "Content-Type": "application/json", ...this.signedHeaders(signature) },
|
|
142
|
+
body
|
|
143
|
+
});
|
|
144
|
+
if (!response?.status) throw new GameOnPlatformError(200, response, "usercoin-action/update");
|
|
145
|
+
return response;
|
|
146
|
+
}
|
|
147
|
+
// --- transport ---
|
|
148
|
+
post(path, payload) {
|
|
149
|
+
return this.call("POST", path, {
|
|
150
|
+
headers: { "Content-Type": "application/json" },
|
|
151
|
+
body: JSON.stringify(payload)
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
async call(method, path, init = {}) {
|
|
155
|
+
const url = this.options.baseUrl.replace(/\/+$/, "") + path;
|
|
156
|
+
const response = await (this.options.fetchApi ?? fetch)(url, {
|
|
157
|
+
method,
|
|
158
|
+
headers: init.headers,
|
|
159
|
+
body: init.body,
|
|
160
|
+
signal: AbortSignal.timeout(this.options.timeoutMs ?? 15e3)
|
|
161
|
+
});
|
|
162
|
+
const text = await response.text();
|
|
163
|
+
let parsed;
|
|
164
|
+
try {
|
|
165
|
+
parsed = text ? JSON.parse(text) : void 0;
|
|
166
|
+
} catch {
|
|
167
|
+
parsed = text;
|
|
168
|
+
}
|
|
169
|
+
if (!response.ok) {
|
|
170
|
+
throw new GameOnPlatformError(response.status, parsed, path.split("?")[0]);
|
|
171
|
+
}
|
|
172
|
+
return parsed;
|
|
173
|
+
}
|
|
174
|
+
signedHeaders(signature) {
|
|
175
|
+
if (!this.options.developerId) {
|
|
176
|
+
throw new Error("This call is signed: pass developerId in GameOnPlatform options");
|
|
177
|
+
}
|
|
178
|
+
return { "X-Developer-ID": this.options.developerId, "X-Signature": signature };
|
|
179
|
+
}
|
|
180
|
+
requirePrivateKey() {
|
|
181
|
+
if (!this.options.privateKey) {
|
|
182
|
+
throw new Error("This call is signed: pass privateKey (PEM) in GameOnPlatform options");
|
|
183
|
+
}
|
|
184
|
+
return this.options.privateKey;
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
188
|
+
0 && (module.exports = {
|
|
189
|
+
GameOnPlatform,
|
|
190
|
+
GameOnPlatformError,
|
|
191
|
+
WIN_POINTS,
|
|
192
|
+
signPayload
|
|
193
|
+
});
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { GameStatus, GameType, WinState } from './types.js';
|
|
2
|
+
export type CoinAction = 'HOLD' | 'RELEASE' | 'CAPTURE' | 'WIN';
|
|
3
|
+
export type PlayerResult = WinState | 'CRASHED';
|
|
4
|
+
export interface GameOnPlatformOptions {
|
|
5
|
+
/** GameOn platform backend (GAMEON_BACKEND_URL). */
|
|
6
|
+
baseUrl: string;
|
|
7
|
+
/** X-Developer-ID; needed for signed calls (balance, coin actions). */
|
|
8
|
+
developerId?: string;
|
|
9
|
+
/** PEM private key used to sign requests; needed for signed calls. */
|
|
10
|
+
privateKey?: string;
|
|
11
|
+
/** Per-request timeout. Default 15s. */
|
|
12
|
+
timeoutMs?: number;
|
|
13
|
+
fetchApi?: typeof fetch;
|
|
14
|
+
}
|
|
15
|
+
export interface ResultPlayer {
|
|
16
|
+
uuid: string;
|
|
17
|
+
name?: string;
|
|
18
|
+
winState: PlayerResult;
|
|
19
|
+
}
|
|
20
|
+
export interface GameResult {
|
|
21
|
+
gameSessionUuid: string;
|
|
22
|
+
gameType: GameType;
|
|
23
|
+
/** Required for TOURNAMENT games. */
|
|
24
|
+
matchId?: number | null;
|
|
25
|
+
/** Sent for non-tournament games: FINISHED, DROPPED or CRASHED. */
|
|
26
|
+
gameStatus: Extract<GameStatus, 'FINISHED' | 'DROPPED' | 'CRASHED'>;
|
|
27
|
+
players: ResultPlayer[];
|
|
28
|
+
}
|
|
29
|
+
export interface FinishGameSessionInput {
|
|
30
|
+
gameSessionUuid: string;
|
|
31
|
+
gameStatus: Extract<GameStatus, 'FINISHED' | 'DROPPED' | 'CRASHED'>;
|
|
32
|
+
players: {
|
|
33
|
+
uuid: string;
|
|
34
|
+
points: number;
|
|
35
|
+
userGameSessionStatus: PlayerResult;
|
|
36
|
+
}[];
|
|
37
|
+
}
|
|
38
|
+
export interface TournamentResultInput {
|
|
39
|
+
winnerUuid: string;
|
|
40
|
+
loserUuid: string;
|
|
41
|
+
/** Keyed by player name. */
|
|
42
|
+
score: Record<string, number>;
|
|
43
|
+
gameSessionUuid: string;
|
|
44
|
+
}
|
|
45
|
+
export interface CreateUserGameSessionInput {
|
|
46
|
+
sessionUuid: string;
|
|
47
|
+
/** From exchange-launch-ticket; the platform derives the player from it. */
|
|
48
|
+
sessionToken: string;
|
|
49
|
+
gameSessionUuid: string;
|
|
50
|
+
amount: number;
|
|
51
|
+
/** The market the bet is on, if the game has several (e.g. roulette: straight, red). */
|
|
52
|
+
type?: string;
|
|
53
|
+
}
|
|
54
|
+
export interface CoinActionInput {
|
|
55
|
+
uuid: string;
|
|
56
|
+
actionType: CoinAction;
|
|
57
|
+
amount: number;
|
|
58
|
+
sessionUuid: string;
|
|
59
|
+
type?: string;
|
|
60
|
+
}
|
|
61
|
+
/** Points a player gets in game_session_finish. */
|
|
62
|
+
export declare const WIN_POINTS = 100;
|
|
63
|
+
export declare class GameOnPlatformError extends Error {
|
|
64
|
+
readonly status: number;
|
|
65
|
+
readonly body: any;
|
|
66
|
+
constructor(status: number, body: any, path: string);
|
|
67
|
+
/** GameOn's numeric error code, e.g. 420001 (invalid signature). */
|
|
68
|
+
get errorCode(): number | undefined;
|
|
69
|
+
}
|
|
70
|
+
/** RSA-SHA256 over JSON.stringify(payload), base64 - same as gameon-sdk-auth. */
|
|
71
|
+
export declare function signPayload(payload: unknown, privateKey: string): {
|
|
72
|
+
signature: string;
|
|
73
|
+
body: string;
|
|
74
|
+
};
|
|
75
|
+
export declare class GameOnPlatform {
|
|
76
|
+
private readonly options;
|
|
77
|
+
constructor(options: GameOnPlatformOptions);
|
|
78
|
+
/**
|
|
79
|
+
* Reports a finished game the same way for every game: tournament games go
|
|
80
|
+
* to the match result, all others to game_session_finish. A tournament with
|
|
81
|
+
* no clear winner and loser (a draw) is not reported; returns false then.
|
|
82
|
+
*/
|
|
83
|
+
reportGameResult(result: GameResult): Promise<boolean>;
|
|
84
|
+
/** POST /api/external_game/v1/game_session_finish */
|
|
85
|
+
finishGameSession(input: FinishGameSessionInput): Promise<any>;
|
|
86
|
+
/** POST /tounament/api/matches/{matchId}/result (the platform's path is spelled "tounament"). */
|
|
87
|
+
reportTournamentResult(matchId: number, input: TournamentResultInput): Promise<any>;
|
|
88
|
+
/** The player's live coin balance (signed). */
|
|
89
|
+
getUserCoinBalance(userUuid: string): Promise<number>;
|
|
90
|
+
/** Whether a player uuid belongs to a platform bot. */
|
|
91
|
+
isBot(uuid: string): Promise<boolean>;
|
|
92
|
+
/** Creates the player's game session and holds the stake. */
|
|
93
|
+
createUserGameSession(input: CreateUserGameSessionInput): Promise<any>;
|
|
94
|
+
/** Moves coins for a player: RELEASE, CAPTURE or WIN (signed). Not retried - the caller decides. */
|
|
95
|
+
updateUserCoins(input: CoinActionInput): Promise<any>;
|
|
96
|
+
private post;
|
|
97
|
+
private call;
|
|
98
|
+
private signedHeaders;
|
|
99
|
+
private requirePrivateKey;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
// Server-side only (Node): the calls every game backend makes to the GameOn
|
|
2
|
+
// platform, so no game writes its own. Import from 'gameon-sdk/server' -
|
|
3
|
+
// it uses node:crypto and must never end up in a browser bundle.
|
|
4
|
+
// The paths are documented in specs/platform.yaml.
|
|
5
|
+
import { createSign } from 'node:crypto';
|
|
6
|
+
/** Points a player gets in game_session_finish. */
|
|
7
|
+
export const WIN_POINTS = 100;
|
|
8
|
+
export class GameOnPlatformError extends Error {
|
|
9
|
+
constructor(status, body, path) {
|
|
10
|
+
super(`GameOn ${path} failed (HTTP ${status})${body?.message ? `: ${body.message}` : ''}`);
|
|
11
|
+
this.status = status;
|
|
12
|
+
this.body = body;
|
|
13
|
+
this.name = 'GameOnPlatformError';
|
|
14
|
+
}
|
|
15
|
+
/** GameOn's numeric error code, e.g. 420001 (invalid signature). */
|
|
16
|
+
get errorCode() {
|
|
17
|
+
return this.body?.error_code;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/** RSA-SHA256 over JSON.stringify(payload), base64 - same as gameon-sdk-auth. */
|
|
21
|
+
export function signPayload(payload, privateKey) {
|
|
22
|
+
const body = JSON.stringify(payload);
|
|
23
|
+
const signer = createSign('RSA-SHA256');
|
|
24
|
+
signer.update(body);
|
|
25
|
+
signer.end();
|
|
26
|
+
return { signature: signer.sign(privateKey, 'base64'), body };
|
|
27
|
+
}
|
|
28
|
+
export class GameOnPlatform {
|
|
29
|
+
constructor(options) {
|
|
30
|
+
this.options = options;
|
|
31
|
+
}
|
|
32
|
+
// --- results ---
|
|
33
|
+
/**
|
|
34
|
+
* Reports a finished game the same way for every game: tournament games go
|
|
35
|
+
* to the match result, all others to game_session_finish. A tournament with
|
|
36
|
+
* no clear winner and loser (a draw) is not reported; returns false then.
|
|
37
|
+
*/
|
|
38
|
+
async reportGameResult(result) {
|
|
39
|
+
if (result.gameType === 'TOURNAMENT') {
|
|
40
|
+
const winner = result.players.find((p) => p.winState === 'WON');
|
|
41
|
+
const loser = result.players.find((p) => ['DEFEATED', 'DROPPED', 'CRASHED'].includes(p.winState));
|
|
42
|
+
if (!winner || !loser)
|
|
43
|
+
return false;
|
|
44
|
+
if (result.matchId == null) {
|
|
45
|
+
throw new Error(`Tournament game ${result.gameSessionUuid} has no matchId`);
|
|
46
|
+
}
|
|
47
|
+
await this.reportTournamentResult(result.matchId, {
|
|
48
|
+
winnerUuid: winner.uuid,
|
|
49
|
+
loserUuid: loser.uuid,
|
|
50
|
+
score: { [winner.name ?? winner.uuid]: WIN_POINTS, [loser.name ?? loser.uuid]: 0 },
|
|
51
|
+
gameSessionUuid: result.gameSessionUuid,
|
|
52
|
+
});
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
await this.finishGameSession({
|
|
56
|
+
gameSessionUuid: result.gameSessionUuid,
|
|
57
|
+
gameStatus: result.gameStatus,
|
|
58
|
+
players: result.players.map((p) => ({
|
|
59
|
+
uuid: p.uuid,
|
|
60
|
+
points: p.winState === 'WON' ? WIN_POINTS : 0,
|
|
61
|
+
userGameSessionStatus: p.winState,
|
|
62
|
+
})),
|
|
63
|
+
});
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
/** POST /api/external_game/v1/game_session_finish */
|
|
67
|
+
finishGameSession(input) {
|
|
68
|
+
return this.post('/api/external_game/v1/game_session_finish', input);
|
|
69
|
+
}
|
|
70
|
+
/** POST /tounament/api/matches/{matchId}/result (the platform's path is spelled "tounament"). */
|
|
71
|
+
reportTournamentResult(matchId, input) {
|
|
72
|
+
return this.post(`/tounament/api/matches/${encodeURIComponent(matchId)}/result`, {
|
|
73
|
+
winner_uuid: input.winnerUuid,
|
|
74
|
+
loser_uuid: input.loserUuid,
|
|
75
|
+
score: input.score,
|
|
76
|
+
game_session_id: input.gameSessionUuid,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
// --- players & coins ---
|
|
80
|
+
/** The player's live coin balance (signed). */
|
|
81
|
+
async getUserCoinBalance(userUuid) {
|
|
82
|
+
const { signature } = signPayload({ userUuid }, this.requirePrivateKey());
|
|
83
|
+
const body = await this.call('GET', `/api/sdk/v1/game-session/get-user-coin-balance?userUuid=${encodeURIComponent(userUuid)}`, {
|
|
84
|
+
headers: this.signedHeaders(signature),
|
|
85
|
+
});
|
|
86
|
+
if (!body?.status || typeof body.content !== 'number') {
|
|
87
|
+
throw new GameOnPlatformError(200, body, 'get-user-coin-balance');
|
|
88
|
+
}
|
|
89
|
+
return body.content;
|
|
90
|
+
}
|
|
91
|
+
/** Whether a player uuid belongs to a platform bot. */
|
|
92
|
+
async isBot(uuid) {
|
|
93
|
+
const body = await this.call('GET', `/api/sdk/v1/game-session/is-bot?uuid=${encodeURIComponent(uuid)}`);
|
|
94
|
+
return body?.content === true;
|
|
95
|
+
}
|
|
96
|
+
/** Creates the player's game session and holds the stake. */
|
|
97
|
+
async createUserGameSession(input) {
|
|
98
|
+
const body = await this.post('/api/sdk/v1/game-session/create-user-game-sessionv2', {
|
|
99
|
+
sessionUuid: input.sessionUuid,
|
|
100
|
+
sessionToken: input.sessionToken,
|
|
101
|
+
gameSessionUuid: input.gameSessionUuid,
|
|
102
|
+
amount: input.amount,
|
|
103
|
+
actionType: 'HOLD',
|
|
104
|
+
...(input.type ? { type: input.type } : {}),
|
|
105
|
+
});
|
|
106
|
+
if (!body?.status)
|
|
107
|
+
throw new GameOnPlatformError(200, body, 'create-user-game-sessionv2');
|
|
108
|
+
return body;
|
|
109
|
+
}
|
|
110
|
+
/** Moves coins for a player: RELEASE, CAPTURE or WIN (signed). Not retried - the caller decides. */
|
|
111
|
+
async updateUserCoins(input) {
|
|
112
|
+
const payload = {
|
|
113
|
+
uuid: input.uuid,
|
|
114
|
+
actionType: input.actionType,
|
|
115
|
+
amount: input.amount,
|
|
116
|
+
sessionUuid: input.sessionUuid,
|
|
117
|
+
...(input.type ? { type: input.type } : {}),
|
|
118
|
+
};
|
|
119
|
+
const { signature, body } = signPayload(payload, this.requirePrivateKey());
|
|
120
|
+
const response = await this.call('POST', '/api/sdk/v1/game-session/usercoin-action/update', {
|
|
121
|
+
headers: { 'Content-Type': 'application/json', ...this.signedHeaders(signature) },
|
|
122
|
+
body,
|
|
123
|
+
});
|
|
124
|
+
if (!response?.status)
|
|
125
|
+
throw new GameOnPlatformError(200, response, 'usercoin-action/update');
|
|
126
|
+
return response;
|
|
127
|
+
}
|
|
128
|
+
// --- transport ---
|
|
129
|
+
post(path, payload) {
|
|
130
|
+
return this.call('POST', path, {
|
|
131
|
+
headers: { 'Content-Type': 'application/json' },
|
|
132
|
+
body: JSON.stringify(payload),
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
async call(method, path, init = {}) {
|
|
136
|
+
const url = this.options.baseUrl.replace(/\/+$/, '') + path;
|
|
137
|
+
const response = await (this.options.fetchApi ?? fetch)(url, {
|
|
138
|
+
method,
|
|
139
|
+
headers: init.headers,
|
|
140
|
+
body: init.body,
|
|
141
|
+
signal: AbortSignal.timeout(this.options.timeoutMs ?? 15000),
|
|
142
|
+
});
|
|
143
|
+
const text = await response.text();
|
|
144
|
+
let parsed;
|
|
145
|
+
try {
|
|
146
|
+
parsed = text ? JSON.parse(text) : undefined;
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
parsed = text;
|
|
150
|
+
}
|
|
151
|
+
if (!response.ok) {
|
|
152
|
+
throw new GameOnPlatformError(response.status, parsed, path.split('?')[0]);
|
|
153
|
+
}
|
|
154
|
+
return parsed;
|
|
155
|
+
}
|
|
156
|
+
signedHeaders(signature) {
|
|
157
|
+
if (!this.options.developerId) {
|
|
158
|
+
throw new Error('This call is signed: pass developerId in GameOnPlatform options');
|
|
159
|
+
}
|
|
160
|
+
return { 'X-Developer-ID': this.options.developerId, 'X-Signature': signature };
|
|
161
|
+
}
|
|
162
|
+
requirePrivateKey() {
|
|
163
|
+
if (!this.options.privateKey) {
|
|
164
|
+
throw new Error('This call is signed: pass privateKey (PEM) in GameOnPlatform options');
|
|
165
|
+
}
|
|
166
|
+
return this.options.privateKey;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,yEAAyE;AACzE,iEAAiE;AACjE,mDAAmD;AAEnD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAkEzC,mDAAmD;AACnD,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAC;AAE9B,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC1C,YACoB,MAAc,EACd,IAAS,EACzB,IAAY;QAEZ,KAAK,CAAC,UAAU,IAAI,iBAAiB,MAAM,IAAI,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;sBAJ3E,MAAM;oBACN,IAAI;QAIpB,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACtC,CAAC;IAED,oEAAoE;IACpE,IAAI,SAAS;QACT,OAAO,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC;IACjC,CAAC;CACJ;AAED,iFAAiF;AACjF,MAAM,UAAU,WAAW,CAAC,OAAgB,EAAE,UAAkB;IAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IACxC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpB,MAAM,CAAC,GAAG,EAAE,CAAC;IACb,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC;AAClE,CAAC;AAED,MAAM,OAAO,cAAc;IACvB,YAA6B,OAA8B;uBAA9B,OAAO;IAA0B,CAAC;IAE/D,kBAAkB;IAElB;;;;OAIG;IACH,KAAK,CAAC,gBAAgB,CAAC,MAAkB;QACrC,IAAI,MAAM,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;YACnC,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,KAAK,CAAC,CAAC;YAChE,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YAClG,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK;gBAAE,OAAO,KAAK,CAAC;YACpC,IAAI,MAAM,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;gBACzB,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,CAAC,eAAe,iBAAiB,CAAC,CAAC;YAChF,CAAC;YACD,MAAM,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,EAAE;gBAC9C,UAAU,EAAE,MAAM,CAAC,IAAI;gBACvB,SAAS,EAAE,KAAK,CAAC,IAAI;gBACrB,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,CAAC,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;gBAClF,eAAe,EAAE,MAAM,CAAC,eAAe;aAC1C,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,MAAM,IAAI,CAAC,iBAAiB,CAAC;YACzB,eAAe,EAAE,MAAM,CAAC,eAAe;YACvC,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAChC,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,MAAM,EAAE,CAAC,CAAC,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBAC7C,qBAAqB,EAAE,CAAC,CAAC,QAAQ;aACpC,CAAC,CAAC;SACN,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,qDAAqD;IACrD,iBAAiB,CAAC,KAA6B;QAC3C,OAAO,IAAI,CAAC,IAAI,CAAC,2CAA2C,EAAE,KAAK,CAAC,CAAC;IACzE,CAAC;IAED,iGAAiG;IACjG,sBAAsB,CAAC,OAAe,EAAE,KAA4B;QAChE,OAAO,IAAI,CAAC,IAAI,CAAC,0BAA0B,kBAAkB,CAAC,OAAO,CAAC,SAAS,EAAE;YAC7E,WAAW,EAAE,KAAK,CAAC,UAAU;YAC7B,UAAU,EAAE,KAAK,CAAC,SAAS;YAC3B,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,eAAe,EAAE,KAAK,CAAC,eAAe;SACzC,CAAC,CAAC;IACP,CAAC;IAED,0BAA0B;IAE1B,+CAA+C;IAC/C,KAAK,CAAC,kBAAkB,CAAC,QAAgB;QACrC,MAAM,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC,EAAE,QAAQ,EAAE,EAAE,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC;QAC1E,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,2DAA2D,kBAAkB,CAAC,QAAQ,CAAC,EAAE,EAAE;YAC3H,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC;SACzC,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,EAAE,MAAM,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YACpD,MAAM,IAAI,mBAAmB,CAAC,GAAG,EAAE,IAAI,EAAE,uBAAuB,CAAC,CAAC;QACtE,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC;IACxB,CAAC;IAED,uDAAuD;IACvD,KAAK,CAAC,KAAK,CAAC,IAAY;QACpB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,wCAAwC,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACxG,OAAO,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAClC,CAAC;IAED,6DAA6D;IAC7D,KAAK,CAAC,qBAAqB,CAAC,KAAiC;QACzD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,qDAAqD,EAAE;YAChF,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,eAAe,EAAE,KAAK,CAAC,eAAe;YACtC,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,UAAU,EAAE,MAAM;YAClB,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9C,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,EAAE,MAAM;YAAE,MAAM,IAAI,mBAAmB,CAAC,GAAG,EAAE,IAAI,EAAE,4BAA4B,CAAC,CAAC;QAC1F,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,oGAAoG;IACpG,KAAK,CAAC,eAAe,CAAC,KAAsB;QACxC,MAAM,OAAO,GAAG;YACZ,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9C,CAAC;QACF,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC;QAC3E,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,iDAAiD,EAAE;YACxF,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE;YACjF,IAAI;SACP,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,EAAE,MAAM;YAAE,MAAM,IAAI,mBAAmB,CAAC,GAAG,EAAE,QAAQ,EAAE,wBAAwB,CAAC,CAAC;QAC9F,OAAO,QAAQ,CAAC;IACpB,CAAC;IAED,oBAAoB;IAEZ,IAAI,CAAC,IAAY,EAAE,OAAgB;QACvC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE;YAC3B,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;SAChC,CAAC,CAAC;IACP,CAAC;IAEO,KAAK,CAAC,IAAI,CAAC,MAAc,EAAE,IAAY,EAAE,IAAI,GAAwD,EAAE;QAC3G,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC;QAC5D,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,KAAK,CAAC,CAAC,GAAG,EAAE;YACzD,MAAM;YACN,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC;SAC/D,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,MAAW,CAAC;QAChB,IAAI,CAAC;YACD,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC;YACL,MAAM,GAAG,IAAI,CAAC;QAClB,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,IAAI,mBAAmB,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC;QAChF,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAEO,aAAa,CAAC,SAAiB;QACnC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;QACvF,CAAC;QACD,OAAO,EAAE,gBAAgB,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;IACpF,CAAC;IAEO,iBAAiB;QACrB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;QAC5F,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;IACnC,CAAC;CACJ"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
export type GameType = 'MULTIPLAYER' | 'BOT_GAME' | 'TOURNAMENT' | 'DEMO';
|
|
2
|
+
export type GameStatus = 'ACTIVE' | 'FINISHED' | 'DROPPED' | 'DRAW' | 'CRASHED';
|
|
3
|
+
export type WinState = 'WON' | 'DEFEATED' | 'DROPPED' | 'DRAW';
|
|
4
|
+
export type Role = 'player' | 'spectator';
|
|
5
|
+
export interface PlayerInput {
|
|
6
|
+
uuid: string;
|
|
7
|
+
name: string;
|
|
8
|
+
profileImage?: string | null;
|
|
9
|
+
ready?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface CreateRoomInput {
|
|
12
|
+
room: {
|
|
13
|
+
gameSessionUuid: string;
|
|
14
|
+
name: string;
|
|
15
|
+
/** 1 for a tournament room. */
|
|
16
|
+
tournament?: 0 | 1;
|
|
17
|
+
matchId?: number | null;
|
|
18
|
+
};
|
|
19
|
+
players: PlayerInput[];
|
|
20
|
+
}
|
|
21
|
+
export interface CreatedRoom {
|
|
22
|
+
gameSessionUuid: string;
|
|
23
|
+
gameStateId?: string;
|
|
24
|
+
/** Play links in player order. */
|
|
25
|
+
links: string[];
|
|
26
|
+
/** The backend's full response, for game-only fields (e.g. roulette's balance). */
|
|
27
|
+
raw: any;
|
|
28
|
+
}
|
|
29
|
+
export interface RoomPlayer extends PlayerInput {
|
|
30
|
+
winState?: WinState;
|
|
31
|
+
}
|
|
32
|
+
export interface GameDetails {
|
|
33
|
+
gameSessionUuid: string;
|
|
34
|
+
name?: string | null;
|
|
35
|
+
players: RoomPlayer[];
|
|
36
|
+
matchId?: number | null;
|
|
37
|
+
createdDate?: string;
|
|
38
|
+
gameStatus: GameStatus;
|
|
39
|
+
gameType: GameType;
|
|
40
|
+
winnerSent?: boolean;
|
|
41
|
+
[field: string]: unknown;
|
|
42
|
+
}
|
|
43
|
+
export interface StatusResponse {
|
|
44
|
+
status: boolean;
|
|
45
|
+
message?: string;
|
|
46
|
+
errorCode?: string;
|
|
47
|
+
}
|
|
48
|
+
export interface GameDetailsResponse extends StatusResponse {
|
|
49
|
+
gameDetails: GameDetails;
|
|
50
|
+
}
|
|
51
|
+
export interface BalanceResponse {
|
|
52
|
+
success: boolean;
|
|
53
|
+
balance?: number;
|
|
54
|
+
message?: string;
|
|
55
|
+
error?: string;
|
|
56
|
+
}
|
|
57
|
+
export interface HealthResponse {
|
|
58
|
+
status: boolean;
|
|
59
|
+
game?: string;
|
|
60
|
+
time?: number;
|
|
61
|
+
}
|
|
62
|
+
export interface Joined {
|
|
63
|
+
playerNumber?: number;
|
|
64
|
+
role?: Role;
|
|
65
|
+
}
|
|
66
|
+
export interface SpectatorJoined {
|
|
67
|
+
role?: Role;
|
|
68
|
+
gameType?: GameType;
|
|
69
|
+
gameSessionUuid?: string;
|
|
70
|
+
message?: string;
|
|
71
|
+
room?: unknown;
|
|
72
|
+
}
|
|
73
|
+
export interface GameOver {
|
|
74
|
+
winner?: number | null;
|
|
75
|
+
isDraw?: boolean;
|
|
76
|
+
/** e.g. 'timeout', 'opponent_timeout', 'both_dropped', 'Game has already ended' */
|
|
77
|
+
reason?: string;
|
|
78
|
+
gameStatus?: GameStatus;
|
|
79
|
+
/** Set when rejoining a game that already finished. */
|
|
80
|
+
callPostMessage?: boolean;
|
|
81
|
+
/** Game-only fields, e.g. connect4's winningCoords. */
|
|
82
|
+
[field: string]: unknown;
|
|
83
|
+
}
|
|
84
|
+
export interface ReconnectionTimer {
|
|
85
|
+
playerUuid: string;
|
|
86
|
+
playerNumber: number;
|
|
87
|
+
secondsLeft: number;
|
|
88
|
+
}
|
|
89
|
+
export interface AutoMove {
|
|
90
|
+
playerName: string;
|
|
91
|
+
playerNumber?: number;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,iDAAiD"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gameon-sdk",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "One SDK for every GameOn game: GameClient (game frontends) and GameOnPlatform (game servers). Contracts: specs/gameon.yaml, specs/platform.yaml",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -9,26 +9,53 @@
|
|
|
9
9
|
".": {
|
|
10
10
|
"types": "./dist/index.d.ts",
|
|
11
11
|
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./server": {
|
|
14
|
+
"types": "./dist/server.d.ts",
|
|
15
|
+
"import": "./dist/server.js",
|
|
16
|
+
"require": "./dist/server.cjs"
|
|
12
17
|
}
|
|
13
18
|
},
|
|
14
19
|
"files": [
|
|
15
20
|
"dist"
|
|
16
21
|
],
|
|
17
22
|
"scripts": {
|
|
18
|
-
"
|
|
19
|
-
"build": "rm -rf dist && tsc -p tsconfig.json",
|
|
20
|
-
"sdk": "npm run generate && npm run build",
|
|
23
|
+
"build": "rm -rf dist && tsc -p tsconfig.json && esbuild src/server.ts --bundle --platform=node --format=cjs --target=node18 --outfile=dist/server.cjs",
|
|
21
24
|
"test": "tsx tests/test-all.ts",
|
|
22
25
|
"prepublishOnly": "npm run build"
|
|
23
26
|
},
|
|
24
|
-
"keywords": [
|
|
27
|
+
"keywords": [
|
|
28
|
+
"gameon",
|
|
29
|
+
"sdk",
|
|
30
|
+
"roulette",
|
|
31
|
+
"connect4",
|
|
32
|
+
"typescript",
|
|
33
|
+
"api-client"
|
|
34
|
+
],
|
|
35
|
+
"author": "Gameonworld.ai",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/Gameonworld-ai/game-idk.git"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/Gameonworld-ai/game-idk#readme",
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/Gameonworld-ai/game-idk/issues"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=18"
|
|
47
|
+
},
|
|
48
|
+
"directories": {
|
|
49
|
+
"test": "tests"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"socket.io-client": "^4.8.4"
|
|
53
|
+
},
|
|
25
54
|
"devDependencies": {
|
|
26
|
-
"@
|
|
55
|
+
"@types/node": "^22.20.5",
|
|
56
|
+
"esbuild": "^0.28.2",
|
|
27
57
|
"ts-node": "^10.9.2",
|
|
28
58
|
"tsx": "^4.23.15",
|
|
29
59
|
"typescript": "^7.0.2"
|
|
30
|
-
},
|
|
31
|
-
"directories": {
|
|
32
|
-
"test": "tests"
|
|
33
60
|
}
|
|
34
61
|
}
|