@suigar/sdk 2.0.0-beta.0 → 2.0.0-beta.2

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,30 @@
1
1
  # @suigar/sdk
2
2
 
3
+ ## 2.0.0-beta.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 128cb6c: - `suigar()` now only accepts the extension `name`.
8
+ - The SDK now validates the connected client network and supports `mainnet` and `testnet`.
9
+ - Added `client.suigar.getConfig()` to inspect the resolved network config at runtime.
10
+ - Exported the `SuiNetwork` type and `resolveGamePackageId()` helper.
11
+ - Reworked `SuigarConfig` into a network-resolved structure with `packageIds`, `coinTypes`, and `priceInfoObjectIds`.
12
+ - Replaced the old Pyth-specific price object resolution flow with supported-coin-based `priceInfoObjectId` resolution.
13
+ - Split package and coin configuration into explicit `mainnet` and `testnet` maps and updated transaction builders to use the new structure.
14
+ - Updated generated event helpers, tests, and documentation to match the new configuration and event parsing flow.
15
+
16
+ Notes:
17
+ - Existing prerelease integrations using `suigar({ ...configOverrides })` will need to migrate to `suigar()`.
18
+ - Runtime config inspection should now use `client.suigar.getConfig()`.
19
+
20
+ ## 2.0.0-beta.1
21
+
22
+ ### Patch Changes
23
+
24
+ - Updated the npm release workflows to install dependencies without a committed lockfile and removed the obsolete Node.js cache configuration.
25
+ - Simplified previous-release deprecation logic so prerelease publishes do not attempt to deprecate earlier npm versions.
26
+ - Stopped tracking `package-lock.json` and removed the obsolete changeset file after the version bump.
27
+
3
28
  ## 2.0.0-beta.0
4
29
 
5
30
  ### Major Changes
package/README.md CHANGED
@@ -2,13 +2,6 @@
2
2
 
3
3
  TypeScript SDK for building Suigar v2 game transactions on Sui.
4
4
 
5
- The published package entrypoint currently exposes:
6
-
7
- - `suigar`
8
- - `SuigarClient`
9
-
10
- It does not currently export the individual game builder functions from the package root.
11
-
12
5
  ## Installation
13
6
 
14
7
  ```bash
@@ -18,19 +11,59 @@ npm install @suigar/sdk
18
11
  Runtime requirements:
19
12
 
20
13
  - Node.js `>=22`
14
+ - `@mysten/sui`
15
+
16
+ ## What This Package Exposes
17
+
18
+ The package root currently exposes the extension factory:
19
+
20
+ ```ts
21
+ import { suigar } from '@suigar/sdk';
22
+ ```
23
+
24
+ It does not export the individual transaction builders from the package root.
25
+ It also does not export `SuigarClient` as a public root symbol.
26
+
27
+ What you actually use at runtime is the registered extension instance:
28
+
29
+ ```ts
30
+ const client = new SuiClient({ url }).$extend(suigar());
31
+
32
+ client.suigar.serializeTransactionToBase64(...);
33
+ client.suigar.getConfig();
34
+ client.suigar.bcs;
35
+ client.suigar.tx;
36
+ ```
21
37
 
22
- ## Public API
38
+ ## Quick Start
23
39
 
24
40
  ```ts
41
+ import { getFullnodeUrl, SuiClient } from '@mysten/sui/client';
25
42
  import { suigar } from '@suigar/sdk';
43
+
44
+ const client = new SuiClient({
45
+ url: getFullnodeUrl('testnet'),
46
+ }).$extend(suigar());
47
+
48
+ const tx = client.suigar.tx.createBetTransaction('coinflip', {
49
+ owner: '0x123',
50
+ coinType: '0x2::sui::SUI',
51
+ stake: 1_000_000_000n,
52
+ side: 'heads',
53
+ });
54
+
55
+ const base64 = await client.suigar.serializeTransactionToBase64(tx);
26
56
  ```
27
57
 
58
+ ## Extension Registration
59
+
28
60
  ### `suigar(options?)`
29
61
 
30
62
  Creates a named Sui client extension. By default, it registers under `client.suigar`.
31
63
 
32
64
  ```ts
33
65
  const client = new SuiClient({ url }).$extend(suigar());
66
+
34
67
  client.suigar;
