[RFC] @alchemy/data-apis v1 — publish-ready surface#2540
Closed
blakecduncan wants to merge 8 commits into
Closed
Conversation
…n specs Snapshots now pinned to alchemyplatform/docs main (becfd714) instead of a feature branch. prices (REST) and token (OpenRPC) enter the manifest so generation covers all five v1 spec sources; actions land in follow-ups. RPC emitter now strips non-root schema titles before compilation — title-named shared subschemas (e.g. token's Hex Encoded Address) otherwise hoist duplicate identifiers when one spec has multiple methods. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…est-id) - RestRequestSchema gains an optional Query channel; RestRequestParams maps it via a keyof guard so legacy entries without Query keep compiling and reject query payloads. Route-literal Response narrowing unchanged. - Bounded retries with exponential backoff on 429/5xx/network failures only, honoring Retry-After; per-attempt AbortSignal.timeout merged with the caller's signal (caller aborts are never retried); per-request UUID sent as X-Alchemy-Client-Request-Id on every attempt. - New AlchemyApiError base (status/code/requestId/retryAfter) under BaseError; ServerError/FetchError re-parented onto it with an additive trailing details param — existing instanceof checks and constructor calls are unaffected. - composeSignals/sleep utils; 11 new rest client tests (query serialization, retry/backoff/Retry-After, abort, request-id propagation, error fields). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…recated ops - REST tuples now carry the Query channel (required when any query param is required); standalone Query alias emitted whenever query params exist. - Manifest gains optional pagination metadata per operation/method (pageParam / responseCursorField / itemsField, dotted paths for nested cursors); validated against snapshots at generate time — drift in cursor fields fails generation. Consumed by hand-written *Pages actions; emits no runtime code. - Referencing a spec-deprecated operation hard-fails generation. - NFT action drops the URLSearchParams route cast: typed query channel + abort signal via the hardened AlchemyRestClient. Actions accept an optional RequestOptions third arg. - Snapshot lockfile labels detached-HEAD checkouts '(detached)'. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- portfolio: + getTokenBalancesByAddress, getNftsByAddress, getNftContractsByAddress (global Data API, multi-network bodies; per-entry fields like address-level filters preserved, network-slug enum deliberately widened for the escape hatch) - prices: getTokenPricesBySymbol (chain-agnostic GET), getTokenPricesByAddress (per-entry network resolution), getHistoricalTokenPrices (symbol or network+address forms) - nft: full v3 read surface — 21 actions (ownership/contract/collection listings, metadata + batch, owners, sales, floor price, search, spam/ airdrop/rarity checks). Mutations and deprecated/v2 ops excluded per scope plan. Bracketed wire keys (contractAddresses[], *Filters[]) exposed unbracketed in params and restored by the actions. - token: getTokenBalances (positional optionals trimmed), getTokenMetadata, getTokenAllowance over a shared getRpcRequest helper (also adopted by transfers.getAssetTransfers) - DataRpcSchema now aggregates transfers + token entries; REST actions all accept an options arg with an abort signal - 29 new wire-level tests (URL/method/body/query assertions per namespace) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- paginate(): shared async-generator driver yielding whole pages; stops on missing/empty cursors, throws on a repeated cursor (infinite-loop guard), supports AbortSignal + maxPages - 9 *Pages companion actions for every paginated method (nft owner/contract/ collection listings + sales, portfolio nfts/contracts by address, transfers), wired into the decorator namespaces; cursor wiring (pageKey vs startToken→pageKey/nextToken, body vs query vs rpc-param) follows the manifest's validated pagination metadata - wrapRpcError(): JSON-RPC failures normalize into AlchemyApiError (code/ status), with /v2/<key> and apiKey query credentials redacted from any URL-bearing text — keys never leak through error chains. REST is already normalized inside AlchemyRestClient. - 10 new tests (cursor walking, repeat-cursor guard, maxPages, consumer break, abort, redaction, error mapping) + a decorator-level paging test Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- version 5.0.3-alpha.0 with publishConfig.tag 'alpha'; deliberately NOT in lerna.json's fixed-version publish set so the regular release can't ship it as latest — alpha publishing + graduation checklist documented in the README - typedoc: data-apis entry point + tsconfig.typedoc include + nav registration in generate-typedoc-yaml.ts; generated reference docs committed under docs/pages/reference/data-apis (CI's docs:sdk drift check now covers the package) - README rewritten: install, both entry points, per-namespace quickstart, three network formats, pagination, error semantics, release process Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- on-pull-request: 'pnpm generate && git diff --exit-code' over generated output and spec snapshots, mirroring the existing docs:sdk drift check — fails if generation is stale or snapshots were hand-edited (offline, no new secrets) - bump-api-specs (workflow_dispatch): checks out the public docs repo at main, re-snapshots, regenerates, and opens a PR via create-pull-request; manifest validation hard-fails the run when an SDK-referenced operation was renamed/removed upstream Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- index.test-d.ts: 7 vitest typecheck tests (client/decorator surface equivalence, AlchemyTransport constraint enforcement, spec-accurate result shapes, three-format network params, Pages generator types); data-apis vitest config now enables typecheck under TYPECHECK=true like the shared config - exports.test.ts: locks the package's runtime export surface; generated internals barrel stays internal - smoke test grown 14 → 30 live tests: every namespace exercised against the real API (portfolio x3 new, prices x3, nft x5 new, token x3) plus two-page pagination walks for nft and transfers companions — all passing Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Collaborator
Author
|
Superseded by #2541, which contains this branch's full surface plus the dependency-free core inversion approved at eng tech review (decision doc). All 31 methods, the codegen pipeline, pagination, and the 30-test live smoke suite carry over — verified green on the inverted core. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Takes
@alchemy/data-apisfrom the RFC vertical slice (#2539) to publish-ready: the full v1 method surface, hardened REST infrastructure, pagination, normalized errors, docs, CI gates, and alpha-release packaging. Stacked onblake/data-sdk-mvp.31 methods across 5 namespaces (+ 9 auto-paginating
*Pagescompanions):portfoliopricesnfttokentransfersHighlights
@alchemy/commonREST hardening:RestRequestSchemagains a typed Query channel (legacy schemas unaffected — verified by type tests);AlchemyRestClientgets bounded retries with backoff (429/5xx/network only, honors Retry-After), per-attempt timeouts, abort support, and a per-requestX-Alchemy-Client-Request-Id. NewAlchemyApiErrorfamily (status/code/requestId/retryAfter);ServerError/FetchErrorre-parented additively.paginate()async-generator (stops on empty cursors, throws on repeated cursors, AbortSignal + maxPages) behind 9 hand-written*Pagesactions; cursor metadata is declared incodegen.manifest.tsand validated against the spec snapshots at generate time.AlchemyApiError; JSON-RPC failures are wrapped at action boundaries with URL-credential redaction (keys never leak through error chains — tested).main(becfd714); prices + token specs added. The pagination validator caught a real docs-spec gap:alchemy_getTokenBalancesomitspageKeyfrom its result schema (flagged for the docs team; no Pages companion until fixed).pnpm generate && git diff --exit-code);bump-api-specsworkflow_dispatch that re-snapshots docs main and opens a PR.docs/pages/reference/data-apis(covered by the existing docs drift check).Release packaging (alpha-first)
5.0.3-alpha.0withpublishConfig.tag: "alpha", deliberately not inlerna.json's fixed-version set so the regular release can't ship it aslatest. Alpha publish command + graduation checklist in the package README.Deliberate public-type deltas (spec-accurate)
Fields the specs don't mark
requiredare optional (transfers,ownedNfts,totalCount, ...); bracketed wire keys (contractAddresses[],excludeFilters[]) are exposed unbracketed; the transfers"Not Found (null)"string result branch is collapsed; portfolio/NFT network-slug enums are widened to support the registry-unknown-slug escape hatch.Test plan
TYPECHECK=true), 30 live smoke tests (every namespace against the real API, including two-page pagination walks), export-boundary lockpnpm generateidempotent; snapshot deterministic; lint + build +npm pack --dry-runclean (no .env/scripts/manifest in the tarball)Out of scope (cross-team, tracked in the scope plan)
ws-tools
{slug, chainId, caip2}registry emission; docs-team spec fixes (token pageKey, nft.yaml inline schemas,requiredlists); wallet-apis three-format adoption;@alchemy/api-specsnpm artifact.🤖 Generated with Claude Code
PR-Codex overview
This PR primarily focuses on updating the
VERSIONof thedata-apispackage and enhancing its functionality by adding new types, endpoints, and documentation. It also includes changes to error handling and introduces new features related to token metadata and pricing.Detailed summary
VERSIONinpackages/data-apis/src/version.tsto"5.0.3-alpha.0".PRICES_API_URLinpackages/data-apis/src/internal/endpoints.ts.PricesRestSchemainpackages/data-apis/src/schema/rest.ts.FetchErrorandServerErrorclasses to include detailed API error information.docs/pages/reference/data-apis.package.jsonto reflect new version and description.commonpackage for better error handling and signal management.