@provable-games/budokan-sdk 0.1.19 → 0.1.21

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,47 +343,30 @@ 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,
390
356
  timeout: ctx?.timeout
391
357
  };
392
358
  }
393
- async function getActivity(baseUrl, params, ctx) {
394
- const qs = buildQueryString({
395
- event_type: params?.eventType,
396
- tournament_id: params?.tournamentId,
397
- player_address: params?.playerAddress,
398
- limit: params?.limit,
399
- offset: params?.offset
400
- });
401
- const result = await apiFetch(`${baseUrl}/activity${qs}`, fetchOpts4(ctx));
402
- const { total, limit: resLimit, offset: resOffset } = extractPagination(result, { limit: params?.limit, offset: params?.offset });
403
- return {
404
- data: result.data.map((item) => snakeToCamel(item)),
405
- total,
406
- limit: resLimit,
407
- offset: resOffset
408
- };
409
- }
410
359
  async function getActivityStats(baseUrl, ctx) {
411
360
  const result = await apiFetch(
412
361
  `${baseUrl}/activity/stats`,
413
- fetchOpts4(ctx)
362
+ fetchOpts3(ctx)
414
363
  );
415
364
  return snakeToCamel(result.data);
416
365
  }
417
366
  async function getPrizeStats(baseUrl, ctx) {
418
367
  const result = await apiFetch(
419
368
  `${baseUrl}/activity/prize-stats`,
420
- fetchOpts4(ctx)
369
+ fetchOpts3(ctx)
421
370
  );
422
371
  return snakeToCamel(result.data);
423
372
  }
@@ -979,8 +928,6 @@ function parseRegistration(raw, tournamentId) {
979
928
  gameTokenId: num.toHex(obj.game_token_id),
980
929
  gameAddress: "",
981
930
  // Not in on-chain struct
982
- playerAddress: "",
983
- // Not in on-chain struct
984
931
  entryNumber: Number(obj.entry_id ?? 0),
985
932
  hasSubmitted: Boolean(obj.has_submitted),
986
933
  isBanned: Boolean(obj.is_banned)
@@ -1139,20 +1086,6 @@ async function viewerRegistrations(contract, tournamentId, offset, limit) {
1139
1086
  };
1140
1087
  }, contract.address);
1141
1088
  }
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
1089
  async function viewerRegistrationsByTokenIds(contract, tournamentId, tokenIds, offset, limit) {
1157
1090
  return wrapRpcCall(async () => {
1158
1091
  const result = await contract.call("tournament_registrations_by_token_ids", [tournamentId, tokenIds, offset, limit]);
@@ -1198,12 +1131,6 @@ async function viewerRewardClaims(contract, tournamentId, offset, limit) {
1198
1131
  };
1199
1132
  }, contract.address);
1200
1133
  }
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
1134
 
1208
1135
  // src/rpc/abis/budokanViewer.json