35
68
  ```
36
69
 
@@ -39,47 +72,68 @@ You can rename the extension:
39
72
  ```ts
40
73
  const client = new SuiClient({ url }).$extend(suigar({ name: 'casino' }));
41
74
 
42
- client.casino;
75
+ client.casino.tx;
76
+ client.casino.bcs;
43
77
  ```
44
78
 
45
- ### `SuigarClient`
79
+ ## Config
46
80
 
47
- The registered extension instance exposes:
81
+ `suigar(options?)` resolves config from:
48
82
 
49
- - `serializeTransactionToBase64(transaction)`
50
- - `bcs.BetResultEvent`
51
- - `tx.createBetTransaction(gameId, options)`
83
+ - internal package ids by network
84
+ - internal supported coin types by network
85
+ - internal price info object ids by network
86
+ - the connected Sui client network
87
+ - the extension name
52
88
 
53
- ## Quick start
89
+ Supported override areas:
90
+
91
+ - `name`
92
+
93
+ ## Runtime Surface
94
+
95
+ The registered extension instance exposes three main areas:
96
+
97
+ - `getConfig()`
98
+ - `serializeTransactionToBase64(transaction, options?)`
99
+ - `bcs`
100
+ - `tx`
101
+
102
+ ### `getConfig()`
103
+
104
+ Returns the resolved SDK configuration for the connected network.
105
+
106
+ This is intended mainly for debugging and inspection, for example to verify the
107
+ resolved package ids or supported coin mappings for the active client network.
108
+
109
+ It includes:
110
+
111
+ - `packageIds`
112
+ - `coinTypes`
113
+ - `priceInfoObjectIds`
54
114
 
55
115
  ```ts
56
- import { SuiClient, getFullnodeUrl } from '@mysten/sui/client';
57
- import { suigar } from '@suigar/sdk';
116
+ const config = client.suigar.getConfig();
117
+ console.log(config.packageIds);
118
+ ```
58
119
 
59
- const client = new SuiClient({
60
- url: getFullnodeUrl('testnet'),
61
- }).$extend(
62
- suigar({
63
- pyth: {
64
- suiPriceInfoObjectId: '0xPYTH_SUI_PRICE_INFO',
65
- usdcPriceInfoObjectId: '0xPYTH_USDC_PRICE_INFO',
66
- },
67
- }),
68
- );
120
+ ### `serializeTransactionToBase64(transaction, options?)`
69
121
 
70
- const tx = client.suigar.tx.createBetTransaction('coinflip', {
71
- owner: '0x123',
72
- coinType: '0x2::sui::SUI',
73
- stake: 1_000_000_000n,
74
- side: 'heads',
75
- });
122
+ Builds a transaction with the configured Sui client and returns base64-encoded transaction bytes.
76
123
 
124
+ Use this when you need a transport-safe payload for a wallet, API, or external signer.
125
+
126
+ ```ts
77
127
  const base64 = await client.suigar.serializeTransactionToBase64(tx);
