import { useCallback, useEffect, useRef, useState } from 'react';
import { LITIUM_REFER_CONTRACT } from 'src/constants/mining';
import { useQueryClient as useCyberQueryClient } from 'src/contexts/queryClient';
import type {
ReferralInfoResponse,
ReferrerOfResponse,
} from 'src/generated/lithium/LitiumRefer.types';
type ReferralInfoWithReferrer = ReferralInfoResponse & { referrer: string | null };
const POLL_INTERVAL = 15_000;
function useReferralInfo(address: string | undefined) {
const queryClient = useCyberQueryClient();
const [referralInfo, setReferralInfo] = useState<ReferralInfoWithReferrer | undefined>();
const [loading, setLoading] = useState(false);
const [counter, setCounter] = useState(0);
const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
// Store latest fetch function in a ref to avoid interval churn
const fetchRef = useRef<() => void>(() => {});
const fetchInfo = useCallback(async () => {
if (!queryClient || !address) {
setReferralInfo(undefined);
return;
}
setLoading(true);
try {
const [infoData, referrerData] = await Promise.all([
queryClient.queryContractSmart(
LITIUM_REFER_CONTRACT,
{ referral_info: { address } }
).catch(() => null),
queryClient.queryContractSmart(
LITIUM_REFER_CONTRACT,
{ referrer_of: { miner: address } }
).catch(() => null),
]);
const rawInfo = infoData as Omit<ReferralInfoWithReferrer, 'referrer'> | null;
const referrerOf = referrerData as ReferrerOfResponse | null;
if (rawInfo) {
setReferralInfo({
...rawInfo,
referrer: referrerOf?.referrer ?? null,
});
} else {
setReferralInfo(undefined);
}
} catch {
setReferralInfo(undefined);
} finally {
setLoading(false);
}
}, [queryClient, address]);
fetchRef.current = fetchInfo;
useEffect(() => {
fetchInfo();
}, [fetchInfo, counter]);
// Periodic polling disabled โ manual refetch via refetch() callback
void intervalRef;
const refetch = useCallback(() => {
setCounter((c) => c + 1);
}, []);
return {
referralInfo,
loading,
refetch,
};
}
export default useReferralInfo;