1209
1136
  var budokanViewer_default = [
@@ -4511,9 +4438,6 @@ var BudokanClient = class {
4511
4438
  const contract = await this.getViewerContract();
4512
4439
  const offset = params?.offset ?? 0;
4513
4440
  const limit = params?.limit ?? 20;
4514
- if (params?.playerAddress) {
4515
- return viewerRegistrationsByOwner(contract, tournamentId, params.playerAddress, offset, limit);
4516
- }
4517
4441
  if (params?.gameTokenIds?.length) {
4518
4442
  return viewerRegistrationsByTokenIds(contract, tournamentId, params.gameTokenIds, offset, limit);
4519
4443
  }
@@ -4546,43 +4470,6 @@ var BudokanClient = class {
4546
4470
  this.connectionStatus
4547
4471
  );
4548
4472
  }
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
4473
  // ---- Game Queries ----
4587
4474
  /**
4588
4475
  * Fetch tournaments for a specific game.
@@ -4681,13 +4568,6 @@ var BudokanClient = class {
4681
4568
  return getTournamentPrizeAggregation(this.resolvedConfig.apiBaseUrl, tournamentId, this.apiCtx);
4682
4569
  }
4683
4570
  // ---- Activity Queries (API-only, activity is indexed) ----
4684
- /**
4685
- * Fetch activity events with optional filtering.
4686
- * API-only — no RPC fallback available.
4687
- */
4688
- async getActivity(params) {
4689
- return getActivity(this.resolvedConfig.apiBaseUrl, params, this.apiCtx);
4690
- }
4691
4571
  /**
4692
4572
  * Fetch platform-wide activity stats.
4693
4573
  * API-only — no RPC fallback available.
@@ -4848,30 +4728,6 @@ function useTournamentCount(phase) {
4848
4728
  }, [fetch2]);
4849
4729
  return { count, loading, error, refetch: fetch2 };
4850
4730
  }
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
4731
  function useLeaderboard(tournamentId) {
4876
4732
  const client = useBudokanClient();
4877
4733
  const [leaderboard, setLeaderboard] = useState(null);
@@ -4921,84 +4777,157 @@ function useRegistrations(tournamentId, params) {
4921
4777
  }, [fetch2]);
4922
4778
  return { registrations, loading, error, refetch: fetch2 };
4923
4779
  }
4924
- function usePlayer(address, params) {
4780
+ var MAX_OWNED_TOKENS = 1e3;
4781
+ var emptyPage = (limit, offset) => ({
4782
+ data: [],
4783
+ total: 0,
4784
+ limit,
4785
+ offset
4786
+ });
4787
+ function useOwnedTournamentIds(owner, contextId) {
4925
4788
  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);
4789
+ const budokanAddress = client.clientConfig.budokanAddress;
4790
+ const enabled = !!owner && !!budokanAddress;
4791
+ const { data, isLoading } = useTokens(
4792
+ enabled ? {
4793
+ owner,
4794
+ minterAddress: budokanAddress,
4795
+ hasContext: true,
4796
+ ...{},
4797
+ limit: MAX_OWNED_TOKENS
4798
+ } : void 0
4799
+ );
4800
+ const tournamentIds = useMemo(() => {
4801
+ if (!enabled) return null;
4802
+ if (!data?.data) return null;
4803
+ const ids = /* @__PURE__ */ new Set();
4804
+ for (const t of data.data) {
4805
+ if (t.contextId) ids.add(String(t.contextId));
4947
4806
  }
4948
- }, [client, address, paramsKey]);
4949
- useEffect(() => {
4950
- fetch2();
4951
- }, [fetch2]);
4952
- return { tournaments, stats, loading, error };
4807
+ return [...ids];
4808
+ }, [enabled, data]);
4809
+ return { tournamentIds, loading: isLoading };
4953
4810
  }
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);
4811
+ function useTournamentsByOwner(owner, params) {
4812
+ const { tournamentIds, loading: tokensLoading } = useOwnedTournamentIds(owner);
4813
+ const inner = useTournaments(
4814
+ tournamentIds && tournamentIds.length > 0 ? {
4815
+ tournamentIds,
4816
+ phase: params?.phase,
4817
+ limit: params?.limit,
4818
+ offset: params?.offset,
4819
+ sort: params?.sort,
4820
+ includePrizeSummary: params?.includePrizeSummary
4821
+ } : void 0
4822
+ );
4823
+ if (tournamentIds !== null && tournamentIds.length === 0) {
4824
+ return {
4825
+ tournaments: emptyPage(
4826
+ params?.limit ?? 50,
4827
+ params?.offset ?? 0
4828
+ ),
4829
+ loading: false,
4830
+ error: null,
4831
+ refetch: async () => {
4832
+ }
4833
+ };
4834
+ }
4835
+ return {
4836
+ tournaments: inner.tournaments,
4837
+ loading: tokensLoading || inner.loading,
4838
+ error: inner.error,
4839
+ refetch: inner.refetch
4840
+ };
4841
+ }
4842
+ function useTournamentsByOwnerCount(owner, params) {
4843
+ const { tournamentIds, loading: tokensLoading } = useOwnedTournamentIds(owner);
4844
+ const phaseFilter = params?.phase;
4845
+ const filtered = useTournaments(
4846
+ phaseFilter && tournamentIds && tournamentIds.length > 0 ? { tournamentIds, phase: phaseFilter, limit: 1 } : void 0
4847
+ );
4848
+ if (tournamentIds === null) {
4849
+ return {
4850
+ count: null,
4851
+ loading: tokensLoading,
4852
+ error: null,
4853
+ refetch: async () => {
4854
+ }
4855
+ };
4856
+ }
4857
+ if (tournamentIds.length === 0) {
4858
+ return {
4859
+ count: 0,
4860
+ loading: false,
4861
+ error: null,
4862
+ refetch: async () => {
4863
+ }
4864
+ };
4865
+ }
4866
+ if (!phaseFilter) {
4867
+ return {
4868
+ count: tournamentIds.length,
4869
+ loading: false,
4870
+ error: null,
4871
+ refetch: async () => {
4872
+ }
4873
+ };
4874
+ }
4875
+ return {
4876
+ count: filtered.tournaments?.total ?? null,
4877
+ loading: filtered.loading,
4878
+ error: filtered.error,
4879
+ refetch: async () => {
4971
4880
  }
4972
- }, [client, address]);
4973
- useEffect(() => {
4974
- fetch2();
4975
- }, [fetch2]);
4976
- return { stats, loading, error, refetch: fetch2 };
4881
+ };
4977
4882
  }
