trucoshi 7.0.0 → 7.2.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.
package/dist/events.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { EMatchState } from "@trucoshi/prisma";
2
2
  import { SocketError } from "./server";
3
- import { IAccountDetails, IChatMessage, ILobbyOptions, IMatchDetails, IMatchPreviousHand, IPublicChatRoom, IPublicMatch, IPublicMatchInfo, IUserData, IWaitingPlayData, IWaitingSayData } from "./types";
3
+ import { IAccountDetails, IChatMessage, ILobbyOptions, IMatchDetails, IMatchPreviousHand, IPlayerRanking, IPublicChatRoom, IPublicMatch, IPublicMatchInfo, IUserData, IWaitingPlayData, IWaitingSayData } from "./types";
4
4
  import { User } from "lightning-accounts";
5
5
  export type IEventCallback<T = {}> = (args: {
6
6
  success: boolean;
@@ -43,6 +43,7 @@ export declare enum EClientEvent {
43
43
  FETCH_MATCH_DETAILS = "FETCH_MATCH_DETAILS",
44
44
  SET_MATCH_OPTIONS = "SET_MATCH_OPTIONS",
45
45
  LIST_MATCHES = "LIST_MATCHES",
46
+ LIST_RANKING = "LIST_RANKING",
46
47
  JOIN_MATCH = "JOIN_MATCH",
47
48
  START_MATCH = "START_MATCH",
48
49
  SET_PLAYER_READY = "SET_PLAYER_READY",
@@ -90,6 +91,9 @@ export interface ClientToServerEvents {
90
91
  }, callback: IEventCallback<{
91
92
  matches: Array<IPublicMatchInfo>;
92
93
  }>) => void;
94
+ [EClientEvent.LIST_RANKING]: (filters: {}, callback: IEventCallback<{
95
+ ranking: Array<IPlayerRanking>;
96
+ }>) => void;
93
97
  [EClientEvent.LOGIN]: (user: User, identityToken: string, callback: IEventCallback<{
94
98
  activeMatches?: IPublicMatchInfo[];
95
99
  }>) => void;
package/dist/events.js CHANGED
@@ -23,6 +23,7 @@ export var EClientEvent;
23
23
  EClientEvent["FETCH_MATCH_DETAILS"] = "FETCH_MATCH_DETAILS";
24
24
  EClientEvent["SET_MATCH_OPTIONS"] = "SET_MATCH_OPTIONS";
25
25
  EClientEvent["LIST_MATCHES"] = "LIST_MATCHES";
26
+ EClientEvent["LIST_RANKING"] = "LIST_RANKING";
26
27
  EClientEvent["JOIN_MATCH"] = "JOIN_MATCH";
27
28
  EClientEvent["START_MATCH"] = "START_MATCH";
28
29
  EClientEvent["SET_PLAYER_READY"] = "SET_PLAYER_READY";
@@ -1,18 +1,27 @@
1
+ import { RequestParams } from "lightning-accounts";
1
2
  import { IRandom } from "../../types";
3
+ import { AxiosResponse } from "axios";
2
4
  export declare const Random: () => IRandom;
3
5
  export interface IRng {
4
- combine(client: string, server: string, nonce: number): string;
6
+ combine(client: string, server: string, bitcoinHash: string, nonce: number): string;
5
7
  sha512(string: string): string;
6
8
  generateServerSeed(): string;
9
+ getBitcoinLatestBlockHash(fn: (params?: RequestParams) => Promise<AxiosResponse<{
10
+ hash: string;
11
+ height: number;
12
+ }, any>>): Promise<{
13
+ hash: string;
14
+ height: number;
15
+ }>;
7
16
  hexToBytes(hex: string): Uint8Array;
8
- byteGenerator(clientseed: string, serverseed: string, nonce: number): Uint8Array;
9
- generateInteger(clientSeed: string, serverSeed: string, nonce: number, min: number, max: number): number;
10
- generateFloat(clientSeed: string, serverSeed: string, nonce: number, precision?: number): number;
11
- generateBool(clientSeed: string, serverSeed: string, nonce: number): boolean;
17
+ byteGenerator(clientseed: string, serverseed: string, bitcoinHash: string, nonce: number): Uint8Array;
18
+ generateInteger(clientSeed: string, serverSeed: string, bitcoinHash: string, nonce: number, min: number, max: number): number;
19
+ generateFloat(clientSeed: string, serverSeed: string, bitcoinHash: string, nonce: number, precision?: number): number;
20
+ generateBool(clientSeed: string, serverSeed: string, bitcoinHash: string, nonce: number): boolean;
12
21
  selectRandomObject<T extends {
13
22
  probability: number;
14
23
  } = {
15
24
  probability: number;
16
25
  [x: string]: any;
17
- }>(clientSeed: string, serverSeed: string, nonce: number, objects: Array<T>): T | null;
26
+ }>(clientSeed: string, serverSeed: string, bitcoinHash: string, nonce: number, objects: Array<T>): T | null;
18
27
  }
@@ -1,18 +1,41 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
1
10
  import forge from "node-forge";
2
11
  const rnd = Rng();
3
12
  export const Random = () => {
4
13
  const random = {
5
14
  secret: rnd.generateServerSeed(),
6
15
  clients: [],
16
+ bitcoinHash: "",
17
+ bitcoinHeight: 0,
7
18
  nonce: 0,
19
+ getLatestBitcoinBlock(fn) {
20
+ return __awaiter(this, void 0, void 0, function* () {
21
+ const { hash, height } = yield rnd.getBitcoinLatestBlockHash(fn);
22
+ random.bitcoinHash = hash;
23
+ random.bitcoinHeight = height;
24
+ });
25
+ },
8
26
  pick(key, max) {
9
- return rnd.generateInteger(random.clients[key], random.secret, random.nonce, 0, max);
27
+ return rnd.generateInteger(random.clients[key], random.secret, random.bitcoinHash, random.nonce, 0, max);
10
28
  },
11
29
  next() {
12
30
  random.nonce++;
13
31
  },
14
32
  reveal() {
15
- return { secret: random.secret, clients: [...random.clients] };
33
+ return {
34
+ secret: random.secret,
35
+ clients: [...random.clients],
36
+ bitcoinHash: random.bitcoinHash,
37
+ bitcoinHeight: random.bitcoinHeight,
38
+ };
16
39
  },
17
40
  };
18
41
  return random;
@@ -22,12 +45,13 @@ function Rng() {
22
45
  /**
23
46
  * Generates a random 256 long hex hash
24
47
  *
25
- * @param {string} clientSeed - the clientSeed
26
- * @param {string} serverSeed - the serverSeed
27
- * @param {number} nonce - the nonce
48
+ * @param {string} clientSeed - the clientSeed
49
+ * @param {string} serverSeed - the serverSeed
50
+ * @param {string} bitcoinHash - The latest bitcoin block hash.
51
+ * @param {number} nonce - the nonce
28
52
  * @returns {string} combined string
29
53
  */
30
- combine: (clientSeed, serverSeed, nonce) => clientSeed + serverSeed + nonce,
54
+ combine: (clientSeed, serverSeed, bitcoinHash, nonce) => clientSeed + serverSeed + bitcoinHash + nonce,
31
55
  /**
32
56
  * Generates a sha512 hash from a string
33
57
  *
@@ -62,11 +86,12 @@ function Rng() {
62
86
  *
63
87
  * @param {string} clientseed - The clientseed to use.
64
88
  * @param {string} serverseed - The serverseed to use.
89
+ * @param {string} bitcoinHash - The latest bitcoin block hash.
65
90
  * @param {number} nonce - The nonce to use.
66
91
  * @returns {Uint8Array} - The generated bytes as a Uint8Array.
67
92
  */
68
- byteGenerator: function (clientseed, serverseed, nonce) {
69
- const preHash = this.combine(clientseed, serverseed, nonce);
93
+ byteGenerator: function (clientseed, serverseed, bitcoinHash, nonce) {
94
+ const preHash = this.combine(clientseed, serverseed, bitcoinHash, nonce);
70
95
  const hash = this.sha512(preHash);
71
96
  return this.hexToBytes(hash.slice(0, 64));
72
97
  },
@@ -75,27 +100,29 @@ function Rng() {
75
100
  *
76
101
  * @param {string} clientSeed - The client seed.
77
102
  * @param {string} serverSeed - The server seed.
103
+ * @param {string} bitcoinHash - The latest bitcoin block hash.
78
104
  * @param {number} nonce - The nonce.
79
105
  * @param {number} min - The minimum value of the range.
80
106
  * @param {number} max - The maximum value of the range.
81
107
  * @returns {number} A random integer between min and max (inclusive).
82
108
  */
83
- generateInteger: function (clientSeed, serverSeed, nonce, min, max) {
84
- const preHash = this.combine(clientSeed, serverSeed, nonce);
109
+ generateInteger: function (clientSeed, serverSeed, bitcoinHash, nonce, min, max) {
110
+ const preHash = this.combine(clientSeed, serverSeed, bitcoinHash, nonce);
85
111
  const hash = this.sha512(preHash);
86
112
  const range = max - min + 1;
87
- return (parseInt(hash.slice(0, 8), 16) % range) + min;
113
+ return (parseInt(hash.slice(0, 16), 16) % range) + min;
88
114
  },
89
115
  /**
90
116
  * Generates a random float between 0 and 1 using the fairjs library.
91
117
  * @param {string} clientSeed - The client seed to use for the random number generation.
92
118
  * @param {string} serverSeed - The server seed to use for the random number generation.
119
+ * @param {string} bitcoinHash - The latest bitcoin block hash.
93
120
  * @param {number} nonce - The nonce to use for the random number generation.
94
121
  * @param {number} [precision=2] - The number of decimal places to include in the result.
95
122
  * @returns {number} - The random float between 0 and 1.
96
123
  */
97
- generateFloat: function (clientSeed, serverSeed, nonce, precision = 2) {
98
- const bytes = this.byteGenerator(clientSeed, serverSeed, nonce);
124
+ generateFloat: function (clientSeed, serverSeed, bitcoinHash, nonce, precision = 2) {
125
+ const bytes = this.byteGenerator(clientSeed, serverSeed, bitcoinHash, nonce);
99
126
  const float = parseFloat("0." + bytes.join(""));
100
127
  return parseFloat(float.toFixed(precision));
101
128
  },
@@ -107,25 +134,28 @@ function Rng() {
107
134
  * @param {number} nonce - The nonce.
108
135
  * @returns {float, boolean} random boolean true/false
109
136
  */
110
- generateBool: function (clientSeed, serverSeed, nonce) {
111
- return this.generateFloat(clientSeed, serverSeed, nonce, 10) <= 0.5 ? true : false;
137
+ generateBool: function (clientSeed, serverSeed, bitcoinHash, nonce) {
138
+ return this.generateFloat(clientSeed, serverSeed, bitcoinHash, nonce, 10) <= 0.5
139
+ ? true
140
+ : false;
112
141
  },
113
142
  /**
114
143
  * Selects a random object from an array of objects based on their probabilities.
115
144
  *
116
145
  * @param {string} clientSeed - The client seed.
117
146
  * @param {string} serverSeed - The server seed.
147
+ * @param {string} bitcoinHash - The latest bitcoin block hash.
118
148
  * @param {number} nonce - The nonce.
119
149
  * @param {Array} objects - An array of objects with an ID and a probability property.
120
150
  * @returns {String} The ID of the randomly selected object.
121
151
  */
122
- selectRandomObject: function (clientSeed, serverSeed, nonce, objects) {
152
+ selectRandomObject: function (clientSeed, serverSeed, bitcoinHash, nonce, objects) {
123
153
  let totalProbability = 0;
124
154
  for (const obj of objects) {
125
155
  totalProbability += obj.probability;
126
156
  }
127
157
  const normalizedProbabilities = objects.map((obj) => obj.probability / totalProbability);
128
- const randomFloat = this.generateFloat(clientSeed, serverSeed, nonce, 10);
158
+ const randomFloat = this.generateFloat(clientSeed, serverSeed, bitcoinHash, nonce, 10);
129
159
  let index = 0;
130
160
  for (let i = 0; i < normalizedProbabilities.length; i++) {
131
161
  index += normalizedProbabilities[i];
@@ -136,5 +166,20 @@ function Rng() {
136
166
  // If no object is selected, return null
137
167
  return null;
138
168
  },
169
+ /**
170
+ * Gets the latest Bitcoin block hash from the LND node
171
+ *
172
+ * @returns {Promise<string>} The latest Bitcoin block hash
173
+ */
174
+ getBitcoinLatestBlockHash: function (fn) {
175
+ return __awaiter(this, void 0, void 0, function* () {
176
+ try {
177
+ return (yield fn()).data || { hash: "", height: 0 };
178
+ }
179
+ catch (error) {
180
+ return { hash: "", height: 0 };
181
+ }
182
+ });
183
+ },
139
184
  };
140
185
  }
package/dist/types.d.ts CHANGED
@@ -1,15 +1,17 @@
1
1
  export * from "./events";
2
2
  export { CARDS, CARDS_HUMAN_READABLE, BURNT_CARD } from "./lib/constants";
3
- import { User } from "lightning-accounts";
3
+ import { RequestParams, User } from "lightning-accounts";
4
4
  import { Match, MatchPlayer, MatchHand, UserStats } from "@trucoshi/prisma";
5
5
  import { IHand } from "./truco";
6
6
  import { CARDS } from "./lib";
7
+ import { AxiosResponse } from "axios";
7
8
  export declare enum EMatchState {
8
9
  UNREADY = "UNREADY",
9
10
  READY = "READY",
10
11
  STARTED = "STARTED",
11
12
  FINISHED = "FINISHED"
12
13
  }
14
+ export type IPlayerRanking = Omit<UserStats, "id" | "satsBet" | "satsWon" | "satsLost"> & Pick<User, "name" | "avatarUrl">;
13
15
  export interface IMatchDetails extends Match {
14
16
  players: Array<Pick<MatchPlayer, "id" | "accountId" | "teamIdx" | "name" | "idx">>;
15
17
  hands: Array<MatchHand>;
@@ -237,12 +239,20 @@ export interface IHandPoints {
237
239
  export interface IRandom {
238
240
  secret: string;
239
241
  clients: string[];
242
+ bitcoinHash: string;
243
+ bitcoinHeight: number;
240
244
  nonce: number;
245
+ getLatestBitcoinBlock(fn: (params?: RequestParams) => Promise<AxiosResponse<{
246
+ hash: string;
247
+ height: number;
248
+ }, any>>): Promise<void>;
241
249
  next(): void;
242
250
  pick(idx: number, max: number): number;
243
251
  reveal(): {
244
252
  secret: string;
245
253
  clients: string[];
254
+ bitcoinHash: string;
255
+ bitcoinHeight: number;
246
256
  };
247
257
  }
248
258
  export type IPublicPlayer = Pick<IPlayer, "idx" | "key" | "name" | "abandonedTime" | "accountId" | "avatarUrl" | "disabled" | "abandoned" | "ready" | "hand" | "usedHand" | "prevHand" | "teamIdx" | "isTurn" | "turnExpiresAt" | "turnExtensionExpiresAt" | "isEnvidoTurn" | "isOwner"> & ({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trucoshi",
3
- "version": "7.0.0",
3
+ "version": "7.2.0",
4
4
  "description": "Lightning Truco Server",
5
5
  "main": "dist/types.js",
6
6
  "license": "GPL-3.0",
@@ -76,7 +76,7 @@
76
76
  "dotenv-cli": "^7.3.0",
77
77
  "form-data": "^4.0.0",
78
78
  "jsonwebtoken": "^9.0.2",
79
- "lightning-accounts": "^4.1.0",
79
+ "lightning-accounts": "4.3.0",
80
80
  "node-forge": "^1.3.1",
81
81
  "path-scurry": "^1.9.2",
82
82
  "pino": "^9.3.2",