@provable-games/budokan-sdk 0.1.19 → 0.1.20

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/react.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { createContext, useMemo, useRef, useEffect, useContext, useState, useCallback } from 'react';
2
2
  import { num, CairoCustomEnum } from 'starknet';
3
3
  import { jsx } from 'react/jsx-runtime';
4
+ import { useTokens } from '@provable-games/denshokan-sdk/react';
4
5
 
5
6
  // src/react/context.tsx
6
7
 
@@ -241,7 +242,6 @@ async function getTournament(baseUrl, tournamentId, ctx) {
241
242
  }
242
243
  async function getTournamentRegistrations(baseUrl, tournamentId, params, ctx) {
243
244
  const qs = buildQueryString({
244
- player_address: params?.playerAddress,
245
245
  game_token_ids: params?.gameTokenIds?.length ? params.gameTokenIds.join(",") : void 0,
246
246
  has_submitted: params?.hasSubmitted,
247
247
  is_banned: params?.isBanned,
@@ -314,42 +314,8 @@ function normalizeAddress(address) {
314
314
  return ("0x" + stripped.padStart(64, "0")).toLowerCase();
315
315
  }
316
316
 
317
- // src/api/players.ts
318
- function fetchOpts2(ctx) {
319
- return {
320
- retryAttempts: ctx?.retryAttempts,
321
- retryDelay: ctx?.retryDelay,
322
- timeout: ctx?.timeout
323
- };
324
- }
325
- async function getPlayerTournaments(baseUrl, address, params, ctx) {
326
- const normalized = normalizeAddress(address);
327
- const qs = buildQueryString({
328
- limit: params?.limit,
329
- offset: params?.offset,
330
- phase: params?.phase,
331
- game_token_ids: params?.gameTokenIds?.join(",")
332
- });
333
- const result = await apiFetch(`${baseUrl}/players/${normalized}/tournaments${qs}`, fetchOpts2(ctx));
334
- const { total, limit: resLimit, offset: resOffset } = extractPagination(result, { limit: params?.limit, offset: params?.offset });
335
- return {
336
- data: result.data.map((item) => snakeToCamel(item)),
337
- total,
338
- limit: resLimit,
339
- offset: resOffset
340
- };
341
- }
342
- async function getPlayerStats(baseUrl, address, ctx) {
343
- const normalized = normalizeAddress(address);
344
- const result = await apiFetch(
345
- `${baseUrl}/players/${normalized}/stats`,
346
- fetchOpts2(ctx)
347
- );
348
- return snakeToCamel(result.data);
349
- }
350
-
351
317
  // src/api/games.ts
352
- function fetchOpts3(ctx) {
318
+ function fetchOpts2(ctx) {
353
319
  return {
354
320
  retryAttempts: ctx?.retryAttempts,
355
321
  retryDelay: ctx?.retryDelay,
@@ -364,7 +330,7 @@ async function getGameTournaments(baseUrl, gameAddress, params, ctx) {
364
330
  limit: params?.limit,
365
331
  offset: params?.offset
366
332
  });
367
- const result = await apiFetch(`${baseUrl}/games/${normalized}/tournaments${qs}`, fetchOpts3(ctx));
333
+ const result = await apiFetch(`${baseUrl}/games/${normalized}/tournaments${qs}`, fetchOpts2(ctx));
368
334
  const { total, limit: resLimit, offset: resOffset } = extractPagination(result, { limit: params?.limit, offset: params?.offset });
369
335
  return {
370
336
  data: result.data.map((item) => snakeToCamel(item)),
@@ -377,13 +343,13 @@ async function getGameStats(baseUrl, gameAddress, ctx) {
377
343
  const normalized = normalizeAddress(gameAddress);
378
344
  const result = await apiFetch(
379
345
  `${baseUrl}/games/${normalized}/stats`,
380
- fetchOpts3(ctx)
346
+ fetchOpts2(ctx)
381
347
  );
382
348
  return snakeToCamel(result.data);
383
349
  }
384
350
 
385
351
  // src/api/activity.ts
386
- function fetchOpts4(ctx) {
352
+ function fetchOpts3(ctx) {
387
353
  return {
388
354
  retryAttempts: ctx?.retryAttempts,
389
355
  retryDelay: ctx?.retryDelay,
@@ -398,7 +364,7 @@ async function getActivity(baseUrl, params, ctx) {
398
364
  limit: params?.limit,
399
365
  offset: params?.offset
400
366
  });
401
- const result = await apiFetch(`${baseUrl}/activity${qs}`, fetchOpts4(ctx));
367
+ const result = await apiFetch(`${baseUrl}/activity${qs}`, fetchOpts3(ctx));
402
368
  const { total, limit: resLimit, offset: resOffset } = extractPagination(result, { limit: params?.limit, offset: params?.offset });
403
369
  return {
404
370
  data: result.data.map((item) => snakeToCamel(item)),
@@ -410,14 +376,14 @@ async function getActivity(baseUrl, params, ctx) {
410
376
  async function getActivityStats(baseUrl, ctx) {
411
377
  const result = await apiFetch(
412
378
  `${baseUrl}/activity/stats`,
413
- fetchOpts4(ctx)
379
+ fetchOpts3(ctx)
414
380
  );
415
381
  return snakeToCamel(result.data);
416
382
  }
417
383
  async function getPrizeStats(baseUrl, ctx) {
418
384
  const result = await apiFetch(
419
385
  `${baseUrl}/activity/prize-stats`,
420
- fetchOpts4(ctx)
386
+ fetchOpts3(ctx)
421
387
  );
422
388
  return snakeToCamel(result.data);
423
389
  }
@@ -979,8 +945,6 @@ function parseRegistration(raw, tournamentId) {
979
945
  gameTokenId: num.toHex(obj.game_token_id),
980
946
  gameAddress: "",
981
947
  // Not in on-chain struct
982
- playerAddress: "",
983
- // Not in on-chain struct
984
948
  entryNumber: Number(obj.entry_id ?? 0),
985
949
  hasSubmitted: Boolean(obj.has_submitted),
986
950
  isBanned: Boolean(obj.is_banned)
@@ -1139,20 +1103,6 @@ async function viewerRegistrations(contract, tournamentId, offset, limit) {
1139
1103
  };
1140
1104
  }, contract.address);
1141
1105
  }
1142
- async function viewerRegistrationsByOwner(contract, tournamentId, owner, offset, limit) {
1143
- return wrapRpcCall(async () => {
1144
- const result = await contract.call("tournament_registrations_by_owner", [tournamentId, owner, offset, limit]);
1145
- const obj = result;
1146
- const entries = obj.entries ?? [];
1147
- const total = Number(obj.total ?? 0);
1148
- return {
1149
- data: entries.map((e) => parseRegistration(e, tournamentId)),
1150
- total,
1151
- limit,
1152
- offset
1153
- };
1154
- }, contract.address);
1155
- }
1156
1106
  async function viewerRegistrationsByTokenIds(contract, tournamentId, tokenIds, offset, limit) {
1157
1107
  return wrapRpcCall(async () => {
1158
1108
  const result = await contract.call("tournament_registrations_by_token_ids", [tournamentId, tokenIds, offset, limit]);
@@ -1198,12 +1148,6 @@ async function viewerRewardClaims(contract, tournamentId, offset, limit) {
1198
1148
  };
1199
1149
  }, contract.address);
1200
1150
  }
1201
- async function viewerPlayerTournaments(contract, playerAddress, offset, limit) {
1202
- return wrapRpcCall(async () => {
1203
- const result = await contract.call("player_tournaments", [playerAddress, offset, limit]);
1204
- return parseFilterResult(result);
1205
- }, contract.address);
1206
- }
1207
1151
 
1208
1152
  // src/rpc/abis/budokanViewer.json
1209
1153
  var budokanViewer_default = [
@@ -4511,9 +4455,6 @@ var BudokanClient = class {
4511
4455
  const contract = await this.getViewerContract();
4512
4456
  const offset = params?.offset ?? 0;
4513
4457
  const limit = params?.limit ?? 20;
4514
- if (params?.playerAddress) {
4515
- return viewerRegistrationsByOwner(contract, tournamentId, params.playerAddress, offset, limit);
4516
- }
4517
4458
  if (params?.gameTokenIds?.length) {
4518
4459
  return viewerRegistrationsByTokenIds(contract, tournamentId, params.gameTokenIds, offset, limit);
4519
4460
  }
@@ -4546,43 +4487,6 @@ var BudokanClient = class {
4546
4487
  this.connectionStatus
4547
4488
  );
4548
4489
  }
4549
- // ---- Player Queries (API-only, no on-chain equivalent) ----
4550
- /**
4551
- * Fetch tournaments that a player has registered for.
4552
- * Supports RPC fallback via viewer contract.
4553
- */
4554
- async getPlayerTournaments(address, params) {
4555
- const rpcFallback = async () => {
4556
- const contract = await this.getViewerContract();
4557
- const offset = params?.offset ?? 0;
4558
- const limit = params?.limit ?? 20;
4559
- const filterResult = await viewerPlayerTournaments(contract, address, offset, limit);
4560
- let data = [];
4561
- if (filterResult.tournamentIds.length > 0) {
4562
- const tournaments = await viewerTournamentsBatch(contract, filterResult.tournamentIds);
4563
- data = tournaments.map((t) => ({
4564
- ...t,
4565
- tournamentId: t.id
4566
- }));
4567
- }
4568
- return { data, total: filterResult.total, limit, offset };
4569
- };
4570
- if (this.resolvedConfig.primarySource === "rpc") {
4571
- return rpcFallback();
4572
- }
4573
- return withFallback(
4574
- () => getPlayerTournaments(this.resolvedConfig.apiBaseUrl, address, params, this.apiCtx),
4575
- rpcFallback,
4576
- this.connectionStatus
4577
- );
4578
- }
4579
- /**
4580
- * Fetch stats for a player.
4581
- * API-only — no RPC fallback available.
4582
- */
4583
- async getPlayerStats(address) {
4584
- return getPlayerStats(this.resolvedConfig.apiBaseUrl, address, this.apiCtx);
4585
- }
4586
4490
  // ---- Game Queries ----
4587
4491
  /**
4588
4492
  * Fetch tournaments for a specific game.
@@ -4848,30 +4752,6 @@ function useTournamentCount(phase) {
4848
4752
  }, [fetch2]);
4849
4753
  return { count, loading, error, refetch: fetch2 };
4850
4754
  }
4851
- function usePlayerTournamentCount(address, phase) {
4852
- const client = useBudokanClient();
4853
- const [count, setCount] = useState(null);
4854
- const [loading, setLoading] = useState(!!address);
4855
- const [error, setError] = useState(null);
4856
- useResetOnClient(client, setCount, setError);
4857
- const fetch2 = useCallback(async () => {
4858
- if (!address) return;
4859
- setLoading(true);
4860
- setError(null);
4861
- try {
4862
- const result = await client.getPlayerTournaments(address, { phase, limit: 1 });
4863
- setCount(result.total ?? 0);
4864
- } catch (e) {
4865
- setError(e);
4866
- } finally {
4867
- setLoading(false);
4868
- }
4869
- }, [client, address, phase]);
4870
- useEffect(() => {
4871
- fetch2();
4872
- }, [fetch2]);
4873
- return { count, loading, error, refetch: fetch2 };
4874
- }
4875
4755
  function useLeaderboard(tournamentId) {
4876
4756
  const client = useBudokanClient();
4877
4757
  const [leaderboard, setLeaderboard] = useState(null);
@@ -4921,84 +4801,157 @@ function useRegistrations(tournamentId, params) {
4921
4801
  }, [fetch2]);
4922
4802
  return { registrations, loading, error, refetch: fetch2 };
4923
4803
  }
4924
- function usePlayer(address, params) {
4804
+ var MAX_OWNED_TOKENS = 1e3;
4805
+ var emptyPage = (limit, offset) => ({
4806
+ data: [],
4807
+ total: 0,
4808
+ limit,
4809
+ offset
4810
+ });
4811
+ function useOwnedTournamentIds(owner, contextId) {
4925
4812
  const client = useBudokanClient();
4926
- const [tournaments, setTournaments] = useState(null);
4927
- const [stats, setStats] = useState(null);
4928
- const [loading, setLoading] = useState(!!address);
4929
- const [error, setError] = useState(null);
4930
- useResetOnClient(client, setTournaments, setStats, setError);
4931
- const paramsKey = JSON.stringify(params);
4932
- const fetch2 = useCallback(async () => {
4933
- if (!address) return;
4934
- setLoading(true);
4935
- setError(null);
4936
- try {
4937
- const [tournamentsResult, statsResult] = await Promise.all([
4938
- client.getPlayerTournaments(address, params),
4939
- client.getPlayerStats(address)
4940
- ]);
4941
- setTournaments(tournamentsResult);
4942
- setStats(statsResult);
4943
- } catch (e) {
4944
- setError(e);
4945
- } finally {
4946
- setLoading(false);
4813
+ const budokanAddress = client.clientConfig.budokanAddress;
4814
+ const enabled = !!owner && !!budokanAddress;
4815
+ const { data, isLoading } = useTokens(
4816
+ enabled ? {
4817
+ owner,
4818
+ minterAddress: budokanAddress,
4819
+ hasContext: true,
4820
+ ...{},
4821
+ limit: MAX_OWNED_TOKENS
4822
+ } : void 0
4823
+ );
4824
+ const tournamentIds = useMemo(() => {
4825
+ if (!enabled) return null;
4826
+ if (!data?.data) return null;
4827
+ const ids = /* @__PURE__ */ new Set();
4828
+ for (const t of data.data) {
4829
+ if (t.contextId) ids.add(String(t.contextId));
4947
4830
  }
4948
- }, [client, address, paramsKey]);
4949
- useEffect(() => {
4950
- fetch2();
4951
- }, [fetch2]);
4952
- return { tournaments, stats, loading, error };
4831
+ return [...ids];
4832
+ }, [enabled, data]);
4833
+ return { tournamentIds, loading: isLoading };
4953
4834
  }
4954
- function usePlayerStats(address) {
4955
- const client = useBudokanClient();
4956
- const [stats, setStats] = useState(null);
4957
- const [loading, setLoading] = useState(!!address);
4958
- const [error, setError] = useState(null);
4959
- useResetOnClient(client, setStats, setError);
4960
- const fetch2 = useCallback(async () => {
4961
- if (!address) return;
4962
- setLoading(true);
4963
- setError(null);
4964
- try {
4965
- const result = await client.getPlayerStats(address);
4966
- setStats(result);
4967
- } catch (e) {
4968
- setError(e);
4969
- } finally {
4970
- setLoading(false);
4835
+ function useTournamentsByOwner(owner, params) {
4836
+ const { tournamentIds, loading: tokensLoading } = useOwnedTournamentIds(owner);
4837
+ const inner = useTournaments(
4838
+ tournamentIds && tournamentIds.length > 0 ? {
4839
+ tournamentIds,
4840
+ phase: params?.phase,
4841
+ limit: params?.limit,
4842
+ offset: params?.offset,
4843
+ sort: params?.sort,
4844
+ includePrizeSummary: params?.includePrizeSummary
4845
+ } : void 0
4846
+ );
4847
+ if (tournamentIds !== null && tournamentIds.length === 0) {
4848
+ return {
4849
+ tournaments: emptyPage(
4850
+ params?.limit ?? 50,
4851
+ params?.offset ?? 0
4852
+ ),
4853
+ loading: false,
4854
+ error: null,
4855
+ refetch: async () => {
4856
+ }
4857
+ };
4858
+ }
4859
+ return {
4860
+ tournaments: inner.tournaments,
4861
+ loading: tokensLoading || inner.loading,
4862
+ error: inner.error,
4863
+ refetch: inner.refetch
4864
+ };
4865
+ }
4866
+ function useTournamentsByOwnerCount(owner, params) {
4867
+ const { tournamentIds, loading: tokensLoading } = useOwnedTournamentIds(owner);
4868
+ const phaseFilter = params?.phase;
4869
+ const filtered = useTournaments(
4870
+ phaseFilter && tournamentIds && tournamentIds.length > 0 ? { tournamentIds, phase: phaseFilter, limit: 1 } : void 0
4871
+ );
4872
+ if (tournamentIds === null) {
4873
+ return {
4874
+ count: null,
4875
+ loading: tokensLoading,
4876
+ error: null,
4877
+ refetch: async () => {
4878
+ }
4879
+ };
4880
+ }
4881
+ if (tournamentIds.length === 0) {
4882
+ return {
4883
+ count: 0,
4884
+ loading: false,
4885
+ error: null,
4886
+ refetch: async () => {
4887
+ }
4888
+ };
4889
+ }
4890
+ if (!phaseFilter) {
4891
+ return {
4892
+ count: tournamentIds.length,
4893
+ loading: false,
4894
+ error: null,
4895
+ refetch: async () => {
4896
+ }
4897
+ };
4898
+ }
4899
+ return {
4900
+ count: filtered.tournaments?.total ?? null,
4901
+ loading: filtered.loading,
4902
+ error: filtered.error,
4903
+ refetch: async () => {
4971
4904
  }
4972
- }, [client, address]);
4973
- useEffect(() => {
4974
- fetch2();
4975
- }, [fetch2]);
4976
- return { stats, loading, error, refetch: fetch2 };
4905
+ };
4977
4906
  }
4978
- function usePlayerTournaments(address, params) {
4907
+ function useRegistrationsByOwner(tournamentId, owner, params) {
4979
4908
  const client = useBudokanClient();
4980
- const [tournaments, setTournaments] = useState(null);
4981
- const [loading, setLoading] = useState(!!address);
4982
- const [error, setError] = useState(null);
4983
- useResetOnClient(client, setTournaments, setError);
4984
- const paramsKey = JSON.stringify(params);
4985
- const fetch2 = useCallback(async () => {
4986
- if (!address) return;
4987
- setLoading(true);
4988
- setError(null);
4989
- try {
4990
- const result = await client.getPlayerTournaments(address, params);
4991
- setTournaments(result);
4992
- } catch (e) {
4993
- setError(e);
4994
- } finally {
4995
- setLoading(false);
4909
+ const budokanAddress = client.clientConfig.budokanAddress;
4910
+ const contextId = tournamentId ? Number(tournamentId) : void 0;
4911
+ const enabled = !!owner && !!budokanAddress && tournamentId != null && contextId !== void 0;
4912
+ const { data: tokensResult, isLoading: tokensLoading } = useTokens(
4913
+ enabled ? {
4914
+ owner,
4915
+ minterAddress: budokanAddress,
4916
+ contextId,
4917
+ limit: MAX_OWNED_TOKENS
4918
+ } : void 0
4919
+ );
4920
+ const ownedGameTokenIds = useMemo(() => {
4921
+ if (!enabled) return null;
4922
+ if (!tokensResult?.data) return null;
4923
+ const ids = [];
4924
+ for (const t of tokensResult.data) {
4925
+ if (t.tokenId == null) continue;
4926
+ try {
4927
+ ids.push(BigInt(String(t.tokenId)).toString());
4928
+ } catch {
4929
+ }
4996
4930
  }
4997
- }, [client, address, paramsKey]);
4998
- useEffect(() => {
4999
- fetch2();
5000
- }, [fetch2]);
5001
- return { tournaments, loading, error, refetch: fetch2 };
4931
+ return ids;
4932
+ }, [enabled, tokensResult]);
4933
+ const inner = useRegistrations(
4934
+ ownedGameTokenIds && ownedGameTokenIds.length > 0 ? tournamentId : void 0,
4935
+ ownedGameTokenIds && ownedGameTokenIds.length > 0 ? { ...params, gameTokenIds: ownedGameTokenIds } : void 0
4936
+ );
4937
+ if (ownedGameTokenIds !== null && ownedGameTokenIds.length === 0) {
4938
+ return {
4939
+ registrations: emptyPage(
4940
+ params?.limit ?? 50,
4941
+ params?.offset ?? 0
4942
+ ),
4943
+ loading: false,
4944
+ error: null,
4945
+ refetch: async () => {
4946
+ }
4947
+ };
4948
+ }
4949
+ return {
4950
+ registrations: inner.registrations,
4951
+ loading: tokensLoading || inner.loading,
4952
+ error: inner.error,
4953
+ refetch: inner.refetch
4954
+ };
5002
4955
  }
5003
4956
  function useRewardClaims(tournamentId, params) {
5004
4957
  const client = useBudokanClient();
@@ -5213,6 +5166,6 @@ function useConnectionStatus() {
5213
5166
  return { isConnected, datasourceMode };
5214
5167
  }
5215
5168
 
5216
- export { BudokanProvider, useActivityStats, useBudokanClient, useConnectionStatus, useLeaderboard, usePlayer, usePlayerStats, usePlayerTournamentCount, usePlayerTournaments, usePrizeAggregation, usePrizeStats, usePrizes, useQualifications, useRegistrations, useRewardClaims, useRewardClaimsSummary, useSubscription, useTournament, useTournamentCount, useTournaments };
5169
+ export { BudokanProvider, useActivityStats, useBudokanClient, useConnectionStatus, useLeaderboard, usePrizeAggregation, usePrizeStats, usePrizes, useQualifications, useRegistrations, useRegistrationsByOwner, useRewardClaims, useRewardClaimsSummary, useSubscription, useTournament, useTournamentCount, useTournaments, useTournamentsByOwner, useTournamentsByOwnerCount };
5217
5170
  //# sourceMappingURL=react.js.map
5218
5171
  //# sourceMappingURL=react.js.map