Problem
The frontend reaches the backend three different ways, which duplicates configuration and error handling:
src/api.ts uses BASE = "/api" with raw fetch.
- Several pages call relative paths directly, e.g.
fetch("/api/rpc-metrics") (src/pages/RpcMetricsDashboard.tsx), fetch("/api/setup/doctor") (src/pages/SetupPage.tsx), fetch("/api/batch/simulate") (src/pages/BatchMultiCall.tsx), fetch("/api/admin/analytics/...") (src/pages/RateLimitDashboard.tsx), useTxStatus.ts.
src/services/sandbox-api.ts uses import.meta.env.VITE_API_URL with its own base.
What needs to be done
- Create a single API client (e.g.
src/services/apiClient.ts) that owns the base URL (from the configurable-base issue), JSON handling, error normalization, and (optionally) auth headers for admin routes.
- Route all existing calls through it:
src/api.ts, the inline fetch calls in the pages listed above, useTxStatus.ts, and sandbox-api.ts.
- Standardize error handling: non-2xx responses throw a typed error with status and message.
Files
- new
src/services/apiClient.ts
src/api.ts, src/services/sandbox-api.ts, src/hooks/useTxStatus.ts
src/pages/RpcMetricsDashboard.tsx, src/pages/SetupPage.tsx, src/pages/BatchMultiCall.tsx, src/pages/RateLimitDashboard.tsx
Acceptance deliverables
- Exactly one module defines the API base and fetch/error behavior.
- No page constructs API URLs or handles fetch errors ad hoc.
Tests to pass
- Unit tests for
apiClient: success parsing, non-2xx throwing a typed error, base URL resolution.
- Existing page tests continue to pass.
Problem
The frontend reaches the backend three different ways, which duplicates configuration and error handling:
src/api.tsusesBASE = "/api"with rawfetch.fetch("/api/rpc-metrics")(src/pages/RpcMetricsDashboard.tsx),fetch("/api/setup/doctor")(src/pages/SetupPage.tsx),fetch("/api/batch/simulate")(src/pages/BatchMultiCall.tsx),fetch("/api/admin/analytics/...")(src/pages/RateLimitDashboard.tsx),useTxStatus.ts.src/services/sandbox-api.tsusesimport.meta.env.VITE_API_URLwith its own base.What needs to be done
src/services/apiClient.ts) that owns the base URL (from the configurable-base issue), JSON handling, error normalization, and (optionally) auth headers for admin routes.src/api.ts, the inlinefetchcalls in the pages listed above,useTxStatus.ts, andsandbox-api.ts.Files
src/services/apiClient.tssrc/api.ts,src/services/sandbox-api.ts,src/hooks/useTxStatus.tssrc/pages/RpcMetricsDashboard.tsx,src/pages/SetupPage.tsx,src/pages/BatchMultiCall.tsx,src/pages/RateLimitDashboard.tsxAcceptance deliverables
Tests to pass
apiClient: success parsing, non-2xx throwing a typed error, base URL resolution.