From dae3a5d3a14e7264991619c37725460e9c003cc3 Mon Sep 17 00:00:00 2001 From: Jeesun Kim Date: Fri, 26 Jun 2026 14:54:25 -0700 Subject: [PATCH 1/7] [Query] Type queryFn return instead of useQuery generic Move the result type from the useQuery generic onto each queryFn return annotation so TData is inferred from the function. Widen useSEContractInfo's consumer prop to accept the now-accurate null. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../components/ContractInfo.tsx | 2 +- src/query/external/useSEContractInfo.ts | 4 ++-- src/query/external/useSEContractStorage.ts | 4 ++-- .../external/useSEContractVersionHistory.ts | 4 ++-- src/query/external/useSEContractWasmBinary.ts | 4 ++-- src/query/external/useSEContractsList.ts | 12 +++++------ src/query/useContractClientFromRpc.ts | 4 ++-- src/query/useGetContractDataFromRpcById.ts | 21 +++++++++++-------- src/query/useGitHubFile.ts | 4 ++-- src/query/useGitHubReadmeText.ts | 4 ++-- src/query/useMaintenanceData.ts | 4 ++-- src/query/useWasmBinaryFromRpc.ts | 4 ++-- src/query/useWasmGitHubAttestation.ts | 4 ++-- 13 files changed, 39 insertions(+), 36 deletions(-) diff --git a/src/app/(sidebar)/smart-contracts/contract-explorer/components/ContractInfo.tsx b/src/app/(sidebar)/smart-contracts/contract-explorer/components/ContractInfo.tsx index d2c5d18d8..0b092fc4c 100644 --- a/src/app/(sidebar)/smart-contracts/contract-explorer/components/ContractInfo.tsx +++ b/src/app/(sidebar)/smart-contracts/contract-explorer/components/ContractInfo.tsx @@ -52,7 +52,7 @@ export const ContractInfo = ({ isLoading, isSacType, }: { - infoData: ContractInfoApiResponse | undefined; + infoData: ContractInfoApiResponse | null | undefined; contractId: string; backendStatus: "healthy" | "unhealthy"; wasmData: WasmData | null | undefined; diff --git a/src/query/external/useSEContractInfo.ts b/src/query/external/useSEContractInfo.ts index ec0ee102b..354d34c3c 100644 --- a/src/query/external/useSEContractInfo.ts +++ b/src/query/external/useSEContractInfo.ts @@ -13,9 +13,9 @@ export const useSEContractInfo = ({ networkId: NetworkType; contractId: string; }) => { - const query = useQuery({ + const query = useQuery({ queryKey: ["useSEContractInfo", networkId, contractId], - queryFn: async () => { + queryFn: async (): Promise => { const network = getStellarExpertNetwork(networkId); if (!network) { diff --git a/src/query/external/useSEContractStorage.ts b/src/query/external/useSEContractStorage.ts index ce76f05a3..35ad2d003 100644 --- a/src/query/external/useSEContractStorage.ts +++ b/src/query/external/useSEContractStorage.ts @@ -20,9 +20,9 @@ export const useSEContractStorage = ({ contractId: string; totalEntriesCount: number | undefined; }) => { - const query = useQuery({ + const query = useQuery({ queryKey: ["useSEContractStorage", networkId, contractId], - queryFn: async () => { + queryFn: async (): Promise => { // No entries if (!totalEntriesCount) { return null; diff --git a/src/query/external/useSEContractVersionHistory.ts b/src/query/external/useSEContractVersionHistory.ts index ebbedb17b..369c9ede4 100644 --- a/src/query/external/useSEContractVersionHistory.ts +++ b/src/query/external/useSEContractVersionHistory.ts @@ -15,9 +15,9 @@ export const useSEContractVersionHistory = ({ networkId: NetworkType; contractId: string; }) => { - const query = useQuery({ + const query = useQuery({ queryKey: ["useSEContractVersionHistory", networkId, contractId], - queryFn: async () => { + queryFn: async (): Promise => { const network = getStellarExpertNetwork(networkId); if (!network) { diff --git a/src/query/external/useSEContractWasmBinary.ts b/src/query/external/useSEContractWasmBinary.ts index e0af387ab..ee61f20d7 100644 --- a/src/query/external/useSEContractWasmBinary.ts +++ b/src/query/external/useSEContractWasmBinary.ts @@ -13,9 +13,9 @@ export const useSEContractWasmBinary = ({ networkId: NetworkType; wasmHash: string; }) => { - const query = useQuery({ + const query = useQuery({ queryKey: ["useSEContractWasmBinary", networkId, wasmHash], - queryFn: async () => { + queryFn: async (): Promise => { const network = getStellarExpertNetwork(networkId); if (!network) { diff --git a/src/query/external/useSEContractsList.ts b/src/query/external/useSEContractsList.ts index b64e5b4d4..3e36959d0 100644 --- a/src/query/external/useSEContractsList.ts +++ b/src/query/external/useSEContractsList.ts @@ -15,13 +15,13 @@ export const useSEContractsList = ({ cursor?: string; order?: "asc" | "desc"; }) => { - const query = useQuery<{ - records: ContractListRecord[]; - prevCursor: string | null; - nextCursor: string | null; - } | null>({ + const query = useQuery({ queryKey: ["useSEContractsList", networkId, cursor, order], - queryFn: async () => { + queryFn: async (): Promise<{ + records: ContractListRecord[]; + prevCursor: string | null; + nextCursor: string | null; + } | null> => { const network = getStellarExpertNetwork(networkId); if (!network) { diff --git a/src/query/useContractClientFromRpc.ts b/src/query/useContractClientFromRpc.ts index 6db913ca7..bce92d4d4 100644 --- a/src/query/useContractClientFromRpc.ts +++ b/src/query/useContractClientFromRpc.ts @@ -10,9 +10,9 @@ export const useContractClientFromRpc = ({ networkPassphrase: string; rpcUrl: string; }) => { - const query = useQuery({ + const query = useQuery({ queryKey: ["useClientFromRpc", contractId, networkPassphrase, rpcUrl], - queryFn: async () => { + queryFn: async (): Promise => { try { const client = await contract.Client.from({ contractId, diff --git a/src/query/useGetContractDataFromRpcById.ts b/src/query/useGetContractDataFromRpcById.ts index 044cbe198..feeee1dd7 100644 --- a/src/query/useGetContractDataFromRpcById.ts +++ b/src/query/useGetContractDataFromRpcById.ts @@ -16,16 +16,19 @@ export const useGetContractDataFromRpcById = ({ const execStellarAssetType = xdr.ContractExecutableType.contractExecutableStellarAsset().name; - const query = useQuery< - | { - contractType: typeof execWasmType | typeof execStellarAssetType | null; - wasmHash: string; - } - | null - | undefined - >({ + const query = useQuery({ queryKey: ["useGetContractDataFromRpcById", contractId, rpcUrl], - queryFn: async () => { + queryFn: async (): Promise< + | { + contractType: + | typeof execWasmType + | typeof execStellarAssetType + | null; + wasmHash: string; + } + | null + | undefined + > => { if (!contractId || !rpcUrl) { return null; } diff --git a/src/query/useGitHubFile.ts b/src/query/useGitHubFile.ts index b18ea7641..8b9914589 100644 --- a/src/query/useGitHubFile.ts +++ b/src/query/useGitHubFile.ts @@ -14,9 +14,9 @@ export const useGitHubFile = ({ file: string; isActive: boolean; }) => { - const query = useQuery({ + const query = useQuery({ queryKey: ["useGitHubFile", repo, path, file], - queryFn: async () => { + queryFn: async (): Promise => { if (!repo || !path || !file) { return null; } diff --git a/src/query/useGitHubReadmeText.ts b/src/query/useGitHubReadmeText.ts index 88cec667a..34a05fb0c 100644 --- a/src/query/useGitHubReadmeText.ts +++ b/src/query/useGitHubReadmeText.ts @@ -12,9 +12,9 @@ export const useGitHubReadmeText = ({ commit: string; isActive: boolean; }) => { - const query = useQuery({ + const query = useQuery({ queryKey: ["useGitHubReadmeText", repo, commit], - queryFn: async () => { + queryFn: async (): Promise => { if (!repo || !commit) { return null; } diff --git a/src/query/useMaintenanceData.ts b/src/query/useMaintenanceData.ts index fc40a1c61..754a7c89d 100644 --- a/src/query/useMaintenanceData.ts +++ b/src/query/useMaintenanceData.ts @@ -2,9 +2,9 @@ import { useQuery } from "@tanstack/react-query"; import { StatusPageScheduled } from "@/types/types"; export const useMaintenanceData = () => { - const query = useQuery({ + const query = useQuery({ queryKey: ["maintenanceData"], - queryFn: async () => { + queryFn: async (): Promise => { try { const scheduleResponse = await fetch( "https://9sl3dhr1twv1.statuspage.io/api/v2/summary.json", diff --git a/src/query/useWasmBinaryFromRpc.ts b/src/query/useWasmBinaryFromRpc.ts index ec0f9d742..6971fd599 100644 --- a/src/query/useWasmBinaryFromRpc.ts +++ b/src/query/useWasmBinaryFromRpc.ts @@ -17,9 +17,9 @@ export const useWasmBinaryFromRpc = ({ isActive: boolean; headers?: NetworkHeaders; }) => { - const query = useQuery({ + const query = useQuery({ queryKey: ["useWasmBinaryFromRpc", wasmHash, rpcUrl], - queryFn: async () => { + queryFn: async (): Promise => { if (!wasmHash || !rpcUrl) { return null; } diff --git a/src/query/useWasmGitHubAttestation.ts b/src/query/useWasmGitHubAttestation.ts index 180eb5468..a50ee6238 100644 --- a/src/query/useWasmGitHubAttestation.ts +++ b/src/query/useWasmGitHubAttestation.ts @@ -17,9 +17,9 @@ export const useWasmGitHubAttestation = ({ isActive: boolean; headers?: NetworkHeaders; }) => { - const query = useQuery({ + const query = useQuery({ queryKey: ["useWasmGitHubAttestation", wasmHash, rpcUrl], - queryFn: async () => { + queryFn: async (): Promise => { if (!wasmHash || !rpcUrl) { return null; } From e0b8cdad010a147bc07db6dd5ffd1c1e02d9e9fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?jeesun=20=EC=A7=80=EC=84=A0?= Date: Fri, 26 Jun 2026 15:06:39 -0700 Subject: [PATCH 2/7] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/query/useWasmGitHubAttestation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/query/useWasmGitHubAttestation.ts b/src/query/useWasmGitHubAttestation.ts index a50ee6238..cda7f9af3 100644 --- a/src/query/useWasmGitHubAttestation.ts +++ b/src/query/useWasmGitHubAttestation.ts @@ -19,7 +19,7 @@ export const useWasmGitHubAttestation = ({ }) => { const query = useQuery({ queryKey: ["useWasmGitHubAttestation", wasmHash, rpcUrl], - queryFn: async (): Promise => { + queryFn: async (): Promise => { if (!wasmHash || !rpcUrl) { return null; } From 774a7b14b1f51bb87e6d0b9e3f8422a67acd72ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?jeesun=20=EC=A7=80=EC=84=A0?= Date: Fri, 26 Jun 2026 15:07:12 -0700 Subject: [PATCH 3/7] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/query/useContractClientFromRpc.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/query/useContractClientFromRpc.ts b/src/query/useContractClientFromRpc.ts index bce92d4d4..ec1d40ff1 100644 --- a/src/query/useContractClientFromRpc.ts +++ b/src/query/useContractClientFromRpc.ts @@ -12,7 +12,7 @@ export const useContractClientFromRpc = ({ }) => { const query = useQuery({ queryKey: ["useClientFromRpc", contractId, networkPassphrase, rpcUrl], - queryFn: async (): Promise => { + queryFn: async (): Promise => { try { const client = await contract.Client.from({ contractId, From a584d42d6a58e7ebf4017fe0caa8382440e2d2c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?jeesun=20=EC=A7=80=EC=84=A0?= Date: Fri, 26 Jun 2026 15:07:51 -0700 Subject: [PATCH 4/7] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/query/external/useSEContractsList.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/query/external/useSEContractsList.ts b/src/query/external/useSEContractsList.ts index 3e36959d0..f4a5a5fbd 100644 --- a/src/query/external/useSEContractsList.ts +++ b/src/query/external/useSEContractsList.ts @@ -21,7 +21,7 @@ export const useSEContractsList = ({ records: ContractListRecord[]; prevCursor: string | null; nextCursor: string | null; - } | null> => { + }> => { const network = getStellarExpertNetwork(networkId); if (!network) { From 1c02ecc5dfa788ef217e7c4ba5c504d996d2bdc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?jeesun=20=EC=A7=80=EC=84=A0?= Date: Fri, 26 Jun 2026 15:08:21 -0700 Subject: [PATCH 5/7] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/query/useGetContractDataFromRpcById.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/query/useGetContractDataFromRpcById.ts b/src/query/useGetContractDataFromRpcById.ts index feeee1dd7..6b376574c 100644 --- a/src/query/useGetContractDataFromRpcById.ts +++ b/src/query/useGetContractDataFromRpcById.ts @@ -27,7 +27,6 @@ export const useGetContractDataFromRpcById = ({ wasmHash: string; } | null - | undefined > => { if (!contractId || !rpcUrl) { return null; From 5b8f9c541290e46fc65d537ad4379915e7c74889 Mon Sep 17 00:00:00 2001 From: Jeesun Kim Date: Fri, 26 Jun 2026 15:10:36 -0700 Subject: [PATCH 6/7] add a fallback for scheduled_maintenances --- src/query/useMaintenanceData.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/query/useMaintenanceData.ts b/src/query/useMaintenanceData.ts index 754a7c89d..2d767d90c 100644 --- a/src/query/useMaintenanceData.ts +++ b/src/query/useMaintenanceData.ts @@ -11,7 +11,7 @@ export const useMaintenanceData = () => { ); const scheduleResponseJson = await scheduleResponse.json(); - return scheduleResponseJson.scheduled_maintenances; + return scheduleResponseJson.scheduled_maintenances || []; // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (e) { throw Error("Failed to fetch testnet reset date."); From 5793b028bc2a954f71d1279ce37df57d57c4d795 Mon Sep 17 00:00:00 2001 From: Jeesun Kim Date: Fri, 26 Jun 2026 15:22:49 -0700 Subject: [PATCH 7/7] [Maintenance Banner] Treat non-array schedule as an error Coercing a missing/non-array scheduled_maintenances to [] made a broken API response indistinguishable from a valid empty schedule, silently hiding the testnet reset-date warning. Throw instead so the failure surfaces in the banner's error branch. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/query/useMaintenanceData.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/query/useMaintenanceData.ts b/src/query/useMaintenanceData.ts index 2d767d90c..bb27a0401 100644 --- a/src/query/useMaintenanceData.ts +++ b/src/query/useMaintenanceData.ts @@ -11,7 +11,11 @@ export const useMaintenanceData = () => { ); const scheduleResponseJson = await scheduleResponse.json(); - return scheduleResponseJson.scheduled_maintenances || []; + if (!Array.isArray(scheduleResponseJson.scheduled_maintenances)) { + throw new Error("Failed to fetch testnet reset date."); + } + + return scheduleResponseJson.scheduled_maintenances; // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (e) { throw Error("Failed to fetch testnet reset date.");