@suigar/sdk 2.0.0-beta.3 → 2.0.0-beta.5

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/index.cjs CHANGED
@@ -4,6 +4,8 @@ var utils = require('@mysten/sui/utils');
4
4
  var bcs = require('@mysten/sui/bcs');
5
5
  var transactions = require('@mysten/sui/transactions');
6
6
 
7
+ // src/client.ts
8
+
7
9
  // src/types/network.type.ts
8
10
  var SUPPORTED_SUI_NETWORKS = [
9
11
  "mainnet",
@@ -64,13 +66,31 @@ var PRICE_INFO_OBJECT_IDS = {
64
66
  testnet: { ...TESTNET_PRICE_INFO_OBJECT_IDS }
65
67
  };
66
68
 
67
- // src/utils/config.ts
69
+ // src/configs/registry.mainnet.ts
70
+ var PVP_COINFLIP_REGISTRY_ID = "0x3d73568546c539c1da3eb2b8fe917faef3c0acdbec78a67fe6d52800a0729349";
71
+
72
+ // src/configs/registry.testnet.ts
73
+ var PVP_COINFLIP_REGISTRY_ID2 = "0x99f20d8e4be012ea14a681144ae72ac349d0a1a1585205880183eb167f075bad";
74
+
75
+ // src/configs/registry.ts
76
+ var REGISTRY_IDS = {
77
+ mainnet: {
78
+ pvpCoinflip: PVP_COINFLIP_REGISTRY_ID
79
+ },
80
+ testnet: {
81
+ pvpCoinflip: PVP_COINFLIP_REGISTRY_ID2
82
+ }
83
+ };
84
+
85
+ // src/helpers/config.ts
68
86
  function resolveSuigarConfig(network) {
69
87
  const packageIds = PACKAGE_IDS[network];
88
+ const registryIds = REGISTRY_IDS[network];
70
89
  const coinTypes = COIN_TYPES[network];
71
90
  const priceInfoObjectIds = PRICE_INFO_OBJECT_IDS[network];
72
91
  return {
73
92
  packageIds: { ...packageIds },
93
+ registryIds: { ...registryIds },
74
94
  coinTypes: {
75
95
  sui: utils.normalizeStructTag(coinTypes.sui),
76
96
  usdc: utils.normalizeStructTag(coinTypes.usdc)
@@ -125,11 +145,12 @@ function resolveSupportedCoin(config, coinType) {
125
145
  `Unsupported coin type ${coinType}. Supported coin types: ${entries.map(([, configuredCoinType]) => configuredCoinType).join(", ")}`
126
146
  );
127
147
  }
128
- var ADDRESS_METADATA_KEYS = /* @__PURE__ */ new Set(["referrer", "partner"]);
148
+ var ADDRESS_METADATA_KEYS = /* @__PURE__ */ new Set(["partner"]);
149
+ var RESERVED_METADATA_KEYS = /* @__PURE__ */ new Set([...ADDRESS_METADATA_KEYS, "referrer"]);
129
150
  var textEncoder = new TextEncoder();
130
- var parseHexAddress = (value) => {
151
+ function parseHexAddress(value) {
131
152
  const trimmed = value.trim();
132
- if (!trimmed) return null;
153
+ if (!trimmed || !utils.isValidSuiAddress(trimmed)) return null;
133
154
  try {
134
155
  const normalized = utils.normalizeSuiAddress(trimmed).slice(2);
135
156
  const bytes = new Uint8Array(normalized.length / 2);
@@ -143,53 +164,42 @@ var parseHexAddress = (value) => {
143
164
  } catch {
144
165
  return null;
145
166
  }
146
- };
147
- function encodeBetMetadata(metadata) {
167
+ }
168
+ function encodeMetadataValue(key, value) {
169
+ if (value instanceof Uint8Array) {
170
+ return Array.from(value);
171
+ }
172
+ if (Array.isArray(value)) {
173
+ return value;
174
+ }
175
+ if (typeof value === "string" && ADDRESS_METADATA_KEYS.has(key)) {
176
+ return Array.from(parseHexAddress(value) ?? textEncoder.encode(value));
177
+ }
178
+ return Array.from(textEncoder.encode(String(value)));
179
+ }
180
+ function encodeBetMetadata(metadata, partner) {
148
181
  const keys = [];
149
182
  const values = [];
150
183
  for (const [key, value] of Object.entries(metadata ?? {})) {
151
- if (value === void 0 || value === null) {
184
+ if (RESERVED_METADATA_KEYS.has(key)) {
185
+ console.warn(
186
+ `Metadata key "${key}" is reserved and will be ignored when parsing metadata.`
187
+ );
152
188
  continue;
153
189
  }
154
- let encodedValue;
155
- if (value instanceof Uint8Array) {
156
- encodedValue = Array.from(value);
157
- } else if (Array.isArray(value)) {
158
- encodedValue = value;
159
- } else if (typeof value === "string" && ADDRESS_METADATA_KEYS.has(key)) {
160
- encodedValue = Array.from(
161
- parseHexAddress(value) ?? textEncoder.encode(value)
162
- );
163
- } else {
164
- encodedValue = Array.from(textEncoder.encode(String(value)));
190
+ if (value == null) {
191
+ continue;
165
192
  }
166
193
  keys.push(key);
167
- values.push(encodedValue);
194
+ values.push(encodeMetadataValue(key, value));
168
195
  }
169
- return { keys, values };
170
- }
171
-
172
- // src/utils/shared.ts
173
- var DEFAULT_GAS_BUDGET_MIST = 5e7;
174
- var RANGE_FIXED_POINT_SCALE = 1e6;
175
- var LIMBO_MULTIPLIER_SCALE = 100;
176
- function toBigIntAmount(value, fieldName) {
177
- if (typeof value === "bigint") {
178
- if (value < 0n) {
179
- throw new Error(`${fieldName} must be non-negative`);
180
- }
181
- return value;
182
- }
183
- if (!Number.isFinite(value) || value < 0) {
184
- throw new Error(`${fieldName} must be a finite non-negative number`);
185
- }
186
- return BigInt(Math.trunc(value));
187
- }
188
- function toU8Number(value, fieldName) {
189
- if (!Number.isInteger(value) || value < 0 || value > 255) {
190
- throw new Error(`${fieldName} must be an integer between 0 and 255`);
196
+ if (!partner?.trim()) {
197
+ return { keys, values };
191
198
  }
192
- return value;
199
+ return {
200
+ keys: [...keys, "partner"],
201
+ values: [...values, encodeMetadataValue("partner", partner)]
202
+ };
193
203
  }
194
204
  var MOVE_STDLIB_ADDRESS = utils.normalizeSuiAddress("0x1");
195
205
  var SUI_FRAMEWORK_ADDRESS = utils.normalizeSuiAddress("0x2");
@@ -352,6 +362,41 @@ function play(options) {
352
362
  typeArguments: options.typeArguments
353
363
  });
354
364
  }
365
+ var DEFAULT_GAS_BUDGET_MIST = utils.parseToMist("0.05");
366
+ var DEFAULT_RANGE_SCALE = 1e6;
367
+ var DEFAULT_LIMBO_MULTIPLIER_SCALE = 100;
368
+
369
+ // src/utils/numeric.ts
370
+ function toBigIntAmount(value, fieldName) {
371
+ if (typeof value === "bigint") {
372
+ if (value < 0n) {
373
+ throw new Error(`${fieldName} must be non-negative`);
374
+ }
375
+ return value;
376
+ }
377
+ if (!Number.isFinite(value) || value < 0) {
378
+ throw new Error(`${fieldName} must be a finite non-negative number`);
379
+ }
380
+ return BigInt(Math.trunc(value));
381
+ }
382
+ function toU8Number(value, fieldName) {
383
+ if (!Number.isInteger(value) || value < 0 || value > 255) {
384
+ throw new Error(`${fieldName} must be an integer between 0 and 255`);
385
+ }
386
+ return value;
387
+ }
388
+ var $moduleName = "0xf391858d2a08473e8d4defcc8df89976bd7b123d3865c6b9341b237f7853dbbc::i64";
389
+ var I64 = new MoveStruct({ name: `${$moduleName}::I64`, fields: {
390
+ bits: bcs.bcs.u64()
391
+ } });
392
+
393
+ // src/contracts/core/float.ts
394
+ var $moduleName2 = "0xf391858d2a08473e8d4defcc8df89976bd7b123d3865c6b9341b237f7853dbbc::float";
395
+ var Float = new MoveStruct({ name: `${$moduleName2}::Float`, fields: {
396
+ is_negative: bcs.bcs.bool(),
397
+ exp: I64,
398
+ mant: bcs.bcs.u64()
399
+ } });
355
400
  function createBaseGameTransaction({
356
401
  config,
357
402
  game,
@@ -374,6 +419,7 @@ function buildSharedStandardGameBetCall({
374
419
  cashStake,
375
420
  betCount,
376
421
  metadata,
422
+ partner,
377
423
  allowGasCoinShortcut = true,
378
424
  buildRewardCoin
379
425
  }) {
@@ -383,7 +429,7 @@ function buildSharedStandardGameBetCall({
383
429
  const resolvedStake = toBigIntAmount(stake, "stake");
384
430
  const resolvedCashStake = toBigIntAmount(cashStake ?? stake, "cashStake");
385
431
  const resolvedBetCount = toBigIntAmount(betCount ?? 1, "betCount");
386
- const encodedMetadata = encodeBetMetadata(metadata);
432
+ const encodedMetadata = encodeBetMetadata(metadata, partner);
387
433
  const priceInfoObjectId = resolvePriceInfoObjectId(
388
434
  config,
389
435
  normalizedCoinType
@@ -473,7 +519,7 @@ function play2(options) {
473
519
 
474
520
  // src/transactions/limbo.ts
475
521
  function buildLimboTransaction(options) {
476
- const scale = options.scale ?? LIMBO_MULTIPLIER_SCALE;
522
+ const scale = options.scale ?? DEFAULT_LIMBO_MULTIPLIER_SCALE;
477
523
  const numerator = Math.round(options.targetMultiplier * scale);
478
524
  return buildSharedStandardGameBetTransaction({
479
525
  ...options,
@@ -560,14 +606,42 @@ function buildPlinkoTransaction(options) {
560
606
  })(tx)
561
607
  });
562
608
  }
563
- var $moduleName = "0x0000000000000000000000000000000000000000000000000000000000000001::type_name";
564
- var TypeName = new MoveStruct({ name: `${$moduleName}::TypeName`, fields: {
609
+ var $moduleName3 = "0x2::vec_map";
610
+ function Entry(...typeParameters) {
611
+ return new MoveStruct({ name: `${$moduleName3}::Entry<${typeParameters[0].name}, ${typeParameters[1].name}>`, fields: {
612
+ key: typeParameters[0],
613
+ value: typeParameters[1]
614
+ } });
615
+ }
616
+ function VecMap(...typeParameters) {
617
+ return new MoveStruct({ name: `${$moduleName3}::VecMap<${typeParameters[0].name}, ${typeParameters[1].name}>`, fields: {
618
+ contents: bcs.bcs.vector(Entry(typeParameters[0], typeParameters[1]))
619
+ } });
620
+ }
621
+ var $moduleName4 = "0x2::balance";
622
+ var Balance = new MoveStruct({ name: `${$moduleName4}::Balance<phantom T0>`, fields: {
623
+ value: bcs.bcs.u64()
624
+ } });
625
+ var $moduleName5 = "0x0000000000000000000000000000000000000000000000000000000000000001::type_name";
626
+ var TypeName = new MoveStruct({ name: `${$moduleName5}::TypeName`, fields: {
565
627
  name: bcs.bcs.string()
566
628
  } });
567
629
 
568
630
  // src/contracts/pvp-coinflip/pvp_coinflip.ts
569
- var $moduleName2 = "0xb43cf6583c0c15315c7e66f173af4be79ac40c38aad1fd92ec08638ab2026202::pvp_coinflip";
570
- var GameCreatedEvent = new MoveStruct({ name: `${$moduleName2}::GameCreatedEvent<phantom T0>`, fields: {
631
+ var $moduleName6 = "0xb43cf6583c0c15315c7e66f173af4be79ac40c38aad1fd92ec08638ab2026202::pvp_coinflip";
632
+ var Game = new MoveStruct({ name: `${$moduleName6}::Game<phantom T0>`, fields: {
633
+ id: bcs.bcs.Address,
634
+ creator: bcs.bcs.Address,
635
+ creator_is_tails: bcs.bcs.bool(),
636
+ is_private: bcs.bcs.bool(),
637
+ creator_metadata: VecMap(bcs.bcs.string(), bcs.bcs.vector(bcs.bcs.u8())),
638
+ joiner: bcs.bcs.Address,
639
+ winner: bcs.bcs.Address,
640
+ stake_per_player: bcs.bcs.u64(),
641
+ house_edge_bps: bcs.bcs.u64(),
642
+ stake_pot: Balance
643
+ } });
644
+ var GameCreatedEvent = new MoveStruct({ name: `${$moduleName6}::GameCreatedEvent<phantom T0>`, fields: {
571
645
  game_id: bcs.bcs.Address,
572
646
  creator: bcs.bcs.Address,
573
647
  creator_is_tails: bcs.bcs.bool(),
@@ -577,7 +651,7 @@ var GameCreatedEvent = new MoveStruct({ name: `${$moduleName2}::GameCreatedEvent
577
651
  house_edge_bps: bcs.bcs.u64(),
578
652
  coin_type: TypeName
579
653
  } });
580
- var GameResolvedEvent = new MoveStruct({ name: `${$moduleName2}::GameResolvedEvent<phantom T0>`, fields: {
654
+ var GameResolvedEvent = new MoveStruct({ name: `${$moduleName6}::GameResolvedEvent<phantom T0>`, fields: {
581
655
  game_id: bcs.bcs.Address,
582
656
  creator: bcs.bcs.Address,
583
657
  joiner: bcs.bcs.Address,
@@ -591,7 +665,7 @@ var GameResolvedEvent = new MoveStruct({ name: `${$moduleName2}::GameResolvedEve
591
665
  payout_amount: bcs.bcs.u64(),
592
666
  coin_type: TypeName
593
667
  } });
594
- var GameCancelledEvent = new MoveStruct({ name: `${$moduleName2}::GameCancelledEvent<phantom T0>`, fields: {
668
+ var GameCancelledEvent = new MoveStruct({ name: `${$moduleName6}::GameCancelledEvent<phantom T0>`, fields: {
595
669
  game_id: bcs.bcs.Address,
596
670
  creator: bcs.bcs.Address,
597
671
  creator_is_tails: bcs.bcs.bool(),
@@ -659,7 +733,7 @@ function buildPvPCoinflipTransaction(action, options) {
659
733
  game: "pvp-coinflip"
660
734
  });
661
735
  const normalizedCoinType = utils.normalizeStructTag(options.coinType);
662
- const encodedMetadata = encodeBetMetadata(options.metadata);
736
+ const encodedMetadata = encodeBetMetadata(options.metadata, options.partner);
663
737
  switch (action) {
664
738
  case "create": {
665
739
  const createOptions = options;
@@ -687,12 +761,10 @@ function buildPvPCoinflipTransaction(action, options) {
687
761
  }
688
762
  case "join": {
689
763
  const joinOptions = options;
690
- const stake = toBigIntAmount(joinOptions.stake, "stake");
691
- const betCoin = tx.coin({
692
- type: normalizedCoinType,
693
- balance: stake,
694
- useGasCoin: joinOptions.allowGasCoinShortcut
695
- });
764
+ const priceInfoObjectId = resolvePriceInfoObjectId(
765
+ joinOptions.config,
766
+ normalizedCoinType
767
+ );
696
768
  tx.add(
697
769
  joinGame({
698
770
  package: joinOptions.config.packageIds.pvpCoinflip,
@@ -700,10 +772,10 @@ function buildPvPCoinflipTransaction(action, options) {
700
772
  arguments: [
701
773
  joinOptions.gameId,
702
774
  joinOptions.config.packageIds.sweetHouse,
703
- betCoin,
775
+ tx.add(joinOptions.betCoin),
704
776
  encodedMetadata.keys,
705
777
  encodedMetadata.values,
706
- joinOptions.extraObjectId
778
+ priceInfoObjectId
707
779
  ]
708
780
  })
709
781
  );
@@ -756,7 +828,7 @@ function play4(options) {
756
828
 
757
829
  // src/transactions/range.ts
758
830
  function buildRangeTransaction(options) {
759
- const scale = options.scale ?? RANGE_FIXED_POINT_SCALE;
831
+ const scale = options.scale ?? DEFAULT_RANGE_SCALE;
760
832
  const leftPoint = Math.round(options.leftPoint * scale);
761
833
  const rightPoint = Math.round(options.rightPoint * scale);
762
834
  return buildSharedStandardGameBetTransaction({
@@ -845,62 +917,58 @@ function buildWheelTransaction(options) {
845
917
  })(tx)
846
918
  });
847
919
  }
848
- var $moduleName3 = "0x0000000000000000000000000000000000000000000000000000000000000001::type_name";
849
- var TypeName2 = new MoveStruct({ name: `${$moduleName3}::TypeName`, fields: {
920
+ var $moduleName7 = "0x0000000000000000000000000000000000000000000000000000000000000001::type_name";
921
+ var TypeName2 = new MoveStruct({ name: `${$moduleName7}::TypeName`, fields: {
850
922
  name: bcs.bcs.string()
851
923
  } });
852
- var $moduleName4 = "0xf391858d2a08473e8d4defcc8df89976bd7b123d3865c6b9341b237f7853dbbc::i64";
853
- var I64 = new MoveStruct({ name: `${$moduleName4}::I64`, fields: {
854
- bits: bcs.bcs.u64()
855
- } });
856
-
857
- // src/contracts/core/float.ts
858
- var $moduleName5 = "0xf391858d2a08473e8d4defcc8df89976bd7b123d3865c6b9341b237f7853dbbc::float";
859
- var Float = new MoveStruct({ name: `${$moduleName5}::Float`, fields: {
860
- is_negative: bcs.bcs.bool(),
861
- exp: I64,
862
- mant: bcs.bcs.u64()
863
- } });
864
- var $moduleName6 = "0x2::vec_map";
865
- function Entry(...typeParameters) {
866
- return new MoveStruct({ name: `${$moduleName6}::Entry<${typeParameters[0].name}, ${typeParameters[1].name}>`, fields: {
924
+ var $moduleName8 = "0x2::vec_map";
925
+ function Entry2(...typeParameters) {
926
+ return new MoveStruct({ name: `${$moduleName8}::Entry<${typeParameters[0].name}, ${typeParameters[1].name}>`, fields: {
867
927
  key: typeParameters[0],
868
928
  value: typeParameters[1]
869
929
  } });
870
930
  }
871
- function VecMap(...typeParameters) {
872
- return new MoveStruct({ name: `${$moduleName6}::VecMap<${typeParameters[0].name}, ${typeParameters[1].name}>`, fields: {
873
- contents: bcs.bcs.vector(Entry(typeParameters[0], typeParameters[1]))
931
+ function VecMap2(...typeParameters) {
932
+ return new MoveStruct({ name: `${$moduleName8}::VecMap<${typeParameters[0].name}, ${typeParameters[1].name}>`, fields: {
933
+ contents: bcs.bcs.vector(Entry2(typeParameters[0], typeParameters[1]))
874
934
  } });
875
935
  }
876
936
 
877
937
  // src/contracts/core/core.ts
878
- var $moduleName7 = "0xf391858d2a08473e8d4defcc8df89976bd7b123d3865c6b9341b237f7853dbbc::core";
879
- var BetResultEvent = new MoveStruct({ name: `${$moduleName7}::BetResultEvent<phantom T0>`, fields: {
938
+ var $moduleName9 = "0xf391858d2a08473e8d4defcc8df89976bd7b123d3865c6b9341b237f7853dbbc::core";
939
+ var BetResultEvent = new MoveStruct({ name: `${$moduleName9}::BetResultEvent<phantom T0>`, fields: {
880
940
  player: bcs.bcs.Address,
881
941
  coin_type: TypeName2,
882
942
  stake_amount: bcs.bcs.u64(),
883
943
  unsafe_oracle_usd_coin_price: Float,
884
944
  adjusted_oracle_usd_coin_price: Float,
885
945
  outcome_amount: bcs.bcs.u64(),
886
- game_details: VecMap(bcs.bcs.string(), bcs.bcs.vector(bcs.bcs.u8())),
887
- metadata: VecMap(bcs.bcs.string(), bcs.bcs.vector(bcs.bcs.u8()))
946
+ game_details: VecMap2(bcs.bcs.string(), bcs.bcs.vector(bcs.bcs.u8())),
947
+ metadata: VecMap2(bcs.bcs.string(), bcs.bcs.vector(bcs.bcs.u8()))
888
948
  } });
949
+
950
+ // src/client.ts
889
951
  function suigar({
890
- name = "suigar"
952
+ name = "suigar",
953
+ partner
891
954
  } = {}) {
892
955
  return {
893
956
  name,
894
957
  register: (client) => {
895
- return new SuigarClient({ client });
958
+ return new SuigarClient({ client, partner });
896
959
  }
897
960
  };
898
961
  }
899
962
  var SuigarClient = class {
900
963
  #client;
901
964
  #config;
902
- constructor({ client }) {
965
+ #partner;
966
+ constructor({
967
+ client,
968
+ partner
969
+ }) {
903
970
  this.#client = client;
971
+ this.#partner = partner;
904
972
  const network = this.#client.network;
905
973
  if (!SUPPORTED_SUI_NETWORKS.includes(network)) {
906
974
  throw new Error(`Unsupported network: ${network}`);
@@ -935,9 +1003,88 @@ var SuigarClient = class {
935
1003
  return utils.toBase64(bytes);
936
1004
  }
937
1005
  /**
938
- * BCS struct constructors for decoding Suigar events emitted on-chain.
1006
+ * Lists unresolved PvP coinflip games from the configured registry and resolves
1007
+ * each entry into parsed onchain game state.
1008
+ *
1009
+ * This fetches dynamic fields from the PvP coinflip registry object, then loads
1010
+ * each referenced game object through `resolvePvPConflipGame()`. Registry
1011
+ * membership is the unresolved-state signal: when a game is joined and resolved,
1012
+ * the Move flow removes it from the registry and deletes the live `Game` object.
1013
+ * Use this when a product needs the current set of open PvP coinflip matches for
1014
+ * browsing or lobby views.
1015
+ *
1016
+ * @param options Optional dynamic field pagination forwarded to `listDynamicFields()`, excluding `parentId`.
1017
+ * Pass `rejectOnError: true` to fail the whole lookup when any referenced game
1018
+ * cannot be resolved. By default, failed game resolutions are skipped and only
1019
+ * successfully parsed unresolved games are returned.
1020
+ * @returns Parsed unresolved PvP coinflip game objects for the requested
1021
+ * registry page. When `rejectOnError` is `false`, entries that fail
1022
+ * `resolvePvPConflipGame()` are omitted from the returned array.
1023
+ */
1024
+ async getPvPCoinflipGames(options = {
1025
+ limit: 50
1026
+ }) {
1027
+ const { rejectOnError = false, ...listOptions } = options;
1028
+ const { dynamicFields } = await this.#client.core.listDynamicFields({
1029
+ parentId: this.#config.registryIds.pvpCoinflip,
1030
+ ...listOptions
1031
+ });
1032
+ if (rejectOnError) {
1033
+ return Promise.all(
1034
+ dynamicFields.map(({ childId }) => this.resolvePvPConflipGame(childId))
1035
+ );
1036
+ }
1037
+ const settledGames = await Promise.allSettled(
1038
+ dynamicFields.map(({ childId }) => this.resolvePvPConflipGame(childId))
1039
+ );
1040
+ return settledGames.flatMap(
1041
+ (result) => result.status === "fulfilled" ? [result.value] : []
1042
+ );
1043
+ }
1044
+ /**
1045
+ * Fetches a PvP coinflip game object from chain and parses it into the SDK's
1046
+ * normalized runtime shape.
1047
+ *
1048
+ * This resolves the raw object through the configured client, requires the
1049
+ * object's `content` to be present, decodes that content with the generated
1050
+ * `PvPCoinflipGame` BCS parser, and normalizes the generic coin type into a
1051
+ * standard struct tag string. Use this when a product needs the current state
1052
+ * of a specific PvP coinflip match before rendering join, cancel, or result UI.
1053
+ *
1054
+ * @param gameId On-chain object id of the PvP coinflip game.
1055
+ * @returns Parsed PvP coinflip game state with a normalized `coinType`.
1056
+ * @throws Error If the object cannot be decoded because no content was returned.
1057
+ */
1058
+ async resolvePvPConflipGame(gameId) {
1059
+ const { object } = await this.#client.core.getObject({
1060
+ objectId: gameId,
1061
+ include: { content: true }
1062
+ });
1063
+ if (!object.content) {
1064
+ throw new Error("Unable to resolve PvP coinflip from game object");
1065
+ }
1066
+ return {
1067
+ ...Game.parse(object.content),
1068
+ coinType: utils.normalizeStructTag(utils.parseStructTag(object.type).typeParams[0])
1069
+ };
1070
+ }
1071
+ /**
1072
+ * BCS struct constructors for decoding on-chain objects and events related to Suigar games.
1073
+ *
1074
+ * These can be used to parse the `content` field of on-chain objects and events into structured data with the
1075
+ * expected types. For example, use `client.suigar.bcs.PvPCoinflipGame.parse(object.content)` to decode a PvP
1076
+ * coinflip game object.
1077
+ *
1078
+ * Note that these constructors are not meant for encoding transaction arguments, as the SDK's transaction
1079
+ * builders handle argument serialization internally. Use these primarily for decoding and parsing on-chain data.
939
1080
  */
940
1081
  bcs = {
1082
+ // Objects
1083
+ /**
1084
+ * Object representing the state of a PvP coinflip game, as stored on-chain.
1085
+ */
1086
+ PvPCoinflipGame: Game,
1087
+ // Events
941
1088
  /**
942
1089
  * Event emitted at the end of a standard game (e.g., Coinflip, Limbo), containing the result and payout information.
943
1090
  */
@@ -971,27 +1118,32 @@ var SuigarClient = class {
971
1118
  case "coinflip":
972
1119
  return buildCoinflipTransaction({
973
1120
  ...options,
974
- config: this.#config
1121
+ config: this.#config,
1122
+ partner: this.#partner
975
1123
  });
976
1124
  case "limbo":
977
1125
  return buildLimboTransaction({
978
1126
  ...options,
979
- config: this.#config
1127
+ config: this.#config,
1128
+ partner: this.#partner
980
1129
  });
981
1130
  case "plinko":
982
1131
  return buildPlinkoTransaction({
983
1132
  ...options,
984
- config: this.#config
1133
+ config: this.#config,
1134
+ partner: this.#partner
985
1135
  });
986
1136
  case "range":
987
1137
  return buildRangeTransaction({
988
1138
  ...options,
989
- config: this.#config
1139
+ config: this.#config,
1140
+ partner: this.#partner
990
1141
  });
991
1142
  case "wheel":
992
1143
  return buildWheelTransaction({
993
1144
  ...options,
994
- config: this.#config
1145
+ config: this.#config,
1146
+ partner: this.#partner
995
1147
  });
996
1148
  default:
997
1149
  throw new Error(`Unsupported game: ${gameId}`);
@@ -1005,12 +1157,46 @@ var SuigarClient = class {
1005
1157
  * @returns Prepared PvP coinflip transaction.
1006
1158
  */
1007
1159
  createPvPCoinflipTransaction: (action, options) => {
1008
- return buildPvPCoinflipTransaction(action, {
1009
- ...options,
1010
- config: this.#config
1011
- });
1160
+ switch (action) {
1161
+ case "create":
1162
+ return buildPvPCoinflipTransaction("create", {
1163
+ ...options,
1164
+ config: this.#config,
1165
+ partner: this.#partner
1166
+ });
1167
+ case "join": {
1168
+ const joinOptions = options;
1169
+ return buildPvPCoinflipTransaction("join", {
1170
+ ...joinOptions,
1171
+ betCoin: this.#createPvPCoinflipBetCoin(joinOptions),
1172
+ config: this.#config,
1173
+ partner: this.#partner
1174
+ });
1175
+ }
1176
+ case "cancel":
1177
+ return buildPvPCoinflipTransaction("cancel", {
1178
+ ...options,
1179
+ config: this.#config,
1180
+ partner: this.#partner
1181
+ });
1182
+ default:
1183
+ throw new Error(`Unsupported PvP coinflip action: ${action}`);
1184
+ }
1012
1185
  }
1013
1186
  };
1187
+ #createPvPCoinflipBetCoin(options) {
1188
+ return async (tx) => {
1189
+ const { stake_per_player } = await this.resolvePvPConflipGame(
1190
+ options.gameId
1191
+ );
1192
+ return tx.coin({
1193
+ type: options.coinType,
1194
+ balance: BigInt(stake_per_player),
1195
+ useGasCoin: options.allowGasCoinShortcut
1196
+ });
1197
+ };
1198
+ }
1014
1199
  };
1015
1200
 
1201
+ exports.SuigarClient = SuigarClient;
1016
1202
  exports.suigar = suigar;