78
128
  ```
79
129
 
80
- ## Game transactions
130
+ ## `tx`
81
131
 
82
- `tx.createBetTransaction(gameId, options)` supports these game ids:
132
+ Transaction builders live under `client.suigar.tx`.
133
+
134
+ ### Standard Games
135
+
136
+ Use `createBetTransaction(gameId, options)` for:
83
137
 
84
138
  - `coinflip`
85
139
  - `limbo`
@@ -87,7 +141,16 @@ const base64 = await client.suigar.serializeTransactionToBase64(tx);
87
141
  - `range`
88
142
  - `wheel`
89
143
 
90
- All games share this base option shape:
144
+ ```ts
145
+ const tx = client.suigar.tx.createBetTransaction('coinflip', {
146
+ owner: '0x123',
147
+ coinType: '0x2::sui::SUI',
148
+ stake: 1_000_000_000n,
149
+ side: 'tails',
150
+ });
151
+ ```
152
+
153
+ Shared option shape:
91
154
 
92
155
  - `owner: string`
93
156
  - `coinType: string`
@@ -101,169 +164,156 @@ All games share this base option shape:
101
164
 
102
165
  Shared behavior:
103
166
 
104
- - `stake` is the logical game stake passed into the Move call
105
- - `cashStake` is the actual coin balance withdrawn into the bet coin and defaults to `stake`
167
+ - `stake` is the logical stake passed into the Move call
168
+ - `cashStake` controls the withdrawn balance and defaults to `stake`
106
169
  - `betCount` defaults to `1`
107
170
  - `sender` overrides the transaction sender
108
171
  - `metadata` is encoded into `keys` and `values` byte arrays
109
- - the SDK resolves the Pyth price object from the configured coin mapping
110
- - the built reward object is transferred back to the owner
172
+ - the SDK resolves the price info object from the configured supported-coin mapping
173
+ - the reward object is transferred back to `owner`
111
174
 
112
- ### Coinflip
175
+ Per-game options:
113
176
 
114
- Additional options:
177
+ - `coinflip`: `side: 'heads' | 'tails'`
178
+ - `limbo`: `targetMultiplier: number`, `scale?: number`
179
+ - `plinko`: `configId: number`
180
+ - `range`: `leftPoint: number`, `rightPoint: number`, `outOfRange?: boolean`, `scale?: number`
181
+ - `wheel`: `configId: number`
115
182
 
116
- - `side: 'heads' | 'tails'`
117
-
118
- Example:
183
+ Examples:
119
184
 
120
185
  ```ts
