@suigar/sdk 2.0.0-beta.7 → 2.0.0-beta.9

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,28 @@
1
1
  # @suigar/sdk
2
2
 
3
+ ## 2.0.0-beta.9
4
+
5
+ ### Patch Changes
6
+
7
+ - eaf8b3a: Fix metadata encoding so partner metadata is only added when configured and hex metadata values are encoded consistently as bytes. Improve supported-coin and price-info resolution error handling for transaction configuration.
8
+ - 9929e05: Refine Move parser helpers by simplifying BCS type usage, normalizing missing
9
+ `i64` and float mantissa values to `0`, and documenting the numeric conversion
10
+ behavior in `fromMoveI64` and `fromMoveFloat`.
11
+
12
+ ## 2.0.0-beta.8
13
+
14
+ ### Patch Changes
15
+
16
+ - 0292edb: Rename transaction builder option `owner` to `playerAddress` and remove the separate `sender` option so all game transactions use a single explicit player address.
17
+ - 20311be: Improve the public JSDoc for `parseGameDetails`, `toBigInt`, and `toU8` so the
18
+ generated API surface explains their coercion, validation, and decoding
19
+ behavior more clearly.
20
+ - a2aa324: Update PvP coinflip lookup helpers to use bulk object reads for unresolved lobby discovery and support forwarded lookup options.
21
+ - Make `getPvPCoinflipGames()` parse bulk `client.core.getObjects()` results instead of resolving each game individually.
22
+ - Skip per-object fetch or parse failures by default and continue supporting strict rejection with `throwOnError: true`.
23
+ - Forward supported lookup options such as `signal` through `getPvPCoinflipGames()` and `resolvePvPConflipGame(gameId, options?)`.
24
+ - Update tests, README guidance, and repo-local PvP skill documentation to match the current client behavior.
25
+
3
26
  ## 2.0.0-beta.7
4
27
 
5
28
  ### Patch Changes
package/README.md CHANGED
@@ -92,7 +92,7 @@ const client = new SuiGrpcClient({
92
92
  }).$extend(suigar());
93
93
 
