@suigar/sdk 2.0.0-beta.10 → 2.0.0-beta.12

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/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @suigar/sdk
2
2
 
3
+ ## 2.0.0-beta.12
4
+
5
+ ### Patch Changes
6
+
7
+ - 85ae057: Refine public validation failures to use `RangeError` and `TypeError` instead
8
+ of generic `Error` for unsupported networks, unsupported game or PvP action
9
+ inputs, unsupported configured coin types, bounded integer helpers, and
10
+ `parseCoinType()` parsing failures.
11
+
12
+ ## 2.0.0-beta.11
13
+
14
+ ### Patch Changes
15
+
16
+ - c7685d2: Add `client.suigar.getGameParameters(game, options?)` for reading live onchain game parameter objects, such as min/max stake and game-specific config bounds, directly from SweetHouse settings.
17
+
18
+ The lookup first reads the selected game's settings object from SweetHouse, then reads that game's coin-specific `Parameters<T>` object, parses it with the correct return type for the requested game, and caches the result for SDK integrations that need to display or validate current game limits without repeatedly querying the same onchain objects.
19
+
20
+ This update also broadens the public numeric helpers in `@suigar/sdk/utils`: `toBigInt()` accepts booleans and non-negative integer strings in addition to numbers and `bigint`, `toU8()` accepts plain integer strings such as `'1'` for parsed config ids and other `u8` values, and `toU16()` provides the same validation pattern for `u16` values.
21
+
3
22
  ## 2.0.0-beta.10
4
23
 
5
24
  ### Patch Changes
package/README.md CHANGED
@@ -48,9 +48,33 @@ import {
48
48
  RANGE_POINT_LIMIT,
49
49
  toBigInt,
50
50
  toU8,
51
+ toU16,
51
52
  } from '@suigar/sdk/utils';
52
53
  ```
53
54
 
55
+ Numeric helper behavior:
56
+
57
+ - `toBigInt(value)` accepts `bigint`, finite `number`, non-negative integer
58
+ `string`, and `boolean` inputs and returns a normalized non-negative `bigint`
59
+ while throwing `TypeError` for invalid input shapes and `RangeError` for
60
+ negative values
61
+ - `toU8(value)` accepts a finite integer `number` or plain integer `string` in
62
+ the inclusive `0..255` range, throwing `TypeError` for non-numeric input and
63
+ `RangeError` for booleans, fractional values, or out-of-range integers
64
+ - `toU16(value)` accepts a finite integer `number` or plain integer `string`
65
+ in the inclusive `0..65535` range, throwing `TypeError` for non-numeric
66
+ input and `RangeError` for booleans, fractional values, or out-of-range
67
+ integers
68
+ - `fromMoveI64(value)` converts a generated Move `i64` wrapper into a
69
+ JavaScript `number`
70
+ - `fromMoveFloat(value)` converts a generated Move float struct into a
71
+ JavaScript `number`
72
+ - `parseCoinType(type)` extracts the normalized first generic coin type from a
73
+ Move object type string and throws `TypeError` when no coin type can be parsed
74
+ - `parseGameDetails(gameDetails)` decodes standard `BetResultEvent.game_details`
75
+ byte arrays into the expected string, number, and boolean values while
76
+ preserving the original onchain keys
77
+
54
78
  Game-specific type exports are available from the dedicated `games` subpath:
55
79
 
56
80
  ```ts
@@ -105,6 +129,9 @@ const base64 = await client.suigar.serializeTransactionToBase64(tx);
105
129
 
106
130
  Creates a named Sui client extension. By default, it registers under `client.suigar`.
107
131
 
132
+ The extension constructor throws `RangeError` when the connected client network
133
+ is not one of the SDK's supported Sui networks.
134
+
108
135
  ### Partner Setup
109
136
 
110
137
  > **Important:** `partner` is the partner wallet address. Configure it once
@@ -147,17 +174,22 @@ Supported override areas:
147
174
 
148
175
  - `name`
149
176
  - `partner`
177
+ - `cacheTtl`
150
178
 
151
179
  If `partner` is configured, the SDK automatically writes that partner wallet
