@polygonlabs/staking-api-client
v1.9.1
Published
Type-safe REST client for the Polygon Staking API, generated from the registered Zod schemas
Keywords
Readme
@polygonlabs/staking-api-client
Type-safe REST client for the Polygon Staking API, generated with hey-api from the API's committed OpenAPI spec. Every response is validated at runtime with the same Zod schemas the server enforces.
Why this package exists
Before this client, every consumer of the Staking API hand-rolled its own
response types against /api/v2 and /api/v3 — independent copies that
drifted silently whenever the API changed shape. This client is generated
from the same schema registry the server routes and validates with (via
@polygonlabs/staking-api-schemas),
so an API shape change ships as a new package version instead of a silent
break — and a response that doesn't match its schema fails loudly at the
validation boundary rather than corrupting state downstream.
Install
pnpm add @polygonlabs/staking-api-clientUsage
import { client, getAllValidatorsV3 } from '@polygonlabs/staking-api-client';
client.setConfig({ baseUrl: 'https://staking-api.polygon.technology' });
const { data } = await getAllValidatorsV3();Paging through lists
Use the cursor operations (*PageV2 / *PageV3, served on the /page
routes) for every paged list. The offset operations (limit/offset) are
being deprecated: a deep offset makes the server walk and bill every
skipped row, while a cursor page is a single index seek, and its fixed URL
lets the Cloudflare edge serve it once for every client.
Leave out cursor to get the first page. Each page returns
pagination.nextCursor. Pass it back as cursor until it comes back as
null, which happens exactly on the last page:
import { getCheckpointsSignedPageV3 } from '@polygonlabs/staking-api-client';
let cursor: string | undefined;
do {
const { data } = await getCheckpointsSignedPageV3({
path: { validatorId: 7 },
query: { cursor, limit: 100 },
throwOnError: true
});
for (const checkpoint of data.result.checkpointsSigned) {
// ...
}
cursor = data.pagination.nextCursor ?? undefined;
} while (cursor);Rules a walk must follow:
- The cursor is opaque. Don't build or edit one. A cursor that doesn't
decode is a
400, never a silent first page. - A page can hold fewer than
limitrows and still not be the last. Checkpoint and notification pages end at fixed boundaries so every walk requests the same cursor URLs. OnlynextCursor: nullends the walk; echo every othernextCursorback unchanged. limitis one of 20, 50, 100 or 500, and defaults to 20. Any other value is a400. The fixed list keeps URLs identical across clients so the edge cache is shared.- Send the same filters on every page (e.g.
startTimestamp/endTimestamp). The cursor holds only the position, not the filters. - Totals and counters appear on the first page only (
pagination.total, andnumberOfCheckpointsSigned/numberOfCheckpointsMissedon checkpoints). Later pages omit them so they stay byte-identical and cacheable. Delegator pages carry nototalat all.
React
The /react entry point has no *InfiniteOptions factory for the cursor
operations: the codegen plugin skips infinite queries for any operation with
a registered query schema, and every cursor operation has one. Call the SDK
function from useInfiniteQuery instead:
import { useInfiniteQuery } from '@tanstack/react-query';
import { getCheckpointsSignedPageV3 } from '@polygonlabs/staking-api-client';
const useCheckpoints = (validatorId: number) =>
useInfiniteQuery({
queryKey: ['checkpoints-signed', validatorId],
initialPageParam: undefined as string | undefined,
queryFn: async ({ pageParam, signal }) => {
const { data } = await getCheckpointsSignedPageV3({
path: { validatorId },
query: { cursor: pageParam },
signal,
throwOnError: true
});
return data;
},
getNextPageParam: (lastPage) => lastPage.pagination.nextCursor ?? undefined
});Entry points
@polygonlabs/staking-api-client— the fetch-based SDK: one function per API operation, plus the configurableclientsingleton.@polygonlabs/staking-api-client/react— TanStack Query options factories for React apps. Requires the optionalreactand@tanstack/react-querypeer dependencies; the main entry works without them.@polygonlabs/staking-api-client/factory— the underlying hey-api client factory, for constructing independently-configured client instances.
