@provable-games/budokan-sdk 0.1.21 → 0.1.23
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 +80 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +80 -3
- package/dist/index.js.map +1 -1
- package/dist/{client-0HDPKrdw.d.cts → player-BUynfv7D.d.cts} +66 -21
- package/dist/{client-0HDPKrdw.d.ts → player-BUynfv7D.d.ts} +66 -21
- package/dist/react.cjs +280 -5
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +45 -2
- package/dist/react.d.ts +45 -2
- package/dist/react.js +281 -7
- package/dist/react.js.map +1 -1
- package/package.json +3 -6
package/dist/react.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import { i as BudokanClientConfig, B as BudokanClient, T as Tournament, b as PaginatedResult, e as TournamentListParams, m as Phase, l as LeaderboardEntry, R as Registration, c as RewardClaim, d as RewardClaimSummary, g as PrizeStats, a as Prize, P as PrizeAggregation, Q as QualificationEntry, f as PlatformStats, o as WSEventMessage,
|
|
3
|
+
import { i as BudokanClientConfig, B as BudokanClient, T as Tournament, b as PaginatedResult, e as TournamentListParams, m as Phase, l as LeaderboardEntry, R as Registration, c as RewardClaim, d as RewardClaimSummary, g as PrizeStats, a as Prize, P as PrizeAggregation, Q as QualificationEntry, f as PlatformStats, o as PlayerRewards, q as WSEventMessage, p as WSChannel, C as ConnectionMode } from './player-BUynfv7D.cjs';
|
|
4
4
|
import 'starknet';
|
|
5
5
|
import '@provable-games/metagame-sdk';
|
|
6
6
|
|
|
@@ -200,6 +200,49 @@ interface UseActivityStatsResult {
|
|
|
200
200
|
*/
|
|
201
201
|
declare function useActivityStats(): UseActivityStatsResult;
|
|
202
202
|
|
|
203
|
+
interface UsePlayerRewardsResult {
|
|
204
|
+
rewards: PlayerRewards | null;
|
|
205
|
+
loading: boolean;
|
|
206
|
+
error: Error | null;
|
|
207
|
+
refetch: () => Promise<void>;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Aggregate a player's placement/earnings data across finalized Budokan
|
|
211
|
+
* tournaments they currently hold tokens in.
|
|
212
|
+
*
|
|
213
|
+
* Composition:
|
|
214
|
+
*
|
|
215
|
+
* denshokan useTokens (current ownership)
|
|
216
|
+
* ↓ group by contextId (= tournament id)
|
|
217
|
+
* budokan useTournaments({ tournamentIds })
|
|
218
|
+
* ↓ filter to finalized
|
|
219
|
+
* for each finalized tournament (parallel):
|
|
220
|
+
* budokan getTournamentPrizes — full prize records
|
|
221
|
+
* budokan getTournamentRewardClaims — paginated, all pages
|
|
222
|
+
* denshokan getTokenRanks (bulk) — final ranks for owned tokens
|
|
223
|
+
* ↓ filter ranks to paid positions (max position derived from prizes
|
|
224
|
+
* + entry-fee distribution_count)
|
|
225
|
+
*
|
|
226
|
+
* Per-tournament failures are tolerated: a 5xx on one tournament's prize/
|
|
227
|
+
* claim/rank fetch skips that tournament and continues, rather than
|
|
228
|
+
* failing the whole hook. Failures are logged via `console.warn`.
|
|
229
|
+
*
|
|
230
|
+
* Why source ownership from denshokan: PR #243 dropped
|
|
231
|
+
* `registrations.player_address` because the indexed value goes stale on
|
|
232
|
+
* transfer. The contract keys registrations by token_id only, so the only
|
|
233
|
+
* trustworthy answer to "what tournaments has this wallet placed in" is
|
|
234
|
+
* to ask denshokan who currently holds Budokan-minted tokens.
|
|
235
|
+
*
|
|
236
|
+
* Staleness: the hook only re-fetches when the player's owned token set
|
|
237
|
+
* changes (transfers/new mints) or when the underlying tournament list
|
|
238
|
+
* changes. It does *not* observe time-based finalization transitions on
|
|
239
|
+
* its own — if a tournament's submission window closes while the
|
|
240
|
+
* consumer is mounted, call `refetch()` to pick up the new placement.
|
|
241
|
+
*
|
|
242
|
+
* Pass `undefined` to skip fetching.
|
|
243
|
+
*/
|
|
244
|
+
declare function usePlayerRewards(address: string | undefined): UsePlayerRewardsResult;
|
|
245
|
+
|
|
203
246
|
interface UseSubscriptionResult {
|
|
204
247
|
lastMessage: WSEventMessage | null;
|
|
205
248
|
isConnected: boolean;
|
|
@@ -223,4 +266,4 @@ declare function useConnectionStatus(): {
|
|
|
223
266
|
datasourceMode: ConnectionMode;
|
|
224
267
|
};
|
|
225
268
|
|
|
226
|
-
export { BudokanProvider, type BudokanProviderProps, type UseActivityStatsResult, type UseLeaderboardResult, type UsePrizeAggregationResult, type UsePrizeStatsResult, type UsePrizesResult, type UseQualificationsResult, type UseRegistrationsResult, type UseRewardClaimsResult, type UseRewardClaimsSummaryResult, type UseSubscriptionResult, type UseTournamentCountResult, type UseTournamentResult, type UseTournamentsResult, useActivityStats, useBudokanClient, useConnectionStatus, useLeaderboard, usePrizeAggregation, usePrizeStats, usePrizes, useQualifications, useRegistrations, useRegistrationsByOwner, useRewardClaims, useRewardClaimsSummary, useSubscription, useTournament, useTournamentCount, useTournaments, useTournamentsByOwner, useTournamentsByOwnerCount };
|
|
269
|
+
export { BudokanProvider, type BudokanProviderProps, type UseActivityStatsResult, type UseLeaderboardResult, type UsePlayerRewardsResult, type UsePrizeAggregationResult, type UsePrizeStatsResult, type UsePrizesResult, type UseQualificationsResult, type UseRegistrationsResult, type UseRewardClaimsResult, type UseRewardClaimsSummaryResult, type UseSubscriptionResult, type UseTournamentCountResult, type UseTournamentResult, type UseTournamentsResult, useActivityStats, useBudokanClient, useConnectionStatus, useLeaderboard, usePlayerRewards, usePrizeAggregation, usePrizeStats, usePrizes, useQualifications, useRegistrations, useRegistrationsByOwner, useRewardClaims, useRewardClaimsSummary, useSubscription, useTournament, useTournamentCount, useTournaments, useTournamentsByOwner, useTournamentsByOwnerCount };
|
package/dist/react.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import { i as BudokanClientConfig, B as BudokanClient, T as Tournament, b as PaginatedResult, e as TournamentListParams, m as Phase, l as LeaderboardEntry, R as Registration, c as RewardClaim, d as RewardClaimSummary, g as PrizeStats, a as Prize, P as PrizeAggregation, Q as QualificationEntry, f as PlatformStats, o as WSEventMessage,
|
|
3
|
+
import { i as BudokanClientConfig, B as BudokanClient, T as Tournament, b as PaginatedResult, e as TournamentListParams, m as Phase, l as LeaderboardEntry, R as Registration, c as RewardClaim, d as RewardClaimSummary, g as PrizeStats, a as Prize, P as PrizeAggregation, Q as QualificationEntry, f as PlatformStats, o as PlayerRewards, q as WSEventMessage, p as WSChannel, C as ConnectionMode } from './player-BUynfv7D.js';
|
|
4
4
|
import 'starknet';
|
|
5
5
|
import '@provable-games/metagame-sdk';
|
|
6
6
|
|
|
@@ -200,6 +200,49 @@ interface UseActivityStatsResult {
|
|
|
200
200
|
*/
|
|
201
201
|
declare function useActivityStats(): UseActivityStatsResult;
|
|
202
202
|
|
|
203
|
+
interface UsePlayerRewardsResult {
|
|
204
|
+
rewards: PlayerRewards | null;
|
|
205
|
+
loading: boolean;
|
|
206
|
+
error: Error | null;
|
|
207
|
+
refetch: () => Promise<void>;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Aggregate a player's placement/earnings data across finalized Budokan
|
|
211
|
+
* tournaments they currently hold tokens in.
|
|
212
|
+
*
|
|
213
|
+
* Composition:
|
|
214
|
+
*
|
|
215
|
+
* denshokan useTokens (current ownership)
|
|
216
|
+
* ↓ group by contextId (= tournament id)
|
|
217
|
+
* budokan useTournaments({ tournamentIds })
|
|
218
|
+
* ↓ filter to finalized
|
|
219
|
+
* for each finalized tournament (parallel):
|
|
220
|
+
* budokan getTournamentPrizes — full prize records
|
|
221
|
+
* budokan getTournamentRewardClaims — paginated, all pages
|
|
222
|
+
* denshokan getTokenRanks (bulk) — final ranks for owned tokens
|
|
223
|
+
* ↓ filter ranks to paid positions (max position derived from prizes
|
|
224
|
+
* + entry-fee distribution_count)
|
|
225
|
+
*
|
|
226
|
+
* Per-tournament failures are tolerated: a 5xx on one tournament's prize/
|
|
227
|
+
* claim/rank fetch skips that tournament and continues, rather than
|
|
228
|
+
* failing the whole hook. Failures are logged via `console.warn`.
|
|
229
|
+
*
|
|
230
|
+
* Why source ownership from denshokan: PR #243 dropped
|
|
231
|
+
* `registrations.player_address` because the indexed value goes stale on
|
|
232
|
+
* transfer. The contract keys registrations by token_id only, so the only
|
|
233
|
+
* trustworthy answer to "what tournaments has this wallet placed in" is
|
|
234
|
+
* to ask denshokan who currently holds Budokan-minted tokens.
|
|
235
|
+
*
|
|
236
|
+
* Staleness: the hook only re-fetches when the player's owned token set
|
|
237
|
+
* changes (transfers/new mints) or when the underlying tournament list
|
|
238
|
+
* changes. It does *not* observe time-based finalization transitions on
|
|
239
|
+
* its own — if a tournament's submission window closes while the
|
|
240
|
+
* consumer is mounted, call `refetch()` to pick up the new placement.
|
|
241
|
+
*
|
|
242
|
+
* Pass `undefined` to skip fetching.
|
|
243
|
+
*/
|
|
244
|
+
declare function usePlayerRewards(address: string | undefined): UsePlayerRewardsResult;
|
|
245
|
+
|
|
203
246
|
interface UseSubscriptionResult {
|
|
204
247
|
lastMessage: WSEventMessage | null;
|
|
205
248
|
isConnected: boolean;
|
|
@@ -223,4 +266,4 @@ declare function useConnectionStatus(): {
|
|
|
223
266
|
datasourceMode: ConnectionMode;
|
|
224
267
|
};
|
|
225
268
|
|
|
226
|
-
export { BudokanProvider, type BudokanProviderProps, type UseActivityStatsResult, type UseLeaderboardResult, type UsePrizeAggregationResult, type UsePrizeStatsResult, type UsePrizesResult, type UseQualificationsResult, type UseRegistrationsResult, type UseRewardClaimsResult, type UseRewardClaimsSummaryResult, type UseSubscriptionResult, type UseTournamentCountResult, type UseTournamentResult, type UseTournamentsResult, useActivityStats, useBudokanClient, useConnectionStatus, useLeaderboard, usePrizeAggregation, usePrizeStats, usePrizes, useQualifications, useRegistrations, useRegistrationsByOwner, useRewardClaims, useRewardClaimsSummary, useSubscription, useTournament, useTournamentCount, useTournaments, useTournamentsByOwner, useTournamentsByOwnerCount };
|
|
269
|
+
export { BudokanProvider, type BudokanProviderProps, type UseActivityStatsResult, type UseLeaderboardResult, type UsePlayerRewardsResult, type UsePrizeAggregationResult, type UsePrizeStatsResult, type UsePrizesResult, type UseQualificationsResult, type UseRegistrationsResult, type UseRewardClaimsResult, type UseRewardClaimsSummaryResult, type UseSubscriptionResult, type UseTournamentCountResult, type UseTournamentResult, type UseTournamentsResult, useActivityStats, useBudokanClient, useConnectionStatus, useLeaderboard, usePlayerRewards, usePrizeAggregation, usePrizeStats, usePrizes, useQualifications, useRegistrations, useRegistrationsByOwner, useRewardClaims, useRewardClaimsSummary, useSubscription, useTournament, useTournamentCount, useTournaments, useTournamentsByOwner, useTournamentsByOwnerCount };
|
package/dist/react.js
CHANGED
|
@@ -1,7 +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
|
+
import { useTokens, useDenshokanClient } from '@provable-games/denshokan-sdk/react';
|
|
5
5
|
|
|
6
6
|
// src/react/context.tsx
|
|
7
7
|
|
|
@@ -1112,6 +1112,84 @@ async function viewerPrizes(contract, tournamentId) {
|
|
|
1112
1112
|
return result.map(parsePrize);
|
|
1113
1113
|
}, contract.address);
|
|
1114
1114
|
}
|
|
1115
|
+
function translateCairoRewardType(rewardType) {
|
|
1116
|
+
if (!rewardType || typeof rewardType !== "object") {
|
|
1117
|
+
throw new Error(`Unexpected RewardType payload: ${JSON.stringify(rewardType)}`);
|
|
1118
|
+
}
|
|
1119
|
+
const rt = rewardType;
|
|
1120
|
+
const outer = typeof rt.activeVariant === "function" ? rt.activeVariant() : null;
|
|
1121
|
+
const innerBag = typeof rt.activeVariant === "function" ? rt.variant : rt;
|
|
1122
|
+
if (outer === "Prize" || innerBag.Prize !== void 0) {
|
|
1123
|
+
const prize = innerBag.Prize;
|
|
1124
|
+
const subVariant = typeof prize?.activeVariant === "function" ? prize.activeVariant() : null;
|
|
1125
|
+
const subBag = typeof prize?.activeVariant === "function" ? prize.variant : prize;
|
|
1126
|
+
if (subVariant === "Single" || subBag?.Single !== void 0) {
|
|
1127
|
+
return {
|
|
1128
|
+
claimKind: "prize_single",
|
|
1129
|
+
prizeId: BigInt(subBag.Single).toString(),
|
|
1130
|
+
payoutIndex: null,
|
|
1131
|
+
position: null,
|
|
1132
|
+
refundTokenId: null
|
|
1133
|
+
};
|
|
1134
|
+
}
|
|
1135
|
+
if (subVariant === "Distributed" || subBag?.Distributed !== void 0) {
|
|
1136
|
+
const distributed = subBag.Distributed;
|
|
1137
|
+
const prizeId = distributed?.["0"] ?? distributed?.[0];
|
|
1138
|
+
const payoutIndex = distributed?.["1"] ?? distributed?.[1];
|
|
1139
|
+
return {
|
|
1140
|
+
claimKind: "prize_distributed",
|
|
1141
|
+
prizeId: BigInt(prizeId).toString(),
|
|
1142
|
+
payoutIndex: Number(payoutIndex),
|
|
1143
|
+
position: null,
|
|
1144
|
+
refundTokenId: null
|
|
1145
|
+
};
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
if (outer === "EntryFee" || innerBag.EntryFee !== void 0) {
|
|
1149
|
+
const entryFee = innerBag.EntryFee;
|
|
1150
|
+
const subVariant = typeof entryFee?.activeVariant === "function" ? entryFee.activeVariant() : null;
|
|
1151
|
+
const subBag = typeof entryFee?.activeVariant === "function" ? entryFee.variant : entryFee;
|
|
1152
|
+
if (subVariant === "Position" || subBag?.Position !== void 0) {
|
|
1153
|
+
return {
|
|
1154
|
+
claimKind: "entry_fee_position",
|
|
1155
|
+
prizeId: null,
|
|
1156
|
+
payoutIndex: null,
|
|
1157
|
+
position: Number(subBag.Position),
|
|
1158
|
+
refundTokenId: null
|
|
1159
|
+
};
|
|
1160
|
+
}
|
|
1161
|
+
if (subVariant === "TournamentCreator" || subBag?.TournamentCreator !== void 0) {
|
|
1162
|
+
return {
|
|
1163
|
+
claimKind: "entry_fee_tournament_creator",
|
|
1164
|
+
prizeId: null,
|
|
1165
|
+
payoutIndex: null,
|
|
1166
|
+
position: null,
|
|
1167
|
+
refundTokenId: null
|
|
1168
|
+
};
|
|
1169
|
+
}
|
|
1170
|
+
if (subVariant === "GameCreator" || subBag?.GameCreator !== void 0) {
|
|
1171
|
+
return {
|
|
1172
|
+
claimKind: "entry_fee_game_creator",
|
|
1173
|
+
prizeId: null,
|
|
1174
|
+
payoutIndex: null,
|
|
1175
|
+
position: null,
|
|
1176
|
+
refundTokenId: null
|
|
1177
|
+
};
|
|
1178
|
+
}
|
|
1179
|
+
if (subVariant === "Refund" || subBag?.Refund !== void 0) {
|
|
1180
|
+
return {
|
|
1181
|
+
claimKind: "entry_fee_refund",
|
|
1182
|
+
prizeId: null,
|
|
1183
|
+
payoutIndex: null,
|
|
1184
|
+
position: null,
|
|
1185
|
+
refundTokenId: `0x${BigInt(subBag.Refund).toString(16)}`
|
|
1186
|
+
};
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
throw new Error(
|
|
1190
|
+
`Unrecognised on-chain RewardType variant: ${JSON.stringify(rewardType)}`
|
|
1191
|
+
);
|
|
1192
|
+
}
|
|
1115
1193
|
async function viewerRewardClaims(contract, tournamentId, offset, limit) {
|
|
1116
1194
|
return wrapRpcCall(async () => {
|
|
1117
1195
|
const result = await contract.call("tournament_reward_claims", [tournamentId, offset, limit]);
|
|
@@ -1119,7 +1197,7 @@ async function viewerRewardClaims(contract, tournamentId, offset, limit) {
|
|
|
1119
1197
|
const claims = obj.claims?.map((raw) => {
|
|
1120
1198
|
const claim = raw;
|
|
1121
1199
|
return {
|
|
1122
|
-
|
|
1200
|
+
...translateCairoRewardType(claim.reward_type),
|
|
1123
1201
|
claimed: Boolean(claim.claimed)
|
|
1124
1202
|
};
|
|
1125
1203
|
}) ?? [];
|
|
@@ -4516,8 +4594,7 @@ var BudokanClient = class {
|
|
|
4516
4594
|
const result = await viewerRewardClaims(contract, tournamentId, offset, limit);
|
|
4517
4595
|
const data = result.claims.map((c) => ({
|
|
4518
4596
|
tournamentId,
|
|
4519
|
-
|
|
4520
|
-
claimed: c.claimed
|
|
4597
|
+
...c
|
|
4521
4598
|
}));
|
|
4522
4599
|
return { data, total: result.total, limit, offset };
|
|
4523
4600
|
};
|
|
@@ -4792,7 +4869,6 @@ function useOwnedTournamentIds(owner, contextId) {
|
|
|
4792
4869
|
enabled ? {
|
|
4793
4870
|
owner,
|
|
4794
4871
|
minterAddress: budokanAddress,
|
|
4795
|
-
hasContext: true,
|
|
4796
4872
|
...{},
|
|
4797
4873
|
limit: MAX_OWNED_TOKENS
|
|
4798
4874
|
} : void 0
|
|
@@ -4908,7 +4984,11 @@ function useRegistrationsByOwner(tournamentId, owner, params) {
|
|
|
4908
4984
|
}, [enabled, tokensResult]);
|
|
4909
4985
|
const inner = useRegistrations(
|
|
4910
4986
|
ownedGameTokenIds && ownedGameTokenIds.length > 0 ? tournamentId : void 0,
|
|
4911
|
-
ownedGameTokenIds && ownedGameTokenIds.length > 0 ? {
|
|
4987
|
+
ownedGameTokenIds && ownedGameTokenIds.length > 0 ? {
|
|
4988
|
+
limit: Math.min(ownedGameTokenIds.length, MAX_OWNED_TOKENS),
|
|
4989
|
+
...params,
|
|
4990
|
+
gameTokenIds: ownedGameTokenIds
|
|
4991
|
+
} : void 0
|
|
4912
4992
|
);
|
|
4913
4993
|
if (ownedGameTokenIds !== null && ownedGameTokenIds.length === 0) {
|
|
4914
4994
|
return {
|
|
@@ -5097,6 +5177,200 @@ function useActivityStats() {
|
|
|
5097
5177
|
}, [fetch2]);
|
|
5098
5178
|
return { stats, loading, error, refetch: fetch2 };
|
|
5099
5179
|
}
|
|
5180
|
+
function usePlayerRewards(address) {
|
|
5181
|
+
const budokan = useBudokanClient();
|
|
5182
|
+
const denshokan = useDenshokanClient();
|
|
5183
|
+
const budokanAddress = budokan.clientConfig.budokanAddress;
|
|
5184
|
+
const [rewards, setRewards] = useState(null);
|
|
5185
|
+
const [aggregating, setAggregating] = useState(false);
|
|
5186
|
+
const [error, setError] = useState(null);
|
|
5187
|
+
useResetOnClient(budokan, setRewards, setError);
|
|
5188
|
+
const tokensEnabled = !!address && !!budokanAddress;
|
|
5189
|
+
const { data: tokensResult, isLoading: tokensLoading } = useTokens(
|
|
5190
|
+
tokensEnabled ? {
|
|
5191
|
+
owner: address,
|
|
5192
|
+
minterAddress: budokanAddress,
|
|
5193
|
+
limit: 1e3
|
|
5194
|
+
} : void 0
|
|
5195
|
+
);
|
|
5196
|
+
const tokensByTournament = useMemo(() => {
|
|
5197
|
+
if (!tokensResult?.data) return null;
|
|
5198
|
+
const map = /* @__PURE__ */ new Map();
|
|
5199
|
+
for (const t of tokensResult.data) {
|
|
5200
|
+
if (t.contextId == null || !t.tokenId) continue;
|
|
5201
|
+
const tid = String(t.contextId);
|
|
5202
|
+
let list = map.get(tid);
|
|
5203
|
+
if (!list) {
|
|
5204
|
+
list = [];
|
|
5205
|
+
map.set(tid, list);
|
|
5206
|
+
}
|
|
5207
|
+
list.push(t.tokenId);
|
|
5208
|
+
}
|
|
5209
|
+
return map;
|
|
5210
|
+
}, [tokensResult]);
|
|
5211
|
+
const tournamentIds = useMemo(
|
|
5212
|
+
() => tokensByTournament ? Array.from(tokensByTournament.keys()) : [],
|
|
5213
|
+
[tokensByTournament]
|
|
5214
|
+
);
|
|
5215
|
+
const { tournaments: tournamentsPage, loading: tournamentsLoading } = useTournaments(
|
|
5216
|
+
tournamentIds.length > 0 ? { tournamentIds, limit: 1e3 } : void 0
|
|
5217
|
+
);
|
|
5218
|
+
const tournamentIdsKey = tournamentIds.join(",");
|
|
5219
|
+
const fetch2 = useCallback(async () => {
|
|
5220
|
+
if (!tokensEnabled) {
|
|
5221
|
+
setRewards(null);
|
|
5222
|
+
return;
|
|
5223
|
+
}
|
|
5224
|
+
if (!tokensByTournament) return;
|
|
5225
|
+
if (tokensByTournament.size === 0) {
|
|
5226
|
+
setRewards(emptyRewards());
|
|
5227
|
+
return;
|
|
5228
|
+
}
|
|
5229
|
+
if (!tournamentsPage?.data) return;
|
|
5230
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
5231
|
+
const finalized = tournamentsPage.data.filter((t) => {
|
|
5232
|
+
const sub = Number(t.submissionEndTime ?? 0);
|
|
5233
|
+
return sub > 0 && sub <= now;
|
|
5234
|
+
});
|
|
5235
|
+
if (finalized.length === 0) {
|
|
5236
|
+
setRewards(emptyRewards());
|
|
5237
|
+
return;
|
|
5238
|
+
}
|
|
5239
|
+
setAggregating(true);
|
|
5240
|
+
setError(null);
|
|
5241
|
+
try {
|
|
5242
|
+
const settled = await Promise.allSettled(
|
|
5243
|
+
finalized.map(async (t) => {
|
|
5244
|
+
const tid = t.id;
|
|
5245
|
+
const tokenIds = tokensByTournament.get(tid) ?? [];
|
|
5246
|
+
if (tokenIds.length === 0) return null;
|
|
5247
|
+
const [prizes, allClaims, ranksResult] = await Promise.all([
|
|
5248
|
+
budokan.getTournamentPrizes(tid),
|
|
5249
|
+
fetchAllRewardClaims(budokan, tid),
|
|
5250
|
+
denshokan.getTokenRanks(tokenIds, {
|
|
5251
|
+
contextId: Number(tid),
|
|
5252
|
+
minterAddress: budokanAddress
|
|
5253
|
+
})
|
|
5254
|
+
]);
|
|
5255
|
+
let maxPaid = 0;
|
|
5256
|
+
for (const p of prizes) {
|
|
5257
|
+
if ((p.payoutPosition ?? 0) > 0) {
|
|
5258
|
+
maxPaid = Math.max(maxPaid, p.payoutPosition);
|
|
5259
|
+
}
|
|
5260
|
+
if ((p.distributionCount ?? 0) > 0) {
|
|
5261
|
+
maxPaid = Math.max(maxPaid, p.distributionCount);
|
|
5262
|
+
}
|
|
5263
|
+
}
|
|
5264
|
+
const efDistCount = Number(t.entryFee?.distributionCount ?? 0);
|
|
5265
|
+
if (efDistCount > 0) maxPaid = Math.max(maxPaid, efDistCount);
|
|
5266
|
+
if (maxPaid === 0) return null;
|
|
5267
|
+
const placements = ranksResult.data.filter((r) => r.rank > 0 && r.rank <= maxPaid).map((r) => ({
|
|
5268
|
+
tournamentId: tid,
|
|
5269
|
+
tokenId: r.tokenId,
|
|
5270
|
+
position: r.rank,
|
|
5271
|
+
score: String(r.score ?? "0")
|
|
5272
|
+
}));
|
|
5273
|
+
if (placements.length === 0) return null;
|
|
5274
|
+
return {
|
|
5275
|
+
tournament: t,
|
|
5276
|
+
prizes,
|
|
5277
|
+
rewardClaims: allClaims,
|
|
5278
|
+
placements
|
|
5279
|
+
};
|
|
5280
|
+
})
|
|
5281
|
+
);
|
|
5282
|
+
const valid = settled.map((s, i) => {
|
|
5283
|
+
if (s.status === "fulfilled") return s.value;
|
|
5284
|
+
console.warn(
|
|
5285
|
+
`usePlayerRewards: tournament ${finalized[i].id} fetch failed; skipping`,
|
|
5286
|
+
s.reason
|
|
5287
|
+
);
|
|
5288
|
+
return null;
|
|
5289
|
+
}).filter((r) => r !== null);
|
|
5290
|
+
const allPlacements = valid.flatMap(
|
|
5291
|
+
(r) => r.placements
|
|
5292
|
+
);
|
|
5293
|
+
const wins = allPlacements.length;
|
|
5294
|
+
const bestPlacement = wins > 0 ? Math.min(...allPlacements.map((p) => p.position)) : null;
|
|
5295
|
+
const tournamentsList = valid.map((r) => r.tournament);
|
|
5296
|
+
const prizesList = valid.flatMap((r) => r.prizes);
|
|
5297
|
+
const rewardClaimsList = valid.flatMap(
|
|
5298
|
+
(r) => r.rewardClaims
|
|
5299
|
+
);
|
|
5300
|
+
setRewards({
|
|
5301
|
+
wins,
|
|
5302
|
+
bestPlacement,
|
|
5303
|
+
placements: allPlacements,
|
|
5304
|
+
tournaments: tournamentsList,
|
|
5305
|
+
prizes: prizesList,
|
|
5306
|
+
rewardClaims: rewardClaimsList
|
|
5307
|
+
});
|
|
5308
|
+
} catch (e) {
|
|
5309
|
+
setError(e);
|
|
5310
|
+
} finally {
|
|
5311
|
+
setAggregating(false);
|
|
5312
|
+
}
|
|
5313
|
+
}, [
|
|
5314
|
+
tokensEnabled,
|
|
5315
|
+
tokensByTournament,
|
|
5316
|
+
tournamentsPage,
|
|
5317
|
+
tournamentIdsKey,
|
|
5318
|
+
budokan,
|
|
5319
|
+
denshokan,
|
|
5320
|
+
budokanAddress
|
|
5321
|
+
]);
|
|
5322
|
+
const lastRunRef = useRef("");
|
|
5323
|
+
useEffect(() => {
|
|
5324
|
+
if (!tokensEnabled) {
|
|
5325
|
+
setRewards(null);
|
|
5326
|
+
return;
|
|
5327
|
+
}
|
|
5328
|
+
if (!tokensByTournament || !tournamentsPage?.data) return;
|
|
5329
|
+
const fingerprint = `${address}|${tournamentIdsKey}|${tournamentsPage.data.length}`;
|
|
5330
|
+
if (fingerprint === lastRunRef.current) return;
|
|
5331
|
+
lastRunRef.current = fingerprint;
|
|
5332
|
+
fetch2();
|
|
5333
|
+
}, [
|
|
5334
|
+
address,
|
|
5335
|
+
tokensEnabled,
|
|
5336
|
+
tokensByTournament,
|
|
5337
|
+
tournamentsPage,
|
|
5338
|
+
tournamentIdsKey,
|
|
5339
|
+
fetch2
|
|
5340
|
+
]);
|
|
5341
|
+
const loading = tokensEnabled && (tokensLoading || tournamentsLoading) || aggregating;
|
|
5342
|
+
return { rewards, loading, error, refetch: fetch2 };
|
|
5343
|
+
}
|
|
5344
|
+
function emptyRewards() {
|
|
5345
|
+
return {
|
|
5346
|
+
wins: 0,
|
|
5347
|
+
bestPlacement: null,
|
|
5348
|
+
placements: [],
|
|
5349
|
+
tournaments: [],
|
|
5350
|
+
prizes: [],
|
|
5351
|
+
rewardClaims: []
|
|
5352
|
+
};
|
|
5353
|
+
}
|
|
5354
|
+
async function fetchAllRewardClaims(client, tournamentId) {
|
|
5355
|
+
const first = await client.getTournamentRewardClaims(tournamentId, {
|
|
5356
|
+
limit: 100
|
|
5357
|
+
});
|
|
5358
|
+
const accumulated = [...first.data];
|
|
5359
|
+
const total = first.total ?? accumulated.length;
|
|
5360
|
+
if (accumulated.length >= total) return accumulated;
|
|
5361
|
+
const pageSize = Math.max(first.data.length, 1);
|
|
5362
|
+
let offset = accumulated.length;
|
|
5363
|
+
while (offset < total) {
|
|
5364
|
+
const next = await client.getTournamentRewardClaims(tournamentId, {
|
|
5365
|
+
limit: pageSize,
|
|
5366
|
+
offset
|
|
5367
|
+
});
|
|
5368
|
+
if (next.data.length === 0) break;
|
|
5369
|
+
accumulated.push(...next.data);
|
|
5370
|
+
offset += next.data.length;
|
|
5371
|
+
}
|
|
5372
|
+
return accumulated;
|
|
5373
|
+
}
|
|
5100
5374
|
function useSubscription(channels, tournamentIds) {
|
|
5101
5375
|
const client = useBudokanClient();
|
|
5102
5376
|
const [lastMessage, setLastMessage] = useState(null);
|
|
@@ -5142,6 +5416,6 @@ function useConnectionStatus() {
|
|
|
5142
5416
|
return { isConnected, datasourceMode };
|
|
5143
5417
|
}
|
|
5144
5418
|
|
|
5145
|
-
export { BudokanProvider, useActivityStats, useBudokanClient, useConnectionStatus, useLeaderboard, usePrizeAggregation, usePrizeStats, usePrizes, useQualifications, useRegistrations, useRegistrationsByOwner, useRewardClaims, useRewardClaimsSummary, useSubscription, useTournament, useTournamentCount, useTournaments, useTournamentsByOwner, useTournamentsByOwnerCount };
|
|
5419
|
+
export { BudokanProvider, useActivityStats, useBudokanClient, useConnectionStatus, useLeaderboard, usePlayerRewards, usePrizeAggregation, usePrizeStats, usePrizes, useQualifications, useRegistrations, useRegistrationsByOwner, useRewardClaims, useRewardClaimsSummary, useSubscription, useTournament, useTournamentCount, useTournaments, useTournamentsByOwner, useTournamentsByOwnerCount };
|
|
5146
5420
|
//# sourceMappingURL=react.js.map
|
|
5147
5421
|
//# sourceMappingURL=react.js.map
|