4978
- function usePlayerTournaments(address, params) {
4883
+ function useRegistrationsByOwner(tournamentId, owner, params) {
4979
4884
  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);
4885
+ const budokanAddress = client.clientConfig.budokanAddress;
4886
+ const contextId = tournamentId ? Number(tournamentId) : void 0;
4887
+ const enabled = !!owner && !!budokanAddress && tournamentId != null && contextId !== void 0;
4888
+ const { data: tokensResult, isLoading: tokensLoading } = useTokens(
4889
+ enabled ? {
4890
+ owner,
4891
+ minterAddress: budokanAddress,
4892
+ contextId,
4893
+ limit: MAX_OWNED_TOKENS
4894
+ } : void 0
4895
+ );
4896
+ const ownedGameTokenIds = useMemo(() => {
4897
+ if (!enabled) return null;
4898
+ if (!tokensResult?.data) return null;
4899
+ const ids = [];
4900
+ for (const t of tokensResult.data) {
4901
+ if (t.tokenId == null) continue;
4902
+ try {
4903
+ ids.push(BigInt(String(t.tokenId)).toString());
4904
+ } catch {
4905
+ }
4996
4906
  }
4997
- }, [client, address, paramsKey]);
4998
- useEffect(() => {
4999
- fetch2();
5000
- }, [fetch2]);
5001
- return { tournaments, loading, error, refetch: fetch2 };
4907
+ return ids;
4908
+ }, [enabled, tokensResult]);
4909
+ const inner = useRegistrations(
4910
+ ownedGameTokenIds && ownedGameTokenIds.length > 0 ? tournamentId : void 0,
4911
+ ownedGameTokenIds && ownedGameTokenIds.length > 0 ? { ...params, gameTokenIds: ownedGameTokenIds } : void 0
4912
+ );
4913
+ if (ownedGameTokenIds !== null && ownedGameTokenIds.length === 0) {
4914
+ return {
4915
+ registrations: emptyPage(
4916
+ params?.limit ?? 50,
4917
+ params?.offset ?? 0
4918
+ ),
4919
+ loading: false,
4920
+ error: null,
4921
+ refetch: async () => {
4922
+ }
4923
+ };
4924
+ }
4925
+ return {
4926
+ registrations: inner.registrations,
4927
+ loading: tokensLoading || inner.loading,
4928
+ error: inner.error,
4929
+ refetch: inner.refetch
4930
+ };
5002
4931
  }
5003
4932
  function useRewardClaims(tournamentId, params) {
5004
4933
  const client = useBudokanClient();
@@ -5213,6 +5142,6 @@ function useConnectionStatus() {
5213
5142
  return { isConnected, datasourceMode };
5214
5143
  }
5215
5144
 
5216
- export { BudokanProvider, useActivityStats, useBudokanClient, useConnectionStatus, useLeaderboard, usePlayer, usePlayerStats, usePlayerTournamentCount, usePlayerTournaments, usePrizeAggregation, usePrizeStats, usePrizes, useQualifications, useRegistrations, useRewardClaims, useRewardClaimsSummary, useSubscription, useTournament, useTournamentCount, useTournaments };
5145
+ export { BudokanProvider, useActivityStats, useBudokanClient, useConnectionStatus, useLeaderboard, usePrizeAggregation, usePrizeStats, usePrizes, useQualifications, useRegistrations, useRegistrationsByOwner, useRewardClaims, useRewardClaimsSummary, useSubscription, useTournament, useTournamentCount, useTournaments, useTournamentsByOwner, useTournamentsByOwnerCount };
5217
5146
  //# sourceMappingURL=react.js.map
5218
5147
  //# sourceMappingURL=react.js.map