121
- const tx = client.suigar.tx.createBetTransaction('coinflip', {
186
+ const limboTx = client.suigar.tx.createBetTransaction('limbo', {
122
187
  owner: '0x123',
123
188
  coinType: '0x2::sui::SUI',
124
189
  stake: 1_000_000_000n,
125
- side: 'tails',
190
+ targetMultiplier: 2.5,
126
191
  });
127
- ```
128
-
129
- ### Limbo
130
-
131
- Additional options:
132
-
133
- - `targetMultiplier: number`
134
- - `scale?: number`
135
192
 
136
- Behavior:
137
-
138
- - `scale` defaults to the SDK limbo multiplier scale
139
- - `targetMultiplier` is converted with `Math.round(targetMultiplier * scale)`
140
-
141
- Example:
142
-
143
- ```ts
144
- const tx = client.suigar.tx.createBetTransaction('limbo', {
193
+ const rangeTx = client.suigar.tx.createBetTransaction('range', {
145
194
  owner: '0x123',
146
195
  coinType: '0x2::sui::SUI',
147
196
  stake: 1_000_000_000n,
148
- targetMultiplier: 2.5,
197
+ leftPoint: 0.95,
198
+ rightPoint: 1.05,
199
+ outOfRange: false,
149
200
  });
150
201
  ```
151
202
 
152
- ### Plinko
203
+ Notes:
153
204
 
154
- Additional options:
205
+ - limbo converts `targetMultiplier` with `Math.round(targetMultiplier * scale)`
206
+ - range converts each point with `Math.round(value * scale)`
207
+ - plinko and wheel `configId` must fit in `u8`
155
208
 
156
- - `configId: number`
209
+ ### PvP Coinflip
157
210
 
158
- Behavior:
211
+ Use `createPvPCoinflipTransaction(action, options)` for PvP coinflip flows:
159
212
 
160
- - `configId` must fit in `u8`
213
+ - `create`
214
+ - `join`
215
+ - `cancel`
161
216
 
162
- Example:
217
+ Create:
163
218
 
164
219
  ```ts
165
- const tx = client.suigar.tx.createBetTransaction('plinko', {
220
+ const tx = client.suigar.tx.createPvPCoinflipTransaction('create', {
166
221
  owner: '0x123',
167
222
  coinType: '0x2::sui::SUI',
168
223
  stake: 1_000_000_000n,
169
- configId: 3,
224
+ side: 'heads',
225
+ isPrivate: false,
170
226
  });
171
227
  ```
172
228
 
173
- ### Range
174
-
175
- Additional options:
176
-
177
- - `leftPoint: number`
178
- - `rightPoint: number`
179
- - `outOfRange?: boolean`
180
- - `scale?: number`
181
-
182
- Behavior:
183
-
184
- - `scale` defaults to the SDK fixed-point range scale
185
- - `leftPoint` and `rightPoint` are converted with `Math.round(value * scale)`
186
- - `outOfRange` is coerced with `Boolean(...)`
187
-
188
- Example:
229
+ Join:
189
230
 
190
231
  ```ts
191
- const tx = client.suigar.tx.createBetTransaction('range', {
232
+ const tx = client.suigar.tx.createPvPCoinflipTransaction('join', {
192
233
  owner: '0x123',
193
234
  coinType: '0x2::sui::SUI',
235
+ gameId: '0xGAME_ID',
236
+ extraObjectId: '0xEXTRA_OBJECT_ID',
194
237
  stake: 1_000_000_000n,
195
- leftPoint: 0.95,
196
- rightPoint: 1.05,
197
- outOfRange: false,
198
238
  });
199
239
  ```
200
240
 
201
- ### Wheel
202
-
203
- Additional options:
204
-
205
- - `configId: number`
206
-
207
- Behavior:
208
-
209
- - `configId` must fit in `u8`
210
-
211
- Example:
241
+ Cancel:
212
242
 
213
243
  ```ts
214
- const tx = client.suigar.tx.createBetTransaction('wheel', {
244
+ const tx = client.suigar.tx.createPvPCoinflipTransaction('cancel', {
215
245
  owner: '0x123',
216
246
  coinType: '0x2::sui::SUI',
217
- stake: 1_000_000_000n,
218
- configId: 1,
247
+ gameId: '0xGAME_ID',
219
248
  });
220
249
  ```
221
250
 
222
- ## BCS helpers
251
+ PvP shared options:
252
+
253
+ - `owner: string`
254
+ - `coinType: string`
255
+ - `metadata?: ...`
256
+ - `gasBudget?: number | bigint`
257
+ - `sender?: string`
258
+ - `allowGasCoinShortcut?: boolean`
223
259
 
224
- The client extension also exposes a generated MoveStruct helper for Suigar bet result data:
260
+ Action-specific options:
225
261
 
226
- - `client.suigar.bcs.BetResultEvent`
262
+ - `create`: `stake`, `side`, `isPrivate?`
263
+ - `join`: `gameId`, `extraObjectId`, `stake`
264
+ - `cancel`: `gameId`
227
265
 
228
- Use generated BCS types to parse onchain object data. Fetch the object with `include: { content: true }` and pass `object.content` to the generated type's `.parse()` method.
266
+ ## `bcs`
229
267
 
230
- Always use `content`, not `objectBcs`, when parsing with generated types. The `objectBcs` field contains a full object envelope with additional metadata and is not the payload expected by the generated struct parser.
268
+ BCS helpers live under `client.suigar.bcs`.
231
269
 
232
- ### Parse onchain object content
270
+ Current exposed helpers:
233
271
 
234
- ```ts
235
- async function readBetResult(client: ClientWithCoreApi, id: string) {
236
- const { object } = await client.core.getObject({
237
- objectId: id,
238
- include: {
239
- content: true,
240
- },
241
- });
242
-
243
- const parsed = client.suigar.bcs.BetResultEvent.parse(object.content);
244
-
245
- console.log(parsed.player);
246
- console.log(parsed.coin_type.name);
247
- console.log(parsed.stake_amount);
248
- console.log(parsed.outcome_amount);
249
-
250
- return parsed;
251
- }
252
- ```
272
+ - `BetResultEvent`
273
+ - `PvPCoinflipGameCreated`
274
+ - `PvPCoinflipGameResolved`
275
+ - `PvPCoinflipGameCancelled`
253
276
 
254
- ### Using the generated helper directly
277
+ These are generated Move event decoders. Use them to parse Suigar event payloads from transaction results.
255
278
 
256
- If you already have a content-bearing object response, parse `object.content` directly:
279
+ ### Parse Standard Bet Result Data
257
280
 
258
281
  ```ts
259
- const { object } = await client.core.getObject({
260
- objectId: '0xOBJECT_ID',
282
+ const executeResult = await client.core.executeTransaction({
283
+ transaction: transactionBytes,
284
+ signatures: [signature],
261
285
  include: {
262
- content: true,
286
+ events: true,
263
287
  },
264
288
  });
265
289
 
266
- const decoded = client.suigar.bcs.BetResultEvent.parse(object.content);
290
+ const finalResult = await client.core.waitForTransaction({
291
+ result: executeResult,
292
+ include: {
293
+ effects: true,
294
+ events: true,
295
+ },
296
+ });
297
+
298
+ if (finalResult.Transaction) {
299
+ console.log(finalResult.Transaction.digest);
300
+ } else if (finalResult.FailedTransaction) {
301
+ throw new Error(finalResult.FailedTransaction.status.error.message);
302
+ }
303
+
304
+ const transactionResult =
305
+ finalResult.Transaction ?? finalResult.FailedTransaction;
306
+
307
+ const betResults = [];
308
+
309
+ for (const event of transactionResult.events ?? []) {
310
+ try {
311
+ const decoded = client.suigar.bcs.BetResultEvent.parse(event.bcs);
312
+ betResults.push(decoded);
313
+ } catch {
314
+ // Ignore non-BetResultEvent payloads.
315
+ }
316
+ }
267
317
  ```
268
318
 
269
319
  Parsed fields include:
@@ -277,12 +327,9 @@ Parsed fields include:
277
327
  - `game_details`
278
328
  - `metadata`
279
329
 
280
- For `game_details` and `metadata`, the decoded value is a `VecMap<string, vector<u8>>`-shaped structure, so values come back as byte arrays.
281
-
282
- Example conversion to strings:
330
+ `game_details` and `metadata` decode as `VecMap<string, vector<u8>>`-shaped data, so values come back as byte arrays.
283
331
 
284
332
  ```ts
285
- const decoded = client.suigar.bcs.BetResultEvent.parse(object.data.content);
286
333
  const textDecoder = new TextDecoder();
287
334
 
288
335
  const metadata = new Map(
@@ -293,54 +340,21 @@ const metadata = new Map(
293
340
  );
294
341
  ```
295
342
 
296
- ## Config
343
+ Important:
297
344
 
298
- `suigar(options?)` resolves config from:
299
-
300
- - the connected Sui network
301
- - internal default package ids
302
- - internal default SweetHouse package id by network
303
- - default coin types for `SUI`, `USDC`, and FlowX `USDC`
304
- - user overrides
345
+ - execute or wait for the transaction with `include: { events: true }`
346
+ - parse emitted events from `result.Transaction.events` or `result.FailedTransaction.events`
347
+ - use `event.bcs` for consistent decoding across transports
348
+ - `waitForTransaction({ result, include: { effects: true, events: true } })` is useful when you want the finalized transaction result before decoding
349
+ - these helpers decode the event payload itself, not a full transaction response
305
350
 
306
- Supported override areas:
351
+ ### Parse PvP Coinflip Event Data
307
352
 
308
- - `name`
309
- - `sweetHousePackageId`
310
- - `coinTypes.sui`
311
- - `coinTypes.usdc`
312
- - `coinTypes.usdcFlowx`
313
- - `gamesPackageId.coinflip`
314
- - `gamesPackageId.limbo`
315
- - `gamesPackageId.plinko`
316
- - `gamesPackageId['pvp-coinflip']`
317
- - `gamesPackageId.range`
318
- - `gamesPackageId.wheel`
319
- - `pyth.packageId`
320
- - `pyth.suiPriceInfoObjectId`
321
- - `pyth.usdcPriceInfoObjectId`
322
- - `pyth.priceInfoObjectIds[coinType]`
323
-
324
- Example:
353
+ Use the matching helper for each PvP coinflip event payload found in `transactionResult.events`:
325
354
 
326
- ```ts
327
- const client = new SuiClient({ url }).$extend(
328
- suigar({
329
- sweetHousePackageId: '0xsweethouse',
330
- pyth: {
331
- suiPriceInfoObjectId: '0xsui',
332
- usdcPriceInfoObjectId: '0xusdc',
333
- priceInfoObjectIds: {
334
- '0x123::custom::TOKEN': '0xprice',
335
- },
336
- },
337
- gamesPackageId: {
338
- coinflip: '0xcoinflip',
339
- wheel: '0xwheel',
340
- },
341
- }),
342
- );
343
- ```
355
+ - `client.suigar.bcs.PvPCoinflipGameCreated`
356
+ - `client.suigar.bcs.PvPCoinflipGameResolved`
357
+ - `client.suigar.bcs.PvPCoinflipGameCancelled`
344
358
 
345
359
  ## Development
346
360