@playdotfun/server-sdk 1.0.0

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.
@@ -0,0 +1,354 @@
1
+ // Generated by dts-bundle-generator v9.5.1
2
+
3
+ export type GamesSortField = "totalRewardsAllocatedUsd" | "name" | "createdAt" | "estimatedDailyRewardsUsd" | "totalRewardsPoolValueUsd";
4
+ export type GamesSortDirection = "asc" | "desc";
5
+ export interface GetGamesOpts {
6
+ limit?: number;
7
+ cursor?: string;
8
+ query?: string;
9
+ sortBy?: GamesSortField;
10
+ sortDirection?: GamesSortDirection;
11
+ includeExtra?: boolean;
12
+ }
13
+ export interface GetAuthedGamesOpts {
14
+ limit?: number;
15
+ cursor?: string;
16
+ sort: GamesSortDirection;
17
+ }
18
+ export interface GetGameByIdOpts {
19
+ gameId: string;
20
+ }
21
+ export interface GetGameByTokenIdOpts {
22
+ tokenId: string;
23
+ }
24
+ declare enum GAME_PLATFORM {
25
+ WEB = "web",
26
+ IOS = "ios",
27
+ ANDROID = "android",
28
+ STEAM = "steam",
29
+ ITCH = "itch",
30
+ EPIC = "epic"
31
+ }
32
+ declare enum APPROVAL_STATUS {
33
+ PENDING = "pending",
34
+ PENDING_UPDATE = "pending_update",
35
+ APPROVED = "approved",
36
+ REJECTED = "rejected"
37
+ }
38
+ declare enum TOKEN_GRADUATION_STATUS {
39
+ GRADUATED = "graduated",
40
+ UNDERGRAD = "undergrad"
41
+ }
42
+ declare enum TOKEN_TYPE {
43
+ G_TOKEN = "g_token",
44
+ BASE_TOKEN = "base_token"
45
+ }
46
+ declare class RegisterGameDto {
47
+ name: string;
48
+ gameCoinSymbol?: string | null;
49
+ description: string;
50
+ gameUrl: string;
51
+ isHtmlGame?: boolean;
52
+ iframable?: boolean;
53
+ twitter?: string;
54
+ discord?: string;
55
+ telegram?: string;
56
+ platform: GAME_PLATFORM;
57
+ maxScorePerSession?: number | null;
58
+ maxSessionsPerDay?: number | null;
59
+ maxCumulativePointsPerDay?: number | null;
60
+ base64Image?: string;
61
+ base64CoverImage?: string;
62
+ tokens?: string[];
63
+ launchGameCoin?: boolean;
64
+ airdropConfig?: {
65
+ tokenAddress: string;
66
+ allocationBps: number;
67
+ };
68
+ tokenSplits?: {
69
+ [key: string]: number;
70
+ };
71
+ }
72
+ declare class UpdateGameDto {
73
+ name?: string;
74
+ gameCoinSymbol?: string;
75
+ description?: string;
76
+ gameUrl?: string;
77
+ isHtmlGame?: boolean;
78
+ iframable?: boolean;
79
+ twitter?: string;
80
+ discord?: string;
81
+ telegram?: string;
82
+ platform: GAME_PLATFORM;
83
+ maxScorePerSession?: number | null;
84
+ maxSessionsPerDay?: number | null;
85
+ maxCumulativePointsPerDay?: number | null;
86
+ base64Image?: string;
87
+ base64CoverImage?: string;
88
+ removeCoverImage?: boolean;
89
+ orgRewardsSplit?: {
90
+ [key: string]: number;
91
+ };
92
+ tokens?: string[];
93
+ tokenSplits?: {
94
+ [key: string]: number;
95
+ };
96
+ airdropConfig?: {
97
+ tokenAddress: string;
98
+ allocationBps: number;
99
+ };
100
+ }
101
+ declare class UserSecret {
102
+ id: string;
103
+ secret: string;
104
+ user: User;
105
+ userId: string;
106
+ createdAt: Date;
107
+ updatedAt: Date;
108
+ }
109
+ export declare class User {
110
+ id: string;
111
+ privyId: string;
112
+ email: string | null;
113
+ twitterHandle: string | null;
114
+ twitterProfilePicture: string | null;
115
+ embeddedSolanaWallet: string;
116
+ linkedSolanaWallets: string[];
117
+ secret?: UserSecret;
118
+ isAdmin: boolean;
119
+ games: Game[];
120
+ isPublisher: boolean;
121
+ publisherTakeRateBps: number;
122
+ createdAt: Date;
123
+ updatedAt: Date;
124
+ }
125
+ declare enum INTERACTION_TYPE {
126
+ LIKE = "like",
127
+ SHARE = "share",
128
+ COMMENT = "comment"
129
+ }
130
+ declare class GameInteraction {
131
+ id: string;
132
+ interactionType: INTERACTION_TYPE;
133
+ tokenMint: string | null;
134
+ user: User | null;
135
+ userId: string | null;
136
+ game: Game;
137
+ gameId: string;
138
+ createdAt: Date;
139
+ updatedAt: Date;
140
+ }
141
+ export declare class Game {
142
+ id: string;
143
+ name: string;
144
+ description: string;
145
+ gameUrl: string;
146
+ gameKey: string;
147
+ imageUrl: string;
148
+ coverImage: string | null;
149
+ gameCoinImageUrl: string | null;
150
+ gameCoinSymbol: string | null;
151
+ hasRewards: boolean;
152
+ isHtmlGame: boolean;
153
+ hasSdk: boolean;
154
+ /**
155
+ * True if the game only uses server-side validation (devBatchSavePoints endpoint).
156
+ * Set to false if the game uses client SDK (commit endpoint).
157
+ * Helps identify games with proper server-side score validation.
158
+ */
159
+ serverSideValidation: boolean;
160
+ iframable: boolean;
161
+ hidden: boolean;
162
+ adminHidden: boolean;
163
+ twitter: string | null;
164
+ discord: string | null;
165
+ telegram: string | null;
166
+ domain: string;
167
+ platform: GAME_PLATFORM;
168
+ jwksUrl: string | null;
169
+ maxScorePerSession: number | null;
170
+ maxSessionsPerDay: number | null;
171
+ maxCumulativePointsPerDay: number | null;
172
+ airdropConfig: {
173
+ tokenAddress: string;
174
+ allocationBps: number;
175
+ } | null;
176
+ orgRewardsSplit: {
177
+ [key: string]: number;
178
+ } | null;
179
+ approvalStatus: APPROVAL_STATUS;
180
+ creator: User | null;
181
+ creatorId: string | null;
182
+ owner: User | null;
183
+ ownerId: string | null;
184
+ ownershipValidated: boolean;
185
+ totalRewardsAllocatedUsd: number;
186
+ totalRewardsPoolValueUsd: number;
187
+ estimatedDailyRewardsUsd: number;
188
+ interactions: GameInteraction[];
189
+ likeCount: number;
190
+ gameCoin: Token | null;
191
+ tokenSplits: {
192
+ [tokenMint: string]: number;
193
+ };
194
+ /**
195
+ * Player pool atomic amount in gToken.
196
+ * Updated after each rewards run with the gToken player leftover.
197
+ * Multiplier purchases (also in gToken) increment this value directly.
198
+ * Other token rewards come from swapping gToken during rewards preparation.
199
+ */
200
+ playerPoolAtomic: string;
201
+ /**
202
+ * History of game coin mints.
203
+ */
204
+ gameCoinHistory: string[] | null;
205
+ externalLaunchAvailableAt?: Date | null;
206
+ createdAt: Date;
207
+ updatedAt: Date;
208
+ }
209
+ export declare class Token {
210
+ mint: string;
211
+ decimals: number;
212
+ symbol: string | null;
213
+ graduationStatus: TOKEN_GRADUATION_STATUS | null;
214
+ graduationDate: Date | null;
215
+ tokenType: TOKEN_TYPE;
216
+ name: string | null;
217
+ image: string | null;
218
+ network: string | null;
219
+ usdPrice: number | null;
220
+ marketCap: number | null;
221
+ volume24h: number | null;
222
+ change24h: number | null;
223
+ holders: number | null;
224
+ gtokenVersion: number | null;
225
+ quoteTokenAddress: string | null;
226
+ migrationFeeKey: string | null;
227
+ authConfigPublicKey: string | null;
228
+ distributorId: string | null;
229
+ firstClaimCompleted: boolean | null;
230
+ hidden: boolean;
231
+ gameId: string | null;
232
+ game: Game | null;
233
+ /**
234
+ * Number of days over which the token will be emitted. This is used to calculate the daily emission rate for g_tokens.
235
+ */
236
+ emissionDays: number | null;
237
+ createdAt: Date;
238
+ updatedAt: Date;
239
+ }
240
+ export interface SavePointsOpts {
241
+ gameId: string;
242
+ playerId: string;
243
+ points: number;
244
+ }
245
+ export interface OpenGameClientOpts {
246
+ apiKey?: string;
247
+ secretKey?: string;
248
+ baseUrl?: string;
249
+ }
250
+ export declare class OpenGameClient {
251
+ private apiKey;
252
+ private secretKey;
253
+ private baseUrl;
254
+ constructor(opts: OpenGameClientOpts);
255
+ games: {
256
+ get: ({ ...args }: GetGamesOpts) => Promise<{
257
+ items: Game[];
258
+ nextCursor?: string;
259
+ hasMore: boolean;
260
+ total: number;
261
+ }>;
262
+ getById: ({ gameId }: GetGameByIdOpts) => Promise<Game | null>;
263
+ getManyByIds: ({ gameIds }: {
264
+ gameIds: string[];
265
+ }) => Promise<Game[] | null>;
266
+ register: ({ ...game }: RegisterGameDto & {
267
+ image?: File;
268
+ coverImage?: File;
269
+ }) => Promise<Game | null>;
270
+ update: ({ gameId, ...data }: UpdateGameDto & {
271
+ gameId: string;
272
+ }) => Promise<Game | null>;
273
+ claimOwnership: ({ gameId }: {
274
+ gameId: string;
275
+ }) => Promise<void>;
276
+ getAuthedGames: ({ ...args }: GetAuthedGamesOpts) => Promise<{
277
+ items: Game[];
278
+ nextCursor?: string;
279
+ hasMore: boolean;
280
+ total: number;
281
+ }>;
282
+ getByTokenId: ({ tokenId }: GetGameByTokenIdOpts) => Promise<Game | null>;
283
+ getByBatchTokenIds: ({ tokenIds }: {
284
+ tokenIds: string[];
285
+ }) => Promise<Record<string, Game[]> | null>;
286
+ };
287
+ play: {
288
+ savePoints: ({ gameId, playerId, points }: SavePointsOpts) => Promise<{
289
+ savedCount: number;
290
+ playerIdToOgpId: {
291
+ [key: string]: string;
292
+ };
293
+ message?: string;
294
+ } | null>;
295
+ batchSavePoints: ({ gameId, pointsRecord, }: {
296
+ gameId: string;
297
+ pointsRecord: {
298
+ [x: string]: number;
299
+ } | {
300
+ [x: string]: number;
301
+ }[];
302
+ }) => Promise<{
303
+ savedCount: number;
304
+ playerIdToOgpId: {
305
+ [key: string]: string;
306
+ };
307
+ message?: string;
308
+ } | null>;
309
+ getPoints: ({ gameId, playerId }: {
310
+ gameId: string;
311
+ playerId: string;
312
+ }) => Promise<{
313
+ points: {
314
+ playerId: string;
315
+ points: string;
316
+ }[];
317
+ } | null>;
318
+ getLeaderboard: ({ gameId }: {
319
+ gameId: string;
320
+ }) => Promise<{
321
+ [x: string]: number;
322
+ }[] | null>;
323
+ };
324
+ users: {
325
+ me: () => Promise<User | null>;
326
+ getById: ({ userId }: {
327
+ userId: string;
328
+ }) => Promise<User | null>;
329
+ };
330
+ paginatedFetch<T>(endpoint: string, paginatedOpts: {
331
+ [key: string]: string | number | boolean | undefined;
332
+ limit?: number;
333
+ cursor?: string;
334
+ }, options?: RequestInit & {
335
+ authed?: true;
336
+ }): Promise<{
337
+ items: T[];
338
+ nextCursor?: string;
339
+ hasMore: boolean;
340
+ total: number;
341
+ }>;
342
+ fetch<T>(endpoint: string, options?: RequestInit & {
343
+ authed?: boolean;
344
+ }): Promise<T | null>;
345
+ private _generateHMACSignature;
346
+ }
347
+
348
+ export {
349
+ OpenGameClient as ApiClient,
350
+ RegisterGameDto as RegisterGameOpts,
351
+ UpdateGameDto as UpdateGameOpts,
352
+ };
353
+
354
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,344 @@
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 __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/index.ts
22
+ var index_exports = {};
23
+ __export(index_exports, {
24
+ OpenGameClient: () => OpenGameClient
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+
28
+ // src/utils.ts
29
+ var ISO_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z?$/;
30
+ function isISODateString(value) {
31
+ return typeof value === "string" && ISO_DATE_PATTERN.test(value);
32
+ }
33
+ __name(isISODateString, "isISODateString");
34
+ function transformDates(obj) {
35
+ if (obj === null || obj === void 0) {
36
+ return obj;
37
+ }
38
+ if (isISODateString(obj)) {
39
+ return new Date(obj);
40
+ }
41
+ if (Array.isArray(obj)) {
42
+ return obj.map((item) => transformDates(item));
43
+ }
44
+ if (typeof obj === "object") {
45
+ const transformed = {};
46
+ for (const key in obj) {
47
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
48
+ transformed[key] = transformDates(obj[key]);
49
+ }
50
+ }
51
+ return transformed;
52
+ }
53
+ return obj;
54
+ }
55
+ __name(transformDates, "transformDates");
56
+
57
+ // src/http/games.ts
58
+ var games_default = /* @__PURE__ */ __name(((apiClient) => {
59
+ async function get({ ...args }) {
60
+ return await apiClient.paginatedFetch("/games", args, {
61
+ authed: true
62
+ });
63
+ }
64
+ __name(get, "get");
65
+ async function getById({ gameId }) {
66
+ return await apiClient.fetch(`/games/${gameId}`, {
67
+ authed: true
68
+ });
69
+ }
70
+ __name(getById, "getById");
71
+ async function getManyByIds({ gameIds }) {
72
+ return await apiClient.fetch(`/games/batch/ids`, {
73
+ method: "POST",
74
+ body: JSON.stringify({
75
+ gameIds
76
+ }),
77
+ authed: true
78
+ });
79
+ }
80
+ __name(getManyByIds, "getManyByIds");
81
+ async function register({ ...game }) {
82
+ const formData = new FormData();
83
+ if (game.image) {
84
+ formData.append("image", game.image);
85
+ }
86
+ if (game.coverImage) {
87
+ formData.append("coverImage", game.coverImage);
88
+ }
89
+ for (const [key, value] of Object.entries(game)) {
90
+ if (value !== void 0) {
91
+ formData.append(key, value?.toString() ?? "null");
92
+ }
93
+ }
94
+ return await apiClient.fetch(`/games`, {
95
+ method: "POST",
96
+ body: formData,
97
+ authed: true
98
+ });
99
+ }
100
+ __name(register, "register");
101
+ async function update({ gameId, ...data }) {
102
+ return await apiClient.fetch(`/games/${gameId}`, {
103
+ method: "POST",
104
+ body: JSON.stringify(data),
105
+ authed: true
106
+ });
107
+ }
108
+ __name(update, "update");
109
+ async function claimOwnership({ gameId }) {
110
+ throw new Error("Not implemented");
111
+ }
112
+ __name(claimOwnership, "claimOwnership");
113
+ async function getAuthedGames({ ...args }) {
114
+ return await apiClient.paginatedFetch("/games", args, {
115
+ authed: true
116
+ });
117
+ }
118
+ __name(getAuthedGames, "getAuthedGames");
119
+ async function getByTokenId({ tokenId }) {
120
+ return await apiClient.fetch(`/games/by-token-id/${tokenId}`, {
121
+ authed: true
122
+ });
123
+ }
124
+ __name(getByTokenId, "getByTokenId");
125
+ async function getByBatchTokenIds({ tokenIds }) {
126
+ return await apiClient.fetch(`/games/batch/token-ids`, {
127
+ method: "POST",
128
+ body: JSON.stringify({
129
+ tokenIds
130
+ }),
131
+ authed: true
132
+ });
133
+ }
134
+ __name(getByBatchTokenIds, "getByBatchTokenIds");
135
+ return {
136
+ get,
137
+ getById,
138
+ getManyByIds,
139
+ register,
140
+ update,
141
+ claimOwnership,
142
+ getAuthedGames,
143
+ getByTokenId,
144
+ getByBatchTokenIds
145
+ };
146
+ }), "default");
147
+
148
+ // src/http/play.ts
149
+ var play_default = /* @__PURE__ */ __name(((apiClient) => {
150
+ async function savePoints({ gameId, playerId, points }) {
151
+ return await apiClient.fetch(`/play/dev/batch-save-points`, {
152
+ method: "POST",
153
+ body: JSON.stringify({
154
+ gameApiKey: gameId,
155
+ points: [
156
+ {
157
+ playerId,
158
+ points
159
+ }
160
+ ]
161
+ }),
162
+ authed: true
163
+ });
164
+ }
165
+ __name(savePoints, "savePoints");
166
+ async function batchSavePoints({ gameId, pointsRecord }) {
167
+ return await apiClient.fetch(`/play/dev/batch-save-points`, {
168
+ method: "POST",
169
+ body: JSON.stringify({
170
+ gameApiKey: gameId,
171
+ points: Array.isArray(pointsRecord) ? pointsRecord : Object.entries(pointsRecord).map(([playerId, points]) => ({
172
+ playerId,
173
+ points
174
+ }))
175
+ }),
176
+ authed: true
177
+ });
178
+ }
179
+ __name(batchSavePoints, "batchSavePoints");
180
+ async function getPoints({ gameId, playerId }) {
181
+ return await apiClient.fetch(`/play/dev/points/${gameId}/${playerId}`, {
182
+ authed: true
183
+ });
184
+ }
185
+ __name(getPoints, "getPoints");
186
+ async function getLeaderboard({ gameId }) {
187
+ return await apiClient.fetch(`/play/dev/leaderboard/${gameId}`, {
188
+ authed: true
189
+ });
190
+ }
191
+ __name(getLeaderboard, "getLeaderboard");
192
+ return {
193
+ savePoints,
194
+ batchSavePoints,
195
+ getPoints,
196
+ getLeaderboard
197
+ };
198
+ }), "default");
199
+
200
+ // src/http/user.ts
201
+ var user_default = /* @__PURE__ */ __name(((apiClient) => {
202
+ async function me() {
203
+ return await apiClient.fetch(`/user/me`, {
204
+ authed: true
205
+ });
206
+ }
207
+ __name(me, "me");
208
+ async function getById({ userId }) {
209
+ return await apiClient.fetch(`/user/${userId}`, {
210
+ authed: true
211
+ });
212
+ }
213
+ __name(getById, "getById");
214
+ return {
215
+ me,
216
+ getById
217
+ };
218
+ }), "default");
219
+
220
+ // src/http/client.ts
221
+ var OpenGameClient = class {
222
+ static {
223
+ __name(this, "OpenGameClient");
224
+ }
225
+ apiKey;
226
+ secretKey;
227
+ baseUrl;
228
+ constructor(opts) {
229
+ const { apiKey = process.env.OGP_API_KEY, secretKey = process.env.OGP_API_SECRET_KEY, baseUrl = "https://api.play.fun" } = opts;
230
+ if (!apiKey) {
231
+ throw new Error("OGP_API_KEY is not set in environment. Please set it, or pass `apiKey` to the SDK options.");
232
+ }
233
+ if (!secretKey) {
234
+ throw new Error("OGP_API_SECRET_KEY is not set in environment. Please set it, or pass `secretKey` to the SDK options.");
235
+ }
236
+ this.apiKey = apiKey;
237
+ this.secretKey = secretKey;
238
+ this.baseUrl = baseUrl;
239
+ }
240
+ games = games_default(this);
241
+ play = play_default(this);
242
+ users = user_default(this);
243
+ async paginatedFetch(endpoint, paginatedOpts, options) {
244
+ if (options?.method !== "GET") {
245
+ throw new Error("Only GET requests are supported for paginated fetches");
246
+ }
247
+ const { limit = 100, cursor } = paginatedOpts;
248
+ const params = new URLSearchParams({
249
+ limit: limit.toString()
250
+ });
251
+ if (cursor) {
252
+ params.append("cursor", cursor);
253
+ }
254
+ for (const [key, value] of Object.entries(paginatedOpts)) {
255
+ if (value !== void 0) {
256
+ params.append(key, value.toString());
257
+ }
258
+ }
259
+ let token = null;
260
+ if (options?.authed) {
261
+ token = await this._generateHMACSignature(options?.method || "GET", endpoint);
262
+ }
263
+ const isFormData = options?.body instanceof FormData;
264
+ const headers = {
265
+ ...!isFormData && {
266
+ "Content-Type": "application/json"
267
+ },
268
+ ...options?.authed && {
269
+ Authorization: token ?? ""
270
+ },
271
+ ...options?.headers
272
+ };
273
+ const response = await fetch(`${this.baseUrl}${endpoint}?${params.toString()}`, {
274
+ ...options,
275
+ headers
276
+ });
277
+ if (!response.ok) {
278
+ const errorText = await response.text();
279
+ const error = new Error(errorText || "API Reuqest failed with status " + response.status);
280
+ error.status = response.status;
281
+ error.response = {
282
+ status: response.status
283
+ };
284
+ throw error;
285
+ }
286
+ const data = await response.json();
287
+ return data;
288
+ }
289
+ async fetch(endpoint, options) {
290
+ let token = null;
291
+ if (options?.authed) {
292
+ token = await this._generateHMACSignature(options?.method || "GET", endpoint);
293
+ }
294
+ const isFormData = options?.body instanceof FormData;
295
+ const headers = {
296
+ ...!isFormData && {
297
+ "Content-Type": "application/json"
298
+ },
299
+ ...options?.authed && {
300
+ Authorization: token ?? ""
301
+ },
302
+ ...options?.headers
303
+ };
304
+ const response = await fetch(`${this.baseUrl}${endpoint}`, {
305
+ ...options,
306
+ headers
307
+ });
308
+ if (!response.ok) {
309
+ const errorText = await response.text();
310
+ const error = new Error(errorText || "API Reuqest failed with status " + response.status);
311
+ error.status = response.status;
312
+ error.response = {
313
+ status: response.status
314
+ };
315
+ throw error;
316
+ }
317
+ const data = await response.json();
318
+ return transformDates(data);
319
+ }
320
+ async _generateHMACSignature(method, path) {
321
+ const response = await fetch(`${this.baseUrl}/user/hmac-signature`, {
322
+ method: "POST",
323
+ headers: {
324
+ "Content-Type": "application/json"
325
+ },
326
+ body: JSON.stringify({
327
+ method,
328
+ path,
329
+ apiKey: this.apiKey,
330
+ secretKey: this.secretKey
331
+ })
332
+ });
333
+ if (!response.ok) {
334
+ throw new Error(`Failed to generate HMAC signature for endpoint ${path} with status ${response.status}`);
335
+ }
336
+ const data = await response.json();
337
+ return data.data.signature;
338
+ }
339
+ };
340
+ // Annotate the CommonJS export names for ESM import in node:
341
+ 0 && (module.exports = {
342
+ OpenGameClient
343
+ });
344
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/http/games.ts","../src/http/play.ts","../src/http/user.ts","../src/http/client.ts"],"sourcesContent":["import OpenGameClient from './http/client';\n\nexport { OpenGameClient };\n\nexport type { default as ApiClient } from './http/client';\n\nexport type {\n GetGamesOpts,\n GetAuthedGamesOpts,\n GetGameByIdOpts,\n GetGameByTokenIdOpts,\n} from './http/games';\n\nexport type { SavePointsOpts } from './http/play';\n\nexport type {\n User,\n Game,\n Token,\n RegisterGameDto as RegisterGameOpts,\n UpdateGameDto as UpdateGameOpts,\n} from '@play-fun/types/frontend';\n","const ISO_DATE_PATTERN = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z?$/;\n\nfunction isISODateString(value: unknown): value is string {\n return typeof value === 'string' && ISO_DATE_PATTERN.test(value);\n}\n\nexport function transformDates<T>(obj: T): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (isISODateString(obj)) {\n return new Date(obj) as T;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => transformDates(item)) as T;\n }\n\n if (typeof obj === 'object') {\n const transformed: Record<string, unknown> = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n transformed[key] = transformDates(obj[key]);\n }\n }\n return transformed as T;\n }\n return obj;\n}\n","import type OpenGameClient from './client';\nimport type { Game, RegisterGameOpts, UpdateGameOpts } from '@/index';\n\ntype GamesSortField =\n | 'totalRewardsAllocatedUsd'\n | 'name'\n | 'createdAt'\n | 'estimatedDailyRewardsUsd'\n | 'totalRewardsPoolValueUsd';\n\ntype GamesSortDirection = 'asc' | 'desc';\n\nexport interface GetGamesOpts {\n limit?: number;\n cursor?: string;\n query?: string;\n sortBy?: GamesSortField;\n sortDirection?: GamesSortDirection;\n includeExtra?: boolean;\n}\n\nexport interface GetAuthedGamesOpts {\n limit?: number;\n cursor?: string;\n sort: GamesSortDirection;\n}\n\nexport interface GetGameByIdOpts {\n gameId: string;\n}\n\nexport interface GetGameByTokenIdOpts {\n tokenId: string;\n}\n\nexport default (apiClient: OpenGameClient) => {\n async function get({ ...args }: GetGamesOpts) {\n return await apiClient.paginatedFetch<Game>('/games', args, {\n authed: true,\n });\n }\n\n async function getById({ gameId }: GetGameByIdOpts) {\n return await apiClient.fetch<Game>(`/games/${gameId}`, {\n authed: true,\n });\n }\n\n async function getManyByIds({ gameIds }: { gameIds: string[] }) {\n return await apiClient.fetch<Game[]>(`/games/batch/ids`, {\n method: 'POST',\n body: JSON.stringify({ gameIds }),\n authed: true,\n });\n }\n\n async function register({ ...game }: RegisterGameOpts & { image?: File; coverImage?: File }) {\n const formData = new FormData();\n if (game.image) {\n formData.append('image', game.image);\n }\n if (game.coverImage) {\n formData.append('coverImage', game.coverImage);\n }\n for (const [key, value] of Object.entries(game)) {\n if (value !== undefined) {\n formData.append(key, value?.toString() ?? 'null');\n }\n }\n return await apiClient.fetch<Game>(`/games`, {\n method: 'POST',\n body: formData,\n authed: true,\n });\n }\n\n async function update({ gameId, ...data }: UpdateGameOpts & { gameId: string }) {\n return await apiClient.fetch<Game>(`/games/${gameId}`, {\n method: 'POST',\n body: JSON.stringify(data),\n authed: true,\n });\n }\n\n async function claimOwnership({ gameId }: { gameId: string }) {\n throw new Error('Not implemented');\n }\n\n async function getAuthedGames({ ...args }: GetAuthedGamesOpts) {\n return await apiClient.paginatedFetch<Game>('/games', args, {\n authed: true,\n });\n }\n\n async function getByTokenId({ tokenId }: GetGameByTokenIdOpts) {\n return await apiClient.fetch<Game>(`/games/by-token-id/${tokenId}`, {\n authed: true,\n });\n }\n\n async function getByBatchTokenIds({ tokenIds }: { tokenIds: string[] }) {\n return await apiClient.fetch<Record<string, Game[]>>(`/games/batch/token-ids`, {\n method: 'POST',\n body: JSON.stringify({ tokenIds }),\n authed: true,\n });\n }\n\n return {\n get,\n getById,\n getManyByIds,\n register,\n update,\n claimOwnership,\n getAuthedGames,\n getByTokenId,\n getByBatchTokenIds,\n };\n};\n","import type OpenGameClient from './client';\n\nexport interface SavePointsOpts {\n gameId: string;\n playerId: string;\n points: number;\n}\n\ntype PointsRecord = Record<string, number>;\ntype PointsArray = PointsRecord[];\n\ntype BatchPointsRecord = PointsRecord | PointsArray;\n\nexport default (apiClient: OpenGameClient) => {\n async function savePoints({ gameId, playerId, points }: SavePointsOpts) {\n return await apiClient.fetch<{\n savedCount: number;\n playerIdToOgpId: {\n [key: string]: string;\n };\n message?: string;\n }>(`/play/dev/batch-save-points`, {\n method: 'POST',\n body: JSON.stringify({ gameApiKey: gameId, points: [{ playerId, points }] }),\n authed: true,\n });\n }\n\n async function batchSavePoints({\n gameId,\n pointsRecord,\n }: {\n gameId: string;\n pointsRecord: BatchPointsRecord;\n }) {\n return await apiClient.fetch<{\n savedCount: number;\n playerIdToOgpId: {\n [key: string]: string;\n };\n message?: string;\n }>(`/play/dev/batch-save-points`, {\n method: 'POST',\n body: JSON.stringify({\n gameApiKey: gameId,\n points: Array.isArray(pointsRecord)\n ? pointsRecord\n : Object.entries(pointsRecord).map(([playerId, points]) => ({ playerId, points })),\n }),\n authed: true,\n });\n }\n\n async function getPoints({ gameId, playerId }: { gameId: string; playerId: string }) {\n return await apiClient.fetch<{ points: { playerId: string; points: string }[] }>(\n `/play/dev/points/${gameId}/${playerId}`,\n {\n authed: true,\n },\n );\n }\n\n async function getLeaderboard({ gameId }: { gameId: string }) {\n return await apiClient.fetch<PointsArray>(`/play/dev/leaderboard/${gameId}`, {\n authed: true,\n });\n }\n\n return {\n savePoints,\n batchSavePoints,\n getPoints,\n getLeaderboard,\n };\n};\n","import { User } from '@/index';\nimport OpenGameClient from './client';\n\nexport default (apiClient: OpenGameClient) => {\n async function me() {\n return await apiClient.fetch<User>(`/user/me`, {\n authed: true,\n });\n }\n\n async function getById({ userId }: { userId: string }) {\n return await apiClient.fetch<User>(`/user/${userId}`, {\n authed: true,\n });\n }\n\n return {\n me,\n getById,\n };\n};\n","import { transformDates } from '@/utils';\nimport games from './games';\nimport play from './play';\nimport user from './user';\n\ninterface OpenGameClientOpts {\n apiKey?: string;\n secretKey?: string;\n baseUrl?: string;\n}\n\nexport default class OpenGameClient {\n private apiKey: string;\n private secretKey: string;\n private baseUrl: string;\n\n constructor(opts: OpenGameClientOpts) {\n const {\n apiKey = process.env.OGP_API_KEY,\n secretKey = process.env.OGP_API_SECRET_KEY,\n baseUrl = 'https://api.play.fun',\n } = opts;\n if (!apiKey) {\n throw new Error(\n 'OGP_API_KEY is not set in environment. Please set it, or pass `apiKey` to the SDK options.',\n );\n }\n if (!secretKey) {\n throw new Error(\n 'OGP_API_SECRET_KEY is not set in environment. Please set it, or pass `secretKey` to the SDK options.',\n );\n }\n this.apiKey = apiKey;\n this.secretKey = secretKey;\n this.baseUrl = baseUrl;\n }\n\n public games = games(this);\n public play = play(this);\n public users = user(this);\n\n async paginatedFetch<T>(\n endpoint: string,\n paginatedOpts: {\n [key: string]: string | number | boolean | undefined;\n limit?: number;\n cursor?: string;\n },\n options?: RequestInit & { authed?: true },\n ): Promise<{\n items: T[];\n nextCursor?: string;\n hasMore: boolean;\n total: number;\n }> {\n if (options?.method !== 'GET') {\n throw new Error('Only GET requests are supported for paginated fetches');\n }\n\n const { limit = 100, cursor } = paginatedOpts;\n\n const params = new URLSearchParams({\n limit: limit.toString(),\n });\n\n if (cursor) {\n params.append('cursor', cursor);\n }\n\n for (const [key, value] of Object.entries(paginatedOpts)) {\n if (value !== undefined) {\n params.append(key, value.toString());\n }\n }\n\n let token: string | null = null;\n\n if (options?.authed) {\n token = await this._generateHMACSignature(\n (options?.method as 'GET' | 'POST') || 'GET',\n endpoint,\n );\n }\n\n const isFormData = options?.body instanceof FormData;\n\n const headers = {\n ...(!isFormData && { 'Content-Type': 'application/json' }),\n ...(options?.authed && { Authorization: token ?? '' }),\n ...options?.headers,\n };\n\n const response = await fetch(`${this.baseUrl}${endpoint}?${params.toString()}`, {\n ...options,\n headers,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n const error = new Error(\n errorText || 'API Reuqest failed with status ' + response.status,\n ) as Error & { status?: number; response?: { status: number } };\n error.status = response.status;\n error.response = { status: response.status };\n throw error;\n }\n\n const data = (await response.json()) as {\n items: T[];\n nextCursor?: string;\n hasMore: boolean;\n total: number;\n };\n\n return data;\n }\n\n async fetch<T>(\n endpoint: string,\n options?: RequestInit & { authed?: boolean },\n ): Promise<T | null> {\n let token: string | null = null;\n\n if (options?.authed) {\n token = await this._generateHMACSignature(\n (options?.method as 'GET' | 'POST') || 'GET',\n endpoint,\n );\n }\n\n const isFormData = options?.body instanceof FormData;\n\n const headers = {\n ...(!isFormData && { 'Content-Type': 'application/json' }),\n ...(options?.authed && { Authorization: token ?? '' }),\n ...options?.headers,\n };\n\n const response = await fetch(`${this.baseUrl}${endpoint}`, {\n ...options,\n headers,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n const error = new Error(\n errorText || 'API Reuqest failed with status ' + response.status,\n ) as Error & { status?: number; response?: { status: number } };\n error.status = response.status;\n error.response = { status: response.status };\n throw error;\n }\n\n const data = await response.json();\n return transformDates(data) as T;\n }\n\n private async _generateHMACSignature(method: 'GET' | 'POST', path: string) {\n const response = await fetch(`${this.baseUrl}/user/hmac-signature`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n method,\n path,\n apiKey: this.apiKey,\n secretKey: this.secretKey,\n }),\n });\n\n if (!response.ok) {\n throw new Error(\n `Failed to generate HMAC signature for endpoint ${path} with status ${response.status}`,\n );\n }\n\n const data = (await response.json()) as { data: { signature: string } };\n return data.data.signature;\n }\n}\n"],"mappings":"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","names":["ISO_DATE_PATTERN","isISODateString","value","test","transformDates","obj","undefined","Date","Array","isArray","map","item","transformed","key","Object","prototype","hasOwnProperty","call","apiClient","get","args","paginatedFetch","authed","getById","gameId","fetch","getManyByIds","gameIds","method","body","JSON","stringify","register","game","formData","FormData","image","append","coverImage","key","value","Object","entries","undefined","toString","update","data","claimOwnership","Error","getAuthedGames","getByTokenId","tokenId","getByBatchTokenIds","tokenIds","apiClient","savePoints","gameId","playerId","points","fetch","method","body","JSON","stringify","gameApiKey","authed","batchSavePoints","pointsRecord","Array","isArray","Object","entries","map","getPoints","getLeaderboard","apiClient","me","fetch","authed","getById","userId","OpenGameClient","apiKey","secretKey","baseUrl","opts","process","env","OGP_API_KEY","OGP_API_SECRET_KEY","Error","games","play","users","user","paginatedFetch","endpoint","paginatedOpts","options","method","limit","cursor","params","URLSearchParams","toString","append","key","value","Object","entries","undefined","token","authed","_generateHMACSignature","isFormData","body","FormData","headers","Authorization","response","fetch","ok","errorText","text","error","status","data","json","transformDates","path","JSON","stringify","signature"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,319 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ // src/utils.ts
5
+ var ISO_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z?$/;
6
+ function isISODateString(value) {
7
+ return typeof value === "string" && ISO_DATE_PATTERN.test(value);
8
+ }
9
+ __name(isISODateString, "isISODateString");
10
+ function transformDates(obj) {
11
+ if (obj === null || obj === void 0) {
12
+ return obj;
13
+ }
14
+ if (isISODateString(obj)) {
15
+ return new Date(obj);
16
+ }
17
+ if (Array.isArray(obj)) {
18
+ return obj.map((item) => transformDates(item));
19
+ }
20
+ if (typeof obj === "object") {
21
+ const transformed = {};
22
+ for (const key in obj) {
23
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
24
+ transformed[key] = transformDates(obj[key]);
25
+ }
26
+ }
27
+ return transformed;
28
+ }
29
+ return obj;
30
+ }
31
+ __name(transformDates, "transformDates");
32
+
33
+ // src/http/games.ts
34
+ var games_default = /* @__PURE__ */ __name(((apiClient) => {
35
+ async function get({ ...args }) {
36
+ return await apiClient.paginatedFetch("/games", args, {
37
+ authed: true
38
+ });
39
+ }
40
+ __name(get, "get");
41
+ async function getById({ gameId }) {
42
+ return await apiClient.fetch(`/games/${gameId}`, {
43
+ authed: true
44
+ });
45
+ }
46
+ __name(getById, "getById");
47
+ async function getManyByIds({ gameIds }) {
48
+ return await apiClient.fetch(`/games/batch/ids`, {
49
+ method: "POST",
50
+ body: JSON.stringify({
51
+ gameIds
52
+ }),
53
+ authed: true
54
+ });
55
+ }
56
+ __name(getManyByIds, "getManyByIds");
57
+ async function register({ ...game }) {
58
+ const formData = new FormData();
59
+ if (game.image) {
60
+ formData.append("image", game.image);
61
+ }
62
+ if (game.coverImage) {
63
+ formData.append("coverImage", game.coverImage);
64
+ }
65
+ for (const [key, value] of Object.entries(game)) {
66
+ if (value !== void 0) {
67
+ formData.append(key, value?.toString() ?? "null");
68
+ }
69
+ }
70
+ return await apiClient.fetch(`/games`, {
71
+ method: "POST",
72
+ body: formData,
73
+ authed: true
74
+ });
75
+ }
76
+ __name(register, "register");
77
+ async function update({ gameId, ...data }) {
78
+ return await apiClient.fetch(`/games/${gameId}`, {
79
+ method: "POST",
80
+ body: JSON.stringify(data),
81
+ authed: true
82
+ });
83
+ }
84
+ __name(update, "update");
85
+ async function claimOwnership({ gameId }) {
86
+ throw new Error("Not implemented");
87
+ }
88
+ __name(claimOwnership, "claimOwnership");
89
+ async function getAuthedGames({ ...args }) {
90
+ return await apiClient.paginatedFetch("/games", args, {
91
+ authed: true
92
+ });
93
+ }
94
+ __name(getAuthedGames, "getAuthedGames");
95
+ async function getByTokenId({ tokenId }) {
96
+ return await apiClient.fetch(`/games/by-token-id/${tokenId}`, {
97
+ authed: true
98
+ });
99
+ }
100
+ __name(getByTokenId, "getByTokenId");
101
+ async function getByBatchTokenIds({ tokenIds }) {
102
+ return await apiClient.fetch(`/games/batch/token-ids`, {
103
+ method: "POST",
104
+ body: JSON.stringify({
105
+ tokenIds
106
+ }),
107
+ authed: true
108
+ });
109
+ }
110
+ __name(getByBatchTokenIds, "getByBatchTokenIds");
111
+ return {
112
+ get,
113
+ getById,
114
+ getManyByIds,
115
+ register,
116
+ update,
117
+ claimOwnership,
118
+ getAuthedGames,
119
+ getByTokenId,
120
+ getByBatchTokenIds
121
+ };
122
+ }), "default");
123
+
124
+ // src/http/play.ts
125
+ var play_default = /* @__PURE__ */ __name(((apiClient) => {
126
+ async function savePoints({ gameId, playerId, points }) {
127
+ return await apiClient.fetch(`/play/dev/batch-save-points`, {
128
+ method: "POST",
129
+ body: JSON.stringify({
130
+ gameApiKey: gameId,
131
+ points: [
132
+ {
133
+ playerId,
134
+ points
135
+ }
136
+ ]
137
+ }),
138
+ authed: true
139
+ });
140
+ }
141
+ __name(savePoints, "savePoints");
142
+ async function batchSavePoints({ gameId, pointsRecord }) {
143
+ return await apiClient.fetch(`/play/dev/batch-save-points`, {
144
+ method: "POST",
145
+ body: JSON.stringify({
146
+ gameApiKey: gameId,
147
+ points: Array.isArray(pointsRecord) ? pointsRecord : Object.entries(pointsRecord).map(([playerId, points]) => ({
148
+ playerId,
149
+ points
150
+ }))
151
+ }),
152
+ authed: true
153
+ });
154
+ }
155
+ __name(batchSavePoints, "batchSavePoints");
156
+ async function getPoints({ gameId, playerId }) {
157
+ return await apiClient.fetch(`/play/dev/points/${gameId}/${playerId}`, {
158
+ authed: true
159
+ });
160
+ }
161
+ __name(getPoints, "getPoints");
162
+ async function getLeaderboard({ gameId }) {
163
+ return await apiClient.fetch(`/play/dev/leaderboard/${gameId}`, {
164
+ authed: true
165
+ });
166
+ }
167
+ __name(getLeaderboard, "getLeaderboard");
168
+ return {
169
+ savePoints,
170
+ batchSavePoints,
171
+ getPoints,
172
+ getLeaderboard
173
+ };
174
+ }), "default");
175
+
176
+ // src/http/user.ts
177
+ var user_default = /* @__PURE__ */ __name(((apiClient) => {
178
+ async function me() {
179
+ return await apiClient.fetch(`/user/me`, {
180
+ authed: true
181
+ });
182
+ }
183
+ __name(me, "me");
184
+ async function getById({ userId }) {
185
+ return await apiClient.fetch(`/user/${userId}`, {
186
+ authed: true
187
+ });
188
+ }
189
+ __name(getById, "getById");
190
+ return {
191
+ me,
192
+ getById
193
+ };
194
+ }), "default");
195
+
196
+ // src/http/client.ts
197
+ var OpenGameClient = class {
198
+ static {
199
+ __name(this, "OpenGameClient");
200
+ }
201
+ apiKey;
202
+ secretKey;
203
+ baseUrl;
204
+ constructor(opts) {
205
+ const { apiKey = process.env.OGP_API_KEY, secretKey = process.env.OGP_API_SECRET_KEY, baseUrl = "https://api.play.fun" } = opts;
206
+ if (!apiKey) {
207
+ throw new Error("OGP_API_KEY is not set in environment. Please set it, or pass `apiKey` to the SDK options.");
208
+ }
209
+ if (!secretKey) {
210
+ throw new Error("OGP_API_SECRET_KEY is not set in environment. Please set it, or pass `secretKey` to the SDK options.");
211
+ }
212
+ this.apiKey = apiKey;
213
+ this.secretKey = secretKey;
214
+ this.baseUrl = baseUrl;
215
+ }
216
+ games = games_default(this);
217
+ play = play_default(this);
218
+ users = user_default(this);
219
+ async paginatedFetch(endpoint, paginatedOpts, options) {
220
+ if (options?.method !== "GET") {
221
+ throw new Error("Only GET requests are supported for paginated fetches");
222
+ }
223
+ const { limit = 100, cursor } = paginatedOpts;
224
+ const params = new URLSearchParams({
225
+ limit: limit.toString()
226
+ });
227
+ if (cursor) {
228
+ params.append("cursor", cursor);
229
+ }
230
+ for (const [key, value] of Object.entries(paginatedOpts)) {
231
+ if (value !== void 0) {
232
+ params.append(key, value.toString());
233
+ }
234
+ }
235
+ let token = null;
236
+ if (options?.authed) {
237
+ token = await this._generateHMACSignature(options?.method || "GET", endpoint);
238
+ }
239
+ const isFormData = options?.body instanceof FormData;
240
+ const headers = {
241
+ ...!isFormData && {
242
+ "Content-Type": "application/json"
243
+ },
244
+ ...options?.authed && {
245
+ Authorization: token ?? ""
246
+ },
247
+ ...options?.headers
248
+ };
249
+ const response = await fetch(`${this.baseUrl}${endpoint}?${params.toString()}`, {
250
+ ...options,
251
+ headers
252
+ });
253
+ if (!response.ok) {
254
+ const errorText = await response.text();
255
+ const error = new Error(errorText || "API Reuqest failed with status " + response.status);
256
+ error.status = response.status;
257
+ error.response = {
258
+ status: response.status
259
+ };
260
+ throw error;
261
+ }
262
+ const data = await response.json();
263
+ return data;
264
+ }
265
+ async fetch(endpoint, options) {
266
+ let token = null;
267
+ if (options?.authed) {
268
+ token = await this._generateHMACSignature(options?.method || "GET", endpoint);
269
+ }
270
+ const isFormData = options?.body instanceof FormData;
271
+ const headers = {
272
+ ...!isFormData && {
273
+ "Content-Type": "application/json"
274
+ },
275
+ ...options?.authed && {
276
+ Authorization: token ?? ""
277
+ },
278
+ ...options?.headers
279
+ };
280
+ const response = await fetch(`${this.baseUrl}${endpoint}`, {
281
+ ...options,
282
+ headers
283
+ });
284
+ if (!response.ok) {
285
+ const errorText = await response.text();
286
+ const error = new Error(errorText || "API Reuqest failed with status " + response.status);
287
+ error.status = response.status;
288
+ error.response = {
289
+ status: response.status
290
+ };
291
+ throw error;
292
+ }
293
+ const data = await response.json();
294
+ return transformDates(data);
295
+ }
296
+ async _generateHMACSignature(method, path) {
297
+ const response = await fetch(`${this.baseUrl}/user/hmac-signature`, {
298
+ method: "POST",
299
+ headers: {
300
+ "Content-Type": "application/json"
301
+ },
302
+ body: JSON.stringify({
303
+ method,
304
+ path,
305
+ apiKey: this.apiKey,
306
+ secretKey: this.secretKey
307
+ })
308
+ });
309
+ if (!response.ok) {
310
+ throw new Error(`Failed to generate HMAC signature for endpoint ${path} with status ${response.status}`);
311
+ }
312
+ const data = await response.json();
313
+ return data.data.signature;
314
+ }
315
+ };
316
+ export {
317
+ OpenGameClient
318
+ };
319
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils.ts","../src/http/games.ts","../src/http/play.ts","../src/http/user.ts","../src/http/client.ts"],"sourcesContent":["const ISO_DATE_PATTERN = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z?$/;\n\nfunction isISODateString(value: unknown): value is string {\n return typeof value === 'string' && ISO_DATE_PATTERN.test(value);\n}\n\nexport function transformDates<T>(obj: T): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (isISODateString(obj)) {\n return new Date(obj) as T;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => transformDates(item)) as T;\n }\n\n if (typeof obj === 'object') {\n const transformed: Record<string, unknown> = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n transformed[key] = transformDates(obj[key]);\n }\n }\n return transformed as T;\n }\n return obj;\n}\n","import type OpenGameClient from './client';\nimport type { Game, RegisterGameOpts, UpdateGameOpts } from '@/index';\n\ntype GamesSortField =\n | 'totalRewardsAllocatedUsd'\n | 'name'\n | 'createdAt'\n | 'estimatedDailyRewardsUsd'\n | 'totalRewardsPoolValueUsd';\n\ntype GamesSortDirection = 'asc' | 'desc';\n\nexport interface GetGamesOpts {\n limit?: number;\n cursor?: string;\n query?: string;\n sortBy?: GamesSortField;\n sortDirection?: GamesSortDirection;\n includeExtra?: boolean;\n}\n\nexport interface GetAuthedGamesOpts {\n limit?: number;\n cursor?: string;\n sort: GamesSortDirection;\n}\n\nexport interface GetGameByIdOpts {\n gameId: string;\n}\n\nexport interface GetGameByTokenIdOpts {\n tokenId: string;\n}\n\nexport default (apiClient: OpenGameClient) => {\n async function get({ ...args }: GetGamesOpts) {\n return await apiClient.paginatedFetch<Game>('/games', args, {\n authed: true,\n });\n }\n\n async function getById({ gameId }: GetGameByIdOpts) {\n return await apiClient.fetch<Game>(`/games/${gameId}`, {\n authed: true,\n });\n }\n\n async function getManyByIds({ gameIds }: { gameIds: string[] }) {\n return await apiClient.fetch<Game[]>(`/games/batch/ids`, {\n method: 'POST',\n body: JSON.stringify({ gameIds }),\n authed: true,\n });\n }\n\n async function register({ ...game }: RegisterGameOpts & { image?: File; coverImage?: File }) {\n const formData = new FormData();\n if (game.image) {\n formData.append('image', game.image);\n }\n if (game.coverImage) {\n formData.append('coverImage', game.coverImage);\n }\n for (const [key, value] of Object.entries(game)) {\n if (value !== undefined) {\n formData.append(key, value?.toString() ?? 'null');\n }\n }\n return await apiClient.fetch<Game>(`/games`, {\n method: 'POST',\n body: formData,\n authed: true,\n });\n }\n\n async function update({ gameId, ...data }: UpdateGameOpts & { gameId: string }) {\n return await apiClient.fetch<Game>(`/games/${gameId}`, {\n method: 'POST',\n body: JSON.stringify(data),\n authed: true,\n });\n }\n\n async function claimOwnership({ gameId }: { gameId: string }) {\n throw new Error('Not implemented');\n }\n\n async function getAuthedGames({ ...args }: GetAuthedGamesOpts) {\n return await apiClient.paginatedFetch<Game>('/games', args, {\n authed: true,\n });\n }\n\n async function getByTokenId({ tokenId }: GetGameByTokenIdOpts) {\n return await apiClient.fetch<Game>(`/games/by-token-id/${tokenId}`, {\n authed: true,\n });\n }\n\n async function getByBatchTokenIds({ tokenIds }: { tokenIds: string[] }) {\n return await apiClient.fetch<Record<string, Game[]>>(`/games/batch/token-ids`, {\n method: 'POST',\n body: JSON.stringify({ tokenIds }),\n authed: true,\n });\n }\n\n return {\n get,\n getById,\n getManyByIds,\n register,\n update,\n claimOwnership,\n getAuthedGames,\n getByTokenId,\n getByBatchTokenIds,\n };\n};\n","import type OpenGameClient from './client';\n\nexport interface SavePointsOpts {\n gameId: string;\n playerId: string;\n points: number;\n}\n\ntype PointsRecord = Record<string, number>;\ntype PointsArray = PointsRecord[];\n\ntype BatchPointsRecord = PointsRecord | PointsArray;\n\nexport default (apiClient: OpenGameClient) => {\n async function savePoints({ gameId, playerId, points }: SavePointsOpts) {\n return await apiClient.fetch<{\n savedCount: number;\n playerIdToOgpId: {\n [key: string]: string;\n };\n message?: string;\n }>(`/play/dev/batch-save-points`, {\n method: 'POST',\n body: JSON.stringify({ gameApiKey: gameId, points: [{ playerId, points }] }),\n authed: true,\n });\n }\n\n async function batchSavePoints({\n gameId,\n pointsRecord,\n }: {\n gameId: string;\n pointsRecord: BatchPointsRecord;\n }) {\n return await apiClient.fetch<{\n savedCount: number;\n playerIdToOgpId: {\n [key: string]: string;\n };\n message?: string;\n }>(`/play/dev/batch-save-points`, {\n method: 'POST',\n body: JSON.stringify({\n gameApiKey: gameId,\n points: Array.isArray(pointsRecord)\n ? pointsRecord\n : Object.entries(pointsRecord).map(([playerId, points]) => ({ playerId, points })),\n }),\n authed: true,\n });\n }\n\n async function getPoints({ gameId, playerId }: { gameId: string; playerId: string }) {\n return await apiClient.fetch<{ points: { playerId: string; points: string }[] }>(\n `/play/dev/points/${gameId}/${playerId}`,\n {\n authed: true,\n },\n );\n }\n\n async function getLeaderboard({ gameId }: { gameId: string }) {\n return await apiClient.fetch<PointsArray>(`/play/dev/leaderboard/${gameId}`, {\n authed: true,\n });\n }\n\n return {\n savePoints,\n batchSavePoints,\n getPoints,\n getLeaderboard,\n };\n};\n","import { User } from '@/index';\nimport OpenGameClient from './client';\n\nexport default (apiClient: OpenGameClient) => {\n async function me() {\n return await apiClient.fetch<User>(`/user/me`, {\n authed: true,\n });\n }\n\n async function getById({ userId }: { userId: string }) {\n return await apiClient.fetch<User>(`/user/${userId}`, {\n authed: true,\n });\n }\n\n return {\n me,\n getById,\n };\n};\n","import { transformDates } from '@/utils';\nimport games from './games';\nimport play from './play';\nimport user from './user';\n\ninterface OpenGameClientOpts {\n apiKey?: string;\n secretKey?: string;\n baseUrl?: string;\n}\n\nexport default class OpenGameClient {\n private apiKey: string;\n private secretKey: string;\n private baseUrl: string;\n\n constructor(opts: OpenGameClientOpts) {\n const {\n apiKey = process.env.OGP_API_KEY,\n secretKey = process.env.OGP_API_SECRET_KEY,\n baseUrl = 'https://api.play.fun',\n } = opts;\n if (!apiKey) {\n throw new Error(\n 'OGP_API_KEY is not set in environment. Please set it, or pass `apiKey` to the SDK options.',\n );\n }\n if (!secretKey) {\n throw new Error(\n 'OGP_API_SECRET_KEY is not set in environment. Please set it, or pass `secretKey` to the SDK options.',\n );\n }\n this.apiKey = apiKey;\n this.secretKey = secretKey;\n this.baseUrl = baseUrl;\n }\n\n public games = games(this);\n public play = play(this);\n public users = user(this);\n\n async paginatedFetch<T>(\n endpoint: string,\n paginatedOpts: {\n [key: string]: string | number | boolean | undefined;\n limit?: number;\n cursor?: string;\n },\n options?: RequestInit & { authed?: true },\n ): Promise<{\n items: T[];\n nextCursor?: string;\n hasMore: boolean;\n total: number;\n }> {\n if (options?.method !== 'GET') {\n throw new Error('Only GET requests are supported for paginated fetches');\n }\n\n const { limit = 100, cursor } = paginatedOpts;\n\n const params = new URLSearchParams({\n limit: limit.toString(),\n });\n\n if (cursor) {\n params.append('cursor', cursor);\n }\n\n for (const [key, value] of Object.entries(paginatedOpts)) {\n if (value !== undefined) {\n params.append(key, value.toString());\n }\n }\n\n let token: string | null = null;\n\n if (options?.authed) {\n token = await this._generateHMACSignature(\n (options?.method as 'GET' | 'POST') || 'GET',\n endpoint,\n );\n }\n\n const isFormData = options?.body instanceof FormData;\n\n const headers = {\n ...(!isFormData && { 'Content-Type': 'application/json' }),\n ...(options?.authed && { Authorization: token ?? '' }),\n ...options?.headers,\n };\n\n const response = await fetch(`${this.baseUrl}${endpoint}?${params.toString()}`, {\n ...options,\n headers,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n const error = new Error(\n errorText || 'API Reuqest failed with status ' + response.status,\n ) as Error & { status?: number; response?: { status: number } };\n error.status = response.status;\n error.response = { status: response.status };\n throw error;\n }\n\n const data = (await response.json()) as {\n items: T[];\n nextCursor?: string;\n hasMore: boolean;\n total: number;\n };\n\n return data;\n }\n\n async fetch<T>(\n endpoint: string,\n options?: RequestInit & { authed?: boolean },\n ): Promise<T | null> {\n let token: string | null = null;\n\n if (options?.authed) {\n token = await this._generateHMACSignature(\n (options?.method as 'GET' | 'POST') || 'GET',\n endpoint,\n );\n }\n\n const isFormData = options?.body instanceof FormData;\n\n const headers = {\n ...(!isFormData && { 'Content-Type': 'application/json' }),\n ...(options?.authed && { Authorization: token ?? '' }),\n ...options?.headers,\n };\n\n const response = await fetch(`${this.baseUrl}${endpoint}`, {\n ...options,\n headers,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n const error = new Error(\n errorText || 'API Reuqest failed with status ' + response.status,\n ) as Error & { status?: number; response?: { status: number } };\n error.status = response.status;\n error.response = { status: response.status };\n throw error;\n }\n\n const data = await response.json();\n return transformDates(data) as T;\n }\n\n private async _generateHMACSignature(method: 'GET' | 'POST', path: string) {\n const response = await fetch(`${this.baseUrl}/user/hmac-signature`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n method,\n path,\n apiKey: this.apiKey,\n secretKey: this.secretKey,\n }),\n });\n\n if (!response.ok) {\n throw new Error(\n `Failed to generate HMAC signature for endpoint ${path} with status ${response.status}`,\n );\n }\n\n const data = (await response.json()) as { data: { signature: string } };\n return data.data.signature;\n }\n}\n"],"mappings":"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","names":["ISO_DATE_PATTERN","isISODateString","value","test","transformDates","obj","undefined","Date","Array","isArray","map","item","transformed","key","Object","prototype","hasOwnProperty","call","apiClient","get","args","paginatedFetch","authed","getById","gameId","fetch","getManyByIds","gameIds","method","body","JSON","stringify","register","game","formData","FormData","image","append","coverImage","key","value","Object","entries","undefined","toString","update","data","claimOwnership","Error","getAuthedGames","getByTokenId","tokenId","getByBatchTokenIds","tokenIds","apiClient","savePoints","gameId","playerId","points","fetch","method","body","JSON","stringify","gameApiKey","authed","batchSavePoints","pointsRecord","Array","isArray","Object","entries","map","getPoints","getLeaderboard","apiClient","me","fetch","authed","getById","userId","OpenGameClient","apiKey","secretKey","baseUrl","opts","process","env","OGP_API_KEY","OGP_API_SECRET_KEY","Error","games","play","users","user","paginatedFetch","endpoint","paginatedOpts","options","method","limit","cursor","params","URLSearchParams","toString","append","key","value","Object","entries","undefined","token","authed","_generateHMACSignature","isFormData","body","FormData","headers","Authorization","response","fetch","ok","errorText","text","error","status","data","json","transformDates","path","JSON","stringify","signature"]}
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@playdotfun/server-sdk",
3
+ "version": "1.0.0",
4
+ "description": "Official SDK for interacting with the Play.fun API",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "scripts": {
16
+ "build": "tsup && dts-bundle-generator -o dist/index.d.ts src/index.ts"
17
+ },
18
+ "peerDependencies": {
19
+ "@types/node": "^22 || ^23 || ^24 || ^25",
20
+ "typescript": "^5"
21
+ },
22
+ "devDependencies": {
23
+ "@play-fun/types": "workspace:*",
24
+ "@types/node": "^25.0.0",
25
+ "dts-bundle-generator": "^9.5.1",
26
+ "tsup": "^8.5.1",
27
+ "tsx": "^4.21.0",
28
+ "typescript": "catalog:"
29
+ },
30
+ "files": [
31
+ "dist"
32
+ ]
33
+ }