From daa216f79bf26dfed12cf015536a94e0082a280d Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Tue, 21 Jul 2026 10:46:41 +0200 Subject: [PATCH] fix: source the round on-chain in the pending-stake endpoint /api/pending-stake read the current round from the subgraph and passed it to on-chain pendingStake/pendingFees calls. When indexing falls behind, the stale round understates both values, and a subgraph error or empty response threw "No current round found" and returned a 500. Read currentRound from the RoundsManager via l2PublicClient instead, so the route is a pure contract read that no longer depends on subgraph health. Response shape is unchanged. This was the last caller of the subgraph-backed getCurrentRound() helper, so drop it. queries/currentRound.graphql stays in use by getOrchestrators(). Co-Authored-By: Claude Opus 4.8 (1M context) --- lib/api/ssr.ts | 6 ------ pages/api/pending-stake/[address].tsx | 26 ++++++++++++++------------ 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/lib/api/ssr.ts b/lib/api/ssr.ts index 061ad981..ac07ebce 100644 --- a/lib/api/ssr.ts +++ b/lib/api/ssr.ts @@ -75,12 +75,6 @@ export async function getGatewaySelfRedeem( return lastTimestamp >= cutoff; } -export async function getCurrentRound(client = getApollo()) { - return client.query({ - query: CurrentRoundDocument, - }); -} - export async function getOrchestrators(client = getApollo()) { const protocolResponse = await client.query< CurrentRoundQuery, diff --git a/pages/api/pending-stake/[address].tsx b/pages/api/pending-stake/[address].tsx index e5da3bef..1f3bb49e 100644 --- a/pages/api/pending-stake/[address].tsx +++ b/pages/api/pending-stake/[address].tsx @@ -1,6 +1,10 @@ -import { getCacheControlHeader, getCurrentRound } from "@lib/api"; +import { getCacheControlHeader } from "@lib/api"; import { bondingManager } from "@lib/api/abis/main/BondingManager"; -import { getBondingManagerAddress } from "@lib/api/contracts"; +import { roundsManager } from "@lib/api/abis/main/RoundsManager"; +import { + getBondingManagerAddress, + getRoundsManagerAddress, +} from "@lib/api/contracts"; import { badRequest, internalError, methodNotAllowed } from "@lib/api/errors"; import { PendingFeesAndStake } from "@lib/api/types/get-pending-stake"; import { l2PublicClient } from "@lib/chains"; @@ -20,17 +24,15 @@ const handler = async ( const { address } = req.query; if (!!address && !Array.isArray(address) && isAddress(address)) { - const bondingManagerAddress = await getBondingManagerAddress(); + const [bondingManagerAddress, roundsManagerAddress] = await Promise.all( + [getBondingManagerAddress(), getRoundsManagerAddress()] + ); - const { - data: { protocol }, - } = await getCurrentRound(); - const currentRoundString = protocol?.currentRound?.id; - - if (!currentRoundString) { - throw new Error("No current round found"); - } - const currentRound = BigInt(currentRoundString); + const currentRound = await l2PublicClient.readContract({ + address: roundsManagerAddress, + abi: roundsManager, + functionName: "currentRound", + }); const [pendingStake, pendingFees] = await l2PublicClient.multicall({ allowFailure: false,