94
94
  const tx = client.suigar.tx.createBetTransaction('coinflip', {
95
- owner: '0x123',
95
+ playerAddress: '0x123',
96
96
  coinType: '0x2::sui::SUI',
97
97
  stake: 1_000_000_000n,
98
98
  side: 'heads',
@@ -110,7 +110,7 @@ Creates a named Sui client extension. By default, it registers under `client.sui
110
110
  ### Partner Setup
111
111
 
112
112
  > **Important:** `partner` is the partner wallet address. Configure it once
113
- > when you register the extension so the SDK can append that wallet address to
113
+ > when you register the extension so the SDK can prepend that wallet address to
114
114
  > supported bet metadata automatically.
115
115
 
116
116
  ```ts
@@ -200,17 +200,20 @@ const base64 = await client.suigar.serializeTransactionToBase64(tx);
200
200
  Lists unresolved PvP coinflip games from the configured PvP registry.
201
201
 
202
202
  This reads the registry dynamic fields for the active network and resolves each
203
- entry into parsed game state through `resolvePvPConflipGame()`. Registry
203
+ entry into parsed game state through a bulk `client.core.getObjects()` lookup. Registry
204
204
  membership is the unresolved-state signal: once a match is joined and resolved,
205
205
  the Move flow removes it from the registry and deletes the live `Game` object.
206
206
 
207
207
  Use this when a product needs the current set of open PvP coinflip matches for
208
208
  browsing or lobby views.
209
209
 
210
- By default, failures to resolve an individual game are skipped so one broken or
210
+ By default, per-object fetch or parse failures are skipped so one broken or
211
211
  already-deleted registry entry does not reject the full lookup. Pass
212
212
  `throwOnError: true` if you want the call to reject instead.
213
213
 
214
+ Any supported `listDynamicFields()` options such as `limit`, `cursor`, or
215
+ `signal` can be passed through `options`.
216
+
214
217
  ```ts
215
218
  const games = await client.suigar.getPvPCoinflipGames({ limit: 20 });
216
219
 
@@ -227,14 +230,15 @@ const games = await client.suigar.getPvPCoinflipGames({
227
230
  });
228
231
  ```
229
232
 
230
- ### `resolvePvPConflipGame(gameId)`
233
+ ### `resolvePvPConflipGame(gameId, options?)`
231
234
 
232
235
  Fetches a PvP coinflip game object from chain and parses it into the SDK's
233
236
  normalized runtime shape.
234
237
 
235
238
  This requires the object's `content`, decodes it with the generated
236
239
  `PvPCoinflipGame` parser, and normalizes the generic coin type into a standard
237
- struct tag string.
240
+ struct tag string. You can optionally pass through `getObject()` options such as
241
+ `signal`.
238
242
 
239
243
  Use this when a product needs the live onchain match state for a specific
240
244
  pending match before rendering join or cancel actions, or inspecting the stake
@@ -249,6 +253,14 @@ console.log(game.stake_per_player);
249
253
  console.log(game.is_private);
250
254
  ```
251
255
 
256
+ ```ts
257
+ const controller = new AbortController();
258
+
259
+ const game = await client.suigar.resolvePvPConflipGame('0xGAME_ID', {
260
+ signal: controller.signal,
261
+ });
262
+ ```
263
+
252
264
  > **Note:**
253
265
  >
254
266
  > - it throws if the object response does not include decodable `content`
@@ -274,7 +286,7 @@ Use `createBetTransaction(gameId, options)` for:
274
286
 
275
287
  ```ts
276
288
  const tx = client.suigar.tx.createBetTransaction('coinflip', {
277
- owner: '0x123',
289
+ playerAddress: '0x123',
278
290
  coinType: '0x2::sui::SUI',
279
291
  stake: 1_000_000_000n,
280
292
  side: 'tails',
@@ -283,14 +295,13 @@ const tx = client.suigar.tx.createBetTransaction('coinflip', {
283
295
 
284
296
  Shared option shape:
285
297
 
286
- - `owner: string`
298
+ - `playerAddress: string`
287
299
  - `coinType: string`
288
300
  - `stake: number | bigint`
289
301
  - `cashStake?: number | bigint`
290
302
  - `betCount?: number | bigint`
291
303
  - `metadata?: Record<string, string | number | boolean | bigint | Uint8Array | number[] | null | undefined>`
292
304
  - `gasBudget?: number | bigint`
293
- - `sender?: string`
294
305
  - `allowGasCoinShortcut?: boolean`
295
306
 
296
307
  Shared behavior:
@@ -298,12 +309,11 @@ Shared behavior:
298
309
  - `stake` is the logical stake passed into the Move call
299
310
  - `cashStake` controls the withdrawn balance and defaults to `stake`
300
311
  - `betCount` defaults to `1`
301
- - `sender` overrides the transaction sender
302
312
  - `metadata` is encoded into `keys` and `values` byte arrays
303
- - `partner` configured via `suigar({ partner })` is appended automatically to metadata as the partner wallet address
313
+ - `partner` configured via `suigar({ partner })` is prepended automatically to metadata as the partner wallet address
304
314
  - `metadata.partner` and `metadata.referrer` are reserved and ignored with a warning
305
315
  - the SDK resolves the price info object from the configured supported-coin mapping
306
- - the reward object is transferred back to `owner`
316
+ - the reward object is transferred back to `playerAddress`
307
317
 
308
318
  Per-game options:
309
319
 
@@ -317,14 +327,14 @@ Examples:
317
327
 
318
328
  ```ts
319
329
  const limboTx = client.suigar.tx.createBetTransaction('limbo', {
320
- owner: '0x123',
330
+ playerAddress: '0x123',
321
331
  coinType: '0x2::sui::SUI',
322
332
  stake: 1_000_000_000n,
323
333
  targetMultiplier: 2.5,
324
334
  });
325
335
 
326
336
  const rangeTx = client.suigar.tx.createBetTransaction('range', {
327
- owner: '0x123',
337
+ playerAddress: '0x123',
328
338
  coinType: '0x2::sui::SUI',
329
339
  stake: 1_000_000_000n,
330
340
  leftPoint: 25,
@@ -359,7 +369,7 @@ Create:
359
369
 
360
370
  ```ts
361
371
  const tx = client.suigar.tx.createPvPCoinflipTransaction('create', {
362
- owner: '0x123',
372
+ playerAddress: '0x123',
363
373
  coinType: '0x2::sui::SUI',
364
374
  stake: 1_000_000_000n,
365
375
  side: 'heads',
@@ -371,7 +381,7 @@ Join:
371
381
 
372
382
  ```ts
373
383
  const tx = client.suigar.tx.createPvPCoinflipTransaction('join', {
374
- owner: '0x123',
384
+ playerAddress: '0x123',
375
385
  coinType: '0x2::sui::SUI',
376
386
  gameId: '0xGAME_ID',
377
387
  });
@@ -381,7 +391,7 @@ Cancel:
381
391
 
382
392
  ```ts
383
393
  const tx = client.suigar.tx.createPvPCoinflipTransaction('cancel', {
384
- owner: '0x123',
394
+ playerAddress: '0x123',
385
395
  coinType: '0x2::sui::SUI',
386
396
  gameId: '0xGAME_ID',
387
397
  });
@@ -392,11 +402,10 @@ id for `coinType`.
392
402
 
393
403
  PvP shared options:
394
404
 
395
- - `owner: string`
405
+ - `playerAddress: string`
396
406
  - `coinType: string`
397
407
  - `metadata?: Record<string, string | number | boolean | bigint | Uint8Array | number[] | null | undefined>`
398
408
  - `gasBudget?: number | bigint`
399
- - `sender?: string`
400
409
  - `allowGasCoinShortcut?: boolean`
401
410
 
402
411
  Action-specific options:
@@ -542,7 +551,7 @@ npm test
542
551
 
543
552
  ## Example App
544
553
 
545
- This repository now includes a Next.js integration example in [examples/game-integration](/Users/lucas/Documents/Github/suigar-sdk/examples/game-integration).
554
+ This repository includes a Next.js integration example in [examples/game-integration](examples/game-integration).
546
555
 
547
556
  It demonstrates:
548
557
 
@@ -256,36 +256,28 @@ var GAME_DETAILS_SCHEMA = {
256
256
  };
257
257
 
258
258
  // src/utils/parser.ts
259
- var bcsU8 = bcs.u8();
260
- var bcsU64 = bcs.u64();
261
- var bcsBool = bcs.bool();
262
- var bcsString = bcs.string();
263
259
  var textDecoder = new TextDecoder();
264
260
  var GAME_DETAIL_BCS = {
265
- u8: bcsU8,
266
- u64: bcsU64,
267
- bool: bcsBool,
261
+ u8: bcs.U8,
262
+ u64: bcs.U64,
263
+ bool: bcs.Bool,
268
264
  float: Float,
269
- string: bcsString
265
+ string: bcs.String
270
266
  };
271
267
  function fromMoveI64(i64) {
272
268
  try {
273
- const value = BigInt(i64.bits ?? 0);
274
- const maxPositive = 1n << 63n;
275
- const twoPow64 = 1n << 64n;
276
- const signed = value >= maxPositive ? value - twoPow64 : value;
277
- return Number(signed);
269
+ return Number(BigInt.asIntN(64, BigInt(i64.bits ?? 0)));
278
270
  } catch {
279
271
  return 0;
280
272
  }
281
273
  }
282
274
  function fromMoveFloat(float) {
283
- const mantissa = BigInt(float.mant);
275
+ const mantissa = BigInt(float.mant ?? 0);
284
276
  if (mantissa === 0n) {
285
277
  return 0;
286
278
  }
287
279
  const exponent = fromMoveI64(float.exp) - 52;
288
- const magnitude = Number(mantissa) * Math.pow(2, exponent);
280
+ const magnitude = Number(mantissa) * 2 ** exponent;
289
281
  return float.is_negative ? -magnitude : magnitude;
290
282
  }
291
283
  function normalizeGameDetailValue(valueType, parsed) {
@@ -300,7 +292,7 @@ function normalizeGameDetailValue(valueType, parsed) {
300
292
  function parseStringGameDetail(value) {
301
293
  const bytes = Uint8Array.from(value);
302
294
  try {
303
- return bcsString.parse(bytes);
295
+ return bcs.String.parse(bytes);
304
296
  } catch {
305
297
  return textDecoder.decode(bytes);
306
298
  }
@@ -1,3 +1,5 @@
1
+ import { Transaction } from '@mysten/sui/transactions';
2
+
1
3
  declare const GAMES: readonly ["coinflip", "limbo", "plinko", "pvp-coinflip", "range", "wheel"];
2
4
  type Game = (typeof GAMES)[number];
3
5
  type StandardGame = Exclude<Game, PvPGame>;
@@ -26,22 +28,27 @@ type SuigarConfig = {
26
28
  priceInfoObjectIds: SuigarPriceInfoObjectId;
27
29
  };
28
30
 
29
- type SharedBetTransactionOptions = {
31
+ type WithGasBudget = {
32
+ gasBudget?: Parameters<Transaction['setGasBudgetIfNotSet']>[0];
33
+ };
34
+ type WithThrowOnError<T = object> = T & {
35
+ throwOnError?: boolean;
36
+ };
37
+ type BaseTransactionOptions = WithGasBudget & {
30
38
  config: SuigarConfig;
31
- owner: string;
39
+ playerAddress: string;
40
+ };
41
+ type CoinTransactionOptions = {
32
42
  coinType: string;
33
- stake: number | bigint;
34
- cashStake?: number | bigint;
35
- betCount?: number | bigint;
36
43
  metadata?: BetMetadataInput;
37
- gasBudget?: number | bigint;
38
- sender?: string;
39
44
  allowGasCoinShortcut?: boolean;
40
45
  };
41
-
42
- type WithThrowOnError<T = object> = T & {
43
- throwOnError?: boolean;
46
+ type StakeTransactionOptions = {
47
+ stake: number | bigint;
48
+ cashStake?: number | bigint;
49
+ betCount?: number | bigint;
44
50
  };
51
+ type SharedBetTransactionOptions = BaseTransactionOptions & CoinTransactionOptions & StakeTransactionOptions;
45
52
  type BuildCoinflipTransactionOptions = SharedBetTransactionOptions & {
46
53
  side: CoinSide;
47
54
  };
@@ -62,17 +69,9 @@ type BuildWheelTransactionOptions = SharedBetTransactionOptions & {
62
69
  configId: number;
63
70
  };
64
71
  type PvPCoinflipAction = 'create' | 'join' | 'cancel';
65
- type SharedPvPCoinflipTransactionOptions = {
66
- config: SuigarConfig;
67
- owner: string;
68
- coinType: string;
69
- metadata?: BetMetadataInput;
70
- gasBudget?: number | bigint;
71
- sender?: string;
72
- allowGasCoinShortcut?: boolean;
73
- };
72
+ type SharedPvPCoinflipTransactionOptions = BaseTransactionOptions & CoinTransactionOptions;
74
73
  type BuildCreatePvPCoinflipTransactionOptions = SharedPvPCoinflipTransactionOptions & {
75
- stake: number | bigint;
74
+ stake: StakeTransactionOptions['stake'];
76
75
  side: CoinSide;
77
76
  isPrivate?: boolean;
78
77
  };
@@ -1,3 +1,5 @@
1
+ import { Transaction } from '@mysten/sui/transactions';
2
+
1
3
  declare const GAMES: readonly ["coinflip", "limbo", "plinko", "pvp-coinflip", "range", "wheel"];
2
4
  type Game = (typeof GAMES)[number];
3
5
  type StandardGame = Exclude<Game, PvPGame>;
@@ -26,22 +28,27 @@ type SuigarConfig = {
26
28
  priceInfoObjectIds: SuigarPriceInfoObjectId;
27
29
  };
28
30
 
29
- type SharedBetTransactionOptions = {
31
+ type WithGasBudget = {
32
+ gasBudget?: Parameters<Transaction['setGasBudgetIfNotSet']>[0];
33
+ };
34
+ type WithThrowOnError<T = object> = T & {
35
+ throwOnError?: boolean;
36
+ };
37
+ type BaseTransactionOptions = WithGasBudget & {
30
38
  config: SuigarConfig;
31
- owner: string;
39
+ playerAddress: string;
40
+ };
41
+ type CoinTransactionOptions = {
32
42
  coinType: string;
33
- stake: number | bigint;
34
- cashStake?: number | bigint;
35
- betCount?: number | bigint;
36
43
  metadata?: BetMetadataInput;
37
- gasBudget?: number | bigint;
38
- sender?: string;
39
44
  allowGasCoinShortcut?: boolean;
40
45
  };
41
-
42
- type WithThrowOnError<T = object> = T & {
43
- throwOnError?: boolean;
46
+ type StakeTransactionOptions = {
47
+ stake: number | bigint;
48
+ cashStake?: number | bigint;
49
+ betCount?: number | bigint;
44
50
  };
51
+ type SharedBetTransactionOptions = BaseTransactionOptions & CoinTransactionOptions & StakeTransactionOptions;
45
52
  type BuildCoinflipTransactionOptions = SharedBetTransactionOptions & {
46
53
  side: CoinSide;
47
54
  };
@@ -62,17 +69,9 @@ type BuildWheelTransactionOptions = SharedBetTransactionOptions & {
62
69
  configId: number;
63
70
  };
64
71
  type PvPCoinflipAction = 'create' | 'join' | 'cancel';
65
- type SharedPvPCoinflipTransactionOptions = {
66
- config: SuigarConfig;
67
- owner: string;
68
- coinType: string;
69
- metadata?: BetMetadataInput;
70
- gasBudget?: number | bigint;
71
- sender?: string;
72
- allowGasCoinShortcut?: boolean;
73
- };
72
+ type SharedPvPCoinflipTransactionOptions = BaseTransactionOptions & CoinTransactionOptions;
74
73
  type BuildCreatePvPCoinflipTransactionOptions = SharedPvPCoinflipTransactionOptions & {
75
- stake: number | bigint;
74
+ stake: StakeTransactionOptions['stake'];
76
75
  side: CoinSide;
77
76
  isPrivate?: boolean;
78
77
  };
package/dist/games.d.cts CHANGED
@@ -1 +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--Haw_z7M.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-BccpPyWd.cjs';
2
+ import '@mysten/sui/transactions';
package/dist/games.d.ts CHANGED
@@ -1 +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--Haw_z7M.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-BccpPyWd.js';
2
+ import '@mysten/sui/transactions';
@@ -1,12 +1,12 @@
1
1
  import { BcsType, BcsStruct } from '@mysten/sui/bcs';
2
2
  import { SuiClientTypes, ClientWithCoreApi } from '@mysten/sui/client';
3
3
 
4
- interface GetOptions<Include extends Omit<SuiClientTypes.ObjectInclude, 'content'> = {}> extends SuiClientTypes.GetObjectOptions<Include> {
4
+ type GetOptions<Include extends Omit<SuiClientTypes.ObjectInclude, 'content'> = {}> = SuiClientTypes.GetObjectOptions<Include> & {
5
5
  client: ClientWithCoreApi;
6
- }
7
- interface GetManyOptions<Include extends Omit<SuiClientTypes.ObjectInclude, 'content'> = {}> extends SuiClientTypes.GetObjectsOptions<Include> {
6
+ };
7
+ type GetManyOptions<Include extends Omit<SuiClientTypes.ObjectInclude, 'content'> = {}> = SuiClientTypes.GetObjectsOptions<Include> & {
8
8
  client: ClientWithCoreApi;
9
- }
9
+ };
10
10
  declare class MoveStruct<T extends Record<string, BcsType<any>>, const Name extends string = string> extends BcsStruct<T, Name> {
11
11
  get<Include extends Omit<SuiClientTypes.ObjectInclude, 'content' | 'json'> = {}>({ objectId, ...options }: GetOptions<Include>): Promise<SuiClientTypes.Object<Include & {
12
12
  content: true;
@@ -1,12 +1,12 @@
1
1
  import { BcsType, BcsStruct } from '@mysten/sui/bcs';
2
2
  import { SuiClientTypes, ClientWithCoreApi } from '@mysten/sui/client';
3
3
 
4
- interface GetOptions<Include extends Omit<SuiClientTypes.ObjectInclude, 'content'> = {}> extends SuiClientTypes.GetObjectOptions<Include> {
4
+ type GetOptions<Include extends Omit<SuiClientTypes.ObjectInclude, 'content'> = {}> = SuiClientTypes.GetObjectOptions<Include> & {
5
5
  client: ClientWithCoreApi;
6
- }
7
- interface GetManyOptions<Include extends Omit<SuiClientTypes.ObjectInclude, 'content'> = {}> extends SuiClientTypes.GetObjectsOptions<Include> {
6
+ };
7
+ type GetManyOptions<Include extends Omit<SuiClientTypes.ObjectInclude, 'content'> = {}> = SuiClientTypes.GetObjectsOptions<Include> & {
8
8
  client: ClientWithCoreApi;
9
- }
9
+ };
10
10
  declare class MoveStruct<T extends Record<string, BcsType<any>>, const Name extends string = string> extends BcsStruct<T, Name> {
11
11
  get<Include extends Omit<SuiClientTypes.ObjectInclude, 'content' | 'json'> = {}>({ objectId, ...options }: GetOptions<Include>): Promise<SuiClientTypes.Object<Include & {
12
12
  content: true;