@provable-games/budokan-sdk 0.1.24 → 0.1.25

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
@@ -215,7 +215,8 @@ function camelToSnake(obj) {
215
215
  function normalizeTournament(raw) {
216
216
  const t = snakeToCamel(raw);
217
217
  const id = t.id ?? t.tournamentId;
218
- return { ...t, id, tournamentId: id };
218
+ const protocolFeeShare = t.protocolFeeShare ?? t.entryFee?.protocolFeeShare ?? null;
219
+ return { ...t, id, tournamentId: id, protocolFeeShare };
219
220
  }
220
221
  function fetchOpts(ctx) {
221
222
  return {
@@ -832,7 +833,7 @@ function phaseToRpcArg(phase) {
832
833
  }
833
834
  return new starknet.CairoCustomEnum(variants);
834
835
  }
835
- function parseTournament(raw, entryCount) {
836
+ function parseTournament(raw, entryCount, protocolFeeShare = null) {
836
837
  const obj = raw;
837
838
  const id = String(obj.id ?? "0");
838
839
  const createdAt = Number(obj.created_at ?? 0);
@@ -930,6 +931,8 @@ function parseTournament(raw, entryCount) {
930
931
  leaderboardGameMustBeOver: gameMustBeOver,
931
932
  entryFeeToken,
932
933
  entryFeeAmount,
934
+ // Protocol-fee bps snapshot, surfaced by the viewer's TournamentFullState.
935
+ protocolFeeShare,
933
936
  hasEntryRequirement,
934
937
  schedule: {
935
938
  registrationStartDelay,
@@ -1096,7 +1099,8 @@ function parseFilterResult(raw) {
1096
1099
  function parseTournamentFullState(raw) {
1097
1100
  const obj = raw;
1098
1101
  const entryCount = Number(obj.entry_count ?? 0);
1099
- return parseTournament(obj.tournament, entryCount);
1102
+ const protocolFeeShare = obj.protocol_fee_bps != null ? Number(obj.protocol_fee_bps) : null;
1103
+ return parseTournament(obj.tournament, entryCount, protocolFeeShare);
1100
1104
  }
1101
1105
  async function viewerTournaments(contract, offset, limit) {
1102
1106
  return wrapRpcCall(async () => {
@@ -1272,6 +1276,9 @@ function translateCairoRewardType(rewardType) {
1272
1276
  if (subVariant === "GameCreator" || subBag?.GameCreator !== void 0) {
1273
1277
  return rewardClaim({ claimKind: "entry_fee_game_creator" });
1274
1278
  }
1279
+ if (subVariant === "ProtocolFee" || subBag?.ProtocolFee !== void 0) {
1280
+ return rewardClaim({ claimKind: "entry_fee_protocol_fee" });
1281
+ }
1275
1282
  if (subVariant === "Refund" || subBag?.Refund !== void 0) {
1276
1283
  return rewardClaim({
1277
1284
  claimKind: "entry_fee_refund",
@@ -1744,6 +1751,10 @@ var budokanViewer_default = [
1744
1751
  {
1745
1752
  name: "phase",
1746
1753
  type: "budokan_interfaces::budokan::Phase"
1754
+ },
1755
+ {
1756
+ name: "protocol_fee_bps",
1757
+ type: "core::integer::u16"
1747
1758
  }
1748
1759
  ]
1749
1760
  },
@@ -2014,6 +2025,10 @@ var budokanViewer_default = [
2014
2025
  {
2015
2026
  name: "Refund",
2016
2027
  type: "core::felt252"
2028
+ },
2029
+ {
2030
+ name: "ProtocolFee",
2031
+ type: "()"
2017
2032
  }
2018
2033
  ]
2019
2034
  },
@@ -3392,6 +3407,10 @@ var budokan_default = [
3392
3407
  {
3393
3408
  name: "Refund",
3394
3409
  type: "core::felt252"
3410
+ },
3411
+ {
3412
+ name: "ProtocolFee",
3413
+ type: "()"
3395
3414
  }
3396
3415
  ]
3397
3416
  },
@@ -4680,6 +4699,11 @@ var budokan_default = [
4680
4699
  name: "entry_requirement",
4681
4700
  type: "core::option::Option::<game_components_interfaces::entry_requirement::EntryRequirement>",
4682
4701
  kind: "data"
4702
+ },
4703
+ {
4704
+ name: "protocol_fee_bps",
4705
+ type: "core::integer::u16",
4706
+ kind: "data"
4683
4707
  }
4684
4708
  ]
4685
4709
  },
@@ -4902,6 +4926,108 @@ var budokan_default = [
4902
4926
  name: "QualificationEntriesUpdated",
4903
4927
  type: "budokan::events::QualificationEntriesUpdated",
4904
4928
  kind: "nested"
4929
+ },
4930
+ {
4931
+ name: "ProtocolFeeBpsUpdated",
4932
+ type: "budokan::events::ProtocolFeeBpsUpdated",
4933
+ kind: "nested"
4934
+ },
4935
+ {
4936
+ name: "ProtocolFeeRecipientUpdated",
4937
+ type: "budokan::events::ProtocolFeeRecipientUpdated",
4938
+ kind: "nested"
4939
+ }
4940
+ ]
4941
+ },
4942
+ {
4943
+ type: "interface",
4944
+ name: "budokan::budokan::Budokan::IBudokanProtocolFeeAdmin",
4945
+ items: [
4946
+ {
4947
+ type: "function",
4948
+ name: "set_protocol_fee_bps",
4949
+ inputs: [
4950
+ {
4951
+ name: "bps",
4952
+ type: "core::integer::u16"
4953
+ }
4954
+ ],
4955
+ outputs: [],
4956
+ state_mutability: "external"
4957
+ },
4958
+ {
4959
+ type: "function",
4960
+ name: "set_protocol_fee_recipient",
4961
+ inputs: [
4962
+ {
4963
+ name: "recipient",
4964
+ type: "core::starknet::contract_address::ContractAddress"
4965
+ }
4966
+ ],
4967
+ outputs: [],
4968
+ state_mutability: "external"
4969
+ },
4970
+ {
4971
+ type: "function",
4972
+ name: "protocol_fee_bps",
4973
+ inputs: [],
4974
+ outputs: [
4975
+ {
4976
+ type: "core::integer::u16"
4977
+ }
4978
+ ],
4979
+ state_mutability: "view"
4980
+ },
4981
+ {
4982
+ type: "function",
4983
+ name: "protocol_fee_recipient",
4984
+ inputs: [],
4985
+ outputs: [
4986
+ {
4987
+ type: "core::starknet::contract_address::ContractAddress"
4988
+ }
4989
+ ],
4990
+ state_mutability: "view"
4991
+ },
4992
+ {
4993
+ type: "function",
4994
+ name: "tournament_protocol_fee_bps",
4995
+ inputs: [
4996
+ {
4997
+ name: "tournament_id",
4998
+ type: "core::integer::u64"
4999
+ }
5000
+ ],
5001
+ outputs: [
5002
+ {
5003
+ type: "core::integer::u16"
5004
+ }
5005
+ ],
5006
+ state_mutability: "view"
5007
+ }
5008
+ ]
5009
+ },
5010
+ {
5011
+ type: "event",
5012
+ name: "budokan::events::ProtocolFeeBpsUpdated",
5013
+ kind: "struct",
5014
+ members: [
5015
+ {
5016
+ name: "bps",
5017
+ type: "core::integer::u16",
5018
+ kind: "data"
5019
+ }
5020
+ ]
5021
+ },
5022
+ {
5023
+ type: "event",
5024
+ name: "budokan::events::ProtocolFeeRecipientUpdated",
5025
+ kind: "struct",
5026
+ members: [
5027
+ {
5028
+ name: "recipient",
5029
+ type: "core::starknet::contract_address::ContractAddress",
5030
+ kind: "key"
4905
5031
  }
4906
5032
  ]
4907
5033
  }
@@ -5369,6 +5495,185 @@ function createBudokanClient(config) {
5369
5495
  return new BudokanClient(config);
5370
5496
  }
5371
5497
 
5498
+ // src/utils/prizes.ts
5499
+ function isNonEmptyString(value) {
5500
+ return typeof value === "string" && value.length > 0;
5501
+ }
5502
+ function isNonNegativeIntegerString(value) {
5503
+ if (!isNonEmptyString(value) || value.trim() !== value) return false;
5504
+ if (!/^\d+$/.test(value)) return false;
5505
+ try {
5506
+ return BigInt(value) >= 0n;
5507
+ } catch {
5508
+ return false;
5509
+ }
5510
+ }
5511
+ function isNonNegativeIntegerNumber(value) {
5512
+ return typeof value === "number" && Number.isInteger(value) && value >= 0;
5513
+ }
5514
+ function isPositiveIntegerNumber(value) {
5515
+ return typeof value === "number" && Number.isInteger(value) && value > 0;
5516
+ }
5517
+ function isDistributionType(value) {
5518
+ return value === "linear" || value === "exponential" || value === "uniform" || value === "custom";
5519
+ }
5520
+ function hasNoDistributionFields(prize) {
5521
+ return prize.distributionType === null && prize.distributionWeight === null && prize.distributionShares === null && prize.distributionCount === null;
5522
+ }
5523
+ function hasValidDistributionFields(prize) {
5524
+ if (prize.distributionType === null) return hasNoDistributionFields(prize);
5525
+ if (!isDistributionType(prize.distributionType)) return false;
5526
+ if (!isPositiveIntegerNumber(prize.distributionCount)) return false;
5527
+ if (prize.distributionType === "custom") {
5528
+ return prize.distributionWeight === null && Array.isArray(prize.distributionShares) && prize.distributionShares.length === prize.distributionCount && prize.distributionShares.every(isNonNegativeIntegerNumber) && prize.distributionShares.reduce((sum, share) => sum + share, 0) === 1e4;
5529
+ }
5530
+ if (prize.distributionType === "uniform") {
5531
+ return prize.distributionWeight === null && prize.distributionShares === null;
5532
+ }
5533
+ return isNonNegativeIntegerNumber(prize.distributionWeight) && prize.distributionShares === null;
5534
+ }
5535
+ function hasBasePrizeFields(prize) {
5536
+ return isNonNegativeIntegerString(prize.prizeId) && isNonNegativeIntegerString(prize.tournamentId) && Number.isInteger(prize.payoutPosition) && prize.payoutPosition >= 0 && isNonEmptyString(prize.sponsorAddress);
5537
+ }
5538
+ function hasExtensionConfig(value) {
5539
+ return value === null || Array.isArray(value) && value.every((entry) => typeof entry === "string");
5540
+ }
5541
+ function describePrize(prize) {
5542
+ const prizeId = isNonEmptyString(prize.prizeId) ? prize.prizeId : "<invalid>";
5543
+ return `prizeId=${prizeId}, tokenType=${prize.tokenType}`;
5544
+ }
5545
+ function malformedTokenPrizeError(action, prize) {
5546
+ return new TypeError(
5547
+ `Cannot ${action} malformed Budokan token prize (${describePrize(prize)})`
5548
+ );
5549
+ }
5550
+ function malformedExtensionPrizeError(action, prize) {
5551
+ return new TypeError(
5552
+ `Cannot ${action} malformed Budokan extension prize (${describePrize(prize)})`
5553
+ );
5554
+ }
5555
+ function assertMetagameTokenPosition(prize) {
5556
+ if (Number.isInteger(prize.payoutPosition) && prize.payoutPosition > 0) {
5557
+ return;
5558
+ }
5559
+ if (prize.payoutPosition !== 0) {
5560
+ throw new TypeError(
5561
+ `Cannot adapt Budokan token prize with invalid payout position (${describePrize(prize)})`
5562
+ );
5563
+ }
5564
+ throw new TypeError(
5565
+ `Cannot adapt Budokan token prize with unhydrated payout position (${describePrize(prize)})`
5566
+ );
5567
+ }
5568
+ function assertMetagameExtensionPosition(prize) {
5569
+ if (Number.isInteger(prize.payoutPosition) && prize.payoutPosition > 0) {
5570
+ return;
5571
+ }
5572
+ if (prize.payoutPosition !== 0) {
5573
+ throw new TypeError(
5574
+ `Cannot adapt Budokan extension prize with invalid payout position (${describePrize(prize)})`
5575
+ );
5576
+ }
5577
+ throw new TypeError(
5578
+ `Cannot adapt Budokan extension prize with unhydrated payout position (${describePrize(prize)})`
5579
+ );
5580
+ }
5581
+ function hasHydratedPayoutPosition(prize) {
5582
+ return prize.payoutPosition > 0;
5583
+ }
5584
+ function isRawTokenPrize(prize) {
5585
+ if (!hasBasePrizeFields(prize) || !isNonEmptyString(prize.tokenAddress)) {
5586
+ return false;
5587
+ }
5588
+ return prize.tokenType === "erc20" ? isNonNegativeIntegerString(prize.amount) && prize.tokenId === null && prize.extensionAddress === null && prize.extensionConfig === null && hasValidDistributionFields(prize) : prize.tokenType === "erc721" && prize.amount === null && isNonNegativeIntegerString(prize.tokenId) && prize.extensionAddress === null && prize.extensionConfig === null && hasNoDistributionFields(prize);
5589
+ }
5590
+ function isRawExtensionPrize(prize) {
5591
+ return hasBasePrizeFields(prize) && prize.tokenType === "extension" && prize.tokenAddress === null && prize.amount === null && prize.tokenId === null && hasNoDistributionFields(prize) && isNonEmptyString(prize.extensionAddress) && hasExtensionConfig(prize.extensionConfig);
5592
+ }
5593
+ function isTokenPrize(prize) {
5594
+ return isRawTokenPrize(prize) && hasHydratedPayoutPosition(prize);
5595
+ }
5596
+ function isExtensionPrize(prize) {
5597
+ return isRawExtensionPrize(prize) && hasHydratedPayoutPosition(prize);
5598
+ }
5599
+ function isMetagameAdaptablePrize(prize) {
5600
+ return isTokenPrize(prize) || isExtensionPrize(prize);
5601
+ }
5602
+ function getRawTokenPrizes(prizes) {
5603
+ return prizes.flatMap((prize) => {
5604
+ if (isRawTokenPrize(prize)) return [prize];
5605
+ if (prize.tokenType === "extension") return [];
5606
+ throw malformedTokenPrizeError("read", prize);
5607
+ });
5608
+ }
5609
+ function getTokenPrizes(prizes) {
5610
+ return prizes.flatMap((prize) => {
5611
+ if (isTokenPrize(prize)) return [prize];
5612
+ if (isRawTokenPrize(prize) || prize.tokenType === "extension") return [];
5613
+ throw malformedTokenPrizeError("read", prize);
5614
+ });
5615
+ }
5616
+ function toMetagameTokenPrize(prize) {
5617
+ assertMetagameTokenPosition(prize);
5618
+ if (!isRawTokenPrize(prize)) {
5619
+ throw malformedTokenPrizeError("adapt", prize);
5620
+ }
5621
+ const adapted = {
5622
+ id: prize.prizeId,
5623
+ position: prize.payoutPosition,
5624
+ tokenAddress: prize.tokenAddress,
5625
+ tokenType: prize.tokenType,
5626
+ // Metagame token prizes use `amount` as the token id for ERC721 entries.
5627
+ amount: prize.tokenType === "erc20" ? prize.amount : prize.tokenId,
5628
+ sponsorAddress: prize.sponsorAddress
5629
+ };
5630
+ return adapted;
5631
+ }
5632
+ function toMetagameExtensionPrize(prize) {
5633
+ assertMetagameExtensionPosition(prize);
5634
+ if (!isRawExtensionPrize(prize)) {
5635
+ throw malformedExtensionPrizeError("adapt", prize);
5636
+ }
5637
+ const adapted = {
5638
+ id: prize.prizeId,
5639
+ position: prize.payoutPosition,
5640
+ tokenAddress: null,
5641
+ tokenType: "extension",
5642
+ amount: null,
5643
+ sponsorAddress: prize.sponsorAddress,
5644
+ extensionAddress: prize.extensionAddress,
5645
+ extensionConfig: prize.extensionConfig
5646
+ };
5647
+ return adapted;
5648
+ }
5649
+ function toMetagamePrize(prize) {
5650
+ if (isRawTokenPrize(prize)) return toMetagameTokenPrize(prize);
5651
+ if (isRawExtensionPrize(prize)) return toMetagameExtensionPrize(prize);
5652
+ throw new TypeError(
5653
+ `Cannot adapt malformed Budokan prize (${describePrize(prize)})`
5654
+ );
5655
+ }
5656
+ function tryToMetagamePrize(prize) {
5657
+ if (!isMetagameAdaptablePrize(prize)) return null;
5658
+ return prize.tokenType === "extension" ? toMetagameExtensionPrize(prize) : toMetagameTokenPrize(prize);
5659
+ }
5660
+ function toMetagamePrizes(prizes) {
5661
+ return prizes.map(toMetagamePrize);
5662
+ }
5663
+ function tryToMetagamePrizes(prizes) {
5664
+ return prizes.flatMap((prize) => {
5665
+ const adapted = tryToMetagamePrize(prize);
5666
+ return adapted ? [adapted] : [];
5667
+ });
5668
+ }
5669
+ function toMetagameTokenPrizes(prizes) {
5670
+ return prizes.flatMap((prize) => {
5671
+ if (isRawTokenPrize(prize)) return [toMetagameTokenPrize(prize)];
5672
+ if (prize.tokenType === "extension") return [];
5673
+ throw malformedTokenPrizeError("adapt", prize);
5674
+ });
5675
+ }
5676
+
5372
5677
  // src/games/whitelist.ts
5373
5678
  var STRK = "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d";
5374
5679
  var MAINNET_GAMES_RAW = [
@@ -5755,6 +6060,9 @@ function pushRewardTypeFelts(out, reward) {
5755
6060
  case "entry_fee_refund":
5756
6061
  out.push("0x1", "0x0", "0x3", starknet.num.toHex(reward.tokenId));
5757
6062
  return;
6063
+ case "entry_fee_protocol_fee":
6064
+ out.push("0x1", "0x0", "0x4");
6065
+ return;
5758
6066
  case "entry_fee_extension": {
5759
6067
  out.push("0x1", "0x1");
5760
6068
  if (reward.tokenId !== void 0) {
@@ -5898,6 +6206,8 @@ exports.getGameDefaults = getGameDefaults;
5898
6206
  exports.getGameStats = getGameStats;
5899
6207
  exports.getGameTournaments = getGameTournaments;
5900
6208
  exports.getPrizeStats = getPrizeStats;
6209
+ exports.getRawTokenPrizes = getRawTokenPrizes;
6210
+ exports.getTokenPrizes = getTokenPrizes;
5901
6211
  exports.getTournament = getTournament;
5902
6212
  exports.getTournamentPrizeAggregation = getTournamentPrizeAggregation;
5903
6213
  exports.getTournamentPrizes = getTournamentPrizes;
@@ -5907,11 +6217,23 @@ exports.getTournamentRewardClaims = getTournamentRewardClaims;
5907
6217
  exports.getTournamentRewardClaimsSummary = getTournamentRewardClaimsSummary;
5908
6218
  exports.getTournaments = getTournaments;
5909
6219
  exports.getWhitelistedGames = getWhitelistedGames;
6220
+ exports.isExtensionPrize = isExtensionPrize;
5910
6221
  exports.isGameWhitelisted = isGameWhitelisted;
6222
+ exports.isMetagameAdaptablePrize = isMetagameAdaptablePrize;
6223
+ exports.isRawExtensionPrize = isRawExtensionPrize;
6224
+ exports.isRawTokenPrize = isRawTokenPrize;
6225
+ exports.isTokenPrize = isTokenPrize;
5911
6226
  exports.normalizeAddress = normalizeAddress;
5912
6227
  exports.parseTournamentIdFromReceipt = parseTournamentIdFromReceipt;
5913
6228
  exports.snakeToCamel = snakeToCamel;
6229
+ exports.toMetagameExtensionPrize = toMetagameExtensionPrize;
6230
+ exports.toMetagamePrize = toMetagamePrize;
6231
+ exports.toMetagamePrizes = toMetagamePrizes;
6232
+ exports.toMetagameTokenPrize = toMetagameTokenPrize;
6233
+ exports.toMetagameTokenPrizes = toMetagameTokenPrizes;
5914
6234
  exports.tournamentPageUrl = tournamentPageUrl;
6235
+ exports.tryToMetagamePrize = tryToMetagamePrize;
6236
+ exports.tryToMetagamePrizes = tryToMetagamePrizes;
5915
6237
  exports.u256ToLowHigh = u256ToLowHigh;
5916
6238
  exports.withRetry = withRetry;
5917
6239
  //# sourceMappingURL=index.cjs.map