npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@velocity-chain/schemas

v0.6.0

Published

Shared Zod 4 schemas for the velocity-node read API. Consumed by velocity-bridge-ui and velocity-explorer (and any future velocity-node consumer).

Downloads

2,428

Readme

@velocity-chain/schemas

Shared Zod 4 schemas for the velocity-node read API.

Consumed by velocity-bridge-ui and velocity-explorer (and any future velocity-node consumer). Single source of truth for response-shape validators so the two repos can't drift.

Why this exists

bridge-ui and explorer both consume the same velocity-node REST + SSE endpoints. Each was hand-rolling Zod schemas in their own repo. After both teams converged on Zod 4 (2026-04-26), extracting the shared schemas into one package was the obvious next step — agreed in siblings-comms/explorer/bridge-ui-zod-shipped-and-shared-package-offer.md and acked in siblings-comms/bridge-ui/explorer-yes-shared-schemas-and-yes-account-history.md.

Install

pnpm add @velocity-chain/schemas zod
# zod is a peer dep so consumers control the version

Requirements

  • Node 22+ for any consumer running outside a bundler.
  • Zod 4 (peer dep, range ^4.3). Both velocity-bridge-ui and velocity-explorer are on Zod 4 since 2026-04-26; new consumers should align.
  • ESM-only. No CJS build is published. Vite, esbuild, Webpack 5, and modern Node all import this package directly. CJS-only environments are not supported — file an issue if that becomes a real constraint.

Use

import {
  blockResponseSchema,
  bridgeEventStreamPayloadSchema,
  nonNegBigInt,
} from "@velocity-chain/schemas";

const block = blockResponseSchema.parse(await fetch("/block/42").then(r => r.json()));
//    ^ typed as BlockResponse with bigint heights, etc.

Inventory

28 schemas + 11 helpers, all landed and exported from the package root. Each schema pairs a <name>ResponseSchema const with an inferred <Name>Response type.