152
180
  address into the onchain metadata vec-map. Transaction builder options may also
153
181
  include `metadata`, but reserved keys such as `partner` and `referrer` are
154
182
  ignored with a warning when provided manually.
155
183
 
184
+ `cacheTtl` controls the SDK cache for onchain reads such as parsed game
185
+ parameters. It is expressed in milliseconds and defaults to 30 minutes.
186
+
156
187
  ## Runtime Surface
157
188
 
158
189
  The registered extension instance exposes the main runtime surface:
159
190
 
160
191
  - `getConfig()`
192
+ - `getGameParameters(game, options?)`
161
193
  - `serializeTransactionToBase64(transaction, options?)`
162
194
  - `getPvPCoinflipGames(options?)`
163
195
  - `bcs`
@@ -182,6 +214,32 @@ const config = client.suigar.getConfig();
182
214
  console.log(config.packageIds);
183
215
  ```
184
216
 
217
+ ### `getGameParameters(game, options?)`
218
+
219
+ Returns the onchain `Parameters<T>` object for any supported game and coin type.
220
+ The return type is inferred from `game`.
221
+
222
+ The SDK first reads the selected game's settings object from the configured
223
+ SweetHouse object, then reads that game's coin-specific `Parameters<T>` object.
224
+ This is useful for displaying or validating current limits such as min/max
225
+ stake, house edge, or game-specific config bounds. The parsed result is cached
226
+ using the extension `cacheTtl`.
227
+
228
+ When a parameter field is a generated Move float struct, such as
229
+ `min_target_multiplier`, `max_target_multiplier`, `min_rtp`, or `max_rtp`, use
230
+ `fromMoveFloat()` before treating it as a normal JavaScript number.
231
+
232
+ ```ts
233
+ const parameters = await client.suigar.getGameParameters('coinflip', {
234
+ coinType: '0x2::sui::SUI',
235
+ });
236
+
237
+ console.log(parameters.min_stake);
238
+ ```
239
+
240
+ Pass `ignoreCache: true` to refresh the onchain read and replace the cached
241
+ value.
242
+
185
243
  ### `serializeTransactionToBase64(transaction, options?)`
186
244
 
187
245
  Builds a transaction with the configured Sui client and returns base64-encoded transaction bytes.
@@ -273,6 +331,12 @@ Shared behavior:
273
331
  - the SDK resolves the price info object from the configured supported-coin mapping
274
332
  - the reward object is transferred back to `playerAddress`
275
333
 
334
+ Error behavior:
335
+
336
+ - `RangeError` when `gameId` is unsupported
337
+ - `RangeError` when `coinType` is not in the resolved supported-coin config for the active network
338
+ - `RangeError` from bounded numeric helpers such as `toU8()` when `plinko` or `wheel` `configId` is out of range or not an integer
339
+
276
340
  Per-game options:
277
341
 
278
342
  - `coinflip`: `side: 'heads' | 'tails'`
@@ -372,6 +436,11 @@ Action-specific options:
372
436
  - `join`: `gameId`
373
437
  - `cancel`: `gameId`
374
438
 
439
+ Error behavior:
440
+
441
+ - `RangeError` when `action` is unsupported
442
+ - `RangeError` when `coinType` is not in the resolved supported-coin config for the active network
443
+
375
444
  ## `bcs`
376
445
 
377
446
  BCS helpers live under `client.suigar.bcs`.
@@ -390,6 +459,7 @@ These are generated Move event decoders. Use them to parse Suigar event payloads
390
459
  - `fromMoveI64(float.exp)` converts a generated Move `i64` exponent to a JavaScript number
391
460
  - `fromMoveFloat(float)` converts a generated Move `Float` struct to a JavaScript number
392
461
  - `parseCoinType(type)` extracts the normalized coin type from generic Move object type strings such as PvP coinflip `Game<T>`
462
+ and throws `TypeError` when the type string does not include a first generic coin type
393
463
  - `parseGameDetails(game_details)` decodes `BetResultEvent.game_details` entries into the expected string, number, and boolean values
394
464
 
395
465
  ### Parse PvP Coinflip Game Object Data
@@ -9,36 +9,48 @@ var RANGE_POINT_LIMIT = DEFAULT_RANGE_SCALE * 100;
9
9
  var DEFAULT_LIMBO_MULTIPLIER_SCALE = 100;
10
10
 
11
11
  // src/utils/numeric.ts
12
- function isFiniteNumber(value, message) {
13
- if (typeof value !== "number") {
14
- throw new Error(`${message}: ${String(value)}`);
15
- }
16
- if (!Number.isFinite(value)) {
17
- throw new Error(`Value must be a finite number: ${value}`);
12
+ function assertFiniteNumber(value, errorMessage) {
13
+ if (typeof value !== "number" || !Number.isFinite(value)) {
14
+ throw new TypeError(`${errorMessage}: ${String(value)}`);
18
15
  }
19
16
  }
20
17
  function toBigInt(value) {
21
- if (typeof value === "bigint") {
22
- if (value < 0n) {
23
- throw new Error(`Value must be non-negative: ${value}`);
18
+ let result;
19
+ try {
20
+ if (typeof value === "bigint" || typeof value === "string" || typeof value === "boolean") {
21
+ result = BigInt(value);
22
+ } else {
23
+ assertFiniteNumber(
24
+ value,
25
+ "Value must be a bigint, number, integer string, or boolean"
26
+ );
27
+ result = BigInt(Math.trunc(value));
24
28
  }
25
- return value;
29
+ } catch {
30
+ throw new TypeError(
31
+ `Value must be a bigint, number, integer string, or boolean: ${value}`
32
+ );
26
33
  }
27
- isFiniteNumber(value, "Value must be a bigint or number");
28
- if (value < 0) {
29
- throw new Error(`Value must be a finite non-negative number: ${value}`);
34
+ if (result < 0n) {
35
+ throw new RangeError(`Value must be non-negative: ${value}`);
30
36
  }
31
- return BigInt(Math.trunc(value));
37
+ return result;
32
38
  }
33
- function toU8(value) {
34
- isFiniteNumber(value, "Value must be a number");
35
- if (!Number.isInteger(value)) {
36
- throw new Error(`Value must be an integer: ${value}`);
37
- }
38
- if (value < 0 || value > 255) {
39
- throw new Error(`Value must be an integer between 0 and 255: ${value}`);
39
+ function toBoundedInt(value, max, typeName) {
40
+ const num = typeof value === "string" && value.trim() === "" ? NaN : Number(value);
41
+ assertFiniteNumber(num, "Value must be a finite number or integer string");
42
+ if (typeof value === "boolean" || value == null || !Number.isInteger(num) || num < 0 || num > max) {
43
+ throw new RangeError(
44
+ `Value must be a ${typeName} integer (0-${max}): ${value}`
45
+ );
40
46
  }
41
- return value;
47
+ return num;
48
+ }
49
+ function toU8(value) {
50
+ return toBoundedInt(value, 255, "u8");
51
+ }
52
+ function toU16(value) {
53
+ return toBoundedInt(value, 65535, "u16");
42
54
  }
43
55
  var MOVE_STDLIB_ADDRESS = normalizeSuiAddress("0x1");
44
56
  var SUI_FRAMEWORK_ADDRESS = normalizeSuiAddress("0x2");
@@ -292,7 +304,7 @@ function fromMoveFloat(float) {
292
304
  function parseCoinType(type) {
293
305
  const coinType = parseStructTag(type).typeParams[0];
294
306
  if (!coinType) {
295
- throw new Error(`Unable to parse coin type from ${type}`);
307
+ throw new TypeError(`Unable to parse coin type from ${type}`);
296
308
  }
297
309
  return normalizeStructTag(coinType);
298
310
  }
@@ -328,4 +340,4 @@ function parseGameDetails(gameDetails) {
328
340
  }, {});
329
341
  }
330
342
 
331
- export { DEFAULT_GAS_BUDGET_MIST, DEFAULT_LIMBO_MULTIPLIER_SCALE, DEFAULT_RANGE_SCALE, Float, MoveStruct, RANGE_POINT_LIMIT, fromMoveFloat, fromMoveI64, normalizeMoveArguments, parseCoinType, parseGameDetails, toBigInt, toU8 };
343
+ export { DEFAULT_GAS_BUDGET_MIST, DEFAULT_LIMBO_MULTIPLIER_SCALE, DEFAULT_RANGE_SCALE, Float, MoveStruct, RANGE_POINT_LIMIT, fromMoveFloat, fromMoveI64, normalizeMoveArguments, parseCoinType, parseGameDetails, toBigInt, toU16, toU8 };
@@ -12,7 +12,19 @@ type BetMetadataInput = Record<string, BetMetadataValue | null | undefined>;
12
12
 
13
13
  interface SuigarExtensionOptions<Name = 'suigar'> {
14
14
  name?: Name;
15
+ /**
16
+ * Partner wallet address injected into bet metadata for attribution.
17
+ *
18
+ * Configure this once when registering the `suigar()` client extension
19
+ * instead of passing partner data through per-transaction metadata.
20
+ */
15
21
  partner?: string;
22
+ /**
23
+ * Cache TTL in milliseconds for SDK-managed on-chain config lookups.
24
+ *
25
+ * Defaults to 30 minutes.
26
+ */
27
+ cacheTtl?: number;
16
28
  }
17
29
  type SuigarCoin = 'sui' | 'usdc';
18
30
  type SuigarCoinTypes = Record<SuigarCoin, string>;
@@ -83,4 +95,4 @@ type BuildCancelPvPCoinflipTransactionOptions = SharedPvPCoinflipTransactionOpti
83
95
  };
84
96
  type BuildPvPCoinflipTransactionOptions<Action extends PvPCoinflipAction = PvPCoinflipAction> = Action extends 'create' ? BuildCreatePvPCoinflipTransactionOptions : Action extends 'join' ? BuildJoinPvPCoinflipTransactionOptions : Action extends 'cancel' ? BuildCancelPvPCoinflipTransactionOptions : never;
85
97
 
86
- export type { BuildCoinflipTransactionOptions as B, CoinSide as C, PvPCoinflipAction as P, StandardGame as S, WithThrowOnError as W, BuildWheelTransactionOptions as a, BuildLimboTransactionOptions as b, BuildPlinkoTransactionOptions as c, BuildRangeTransactionOptions as d, SuigarConfig as e, BuildPvPCoinflipTransactionOptions as f, SuigarExtensionOptions as g, BuildCancelPvPCoinflipTransactionOptions as h, BuildCreatePvPCoinflipTransactionOptions as i, BuildJoinPvPCoinflipTransactionOptions as j };
98
+ export type { BuildCoinflipTransactionOptions as B, CoinSide as C, Game as G, PvPCoinflipAction as P, StandardGame as S, WithThrowOnError as W, BuildWheelTransactionOptions as a, BuildLimboTransactionOptions as b, BuildPlinkoTransactionOptions as c, BuildRangeTransactionOptions as d, SuigarConfig as e, BuildPvPCoinflipTransactionOptions as f, SuigarExtensionOptions as g, BuildCancelPvPCoinflipTransactionOptions as h, BuildCreatePvPCoinflipTransactionOptions as i, BuildJoinPvPCoinflipTransactionOptions as j };
@@ -12,7 +12,19 @@ type BetMetadataInput = Record<string, BetMetadataValue | null | undefined>;
12
12
 
13
13
  interface SuigarExtensionOptions<Name = 'suigar'> {
14
14
  name?: Name;
15
+ /**
16
+ * Partner wallet address injected into bet metadata for attribution.
17
+ *
18
+ * Configure this once when registering the `suigar()` client extension
19
+ * instead of passing partner data through per-transaction metadata.
20
+ */
15
21
  partner?: string;
22
+ /**
23
+ * Cache TTL in milliseconds for SDK-managed on-chain config lookups.
24
+ *
25
+ * Defaults to 30 minutes.
26
+ */
27
+ cacheTtl?: number;
16
28
  }
17
29
  type SuigarCoin = 'sui' | 'usdc';
18
30
  type SuigarCoinTypes = Record<SuigarCoin, string>;
@@ -83,4 +95,4 @@ type BuildCancelPvPCoinflipTransactionOptions = SharedPvPCoinflipTransactionOpti
83
95
  };
84
96
  type BuildPvPCoinflipTransactionOptions<Action extends PvPCoinflipAction = PvPCoinflipAction> = Action extends 'create' ? BuildCreatePvPCoinflipTransactionOptions : Action extends 'join' ? BuildJoinPvPCoinflipTransactionOptions : Action extends 'cancel' ? BuildCancelPvPCoinflipTransactionOptions : never;
85
97
 
86
- export type { BuildCoinflipTransactionOptions as B, CoinSide as C, PvPCoinflipAction as P, StandardGame as S, WithThrowOnError as W, BuildWheelTransactionOptions as a, BuildLimboTransactionOptions as b, BuildPlinkoTransactionOptions as c, BuildRangeTransactionOptions as d, SuigarConfig as e, BuildPvPCoinflipTransactionOptions as f, SuigarExtensionOptions as g, BuildCancelPvPCoinflipTransactionOptions as h, BuildCreatePvPCoinflipTransactionOptions as i, BuildJoinPvPCoinflipTransactionOptions as j };
98
+ export type { BuildCoinflipTransactionOptions as B, CoinSide as C, Game as G, PvPCoinflipAction as P, StandardGame as S, WithThrowOnError as W, BuildWheelTransactionOptions as a, BuildLimboTransactionOptions as b, BuildPlinkoTransactionOptions as c, BuildRangeTransactionOptions as d, SuigarConfig as e, BuildPvPCoinflipTransactionOptions as f, SuigarExtensionOptions as g, BuildCancelPvPCoinflipTransactionOptions as h, BuildCreatePvPCoinflipTransactionOptions as i, BuildJoinPvPCoinflipTransactionOptions as j };
package/dist/games.d.cts CHANGED
@@ -1,2 +1,2 @@
1
- export { h as BuildCancelPvPCoinflipTransactionOptions, B as BuildCoinflipTransactionOptions, i as BuildCreatePvPCoinflipTransactionOptions, j as BuildJoinPvPCoinflipTransactionOptions, b as BuildLimboTransactionOptions, c as BuildPlinkoTransactionOptions, d as BuildRangeTransactionOptions, a as BuildWheelTransactionOptions, C as CoinSide, P as PvPCoinflipAction } from './games-BccpPyWd.cjs';
1
+ export { h as BuildCancelPvPCoinflipTransactionOptions, B as BuildCoinflipTransactionOptions, i as BuildCreatePvPCoinflipTransactionOptions, j as BuildJoinPvPCoinflipTransactionOptions, b as BuildLimboTransactionOptions, c as BuildPlinkoTransactionOptions, d as BuildRangeTransactionOptions, a as BuildWheelTransactionOptions, C as CoinSide, P as PvPCoinflipAction } from './games-BHYRg31e.cjs';
2
2
  import '@mysten/sui/transactions';
package/dist/games.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { h as BuildCancelPvPCoinflipTransactionOptions, B as BuildCoinflipTransactionOptions, i as BuildCreatePvPCoinflipTransactionOptions, j as BuildJoinPvPCoinflipTransactionOptions, b as BuildLimboTransactionOptions, c as BuildPlinkoTransactionOptions, d as BuildRangeTransactionOptions, a as BuildWheelTransactionOptions, C as CoinSide, P as PvPCoinflipAction } from './games-BccpPyWd.js';
1
+ export { h as BuildCancelPvPCoinflipTransactionOptions, B as BuildCoinflipTransactionOptions, i as BuildCreatePvPCoinflipTransactionOptions, j as BuildJoinPvPCoinflipTransactionOptions, b as BuildLimboTransactionOptions, c as BuildPlinkoTransactionOptions, d as BuildRangeTransactionOptions, a as BuildWheelTransactionOptions, C as CoinSide, P as PvPCoinflipAction } from './games-BHYRg31e.js';
2
2
  import '@mysten/sui/transactions';