@suigar/sdk 2.0.0-beta.2 → 2.0.0-beta.4
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 +33 -1
- package/README.md +233 -46
- package/dist/chunk-W3WZ2BHO.js +310 -0
- package/dist/games-nFnPbPuK.d.cts +84 -0
- package/dist/games-nFnPbPuK.d.ts +84 -0
- package/dist/games.cjs +2 -0
- package/dist/games.d.cts +1 -0
- package/dist/games.d.ts +1 -0
- package/dist/games.js +1 -0
- package/dist/index-jwSXA8q3.d.cts +25 -0
- package/dist/index-jwSXA8q3.d.ts +25 -0
- package/dist/index.cjs +269 -97
- package/dist/index.d.cts +115 -109
- package/dist/index.d.ts +115 -109
- package/dist/index.js +229 -231
- package/dist/utils.cjs +208 -0
- package/dist/utils.d.cts +79 -0
- package/dist/utils.d.ts +79 -0
- package/dist/utils.js +1 -0
- package/package.json +29 -2
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { Transaction
|
|
1
|
+
import { MoveStruct, Float, toBigIntAmount, toU8Number, DEFAULT_GAS_BUDGET_MIST, normalizeMoveArguments, DEFAULT_LIMBO_MULTIPLIER_SCALE, DEFAULT_RANGE_SCALE } from './chunk-W3WZ2BHO.js';
|
|
2
|
+
import { toBase64, normalizeStructTag, parseStructTag, normalizeSuiAddress, isValidSuiAddress } from '@mysten/sui/utils';
|
|
3
|
+
import { Transaction } from '@mysten/sui/transactions';
|
|
4
|
+
import { bcs } from '@mysten/sui/bcs';
|
|
4
5
|
|
|
5
6
|
// src/types/network.type.ts
|
|
6
7
|
var SUPPORTED_SUI_NETWORKS = [
|
|
@@ -62,13 +63,31 @@ var PRICE_INFO_OBJECT_IDS = {
|
|
|
62
63
|
testnet: { ...TESTNET_PRICE_INFO_OBJECT_IDS }
|
|
63
64
|
};
|
|
64
65
|
|
|
65
|
-
// src/
|
|
66
|
+
// src/configs/registry.mainnet.ts
|
|
67
|
+
var PVP_COINFLIP_REGISTRY_ID = "0x3d73568546c539c1da3eb2b8fe917faef3c0acdbec78a67fe6d52800a0729349";
|
|
68
|
+
|
|
69
|
+
// src/configs/registry.testnet.ts
|
|
70
|
+
var PVP_COINFLIP_REGISTRY_ID2 = "0x99f20d8e4be012ea14a681144ae72ac349d0a1a1585205880183eb167f075bad";
|
|
71
|
+
|
|
72
|
+
// src/configs/registry.ts
|
|
73
|
+
var REGISTRY_IDS = {
|
|
74
|
+
mainnet: {
|
|
75
|
+
pvpCoinflip: PVP_COINFLIP_REGISTRY_ID
|
|
76
|
+
},
|
|
77
|
+
testnet: {
|
|
78
|
+
pvpCoinflip: PVP_COINFLIP_REGISTRY_ID2
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// src/helpers/config.ts
|
|
66
83
|
function resolveSuigarConfig(network) {
|
|
67
84
|
const packageIds = PACKAGE_IDS[network];
|
|
85
|
+
const registryIds = REGISTRY_IDS[network];
|
|
68
86
|
const coinTypes = COIN_TYPES[network];
|
|
69
87
|
const priceInfoObjectIds = PRICE_INFO_OBJECT_IDS[network];
|
|
70
88
|
return {
|
|
71
89
|
packageIds: { ...packageIds },
|
|
90
|
+
registryIds: { ...registryIds },
|
|
72
91
|
coinTypes: {
|
|
73
92
|
sui: normalizeStructTag(coinTypes.sui),
|
|
74
93
|
usdc: normalizeStructTag(coinTypes.usdc)
|
|
@@ -123,11 +142,12 @@ function resolveSupportedCoin(config, coinType) {
|
|
|
123
142
|
`Unsupported coin type ${coinType}. Supported coin types: ${entries.map(([, configuredCoinType]) => configuredCoinType).join(", ")}`
|
|
124
143
|
);
|
|
125
144
|
}
|
|
126
|
-
var ADDRESS_METADATA_KEYS = /* @__PURE__ */ new Set(["
|
|
145
|
+
var ADDRESS_METADATA_KEYS = /* @__PURE__ */ new Set(["partner"]);
|
|
146
|
+
var RESERVED_METADATA_KEYS = /* @__PURE__ */ new Set([...ADDRESS_METADATA_KEYS, "referrer"]);
|
|
127
147
|
var textEncoder = new TextEncoder();
|
|
128
|
-
|
|
148
|
+
function parseHexAddress(value) {
|
|
129
149
|
const trimmed = value.trim();
|
|
130
|
-
if (!trimmed) return null;
|
|
150
|
+
if (!trimmed || !isValidSuiAddress(trimmed)) return null;
|
|
131
151
|
try {
|
|
132
152
|
const normalized = normalizeSuiAddress(trimmed).slice(2);
|
|
133
153
|
const bytes = new Uint8Array(normalized.length / 2);
|
|
@@ -141,190 +161,42 @@ var parseHexAddress = (value) => {
|
|
|
141
161
|
} catch {
|
|
142
162
|
return null;
|
|
143
163
|
}
|
|
144
|
-
};
|
|
145
|
-
function encodeBetMetadata(metadata) {
|
|
146
|
-
const keys = [];
|
|
147
|
-
const values = [];
|
|
148
|
-
for (const [key, value] of Object.entries(metadata ?? {})) {
|
|
149
|
-
if (value === void 0 || value === null) {
|
|
150
|
-
continue;
|
|
151
|
-
}
|
|
152
|
-
let encodedValue;
|
|
153
|
-
if (value instanceof Uint8Array) {
|
|
154
|
-
encodedValue = Array.from(value);
|
|
155
|
-
} else if (Array.isArray(value)) {
|
|
156
|
-
encodedValue = value;
|
|
157
|
-
} else if (typeof value === "string" && ADDRESS_METADATA_KEYS.has(key)) {
|
|
158
|
-
encodedValue = Array.from(
|
|
159
|
-
parseHexAddress(value) ?? textEncoder.encode(value)
|
|
160
|
-
);
|
|
161
|
-
} else {
|
|
162
|
-
encodedValue = Array.from(textEncoder.encode(String(value)));
|
|
163
|
-
}
|
|
164
|
-
keys.push(key);
|
|
165
|
-
values.push(encodedValue);
|
|
166
|
-
}
|
|
167
|
-
return { keys, values };
|
|
168
164
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
var RANGE_FIXED_POINT_SCALE = 1e6;
|
|
173
|
-
var LIMBO_MULTIPLIER_SCALE = 100;
|
|
174
|
-
function toBigIntAmount(value, fieldName) {
|
|
175
|
-
if (typeof value === "bigint") {
|
|
176
|
-
if (value < 0n) {
|
|
177
|
-
throw new Error(`${fieldName} must be non-negative`);
|
|
178
|
-
}
|
|
179
|
-
return value;
|
|
165
|
+
function encodeMetadataValue(key, value) {
|
|
166
|
+
if (value instanceof Uint8Array) {
|
|
167
|
+
return Array.from(value);
|
|
180
168
|
}
|
|
181
|
-
if (
|
|
182
|
-
|
|
169
|
+
if (Array.isArray(value)) {
|
|
170
|
+
return value;
|
|
183
171
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
function toU8Number(value, fieldName) {
|
|
187
|
-
if (!Number.isInteger(value) || value < 0 || value > 255) {
|
|
188
|
-
throw new Error(`${fieldName} must be an integer between 0 and 255`);
|
|
172
|
+
if (typeof value === "string" && ADDRESS_METADATA_KEYS.has(key)) {
|
|
173
|
+
return Array.from(parseHexAddress(value) ?? textEncoder.encode(value));
|
|
189
174
|
}
|
|
190
|
-
return value;
|
|
175
|
+
return Array.from(textEncoder.encode(String(value)));
|
|
191
176
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
} else if ("u32" in parsedTag) {
|
|
201
|
-
return bcs.U32;
|
|
202
|
-
} else if ("u64" in parsedTag) {
|
|
203
|
-
return bcs.U64;
|
|
204
|
-
} else if ("u128" in parsedTag) {
|
|
205
|
-
return bcs.U128;
|
|
206
|
-
} else if ("u256" in parsedTag) {
|
|
207
|
-
return bcs.U256;
|
|
208
|
-
} else if ("address" in parsedTag) {
|
|
209
|
-
return bcs.Address;
|
|
210
|
-
} else if ("bool" in parsedTag) {
|
|
211
|
-
return bcs.Bool;
|
|
212
|
-
} else if ("vector" in parsedTag) {
|
|
213
|
-
const type = getPureBcsSchema(parsedTag.vector);
|
|
214
|
-
return type ? bcs.vector(type) : null;
|
|
215
|
-
} else if ("struct" in parsedTag) {
|
|
216
|
-
const structTag = parsedTag.struct;
|
|
217
|
-
const pkg = normalizeSuiAddress(structTag.address);
|
|
218
|
-
if (pkg === MOVE_STDLIB_ADDRESS) {
|
|
219
|
-
if ((structTag.module === "ascii" || structTag.module === "string") && structTag.name === "String") {
|
|
220
|
-
return bcs.String;
|
|
221
|
-
}
|
|
222
|
-
if (structTag.module === "option" && structTag.name === "Option") {
|
|
223
|
-
const type = getPureBcsSchema(structTag.typeParams[0]);
|
|
224
|
-
return type ? bcs.option(type) : null;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
if (pkg === SUI_FRAMEWORK_ADDRESS && structTag.module === "object" && (structTag.name === "ID" || structTag.name === "UID")) {
|
|
228
|
-
return bcs.Address;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
return null;
|
|
232
|
-
}
|
|
233
|
-
function normalizeMoveArguments(args, argTypes, parameterNames) {
|
|
234
|
-
Array.isArray(args) ? args.length : Object.keys(args).length;
|
|
235
|
-
const normalizedArgs = [];
|
|
236
|
-
let index = 0;
|
|
237
|
-
for (const [i, argType] of argTypes.entries()) {
|
|
238
|
-
if (argType === "0x2::clock::Clock") {
|
|
239
|
-
normalizedArgs.push((tx) => tx.object.clock());
|
|
240
|
-
continue;
|
|
241
|
-
}
|
|
242
|
-
if (argType === "0x2::random::Random") {
|
|
243
|
-
normalizedArgs.push((tx) => tx.object.random());
|
|
244
|
-
continue;
|
|
245
|
-
}
|
|
246
|
-
if (argType === "0x2::deny_list::DenyList") {
|
|
247
|
-
normalizedArgs.push((tx) => tx.object.denyList());
|
|
248
|
-
continue;
|
|
249
|
-
}
|
|
250
|
-
if (argType === "0x3::sui_system::SuiSystemState") {
|
|
251
|
-
normalizedArgs.push((tx) => tx.object.system());
|
|
252
|
-
continue;
|
|
253
|
-
}
|
|
254
|
-
let arg;
|
|
255
|
-
if (Array.isArray(args)) {
|
|
256
|
-
if (index >= args.length) {
|
|
257
|
-
throw new Error(
|
|
258
|
-
`Invalid number of arguments, expected at least ${index + 1}, got ${args.length}`
|
|
259
|
-
);
|
|
260
|
-
}
|
|
261
|
-
arg = args[index];
|
|
262
|
-
} else {
|
|
263
|
-
{
|
|
264
|
-
throw new Error(`Expected arguments to be passed as an array`);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
index += 1;
|
|
268
|
-
if (typeof arg === "function" || isArgument(arg)) {
|
|
269
|
-
normalizedArgs.push(arg);
|
|
270
|
-
continue;
|
|
271
|
-
}
|
|
272
|
-
const type = argTypes[i];
|
|
273
|
-
const bcsType = type === null ? null : getPureBcsSchema(type);
|
|
274
|
-
if (bcsType) {
|
|
275
|
-
const bytes = bcsType.serialize(arg);
|
|
276
|
-
normalizedArgs.push((tx) => tx.pure(bytes));
|
|
177
|
+
function encodeBetMetadata(metadata, partner) {
|
|
178
|
+
const keys = [];
|
|
179
|
+
const values = [];
|
|
180
|
+
for (const [key, value] of Object.entries(metadata ?? {})) {
|
|
181
|
+
if (RESERVED_METADATA_KEYS.has(key)) {
|
|
182
|
+
console.warn(
|
|
183
|
+
`Metadata key "${key}" is reserved and will be ignored when parsing metadata.`
|
|
184
|
+
);
|
|
277
185
|
continue;
|
|
278
186
|
}
|
|
279
|
-
if (
|
|
280
|
-
normalizedArgs.push((tx) => tx.object(arg));
|
|
187
|
+
if (value == null) {
|
|
281
188
|
continue;
|
|
282
189
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
return normalizedArgs;
|
|
286
|
-
}
|
|
287
|
-
var MoveStruct = class extends BcsStruct {
|
|
288
|
-
async get({
|
|
289
|
-
objectId,
|
|
290
|
-
...options
|
|
291
|
-
}) {
|
|
292
|
-
const [res] = await this.getMany({
|
|
293
|
-
...options,
|
|
294
|
-
objectIds: [objectId]
|
|
295
|
-
});
|
|
296
|
-
return res;
|
|
297
|
-
}
|
|
298
|
-
async getMany({
|
|
299
|
-
client,
|
|
300
|
-
...options
|
|
301
|
-
}) {
|
|
302
|
-
const response = await client.core.getObjects({
|
|
303
|
-
...options,
|
|
304
|
-
include: {
|
|
305
|
-
...options.include,
|
|
306
|
-
content: true
|
|
307
|
-
}
|
|
308
|
-
});
|
|
309
|
-
return response.objects.map((obj) => {
|
|
310
|
-
if (obj instanceof Error) {
|
|
311
|
-
throw obj;
|
|
312
|
-
}
|
|
313
|
-
return {
|
|
314
|
-
...obj,
|
|
315
|
-
json: this.parse(obj.content)
|
|
316
|
-
};
|
|
317
|
-
});
|
|
318
|
-
}
|
|
319
|
-
};
|
|
320
|
-
function stringify(val) {
|
|
321
|
-
if (typeof val === "object") {
|
|
322
|
-
return JSON.stringify(val, (val2) => val2);
|
|
190
|
+
keys.push(key);
|
|
191
|
+
values.push(encodeMetadataValue(key, value));
|
|
323
192
|
}
|
|
324
|
-
if (
|
|
325
|
-
return
|
|
193
|
+
if (!partner?.trim()) {
|
|
194
|
+
return { keys, values };
|
|
326
195
|
}
|
|
327
|
-
return
|
|
196
|
+
return {
|
|
197
|
+
keys: [...keys, "partner"],
|
|
198
|
+
values: [...values, encodeMetadataValue("partner", partner)]
|
|
199
|
+
};
|
|
328
200
|
}
|
|
329
201
|
|
|
330
202
|
// src/contracts/coinflip/coinflip.ts
|
|
@@ -372,6 +244,7 @@ function buildSharedStandardGameBetCall({
|
|
|
372
244
|
cashStake,
|
|
373
245
|
betCount,
|
|
374
246
|
metadata,
|
|
247
|
+
partner,
|
|
375
248
|
allowGasCoinShortcut = true,
|
|
376
249
|
buildRewardCoin
|
|
377
250
|
}) {
|
|
@@ -381,7 +254,7 @@ function buildSharedStandardGameBetCall({
|
|
|
381
254
|
const resolvedStake = toBigIntAmount(stake, "stake");
|
|
382
255
|
const resolvedCashStake = toBigIntAmount(cashStake ?? stake, "cashStake");
|
|
383
256
|
const resolvedBetCount = toBigIntAmount(betCount ?? 1, "betCount");
|
|
384
|
-
const encodedMetadata = encodeBetMetadata(metadata);
|
|
257
|
+
const encodedMetadata = encodeBetMetadata(metadata, partner);
|
|
385
258
|
const priceInfoObjectId = resolvePriceInfoObjectId(
|
|
386
259
|
config,
|
|
387
260
|
normalizedCoinType
|
|
@@ -471,7 +344,7 @@ function play2(options) {
|
|
|
471
344
|
|
|
472
345
|
// src/transactions/limbo.ts
|
|
473
346
|
function buildLimboTransaction(options) {
|
|
474
|
-
const scale = options.scale ??
|
|
347
|
+
const scale = options.scale ?? DEFAULT_LIMBO_MULTIPLIER_SCALE;
|
|
475
348
|
const numerator = Math.round(options.targetMultiplier * scale);
|
|
476
349
|
return buildSharedStandardGameBetTransaction({
|
|
477
350
|
...options,
|
|
@@ -558,14 +431,42 @@ function buildPlinkoTransaction(options) {
|
|
|
558
431
|
})(tx)
|
|
559
432
|
});
|
|
560
433
|
}
|
|
561
|
-
var $moduleName = "
|
|
562
|
-
|
|
434
|
+
var $moduleName = "0x2::vec_map";
|
|
435
|
+
function Entry(...typeParameters) {
|
|
436
|
+
return new MoveStruct({ name: `${$moduleName}::Entry<${typeParameters[0].name}, ${typeParameters[1].name}>`, fields: {
|
|
437
|
+
key: typeParameters[0],
|
|
438
|
+
value: typeParameters[1]
|
|
439
|
+
} });
|
|
440
|
+
}
|
|
441
|
+
function VecMap(...typeParameters) {
|
|
442
|
+
return new MoveStruct({ name: `${$moduleName}::VecMap<${typeParameters[0].name}, ${typeParameters[1].name}>`, fields: {
|
|
443
|
+
contents: bcs.vector(Entry(typeParameters[0], typeParameters[1]))
|
|
444
|
+
} });
|
|
445
|
+
}
|
|
446
|
+
var $moduleName2 = "0x2::balance";
|
|
447
|
+
var Balance = new MoveStruct({ name: `${$moduleName2}::Balance<phantom T0>`, fields: {
|
|
448
|
+
value: bcs.u64()
|
|
449
|
+
} });
|
|
450
|
+
var $moduleName3 = "0x0000000000000000000000000000000000000000000000000000000000000001::type_name";
|
|
451
|
+
var TypeName = new MoveStruct({ name: `${$moduleName3}::TypeName`, fields: {
|
|
563
452
|
name: bcs.string()
|
|
564
453
|
} });
|
|
565
454
|
|
|
566
455
|
// src/contracts/pvp-coinflip/pvp_coinflip.ts
|
|
567
|
-
var $
|
|
568
|
-
var
|
|
456
|
+
var $moduleName4 = "0xb43cf6583c0c15315c7e66f173af4be79ac40c38aad1fd92ec08638ab2026202::pvp_coinflip";
|
|
457
|
+
var Game = new MoveStruct({ name: `${$moduleName4}::Game<phantom T0>`, fields: {
|
|
458
|
+
id: bcs.Address,
|
|
459
|
+
creator: bcs.Address,
|
|
460
|
+
creator_is_tails: bcs.bool(),
|
|
461
|
+
is_private: bcs.bool(),
|
|
462
|
+
creator_metadata: VecMap(bcs.string(), bcs.vector(bcs.u8())),
|
|
463
|
+
joiner: bcs.Address,
|
|
464
|
+
winner: bcs.Address,
|
|
465
|
+
stake_per_player: bcs.u64(),
|
|
466
|
+
house_edge_bps: bcs.u64(),
|
|
467
|
+
stake_pot: Balance
|
|
468
|
+
} });
|
|
469
|
+
var GameCreatedEvent = new MoveStruct({ name: `${$moduleName4}::GameCreatedEvent<phantom T0>`, fields: {
|
|
569
470
|
game_id: bcs.Address,
|
|
570
471
|
creator: bcs.Address,
|
|
571
472
|
creator_is_tails: bcs.bool(),
|
|
@@ -575,7 +476,7 @@ var GameCreatedEvent = new MoveStruct({ name: `${$moduleName2}::GameCreatedEvent
|
|
|
575
476
|
house_edge_bps: bcs.u64(),
|
|
576
477
|
coin_type: TypeName
|
|
577
478
|
} });
|
|
578
|
-
var GameResolvedEvent = new MoveStruct({ name: `${$
|
|
479
|
+
var GameResolvedEvent = new MoveStruct({ name: `${$moduleName4}::GameResolvedEvent<phantom T0>`, fields: {
|
|
579
480
|
game_id: bcs.Address,
|
|
580
481
|
creator: bcs.Address,
|
|
581
482
|
joiner: bcs.Address,
|
|
@@ -589,7 +490,7 @@ var GameResolvedEvent = new MoveStruct({ name: `${$moduleName2}::GameResolvedEve
|
|
|
589
490
|
payout_amount: bcs.u64(),
|
|
590
491
|
coin_type: TypeName
|
|
591
492
|
} });
|
|
592
|
-
var GameCancelledEvent = new MoveStruct({ name: `${$
|
|
493
|
+
var GameCancelledEvent = new MoveStruct({ name: `${$moduleName4}::GameCancelledEvent<phantom T0>`, fields: {
|
|
593
494
|
game_id: bcs.Address,
|
|
594
495
|
creator: bcs.Address,
|
|
595
496
|
creator_is_tails: bcs.bool(),
|
|
@@ -657,7 +558,7 @@ function buildPvPCoinflipTransaction(action, options) {
|
|
|
657
558
|
game: "pvp-coinflip"
|
|
658
559
|
});
|
|
659
560
|
const normalizedCoinType = normalizeStructTag(options.coinType);
|
|
660
|
-
const encodedMetadata = encodeBetMetadata(options.metadata);
|
|
561
|
+
const encodedMetadata = encodeBetMetadata(options.metadata, options.partner);
|
|
661
562
|
switch (action) {
|
|
662
563
|
case "create": {
|
|
663
564
|
const createOptions = options;
|
|
@@ -685,12 +586,10 @@ function buildPvPCoinflipTransaction(action, options) {
|
|
|
685
586
|
}
|
|
686
587
|
case "join": {
|
|
687
588
|
const joinOptions = options;
|
|
688
|
-
const
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
useGasCoin: joinOptions.allowGasCoinShortcut
|
|
693
|
-
});
|
|
589
|
+
const priceInfoObjectId = resolvePriceInfoObjectId(
|
|
590
|
+
joinOptions.config,
|
|
591
|
+
normalizedCoinType
|
|
592
|
+
);
|
|
694
593
|
tx.add(
|
|
695
594
|
joinGame({
|
|
696
595
|
package: joinOptions.config.packageIds.pvpCoinflip,
|
|
@@ -698,10 +597,10 @@ function buildPvPCoinflipTransaction(action, options) {
|
|
|
698
597
|
arguments: [
|
|
699
598
|
joinOptions.gameId,
|
|
700
599
|
joinOptions.config.packageIds.sweetHouse,
|
|
701
|
-
betCoin,
|
|
600
|
+
tx.add(joinOptions.betCoin),
|
|
702
601
|
encodedMetadata.keys,
|
|
703
602
|
encodedMetadata.values,
|
|
704
|
-
|
|
603
|
+
priceInfoObjectId
|
|
705
604
|
]
|
|
706
605
|
})
|
|
707
606
|
);
|
|
@@ -754,7 +653,7 @@ function play4(options) {
|
|
|
754
653
|
|
|
755
654
|
// src/transactions/range.ts
|
|
756
655
|
function buildRangeTransaction(options) {
|
|
757
|
-
const scale = options.scale ??
|
|
656
|
+
const scale = options.scale ?? DEFAULT_RANGE_SCALE;
|
|
758
657
|
const leftPoint = Math.round(options.leftPoint * scale);
|
|
759
658
|
const rightPoint = Math.round(options.rightPoint * scale);
|
|
760
659
|
return buildSharedStandardGameBetTransaction({
|
|
@@ -843,32 +742,20 @@ function buildWheelTransaction(options) {
|
|
|
843
742
|
})(tx)
|
|
844
743
|
});
|
|
845
744
|
}
|
|
846
|
-
var $
|
|
847
|
-
var TypeName2 = new MoveStruct({ name: `${$
|
|
745
|
+
var $moduleName5 = "0x0000000000000000000000000000000000000000000000000000000000000001::type_name";
|
|
746
|
+
var TypeName2 = new MoveStruct({ name: `${$moduleName5}::TypeName`, fields: {
|
|
848
747
|
name: bcs.string()
|
|
849
748
|
} });
|
|
850
|
-
var $moduleName4 = "0xf391858d2a08473e8d4defcc8df89976bd7b123d3865c6b9341b237f7853dbbc::i64";
|
|
851
|
-
var I64 = new MoveStruct({ name: `${$moduleName4}::I64`, fields: {
|
|
852
|
-
bits: bcs.u64()
|
|
853
|
-
} });
|
|
854
|
-
|
|
855
|
-
// src/contracts/core/float.ts
|
|
856
|
-
var $moduleName5 = "0xf391858d2a08473e8d4defcc8df89976bd7b123d3865c6b9341b237f7853dbbc::float";
|
|
857
|
-
var Float = new MoveStruct({ name: `${$moduleName5}::Float`, fields: {
|
|
858
|
-
is_negative: bcs.bool(),
|
|
859
|
-
exp: I64,
|
|
860
|
-
mant: bcs.u64()
|
|
861
|
-
} });
|
|
862
749
|
var $moduleName6 = "0x2::vec_map";
|
|
863
|
-
function
|
|
750
|
+
function Entry2(...typeParameters) {
|
|
864
751
|
return new MoveStruct({ name: `${$moduleName6}::Entry<${typeParameters[0].name}, ${typeParameters[1].name}>`, fields: {
|
|
865
752
|
key: typeParameters[0],
|
|
866
753
|
value: typeParameters[1]
|
|
867
754
|
} });
|
|
868
755
|
}
|
|
869
|
-
function
|
|
756
|
+
function VecMap2(...typeParameters) {
|
|
870
757
|
return new MoveStruct({ name: `${$moduleName6}::VecMap<${typeParameters[0].name}, ${typeParameters[1].name}>`, fields: {
|
|
871
|
-
contents: bcs.vector(
|
|
758
|
+
contents: bcs.vector(Entry2(typeParameters[0], typeParameters[1]))
|
|
872
759
|
} });
|
|
873
760
|
}
|
|
874
761
|
|
|
@@ -881,24 +768,32 @@ var BetResultEvent = new MoveStruct({ name: `${$moduleName7}::BetResultEvent<pha
|
|
|
881
768
|
unsafe_oracle_usd_coin_price: Float,
|
|
882
769
|
adjusted_oracle_usd_coin_price: Float,
|
|
883
770
|
outcome_amount: bcs.u64(),
|
|
884
|
-
game_details:
|
|
885
|
-
metadata:
|
|
771
|
+
game_details: VecMap2(bcs.string(), bcs.vector(bcs.u8())),
|
|
772
|
+
metadata: VecMap2(bcs.string(), bcs.vector(bcs.u8()))
|
|
886
773
|
} });
|
|
774
|
+
|
|
775
|
+
// src/client.ts
|
|
887
776
|
function suigar({
|
|
888
|
-
name = "suigar"
|
|
777
|
+
name = "suigar",
|
|
778
|
+
partner
|
|
889
779
|
} = {}) {
|
|
890
780
|
return {
|
|
891
781
|
name,
|
|
892
782
|
register: (client) => {
|
|
893
|
-
return new SuigarClient({ client });
|
|
783
|
+
return new SuigarClient({ client, partner });
|
|
894
784
|
}
|
|
895
785
|
};
|
|
896
786
|
}
|
|
897
787
|
var SuigarClient = class {
|
|
898
788
|
#client;
|
|
899
789
|
#config;
|
|
900
|
-
|
|
790
|
+
#partner;
|
|
791
|
+
constructor({
|
|
792
|
+
client,
|
|
793
|
+
partner
|
|
794
|
+
}) {
|
|
901
795
|
this.#client = client;
|
|
796
|
+
this.#partner = partner;
|
|
902
797
|
const network = this.#client.network;
|
|
903
798
|
if (!SUPPORTED_SUI_NETWORKS.includes(network)) {
|
|
904
799
|
throw new Error(`Unsupported network: ${network}`);
|
|
@@ -933,9 +828,74 @@ var SuigarClient = class {
|
|
|
933
828
|
return toBase64(bytes);
|
|
934
829
|
}
|
|
935
830
|
/**
|
|
936
|
-
*
|
|
831
|
+
* Lists unresolved PvP coinflip games from the configured registry and resolves
|
|
832
|
+
* each entry into parsed onchain game state.
|
|
833
|
+
*
|
|
834
|
+
* This fetches dynamic fields from the PvP coinflip registry object, then loads
|
|
835
|
+
* each referenced game object through `resolvePvPConflipGame()`. Registry
|
|
836
|
+
* membership is the unresolved-state signal: when a game is joined and resolved,
|
|
837
|
+
* the Move flow removes it from the registry and deletes the live `Game` object.
|
|
838
|
+
* Use this when a product needs the current set of open PvP coinflip matches for
|
|
839
|
+
* browsing or lobby views.
|
|
840
|
+
*
|
|
841
|
+
* @param options Optional dynamic field pagination forwarded to `listDynamicFields()`, excluding `parentId`.
|
|
842
|
+
* @returns Parsed unresolved PvP coinflip game objects for the requested registry page.
|
|
843
|
+
*/
|
|
844
|
+
async getPvPCoinflipGames(options = {
|
|
845
|
+
limit: 50
|
|
846
|
+
}) {
|
|
847
|
+
const { dynamicFields } = await this.#client.core.listDynamicFields({
|
|
848
|
+
parentId: this.#config.registryIds.pvpCoinflip,
|
|
849
|
+
...options
|
|
850
|
+
});
|
|
851
|
+
return await Promise.all(
|
|
852
|
+
dynamicFields.map(({ childId }) => this.resolvePvPConflipGame(childId))
|
|
853
|
+
);
|
|
854
|
+
}
|
|
855
|
+
/**
|
|
856
|
+
* Fetches a PvP coinflip game object from chain and parses it into the SDK's
|
|
857
|
+
* normalized runtime shape.
|
|
858
|
+
*
|
|
859
|
+
* This resolves the raw object through the configured client, requires the
|
|
860
|
+
* object's `content` to be present, decodes that content with the generated
|
|
861
|
+
* `PvPCoinflipGame` BCS parser, and normalizes the generic coin type into a
|
|
862
|
+
* standard struct tag string. Use this when a product needs the current state
|
|
863
|
+
* of a specific PvP coinflip match before rendering join, cancel, or result UI.
|
|
864
|
+
*
|
|
865
|
+
* @param gameId On-chain object id of the PvP coinflip game.
|
|
866
|
+
* @returns Parsed PvP coinflip game state with a normalized `coinType`.
|
|
867
|
+
* @throws Error If the object cannot be decoded because no content was returned.
|
|
868
|
+
*/
|
|
869
|
+
async resolvePvPConflipGame(gameId) {
|
|
870
|
+
const { object } = await this.#client.core.getObject({
|
|
871
|
+
objectId: gameId,
|
|
872
|
+
include: { content: true }
|
|
873
|
+
});
|
|
874
|
+
if (!object.content) {
|
|
875
|
+
throw new Error("Unable to resolve PvP coinflip from game object");
|
|
876
|
+
}
|
|
877
|
+
return {
|
|
878
|
+
...Game.parse(object.content),
|
|
879
|
+
coinType: normalizeStructTag(parseStructTag(object.type).typeParams[0])
|
|
880
|
+
};
|
|
881
|
+
}
|
|
882
|
+
/**
|
|
883
|
+
* BCS struct constructors for decoding on-chain objects and events related to Suigar games.
|
|
884
|
+
*
|
|
885
|
+
* These can be used to parse the `content` field of on-chain objects and events into structured data with the
|
|
886
|
+
* expected types. For example, use `client.suigar.bcs.PvPCoinflipGame.parse(object.content)` to decode a PvP
|
|
887
|
+
* coinflip game object.
|
|
888
|
+
*
|
|
889
|
+
* Note that these constructors are not meant for encoding transaction arguments, as the SDK's transaction
|
|
890
|
+
* builders handle argument serialization internally. Use these primarily for decoding and parsing on-chain data.
|
|
937
891
|
*/
|
|
938
892
|
bcs = {
|
|
893
|
+
// Objects
|
|
894
|
+
/**
|
|
895
|
+
* Object representing the state of a PvP coinflip game, as stored on-chain.
|
|
896
|
+
*/
|
|
897
|
+
PvPCoinflipGame: Game,
|
|
898
|
+
// Events
|
|
939
899
|
/**
|
|
940
900
|
* Event emitted at the end of a standard game (e.g., Coinflip, Limbo), containing the result and payout information.
|
|
941
901
|
*/
|
|
@@ -969,27 +929,32 @@ var SuigarClient = class {
|
|
|
969
929
|
case "coinflip":
|
|
970
930
|
return buildCoinflipTransaction({
|
|
971
931
|
...options,
|
|
972
|
-
config: this.#config
|
|
932
|
+
config: this.#config,
|
|
933
|
+
partner: this.#partner
|
|
973
934
|
});
|
|
974
935
|
case "limbo":
|
|
975
936
|
return buildLimboTransaction({
|
|
976
937
|
...options,
|
|
977
|
-
config: this.#config
|
|
938
|
+
config: this.#config,
|
|
939
|
+
partner: this.#partner
|
|
978
940
|
});
|
|
979
941
|
case "plinko":
|
|
980
942
|
return buildPlinkoTransaction({
|
|
981
943
|
...options,
|
|
982
|
-
config: this.#config
|
|
944
|
+
config: this.#config,
|
|
945
|
+
partner: this.#partner
|
|
983
946
|
});
|
|
984
947
|
case "range":
|
|
985
948
|
return buildRangeTransaction({
|
|
986
949
|
...options,
|
|
987
|
-
config: this.#config
|
|
950
|
+
config: this.#config,
|
|
951
|
+
partner: this.#partner
|
|
988
952
|
});
|
|
989
953
|
case "wheel":
|
|
990
954
|
return buildWheelTransaction({
|
|
991
955
|
...options,
|
|
992
|
-
config: this.#config
|
|
956
|
+
config: this.#config,
|
|
957
|
+
partner: this.#partner
|
|
993
958
|
});
|
|
994
959
|
default:
|
|
995
960
|
throw new Error(`Unsupported game: ${gameId}`);
|
|
@@ -1003,12 +968,45 @@ var SuigarClient = class {
|
|
|
1003
968
|
* @returns Prepared PvP coinflip transaction.
|
|
1004
969
|
*/
|
|
1005
970
|
createPvPCoinflipTransaction: (action, options) => {
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
971
|
+
switch (action) {
|
|
972
|
+
case "create":
|
|
973
|
+
return buildPvPCoinflipTransaction("create", {
|
|
974
|
+
...options,
|
|
975
|
+
config: this.#config,
|
|
976
|
+
partner: this.#partner
|
|
977
|
+
});
|
|
978
|
+
case "join": {
|
|
979
|
+
const joinOptions = options;
|
|
980
|
+
return buildPvPCoinflipTransaction("join", {
|
|
981
|
+
...joinOptions,
|
|
982
|
+
betCoin: this.#createPvPCoinflipBetCoin(joinOptions),
|
|
983
|
+
config: this.#config,
|
|
984
|
+
partner: this.#partner
|
|
985
|
+
});
|
|
986
|
+
}
|
|
987
|
+
case "cancel":
|
|
988
|
+
return buildPvPCoinflipTransaction("cancel", {
|
|
989
|
+
...options,
|
|
990
|
+
config: this.#config,
|
|
991
|
+
partner: this.#partner
|
|
992
|
+
});
|
|
993
|
+
default:
|
|
994
|
+
throw new Error(`Unsupported PvP coinflip action: ${action}`);
|
|
995
|
+
}
|
|
1010
996
|
}
|
|
1011
997
|
};
|
|
998
|
+
#createPvPCoinflipBetCoin(options) {
|
|
999
|
+
return async (tx) => {
|
|
1000
|
+
const { stake_per_player } = await this.resolvePvPConflipGame(
|
|
1001
|
+
options.gameId
|
|
1002
|
+
);
|
|
1003
|
+
return tx.coin({
|
|
1004
|
+
type: options.coinType,
|
|
1005
|
+
balance: BigInt(stake_per_player),
|
|
1006
|
+
useGasCoin: options.allowGasCoinShortcut
|
|
1007
|
+
});
|
|
1008
|
+
};
|
|
1009
|
+
}
|
|
1012
1010
|
};
|
|
1013
1011
|
|
|
1014
|
-
export { suigar };
|
|
1012
|
+
export { SuigarClient, suigar };
|