Schema-shape changes since v0.2.0:

  • v0.6.0 — architectural transition: source of truth for blockActionSchema moved from hand-mirrored src/schemas/block-action.ts to velocity-codegen's Rust-driven emitter. The action-internal Zod schemas now live in src/generated/_block-action.ts (do-not-edit; regenerated from canonical chain artifacts). The old src/schemas/block-action.ts becomes a ~50-line re-export shim. Public API stays identical — all existing exports preserved (blockActionSchema, chainActionSchema, BlockAction type, sub-enums, polymorphic enums, committeeQuorumSigSchema); plus 8 additive exports (bridgeAttestationSchema, proofSignerSchema, changesetPathSchema, and const-array companions BRIDGE_ORIGINS / REFUND_REASONS / CHANGESET_PATHS / NAMESPACE_CAPABILITIES). The single drop-from-shim distinction: committeeMemberSchema action-internal version is not re-exported (response-level committee.ts version owns the name; action-internal is reachable via blockActionSchema narrowing). 12 silent wire-shape drift bugs caught and corrected across 3 review iterations between codegen and chain-schemas pre-vendor — Pattern 2 (hand-mirror as second-source) paid off. Per codegen handoff at siblings-comms/codegen/handoff.md and review thread at siblings-comms/codegen/chain-schemas-phase-1b-*. Tests unchanged (225 passing); drift verification unchanged. Forward changes to action wire shapes land via codegen regen + re-vendor, not hand-edit.
  • v0.5.7 — additive registry-widen: SIGNED_ENDPOINT_REGISTRY extended from 20 → 26 entries. Added 4 wallet-coverage /...-signed endpoints (/deposit-fuel-signedDepositFuel, /namespace-admin-signedNamespaceAdmin, /player-manage-signedPlayerManage, /purchase-capability-signedPurchaseCapability) per blockchain commit 97af20d, and 2 dual-shape legacy paths (/account/register-signedRegisterAccount, /account/add-key-signedAddAccountKey) per commit 5d33d5d — these now accept both wrapped-JSON envelope (canonical) and the legacy hex-blob envelope used by velocity-identity's existing flow. All 6 are single-sig (use wrappedSignedActionSchema); §18 multi-sig partition unchanged. Per blockchain heads-up at chain-schemas/v0-5-7-widen-heads-up-6-new-endpoints.md. Two new field-rename pairs (PurchaseCapabilitynamespace_admin_*; AddAccountKeyadded_by/signature) follow the same envelope-canonicalization pattern as cross-ns grants — consumers don't need to surface the rename.
  • v0.5.6 — additive: wrapped-JSON signed-action envelope schemas for the 20 /...-signed endpoints blockchain shipped today. Six new exports: wrappedSignedActionSchema (single-sig, 18 endpoints), committeeQuorumSignedActionSchema + committeeQuorumHttpSigSchema (multi-sig §18 quorum, 2 endpoints), signedActionResponseSchema + committeeQuorumSignedActionResponseSchema (200 OK shapes), SIGNED_ENDPOINT_REGISTRY const (path → variant-name lookup, 20 entries) + COMMITTEE_QUORUM_SIGNED_KINDS const for runtime envelope-shape selection. HTTP-layer fields are hex strings (hashHex / signatureHex), distinct from action-internal [u8; N] arrays — Gotcha doc added. Excludes the 2 legacy binary-envelope account-registration endpoints. Re-opens v0.5.x stream for one final coordination cut; demo May 11 is the next time-bound milestone.
  • v0.5.5 — final-polish patch: retired dead scripts/diff-vs-sdk.mjs (SDK collapsed to a re-export shim in v0.4.0; the diff-tool now compares chain-schemas to itself transitively). Added pnpm verify:pack pre-publish file-list audit (catches stray .tmp* / .env / credential files in the tarball — wired in prepublishOnly). Added opt-in pnpm test:live integration suite that fetches /blocks/latest, /block/{height}, /status, /health from VELOCITY_NODE_URL and parses through the corresponding schemas. Marks the package as feature-complete; further polish ROI is exhausted.
  • v0.5.4 — additive: 4 new Action variants for design §18 admin/quorum recovery paths (32 → 36). ChainAdminForceUnpauseNamespace and ChainAdminForceRotateNamespaceOwner (single chain-admin signer + 48h not_before timelock); CommitteeQuorumForceUnpauseNamespace and CommitteeQuorumForceRotateNamespaceOwner (threshold-many committee bridge_pubkey signatures). Plus committeeQuorumSigSchema exported as a reusable per-signer entry shape. Existing ForceUnpauseNamespace + ForceRotateNamespaceOwner unchanged byte-for-byte (they ARE the NamespaceAdmin path). Per blockchain ship at chain-schemas/18-force-actions-shipped.md (counter-proposal-driven; we picked 4 variants over the originally-proposed shape change at chain-schemas/18-going-with-4-variants.md). verify:drift script also tightened: package-ahead is now a warning (transient absorption window) while package-behind stays a hard fail (real drift).
  • v0.5.3 — additive: "Swap" appended to ACCOUNT_EVENT_KINDS (13 → 14) for Phase 3 fixed-shop trades, symmetric with AmmSwap / FlashSwap. Per explorer ask at chain-schemas/explorer-needs-swap-kind.md — closes the asymmetry where Phase 3 trades were visible on block-detail but invisible on per-account history.
  • v0.5.2 — additive (tightenings + polish): DepositRefundRequest.message.source_chain tightened to bridgeOriginSchema enum (was nonEmptyString); reason tightened to typed refundReasonSchema enum ("UnroutableMemo" | "InactiveDestinationNamespace" | "AmountBelowMinimum" | "Other"). Both per blockchain's ack at chain-schemas/v32-drift-acked-source-chain-tighten-please.md. Polish: dedicated tests for account-keys + finalized-since (coverage gaps from v0.1 closed); JSDoc @example on all 28 schemas (IDE hover docs).
  • v0.5.1 — additive: 32nd Action variant DepositRefundRequest (drift fix; SDK + chain-schemas were behind blockchain's main). Polish: drift-detection CI step (pnpm verify:drift), JSDoc with @example on all 11 helpers, sideEffects: false, source-map drop, v1.0 stability commitment doc, pnpm scaffold:variant codegen helper. Zod aligned to ^4.4.1 to match constellation.
  • v0.5.0 — breaking: block.actions[] is now typed via blockActionSchema (31-variant externally-tagged discriminated union), was z.array(z.unknown()). Lifted from velocity-blockchain's CI-published JSON Schema artifact + golden-mirrored against velocity-js-sdk's ChainActionSchema v0.3.0. Adds 6 helpers (actionAmount, bytes32, bytes64, byteArray, tokenIdSchema, namespaceCapabilitySchema) describing action-internal shapes (distinct from response-level nonNegBigInt/hashHex/signatureHex). Also exports chainActionSchema as an SDK-mirror alias, and tightened sub-enums for NamespaceAdminOp, PlayerManageOp, FlashStep. Consumers narrow via if ("Mint" in action) { ... }.
  • v0.4.2 — additive: accountEventsRequestSchema for client-side request validation. CSV-kinds parsed + per-element validated, direction enum widened to sent|received|both, limit bounded 1..200 (server default 50), permissive cursor (mirrors indexer's bad-cursor → restart posture). Also corrects the inline error-code documentation to match the indexer's actual codes (UNKNOWN_KIND, INVALID_HEIGHT, INVALID_LIMIT — were guessed wrong in v0.4.0).
  • v0.4.1 — additive: wireAccountEventSchema + wireAccountEventsResponseSchema for emitter-side use (indexer's rowToWire). Mirrors accountEventSchema but keeps height and amount as digit-strings instead of transforming to bigint. Lets the indexer collapse its inline WireEvent/WireResponse interfaces to package types.
  • v0.4.0 — added account-events (per-account event history from velocity-explorer's indexer service): accountEventKindEnum (13-string enum, also exported as ACCOUNT_EVENT_KINDS const value), accountEventSchema, accountEventsResponseSchema, accountEventsErrorSchema. Endpoint at {indexer_base}/account/:ns/:user/events. Source-of-truth is explorer's production schema, not chain handlers.rs — the indexer aggregates per-account rows from the block stream.
  • v0.3.0produced_at_unix (u64-stringified, required, 0 = unknown sentinel) added to block, blocks-list (per summary), and blocks-latest. signing_key_origin (string, required) added to health.committee.

Account-scoped:

  • account-eventsGET {indexer}/account/{ns}/{user}/events (per-account history; served by the indexer service, not chain proper)
  • account-keysGET /account/{ns}/{user}/keys
  • account-namespacesGET /accounts/{account}/namespaces
  • balance (single token) — GET /balance/{account}/{ns}/{token}
  • balances (bulk) — GET /account/{ns}/{account}/balances
  • bridge-nonceGET /accounts/{account}/bridge-nonce

Block-scoped:

  • blockGET /block/{height} (typed actions[] via blockActionSchema since v0.5)
  • block-action — typed 31-variant discriminated union for block.actions[]. Use directly when consuming individual actions; auto-applied inside block.actions.
  • blocks-latestGET /blocks/latest
  • blocks-listGET /blocks?from&to&limit

Bridge-scoped:

  • bridge-event-stream — SSE /blocks/stream payload
  • bridge-in-statusGET /bridge-in/{tx}/status
  • bridge-out-statusGET /bridge-out/{event_hash}/status
  • finalized-sinceGET /finalized-since/{height}
  • proofGET /proof/{event_hash} (see Gotchas)

Namespace-scoped:

  • namespacesGET /namespaces
  • namespace-adminsGET /namespaces/{id}/admins
  • namespace-bridgeGET /namespaces/{id}/bridge
  • namespace-capabilitiesGET /namespaces/{id}/capabilities
  • cross-ns-grantsGET /namespaces/{id}/cross-ns-grants

Pools (Phase 3 / Phase 4):

  • swap-poolsGET /swap-pools?namespace=<id> and GET /swap-pools/{ns}/{...} (list + detail share the same shape)
  • amm-poolsGET /amm-pools?namespace=<id> and GET /amm-pools/{ns}/{...} (constant-product, fee in basis points)

Capabilities (Phase 6):

  • capability-pricesGET /capability-prices

Chain vitals:

  • committeeGET /committee
  • healthGET /health
  • metricsGET /metrics
  • statusGET /status
  • validators-healthGET /validators/attestation-health

Helpers:

  • nonNegBigInt — accepts bigint / number / string-u64, validates ≥ 0
  • hashHex — 64-char lowercase hex (strict-lowercase)
  • signatureHex — 128-char lowercase hex (strict-lowercase)
  • nonEmptyStringz.string().min(1)
  • usizez.number().int().nonnegative() for bounded counters

Gotchas

  • proof ships two schemas, not one. proofReadyResponseSchema parses the 200 body (Borsh proof bytes hex-encoded). proofBelowThresholdBodySchema parses the 409 body (attestation progress for the fill bar). Consumers branch on HTTP status before parsing — don't try to parse a 409 with the ready schema or vice versa.
  • u64 fields are JSON strings on the wire (post u64-stringify migration). Always use nonNegBigInt, never z.number(). usize is fine for bounded counters (committee size, batch counts) — those values fit in JS Number safely.
  • Hash regexes are strict-lowercase. Mixed-case hex on the wire indicates drift; strict matching has caught real bugs. Don't loosen hashHex / signatureHex to [0-9a-fA-F].
  • block.actions is z.array(z.unknown()) by design. The 19 Action enum variants live in consumer-side renderers, branched on the top-level discriminator key. Adding a discriminated union here would force every consumer to import every payload shape they don't care about.
  • finalized-since reuses bridgeEventStreamPayloadSchema. Both the SSE frames and the REST list project the same Rust BridgeEventJson struct.
  • Empty arrays vs 404. velocity-node's convention: unknown-but-valid queries return 200 with empty arrays, not 404. Don't add nonempty constraints to account-namespaces, balances, blocks-list, account-keys, finalized-since, or validators-health.
  • produced_at_unix = 0n means "unknown". Older blocks (pre-chain-commit 5da4881) deserialize with 0 for the new producer-wall-clock field. Consumer rendering should fall back to ingest time (or hide the timestamp) on 0n, not display 1970-01-01.
  • health.committee.signing_key_origin is intentionally a loose z.string().min(1). Current values are "loaded_from_path" and "generated_at_boot"; future values like "hsm_attached" are expected. The schema accepts any non-empty string so consumers don't break on chain-side additions. Strict gating (e.g. "refuse to start if origin is generated_at_boot") belongs at the consumer level — see velocity-explorer/services/indexer/src/preflight.ts for the canonical example.
  • account-events is indexer-served, not chain-served. Endpoint base URL is {indexer_base} (typically configured via consumer env var like VITE_INDEXER_URL), not the chain's :3000. Wire shape source of truth is velocity-explorer/src/lib/indexer/schemas.ts, not handlers.rs. The Pattern 2 chain-source cross-check used for other schemas doesn't apply.
  • account-events field-population matrix is documented but not enforced. The schema accepts any kind+direction combo and any null/non-null pattern on counterparty/token/amount/destination_*. Per-kind expectations (e.g. Mint always has direction: "received", counterparty: null) live in source comments and siblings-comms/chain-schemas/explorer-per-account-history-beta.md. The indexer enforces correlation at row creation; the schema validates wire shape only.
  • accountEventsErrorSchema.error.code is loose nonEmptyString to match the signing_key_origin forward-compat policy. Known codes: INVALID_KIND, INVALID_DIRECTION, INVALID_FROM_HEIGHT, INVALID_TO_HEIGHT, HEIGHT_RANGE_INVERTED. New codes don't require a coordinated package bump.
  • wireAccountEventSchemaaccountEventSchema — they describe different layers of the same contract. The wire schema (height, amount as digit-strings) is for emitter-side use (indexer's rowToWire); the post-parse schema (bigint via nonNegBigInt) is for consumer-side parsing. Don't merge them, and don't use the wire schema to validate consumer-received data — consumers should always use accountEventSchema so they get bigint at the boundary.
  • accountEventsRequestSchema bakes in indexer policy choices (limit max 200 default 50; direction enum widened to sent|received|both; cursor permissive). If a future consumer needs different bounds (e.g. a CLI paginating with limit > 200), file an ask to widen the package shape — don't copy-paste a local schema. The whole point is one source of truth for the request surface.
  • blockActionSchema is externally-tagged, not internally-tagged. Each action is { "Mint": { ... } } not { kind: "Mint", ... }. TypeScript narrowing uses if ("Mint" in action) — Zod 4's discriminatedUnion doesn't support outer-key discriminators, so the union is z.union over .strict() single-key objects. Per-variant signature field names vary (authority_key, admin_key, added_by, attester, owner_key — see source comments).
  • Action-internal u64s are plain JSON numbers, response-level u64s are stringified. Different layer of contract: block.actions[].Mint.amount is actionAmount = z.number(); block.height is nonNegBigInt = bigint via union transform. Both come through the same JSON response, encoded differently per Rust serde rules. The package mirrors that asymmetry — don't merge.
  • Action-internal byte arrays are [u8; N] JSON arrays, response-level hashes are hex strings. Same surface-layer split: mintInner.authority_key is bytes32 = 32-element number array; block.block_hash is hashHex = 64-char lowercase hex. Don't try to unify; chain emits each at the correct layer.
  • tokenIdSchema (action-internal) ≠ tokenRefSchema (account-events row). Both have { namespace, name }. tokenIdSchema is action-internal (always present, both fields nonEmptyString); tokenRefSchema is account-events-row (.nullable() for lifecycle events with no token).
  • HTTP envelope hex strings ≠ action-internal byte arrays. wrappedSignedActionSchema.signed_action.authority_key is a 64-char hex string (hashHex); block.actions[].Mint.authority_key is a 32-element number array (bytes32). Same conceptual key, different layer of the contract — chain emits hex on the HTTP envelope, [u8; N] JSON arrays inside action-struct fields. Don't try to unify; pick the layer-appropriate schema. Same applies to signature fields (envelope: signatureHex; action-internal: bytes64).
  • SIGNED_ENDPOINT_REGISTRY includes 2 dual-shape legacy account paths since v0.5.7. /account/register-signed and /account/add-key-signed accept BOTH the wrapped-JSON envelope (canonical, this registry's contract) AND a legacy hex-blob envelope ({ signed_action_hex: "..." }) used by velocity-identity's existing flow. The wrapped form is canonical from the SDK / unity-sdk side; the legacy hex-blob shape stays for backwards-compat. Chain dispatches via untagged serde enum (same pattern as /bridge-out).
  • chainActionSchema is an alias for blockActionSchema — same Zod schema, two export names. SDK consumers can re-export under the SDK's existing ChainActionSchema symbol; chain-schemas-internal callers can use BlockActionSchema to match the block context. Pick the name that fits your mental model; runtime cost is zero.

Versioning

v0.5+ stability posture. As of v0.5.0, the package covers the full chain → consumer wire surface (28 schemas, 11 helpers, 31 → 32 action variants). Three of the four sibling repos (velocity-bridge-ui, velocity-explorer, @velocity-chain/sdk) consume the package as their single source of truth for chain wire shapes; SDK collapsed its local ChainActionSchema to a re-export shim in v0.4.0. Drift detection runs in CI against velocity-blockchain's published JSON Schema artifact on every default-branch commit.

Versioning rules going forward:

  • Patch (0.5.x): additive new exports, doc fixes, internal refactors. Always safe to take.
  • Minor (0.x.0): new schemas for new endpoints; tightening of existing loose-typed shapes; helper additions. Mostly additive, occasional contained breaking changes (clearly flagged in changelog).
  • Major (1.0.0): stability commitment. After 1.0.0, every breaking change goes through a major. Re-exports and new schemas continue as minors.

Pin precision. Pin to a minor range "^0.5.0" for current-best behavior with patch-bump safety. Pin exact "0.5.1" if your repo prefers reproducible installs over auto-upgrade.

Path to v1.0.0. Two gates remaining:

  1. Demo (May 11) ships without surfacing schema-shape bugs in any consumer.
  2. One additional minor cycle absorbs whatever the demo surfaces, post-demo.

Tentative target: v1.0.0 mid-to-late May 2026, conditional on a quiet post-demo period. The 1.0 cut won't add new functionality — it's the stability commitment + a final API audit. Migration from 0.5.x to 1.0.0 is expected to be a no-op pnpm install.

After 1.0.0, breaking changes only arrive via majors with at least one minor of overlap (1.x continues to receive backports during the 2.x ramp-up).

Pre-publish coordination commitments (in effect since v0.4):

  • chain-schemas → js-sdk before any chain-schemas major (now relaxed since SDK v0.4 absorbs via re-export shim, but courtesy heads-ups continue per cadence).
  • chain-schemas → js-sdk before any bridge-nonce schema change at any version.
  • blockchain → chain-schemas + js-sdk before any chain-side struct change to a schema-package-covered shape OR Action variant.
  • Per-version cadence on heads-ups, not batched digests.

Convention has been 7-for-7 clean through v0.5.0; one drift slip caught by the artifact-verification step at v0.5.1.

Contributing

Schema changes that affect either consumer should land here first, then both consumers bump. PRs welcome from bridge-ui and explorer teams. New schemas (e.g. for endpoints velocity-node ships post-demo) come in via PR with golden fixtures matching velocity-node's response handlers.

License

Copyright (c) 2026 Surgent International FZ-LLC. All rights reserved.

This software is proprietary. The source code is made publicly visible for transparency and review purposes only. Public visibility does not constitute a grant of any rights.