diff --git a/app/src/hooks/useHarvestHistory.ts b/app/src/hooks/useHarvestHistory.ts
new file mode 100644
index 0000000..ad0d3c2
--- /dev/null
+++ b/app/src/hooks/useHarvestHistory.ts
@@ -0,0 +1,52 @@
+'use client';
+
+import { useState, useEffect } from 'react';
+
+export interface HarvestEvent {
+ id: string;
+ date: string;
+ ledger: number;
+ yieldAmount: number;
+ bounty: number;
+ caller: string;
+}
+
+export interface HarvestHistoryData {
+ events: HarvestEvent[];
+ isLoading: boolean;
+ error: string | null;
+}
+
+const CALLERS = [
+ 'GABCDXXXX...YYYY',
+ 'GEFGHXXXX...YYYY',
+ 'GIJKLXXXX...YYYY',
+ 'GMNOPXXXX...YYYY',
+];
+
+export function useHarvestHistory(limit = 20): HarvestHistoryData {
+ const [data, setData] = useState({
+ events: [],
+ isLoading: true,
+ error: null,
+ });
+
+ useEffect(() => {
+ // TODO(GF-12): Replace with real event indexer queries
+ const now = Date.now();
+ const events: HarvestEvent[] = Array.from({ length: limit }, (_, i) => {
+ const yieldAmount = 1200 + Math.floor(Math.abs(Math.sin(i * 1.3)) * 800);
+ return {
+ id: `harvest-${i}`,
+ date: new Date(now - i * 7 * 24 * 60 * 60 * 1000).toISOString(),
+ ledger: 5_000_000 - i * 17_280,
+ yieldAmount,
+ bounty: Math.round(yieldAmount * 0.001 * 100) / 100,
+ caller: CALLERS[i % CALLERS.length],
+ };
+ });
+ setData({ events, isLoading: false, error: null });
+ }, [limit]);
+
+ return data;
+}