Monorepo for shared packages used across Polygon Apps Team services and frontends. Rather than each service vendoring its own copy of common utilities — or maintaining a scatter of single-package repos with duplicated tooling — everything lives here with unified versioning, CI, and release management.
All packages are published to npm under the @polygonlabs scope and versioned independently
via changesets.
| Package | Version | Description |
|---|---|---|
| @polygonlabs/apps-team-lint | Shared ESLint, markdownlint, and commitlint configurations | |
| @polygonlabs/express | Request-scoped logger middleware (via AsyncLocalStorage), uniform 404 handler, global error handler that consumes the logger's ethers fetch-error sanitiser for response bodies, and a /registry subpath that materialises a typed Express router from a TypedRegistry (createRegistryRouter().auth().implement().toExpress()) with compile-time exhaustiveness on auth handlers and operation handlers |
|
| @polygonlabs/logger | Pino-based logger with Sentry integration, configured for Datadog ingestion; pino err serializer sanitises ethers v5/v6 fetch-error tokens across the cause chain |
|
| @polygonlabs/openapi-registry | Type-accumulating drop-in for @asteasolutions/zod-to-openapi's OpenAPIRegistry. Each registerPath / registerSecurityScheme narrows the registry's type via asserts this is X, so downstream consumers (Express request/response validation, codegen audits, gateway aggregation) read the accumulated operations and security schemes via inferred return types |
|
| @polygonlabs/sync-github-releases | CLI that syncs GitHub Release bodies and titles from each package's CHANGELOG.md, byte-equal to what changesets/action emits natively. Recovers the GitHub Releases that are skipped when a brand-new package's first npm publish 403s under OIDC and changesets/action exits non-zero before the create-release step |
|
| @polygonlabs/verror | TypeScript-first VError-inspired error handling with cause chains and HTTP error classes | |
| @polygonlabs/viem-event-watcher | Backpressure-aware async-generator wrappers over viem's getLogs — backfillEvents, a self-driven getLogs poll-loop watchEvents, and a gapless backfill-then-live streamEvents. Each yields { logs, toBlock } batches (empty ranges included, so a persisted cursor advances monotonically) and throws on failure; generic over the ABI event tuple for typed args / eventName. No observer, no EventEmitter, no internal logging — the consumer owns cursor, dedup/reorg, restart, and logging. viem is a peer dependency |
|
| @polygonlabs/wallet-kit | Shared React wallet integration for Polygon frontends: Sequence Connect provider, smart-contract-wallet / Sequence-v3 detection helpers, TRM sanctions screening | |
| @polygonlabs/zod-codecs | Zod v4 codecs for the wire formats JSON-on-the-wire services keep reinventing — int64 strings, unbounded big integers, decimal strings, and ISO datetimes — that decode into the right runtime type and round-trip back | |
| @polygonlabs/zod-to-openapi-heyapi | @hey-api/openapi-ts plugin that sources Zod schemas from a @asteasolutions/zod-to-openapi OpenAPIRegistry; emits per-status Responses/Errors types as z.output<typeof Schema> and per-operation parseAsync transformers so codec output (bigint, Date, etc.) reaches the caller |
Each package has its own README.md, package.json, and changelog.
pnpm install # install all dependencies
pnpm run lint # ESLint + markdownlint + typecheck + prettier check
pnpm run format # auto-fix all of the above
pnpm run typecheck # TypeScript across all packages
pnpm run test # run tests across all packagesTo work on a specific package:
pnpm --filter <package-name> run <script>- Create
packages/<name>/— at minimum:package.json, the three-tiertsconfig.json/tsconfig.lib.json/tsconfig.spec.json(copy from the closest existing package), andeslint.config.js - Add a
referencesentry to the roottsconfig.jsonpointing at the new package - Pass
tsconfigRootDir: import.meta.dirnametotypescript()in the package'seslint.config.js— without this,typescript-eslintcannot resolve the correct tsconfig when ESLint runs from the repo root - Add a row to the Packages table above (kept alphabetised by package name) with the npm version badge and a row blurb in the same register as its neighbours
- Run
pnpm installfrom the repo root to wire up the workspace
This repo uses changesets. Every PR that touches package code needs a changeset:
pnpm exec changeset add # code or behaviour changes
pnpm exec changeset add --empty # CI, docs, or tooling-only changesMerging to main triggers the release pipeline: the bot opens a "Release / Deploy" PR
aggregating all pending changesets. Merging that PR publishes changed packages to npm and
creates version tags.