forked from Cylo-Traders/Agrocylo-PIP
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuseAdminCampaigns.ts
More file actions
80 lines (72 loc) · 2.56 KB
/
Copy pathuseAdminCampaigns.ts
File metadata and controls
80 lines (72 loc) · 2.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import { useQuery } from '@tanstack/react-query';
import { loadRecentEscrowEvents } from '../lib/soroban/events';
import { contractMethod, getEscrowClient } from '../lib/soroban/contractClient';
import {
ESCROW_CONTRACT_ID,
RPC_URL,
isEscrowConfigured,
} from '../lib/soroban/config';
import { contractQueryKeys } from './contract/queryKeys';
import type { Campaign, CampaignStatusTag } from '../lib/soroban/types';
const DEFAULT_LOOKBACK_LEDGERS = 120_000;
const LOOKBACK_LEDGERS = (() => {
const parsed = Number(import.meta.env.VITE_SOROBAN_EVENTS_LOOKBACK_LEDGERS);
return Number.isFinite(parsed) && parsed > 0
? parsed
: DEFAULT_LOOKBACK_LEDGERS;
})();
/** Statuses where at least one of the five admin actions is applicable. */
const ACTIONABLE_STATUSES: CampaignStatusTag[] = [
'Active',
'Funding',
'Funded',
'InProduction',
'Harvested',
'Disputed',
];
export interface AdminCampaignOverview {
id: string;
campaign: Campaign;
}
/**
* Discovers campaigns from ProductionEscrowContract event history (there is
* no on-chain "list all campaigns" getter) and fetches their current state,
* filtered to campaigns where an admin action is still applicable. Mirrors
* the event-scanning approach in hooks/useCampaignAnalytics.ts.
*/
export function useAdminCampaigns() {
return useQuery({
queryKey: contractQueryKeys.adminCampaignsOverview(),
enabled: isEscrowConfigured(),
queryFn: async (): Promise<AdminCampaignOverview[]> => {
const events = await loadRecentEscrowEvents({
rpcUrl: RPC_URL!,
contractId: ESCROW_CONTRACT_ID!,
lookbackLedgers: LOOKBACK_LEDGERS,
});
const campaignIds = Array.from(
new Set(events.map((event) => event.campaignId).filter(Boolean)),
);
const client = await getEscrowClient();
const overviews = await Promise.all(
campaignIds.map(async (id): Promise<AdminCampaignOverview | null> => {
try {
const tx = await contractMethod<Campaign>(
client,
'get_campaign',
)({ campaign_id: BigInt(id) });
return { id, campaign: tx.result };
} catch {
// Campaign may no longer resolve (e.g. stale/malformed event) —
// skip it rather than failing the whole dashboard load.
return null;
}
}),
);
return overviews
.filter((o): o is AdminCampaignOverview => o !== null)
.filter((o) => ACTIONABLE_STATUSES.includes(o.campaign.status.tag))
.sort((a, b) => Number(b.id) - Number(a.id));
},
});
}