@playdotfun/game-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,135 @@
1
+ import { rejects } from 'assert';
2
+ import AWS from 'aws-sdk';
3
+ import { PutObjectRequest } from 'aws-sdk/clients/s3';
4
+ import { exec } from 'child_process';
5
+ import { readFile } from 'fs/promises';
6
+ import path, { dirname } from 'path';
7
+ import { fileURLToPath } from 'url';
8
+
9
+ const DEFAULT_FILE_NAME = 'sdk.js';
10
+ const __dirname = dirname(fileURLToPath(import.meta.url));
11
+ const ROOT_DIR = path.resolve(__dirname, '../../');
12
+ const DIST_DIR = path.resolve(ROOT_DIR, 'dist');
13
+ const S3_BUCKET = 'ogp-cdn';
14
+ const S3_PREFIX = 'vanilla-js-sdk';
15
+ const CDN_URL = 'https://sdk.play.fun';
16
+ const CLOUDFRONT_DISTRIBUTION_ID = 'E2RUY7SDQK9F8Y';
17
+
18
+ AWS.config.update({
19
+ region: 'us-east-1',
20
+ });
21
+
22
+ const s3 = new AWS.S3();
23
+
24
+ const uploadToS3 = async (filePath: string, s3Key: string, ContentType?: string) => {
25
+ const fileData = await readFile(filePath);
26
+ const params: PutObjectRequest = {
27
+ Bucket: S3_BUCKET,
28
+ Key: `${S3_PREFIX}/${s3Key}`,
29
+ Body: fileData,
30
+ };
31
+
32
+ if (ContentType) {
33
+ params.ContentType = ContentType;
34
+ }
35
+
36
+ s3.upload(params, async (err, data) => {
37
+ if (err) {
38
+ console.error('Error uploading to S3:', err);
39
+ throw err;
40
+ }
41
+ await spawn('aws', [
42
+ 'cloudfront',
43
+ 'create-invalidation',
44
+ '--distribution-id',
45
+ CLOUDFRONT_DISTRIBUTION_ID,
46
+ '--paths',
47
+ '"/*"',
48
+ ]);
49
+ return data.Location;
50
+ });
51
+ };
52
+
53
+ const deploy = async (
54
+ deployLatest = false,
55
+ target: 'prod' | 'dev' | 'dev-mainnet' | 'staging' = 'prod',
56
+ ) => {
57
+ const filePath = path.resolve(DIST_DIR, DEFAULT_FILE_NAME);
58
+ const pkgVersion = JSON.parse(
59
+ await readFile(path.resolve(ROOT_DIR, 'package.json'), 'utf8'),
60
+ ).version;
61
+
62
+ let s3Key: string;
63
+ if (target === 'prod') {
64
+ // Prod goes to root
65
+ s3Key = deployLatest ? 'sdk.js' : `sdk.v${pkgVersion}.js`;
66
+ } else {
67
+ // Other targets go to subfolders
68
+ s3Key = deployLatest ? `${target}/sdk.js` : `${target}/sdk.v${pkgVersion}.js`;
69
+ }
70
+
71
+ console.log('Deploying to S3:', s3Key);
72
+ await uploadToS3(filePath, s3Key, 'application/javascript');
73
+
74
+ console.log('Deployed to S3: ' + `${CDN_URL}/${s3Key}`);
75
+ if (deployLatest) {
76
+ console.log('Deploying latest to S3');
77
+ const latestKey = target === 'prod' ? 'sdk.latest.js' : `${target}/sdk.latest.js`;
78
+
79
+ console.log('Deploying to S3:', latestKey);
80
+ await uploadToS3(filePath, latestKey, 'application/javascript');
81
+ }
82
+ };
83
+
84
+ const spawn = (cmd: string, args: string[], env: Record<string, string> = {}, verbose = false) =>
85
+ new Promise((resolve, reject) => {
86
+ const combinedEnv = Object.assign({}, process.env, env);
87
+ const cmdStr = `${cmd} ${args.join(' ')}`;
88
+ const runner = exec(cmdStr, { env: combinedEnv }, (err, stdout, stderr) => {
89
+ if (err) {
90
+ console.error(`Error running command: ${cmd} ${args.join(' ')}`);
91
+ return reject(err);
92
+ }
93
+ return resolve(stdout || stderr);
94
+ });
95
+
96
+ if (verbose) {
97
+ runner.stdout?.on('data', function (data) {
98
+ console.log('stdou:', data.toString());
99
+ });
100
+
101
+ runner.stderr?.on('data', function (data) {
102
+ console.log('stderr:', data.toString());
103
+ });
104
+ }
105
+ });
106
+
107
+ const main = async (args: string[]) => {
108
+ let version = null;
109
+ let target: 'prod' | 'dev' | 'dev-mainnet' | 'staging' = 'prod';
110
+ let deployLatest = false;
111
+
112
+ for (let i = 0; i < args.length; i++) {
113
+ const arg = args[i];
114
+ switch (arg) {
115
+ case '--latest':
116
+ case '--deploy-latest':
117
+ deployLatest = true;
118
+ break;
119
+ case '--version':
120
+ version = args[i + 1];
121
+ break;
122
+ case '--target':
123
+ target = args[i + 1] as 'prod' | 'dev' | 'dev-mainnet' | 'staging';
124
+ break;
125
+ }
126
+ }
127
+
128
+ console.log('Starting deploy script with args:', { version, target, deployLatest });
129
+
130
+ deploy(deployLatest, target);
131
+ };
132
+
133
+ (async () => {
134
+ await main(process.argv);
135
+ })();
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Crypto utilities for points hardening
3
+ * Uses Web Crypto API for browser compatibility
4
+ */
5
+
6
+ /**
7
+ * Compute HMAC-SHA256 signature
8
+ */
9
+ export async function hmacSha256(key: string, data: string): Promise<string> {
10
+ const encoder = new TextEncoder();
11
+ const keyData = encoder.encode(key);
12
+ const dataBytes = encoder.encode(data);
13
+
14
+ const cryptoKey = await crypto.subtle.importKey(
15
+ 'raw',
16
+ keyData,
17
+ { name: 'HMAC', hash: 'SHA-256' },
18
+ false,
19
+ ['sign'],
20
+ );
21
+
22
+ const signature = await crypto.subtle.sign('HMAC', cryptoKey, dataBytes);
23
+ return arrayBufferToHex(signature);
24
+ }
25
+
26
+ /**
27
+ * Compute SHA-256 hash
28
+ */
29
+ export async function sha256(data: string): Promise<string> {
30
+ const encoder = new TextEncoder();
31
+ const dataBytes = encoder.encode(data);
32
+ const hashBuffer = await crypto.subtle.digest('SHA-256', dataBytes);
33
+ return arrayBufferToHex(hashBuffer);
34
+ }
35
+
36
+ /**
37
+ * Generate a random UUID (for nonces, client instance IDs, etc.)
38
+ */
39
+ export function generateUUID(): string {
40
+ return crypto.randomUUID();
41
+ }
42
+
43
+ /**
44
+ * Convert ArrayBuffer to hex string
45
+ */
46
+ function arrayBufferToHex(buffer: ArrayBuffer): string {
47
+ const bytes = new Uint8Array(buffer);
48
+ return Array.from(bytes)
49
+ .map((b) => b.toString(16).padStart(2, '0'))
50
+ .join('');
51
+ }