@blockscout/api-types
TypeScript types generated from Blockscout OpenAPI specs via openapi-typescript:
- shorthands (
schemas,operations,paths) — the recommended entry point; flat lookups over the merged spec, spanning every chain type. See Usage - merged — every schema, path, and operation from all specs below combined into one namespace (for universal frontends that handle any chain type at runtime); see Merged schemas
- publicApi — default public API (
BlockScoutWeb.Specs.Public, noCHAIN_TYPE) - privateApi — account API (
BlockScoutWeb.Specs.Private) - chain namespaces — chain-specific public API (
CHAIN_TYPEset; matches generate-swagger.yml)
Build artifacts (openapi/, dist/) are gitignored; run npm run build after clone.
Prerequisites
- Elixir / Mix at the Blockscout repo root (compiled
block_scout_webapp) - Node.js 18+ (for
openapi-typescript)
Generate
From this directory:
npm install
npm run build
build runs:
generate:spec—mix openapi.spec.yamlfor public, private, and each chain typegenerate:types—openapi-typescriptwrites matching files underdist/
Usage
Shorthands (recommended)
Three top-level exports flatten the most common lookups against the merged spec, so you never index through components["schemas"] or ["responses"][200]["content"]["application/json"] by hand. Prefer these for everyday use:
import type { schemas, operations, paths } from "@blockscout/api-types";
// `schemas` — a model by name (merged across all chains; chain-specific props optional).
type Transaction = schemas["Transaction"];
// `operations` — keyed by short operationId, with `json` / `params` / `requestBody`.
type TxJson = operations["TransactionController.transaction"]["json"];
type TxParams = operations["TransactionController.transaction"]["params"];
type EthCallBody = operations["EthController.eth_call"]["requestBody"];
// `paths` — the 200 `application/json` body keyed by path, then HTTP method.
type Blocks = paths["/api/v2/blocks"]["get"];
Notes:
- operationIds are shortened — the controller module prefix (
BlockScoutWeb.API.V2.,BlockScoutWeb.Account.API.V2.,BlockScoutWeb.API.Legacy.) is stripped, soBlockScoutWeb.API.V2.TransactionController.transactionbecomesTransactionController.transaction. jsonis the 200application/jsonresponse body;paramsis the requestquery/pathparameters;requestBodyis theapplication/jsonrequest body (neverfor endpoints without one).pathsonly exposes the HTTP methods an endpoint actually defines; missing methods are absent, notnever.- All three are derived from
merged, so they already span every chain type. Reach for themerged/per-chain namespaces below only when you need something these don't cover (non-200 responses, response headers, raw path items).
Merged schemas
The shorthands above are built on the merged namespace — every schema, path, and operation from all specs combined, so a universal frontend can handle any chain type at runtime from a single type universe. Import merged directly when you need lookups the shorthands don't expose (non-200 responses, response headers, raw path items):
import type { merged } from "@blockscout/api-types";
// Includes the public base plus `arbitrum?`, `zksync?`, blob fields, etc. — all optional.
type Transaction = merged.components["schemas"]["Transaction"];
// Paths/operations are merged too, referencing the merged models:
type Tx = merged.paths["/api/v2/transactions/{transaction_hash_param}"]["get"]["responses"][200];
Per-spec namespaces
Types are also grouped by spec name in the package entry:
import type { publicApi, privateApi, arbitrum, optimismCelo } from "@blockscout/api-types";
type AddressResponse = publicApi.components["schemas"]["AddressResponse"];
type GetAddressParams =
publicApi.paths["/api/v2/addresses/{address_hash_param}"]["get"]["parameters"];
type ArbitrumPath = arbitrum.paths[keyof arbitrum.paths];
publicApi / privateApi avoid TypeScript reserved words (public, private). optimism-celo is exported as optimismCelo (hyphen is invalid in identifiers)
Chain types
Synced with .github/workflows/generate-swagger.yml via scripts/chain-types.sh:
arbitrum, arc, blackfort, ethereum, filecoin, neon, optimism, optimism-celo, rsk, scroll, shibarium, stability, suave, zetachain, zilliqa, zksync
When CI adds or removes a chain type, update scripts/chain-types.sh and index.ts.
Schemas merging
scripts/merge-specs.mjs merges all generated specs (public → private → chains alphabetically) into openapi/merged.yaml, which compiles to dist/merged.schema.ts (exported as merged).
Merge semantics:
- Schemas —
propertiesare unioned;requiredis the intersection across specs defining a schema, so chain-specific properties are optional. Sub-objects defined in a single spec keep theirrequired(e.g.arbitrum.gas_used_for_l1stays required whenarbitrumis present).enumvalues are unioned (e.g.transaction_typesgains chain-specific entries). - Paths & operations — unioned across specs; chain-only endpoints (e.g.
/v2/arbitrum/batches) are included. Shared operations are deep-merged, withparametersmatched by (in, name) and theirschemas unioned (e.g. enum query params gain chain-specific values). All operation$refs point atcomponents.schemas, so they reference the merged models automatically. - Irreconcilable schema shapes (e.g. ethereum redefines
Statusas a beacon-deposit enum) becomeanyOfunions and are reported as warnings on stderr.