Skip to content

Refactor static to publish @polygonlabs/meta with typed ABIs#182

Merged
py-zoid merged 24 commits into
masterfrom
feat/refactoring-with-polygonlabs-renaming
May 15, 2026
Merged

Refactor static to publish @polygonlabs/meta with typed ABIs#182
py-zoid merged 24 commits into
masterfrom
feat/refactoring-with-polygonlabs-renaming

Conversation

@py-zoid
Copy link
Copy Markdown
Contributor

@py-zoid py-zoid commented May 1, 2026

Summary

Refactors 0xPolygon/static to publish a typed-ABI npm package as @polygonlabs/meta@1.0.0, replacing @maticnetwork/meta@2.x. Each contract's ABI is shipped as an as const TypeScript module so viem/wagmi/abitype consumers get full type-level inference at the call site.

The public HTTP endpoint at https://static.polygon.technology/... continues to serve the same JSON files unchanged. Nothing changes for consumers fetching JSON over HTTPS.

Architecture

  • JSON in network/ is the source of truth. The same files served by the HTTP endpoint.
  • scripts/codegen.mjs walks network/ at build time and emits src/abi/<chain>/<network>/<type>/<Contract>.ts (each export const abi = [...] as const;) plus src/info/<chain>/<network>.ts and src/info/networks.ts. Both src/abi/ and src/info/ are gitignored — generated artifacts never enter git.
  • tsc -p tsconfig.build.json compiles the codegenned TS to dist/.
  • prepack runs pnpm run build (codegen + tsc), so pnpm publish always emits a fresh dist.
  • Round-trip self-test in the codegen script parses each emitted TS literal back and JSON.stringify-compares to source, failing the build on any drift.

Net: JSON authored once, both transports (npm + HTTP) ship the same data.

Subpath exports

@polygonlabs/meta                 → Network class (legacy dynamic API, async)
@polygonlabs/meta/abi/<...>       → typed `as const` ABI per contract
@polygonlabs/meta/info/<...>      → typed network metadata, networks list
@polygonlabs/meta/network/<...>   → raw JSON, identical paths to @maticnetwork/meta@2.x

Why as const?

Each generated ABI module looks like:

export const abi = [
  { type: "function", name: "hasRole", inputs: [...], outputs: [...] }
] as const;

The trailing as const is load-bearing, not stylistic. Without it, TypeScript widens the array element type to a generic { type: string; name: string; inputs: ...[] }, which means viem/wagmi/abitype cannot extract function names, argument types, or return types at the call site — the whole point of shipping typed ABIs disappears. With as const, every string literal stays at its exact value and the array becomes a tuple, giving consumers full type-level inference for readContract({ abi, functionName, args }) and friends.

MIGRATION.md and README.md both carry this rationale so consumers see it at the install/migrate step. CONTRIBUTING.md documents that the codegen always emits the trailing as const automatically — don't hand-edit src/abi/, it's gitignored and regenerated.

Commit-by-commit walkthrough

  1. chore: add implementation plan and gitignore ad-hoc plans — commits the session-portable execution plan to plans/refactoring-with-polygonlabs-renaming.md for cross-session continuity.
  2. chore: migrate from npm to pnpm.nvmrc=24, pnpm-workspace.yaml with the team supply-chain block, .npmrc with link-workspace-packages=false, pnpm-lock.yaml replaces package-lock.json.
  3. feat: add TypeScript toolchaintsconfig.{json,build.json} extending @tsconfig/node24 + @tsconfig/node-ts, TS 6.0.3 + @types/node@^24 as devDeps.
  4. feat: add JSON→TS codegen and ESM Network classscripts/codegen.mjs (committed, runs at build time), src/Network.ts (async ESM port of legacy class), src/index.ts. Legacy network/index.js and minify.js deleted.
  5. feat!: rename package to @polygonlabs/meta with subpath exports — new package.json, MIGRATION.md, CONTRIBUTING.md, rewritten README.md. Subpath exports for ./abi/*, ./info/*, ./network/*, root.
  6. feat: adopt changesets and tag-driven npm release.changeset/config.json, .changeset/initial-rename.md (major bump), thin trigger workflows calling 0xPolygon/pipelines's apps-npm-release.yml and apps-changeset-check.yml directly. Legacy npm-release.yml deleted.

What's untouched (deferred)

Per "rest later" direction, these stay for follow-up PRs:

  • Dockerfile, nginx.conf, .github/workflows/{deployment,deployment_gcp,build_and_deploy}.yml, .github/taskdef/* — HTTP-endpoint serving infrastructure, exact-revert from any earlier branch state.
  • Workflow hygiene in the deployment files (secrets: inherit, missing permissions:, unpinned action SHAs).
  • Master → main rename.
  • .github/CODEOWNERS with @0xPolygon/product-applications.
  • Branch protection (require_code_owner_reviews, enforce_admins:false).
  • Auto-delete branch on merge.
  • Claude Code integration (.claude/settings.json, root CLAUDE.md).
  • ESLint / Prettier / Husky / lint-staged / commitlint.

Test plan

  • rm -rf node_modules dist src/abi src/info && pnpm install --frozen-lockfile && pnpm run build from a clean checkout — green; codegen emits 469 ABIs + 4 info + 1 networks; tsc emits 476 .js + 476 .d.ts.
  • dist/abi/mainnet/v1/pos/AccessControl.d.ts retains the full readonly [{ readonly anonymous: false; ... }] as const tuple type.
  • Runtime smoke (node): static import of typed ABI returns 11 entries; info.Main.ChainId typed as 1; Network.create('mainnet','v1') populates dynamic keys; network.abi('AccessControl', 'pos') byte-matches the static import; raw JSON via import x from '...network/.../X.json' with { type: 'json' } byte-matches both.
  • pnpm pack --dry-run ships dist/, network/ (474 JSON files), MIGRATION.md, README.md, CHANGELOG.md (or absent), package.json — no src/, tsconfig*, scripts/, node_modules/, plans/.
  • pnpm exec changeset status reports Packages to be bumped at major: @polygonlabs/meta. Note: package.json version is 0.0.0 on this branch (intentional — the major changeset bumps it to 1.0.0 on the Version Packages PR). Empirically confirmed: 0.0.0 + major = 1.0.0 via pnpm exec changeset version.
  • CI on this PRapps-changeset-check passes (initial changeset present); the apps-npm-release workflow only runs on push: master so it does not fire on PR.

First-release bootstrap

This is the first publish of @polygonlabs/meta, so a few mechanics need a one-time setup. The team-canonical pattern (documented in apps-team-packages/packages/sync-github-releases/README.md) is being followed.

Pre-merge (one-time, performed locally before reviewer approval)

To unblock the OIDC publish on Monday without needing org-admin role on @polygonlabs:

cd repositories/static
pnpm install && pnpm run build
# Edit package.json: "version": "0.0.0" → "1.0.0-dev.0"  (working tree only)
npm login
npm publish --tag dev --access public --provenance
git checkout package.json   # revert; do NOT commit

The first publish makes the publisher (an npm Member of the @polygonlabs org) package admin for @polygonlabs/meta. As package admin, the trusted publisher can be configured per-package without org-admin:

@polygonlabs/meta@1.0.0-dev.0 is also useful as a downstream-app validation artifact under the dev dist-tag — does not affect npm install @polygonlabs/meta (which resolves to latest, unset until 1.0.0 ships).

Post-merge (automatic on master push)

  1. PR merges → apps-npm-release.yml fires → changesets/action opens "Version Packages" PR (0.0.0 → 1.0.0, generates CHANGELOG.md from the changeset body, deletes .changeset/initial-rename.md).
  2. Merge Version Packages PR → action runs again, hasChangesets == false → publish step runs.
  3. OIDC publish succeeds because trusted publisher is configured. @polygonlabs/meta@1.0.0 lands on npm with provenance, becomes the latest dist-tag.
  4. changesets/action creates the GitHub Release with body extracted from CHANGELOG.md.

Fallback (only if trusted publisher not configured by Monday)

The CI publish 403s on auth. Recover locally:

git pull origin master
pnpm install && pnpm run build
pnpm exec changeset publish        # publishes via npm member auth + creates the git tag
GH_TOKEN=$(gh auth token) npx @polygonlabs/sync-github-releases \
  release 0xPolygon/static @polygonlabs/meta@1.0.0 --apply

sync-github-releases populates the GitHub Release body byte-equal to what changesets/action would have produced, so the published release looks identical regardless of which path was taken.

Other follow-ups

  • Confirm CHANGESET_RELEASE_BOT_APP_ID and CHANGESET_RELEASE_BOT_APP_PRIVATE_KEY org secrets are accessible to 0xPolygon/static (used by apps-npm-release.yml to open the Version Packages PR with signed commits).
  • SonarCloud quality gate currently failing on 2 Security Hotspots (review markers, not real vulns) — await import() with computed paths in src/Network.ts and readFileSync/writeFileSync with computed paths in scripts/codegen.mjs. Mark as Safe in the SonarCloud UI when convenient.

History note

An earlier draft of this PR proposed deleting the static.polygon.technology HTTP endpoint and committing TS source files directly (no codegen). That was reversed because the HTTP endpoint is in active use; the cost of cutting it carries unknown blast radius. The branch was force-pushed to drop the deprecation commits and replace them with the codegen approach. The plans/refactoring-with-polygonlabs-renaming.md file in this PR captures the architecture decision and history.

@py-zoid py-zoid marked this pull request as ready for review May 1, 2026 14:57
py-zoid added 6 commits May 1, 2026 23:52
`scripts/codegen.mjs` walks the `network/` JSON tree and emits
`src/abi/<chain>/<network>/<type>/<Contract>.ts` plus
`src/info/<chain>/<network>.ts` with `as const` literal exports,
backed by an inline round-trip self-test that fails the build on any
JSON->TS drift.

JSON stays the source of truth. Both `src/abi/` and `src/info/` are
gitignored so generated artifacts never enter git -- only the JSON
files in `network/` are authored. This keeps the existing
static.polygon.technology HTTP endpoint working (nginx still serves
the JSON tree) while also giving npm consumers typed `as const`
ABIs at build time.

The `as const` assertion on every emitted ABI is load-bearing, not
stylistic. Without it, TypeScript widens the array element type to a
generic `{ type: string; name: string; inputs: ...[] }` shape, and
viem/wagmi/abitype cannot extract function names, argument types, or
return types at the call site -- the whole point of typed ABIs
disappears. With `as const`, every string literal stays at its exact
value and the array becomes a tuple, giving consumers full type-level
inference for `readContract({ abi, functionName, args })` and friends.

The legacy `Network` class is preserved for dynamic name-based
lookup but ported to ESM TS with a private constructor and a static
`Network.create()` async factory -- the constructor cannot `await`
the per-network info import. `artifacts()` and `abi()` are async,
backed by `await import('./abi/<...>.js')`. Documented as a breaking
change in the upcoming MIGRATION.md.

`"type": "module"` is set on the package because verbatimModuleSyntax
(via @tsconfig/node-ts) refuses ESM syntax otherwise. The legacy
CommonJS `network/index.js` and the unused `minify.js` are removed
in this commit.

Build pipeline: `pnpm run build` = codegen then `tsc -p
tsconfig.build.json`. `prepack` (added in the next commit) runs
`build` so `pnpm publish` always emits a fresh dist.
The package moves from `@maticnetwork/meta@2.4.82` to
`@polygonlabs/meta@1.0.0`. The numbering resets because the surface
and runtime requirements change in ways that are not drop-in
upgradable; a continuity bump would mislead consumers into expecting
a compatible release.

The HTTP endpoint at static.polygon.technology continues to serve
the same JSON files unchanged. This commit affects only the npm
package surface.

Subpath exports:

  ".":           dist/index.{js,d.ts}              -- Network class entry
  "./abi/*":     dist/abi/<chain>/<net>/<type>/*  -- typed ABIs per contract
  "./info/*":    dist/info/<chain>/<net> + /networks -- typed metadata
  "./network/*": network/*                         -- raw JSON, identical
                                                      paths to @maticnetwork/meta

The first three import the codegenned, `as const`-typed TS modules
that viem/wagmi/abitype need. The fourth keeps the raw JSON path
working for consumers who want bytes, not types -- same path scheme
as the previous `@maticnetwork/meta@2.x` package and the public
HTTP endpoint, so a JSON consumer migrates by changing only the
package name.

Published `files`: `dist/`, `network/`, MIGRATION.md, README.md,
CHANGELOG.md. Source files, tsconfigs, the codegen script, plans,
and supply-chain config stay in-repo.

`publishConfig.access: "public"` and `publishConfig.provenance: true`
are set so that `changeset publish` from CI uses npm OIDC trusted
publishing and stamps each release with provenance metadata.

MIGRATION.md and README.md both carry a "Why `as const`" section so
consumers see the typing rationale at the migration step. CONTRIBUTING.md
documents the codegen flow: edit JSON in `network/`, run `pnpm run
codegen`, never hand-edit the gitignored `src/abi/` or `src/info/`.
Adds the team-standard release flow used across all `@polygonlabs/*`
packages. Developers add a `.changeset/<name>.md` to each PR that
ships a user-visible change; on merge to `master`, the
`apps-npm-release.yml` shared workflow opens a "Version Packages"
PR that bumps the version, writes the changelog, and deletes
consumed changeset files. Merging *that* PR triggers the publish:
the workflow calls `changeset publish`, which tags the release as
`@polygonlabs/meta@<version>` and pushes to npm via OIDC trusted
publishing with provenance. No manual `npm publish`, no manual
tagging, no static `NPM_AUTH_TOKEN` secret.

Trigger files call `0xPolygon/pipelines` directly because that repo
is public; verbatim local copies are unnecessary. Both triggers
declare explicit `permissions:` and pass secrets by name -- never
`secrets: inherit` -- so the credential surface granted to the
shared workflow is visible at a glance.

The bundled initial-rename changeset describes the rename from
@maticnetwork/meta and the breaking changes (ESM-only, Node >=24,
async Network class). The HTTP endpoint at static.polygon.technology
is explicitly noted as unchanged.

The legacy `npm-release.yml` (Node 12, GitHub Release-triggered, raw
`npm publish`, unpinned action versions) is deleted in this same
commit per the team standard against leaving superseded workflows
in place as "disabled" fallbacks.

`baseBranch` in `.changeset/config.json` is `master` because this
repo predates the team's master->main rename convention; the rename
is a separate PR.
@py-zoid py-zoid force-pushed the feat/refactoring-with-polygonlabs-renaming branch from 17a4a51 to 0c1d7e5 Compare May 1, 2026 20:36
py-zoid added 4 commits May 2, 2026 01:21
`package.json` version drops from 1.0.0 to 0.0.0 so the existing
`major` changeset produces 1.0.0 on the Version Packages PR rather
than 2.0.0. Empirically confirmed: changeset version applied to
`0.0.0 + major` yields `1.0.0`; minor yields 0.1.0; patch yields
0.0.1. Major is the right bump for the rename narrative anyway.

Plan section "First-release bootstrap" rewritten to document the
team-canonical flow:

  1. Locally publish 1.0.0-dev.0 with --tag dev to claim the npm
     package name and become package admin.
  2. Configure the trusted publisher on the package's settings page
     (now accessible via package-admin role, no org-admin needed).
  3. Monday's CI publish goes through OIDC cleanly; changesets/action
     creates the GitHub Release from CHANGELOG.md.

Fallback if the trusted publisher isn't ready by Monday: accept the
CI 403, run `pnpm exec changeset publish` locally, then run
`@polygonlabs/sync-github-releases release <repo> <tag> --apply` to
populate the GitHub Release body byte-equal to what
changesets/action would have produced. That's the documented team
recovery path; we've adopted it as the safety net.
EventsHub is the staking-system contract that emits the newer `*WithId`
event variants (`ShareBurnedWithId`, `DelegatorUnstakeWithId`,
`SharesTransfer`, `UpdateCommissionRate`) which carry the unbond nonce —
critical for the PIP-85 staker-pool subgraph in 0xPolygon/subgraphs to
attribute share movements correctly. The proxy addresses are already in
the registries (`Main.Contracts.EventsHubProxy` on both mainnet/v1 and
testnet/amoy), but the ABI was missing, leaving downstream consumers
(notably the new `pos-staking` subgraph) blocked.

ABI sourced from the legacy `maticnetwork/subgraphs` repo, which has
indexed the same deployed contract for years; events match the wire
format the impl emits behind the proxy. `pnpm run codegen` regenerates
the `src/abi/{mainnet/v1,testnet/amoy}/plasma/EventsHub.ts` modules
(gitignored, not in this commit).
Addresses two SonarCloud Security Hotspots flagged on PR #182 with
real input validation rather than NOSONAR suppressions.

src/Network.ts: tightens the Network class API surface so a caller
cannot path-traverse the abi tree via the dynamic import. Adds
exported `Chain` and `ArtifactType` literal-union types, an
`/^[A-Za-z0-9_]+$/` regex on contract names, an allowlist check on
artifact types via a `asserts type is ArtifactType` user-defined
guard, and a registry-membership check on Network.create. Each
rejection throws a TypeError with a helpful message naming the
expected shape (and, for unknown networks, the known set).

scripts/codegen.mjs: adds a confine() helper that resolves derived
paths against an explicit base and throws if the resolved path
escapes the base. Wraps every read and write so a `..` directory
entry or a malicious symlink under network/ cannot read or write
outside the network/, src/abi/, or src/info/ roots. Also flips the
Array.isArray failure to TypeError to satisfy S7786.

Build still emits 469 ABI + 4 info + 1 networks modules, runtime
smoke confirms AccessControl@pos returns 11 entries on the happy
path and `../etc/passwd`, bogus types, and unknown chains all reject
with TypeError.
Copy link
Copy Markdown
Contributor

@MaximusHaximus MaximusHaximus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a few things in-line

Also:

  1. We need a CI workflow that runs our test & typecheck flow which verifies that our 'build/codegen' process succeeds as a PR check plus any other smoke-level testing that would make sense for the package
  2. Please nest the meta package in packages/meta dir rather than making this a single-package repository that contains a mixture of published and unpublished content at the root
  3. Ideally the package would be committed to the repo intact, in a known-good state, where we can inspect exactly what the package being published is without needing to run codegen. Also, the entire package should be .ts files, not a mixture of .js and .ts; it's not clear to me why there is a mixture of both kinds of files here. See 0xPolygon/pipelines#41 for an approach to detect codegen drift explicitly (I need review on that PR anyway BTW :) 👍 )

Comment thread plans/refactoring-with-polygonlabs-renaming.md Outdated
Comment thread .gitignore Outdated
Comment on lines +4 to +5
src/abi/
src/info/
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please nest all generated code into a generated directory for clarity

Comment thread src/Network.ts Outdated
}
}

export class Network {
Copy link
Copy Markdown
Contributor

@MaximusHaximus MaximusHaximus May 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔪 this entire abstraction can go and be replaced with an explicit, declarative set of paths exports. E.g. if I need addresses I can import from /addresses, if I need ABIs I can import from /abi/...

py-zoid added 6 commits May 7, 2026 16:24
Per PR review feedback, plans/ shouldn't host long-lived fixtures;
durable info belongs in CLAUDE.md, MIGRATION, or README.
Per PR review, all generated code now lives under a single `generated`
directory so the boundary between hand-authored and codegenned source
is obvious at a glance. Public subpath exports (`./abi/*`, `./info/*`)
are unchanged — only the dist mapping moves.
Per PR review, the Network/factory abstraction added nothing the
existing typed deep imports under ./abi/* and ./info/* don't already
provide. Consumers reach addresses, ABIs, and per-network metadata
through declarative subpath exports — fully typed, sync, and
tree-shakable. The package no longer has a root entry point.

BREAKING CHANGE: `import { Network } from '@polygonlabs/meta'` is
removed. Replace with `import { abi } from '@polygonlabs/meta/abi/<chain>/<network>/<type>/<Contract>'`
and `import { info } from '@polygonlabs/meta/info/<chain>/<network>'`.
…/meta/

Per PR review, the npm-published surface and the HTTP-endpoint surface
now live in separate top-level directories so what gets shipped to npm
is obvious at a glance.

- packages/meta/ holds the @polygonlabs/meta source, network/ JSON
  tree, codegen script, and the package's own README / MIGRATION /
  CONTRIBUTING.
- The repo root keeps Dockerfile / nginx.conf / index.html for the
  static.polygon.technology HTTP endpoint, plus a workspace-only root
  package.json and tsconfig.json. The Dockerfile now COPYs from
  packages/meta/network so both surfaces still read the same JSON.

Per-package tsconfig extends ../../tsconfig.json and tsconfig.build.json
gets composite: true so the root config can declare a project
reference. repository.directory in the published package now points at
packages/meta.
Per PR review, the package should not contain a mixture of .js and .ts
sources. The codegen script is the only .mjs file under packages/meta;
moving it to .ts removes the mixture. Explicit parameter and return
types make the script signature self-documenting.

Node 24 strips types natively, so `node scripts/codegen.ts` runs
unchanged without a transpiler. tsconfig.json now includes scripts/ so
`tsc --noEmit` typechecks the script alongside src/.
Per PR review, the published package contents are now committed so
reviewers can inspect the exact .ts modules that will ship without
running codegen locally. The codegen step becomes a PR-gate verifier,
not a build-time emitter:

- src/generated/ is no longer gitignored; 476 files (471 ABI + 4 info
  + networks) land alongside the network/ JSON they derive from.
- codegen-drift-check script regenerates and runs
  git diff --exit-code -- src/generated. Drift in either direction
  (edited JSON without regen, or hand-edited generated .ts) fails the
  gate.
- .gitattributes marks packages/meta/src/generated/** as
  linguist-generated so GitHub collapses it in the PR diff by default
  and excludes it from language stats. Reviewers can still expand
  individual files when needed.
- codegen:watch (chokidar-cli) re-runs codegen ~200 ms after any
  network/**/*.json save, so editing JSON keeps in-editor types
  accurate without a manual rebuild.
- CONTRIBUTING.md documents the committed-generated workflow and the
  watcher.
@py-zoid py-zoid requested review from grajat90 and shan8851 May 11, 2026 12:49
Closes the Priority 1 config-alignment gap from the /assess-repo audit.

- ESLint v10 + @polygonlabs/apps-team-lint at root and per-package
  (packages/meta/eslint.config.js with tsconfigRootDir set), ignoring
  the generated tree.
- Prettier, markdownlint-cli2, commitlint — all using the team's
  shared `@polygonlabs/apps-team-lint` exports, no per-repo overrides.
- Husky pre-commit (lint-staged + typecheck), commit-msg (commitlint),
  pre-push (changeset status against origin/master).
- Root scripts mirror the template: lint runs lint:md / lint:ts /
  typecheck / prettier --check via concurrently; format applies all
  three auto-fixers. `pnpm -r --if-present` propagates per-package
  typecheck and build, so packages/meta now exposes a `typecheck`
  script.
- pnpm-workspace overrides katex@^0.16.38 and the template's
  trustPolicyExclude list, both needed once markdownlint-cli2 is
  installed.

Existing markdown and HTML reformatted to satisfy the new gates;
workflow YAML normalised by prettier (whitespace + quote style only,
no semantic change).
Copy link
Copy Markdown
Contributor

@MaximusHaximus MaximusHaximus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Leave network at the top level of the repo so that this isn't a breaking path change for anyone consuming the data directly from the repository
  2. Codegen the NPM package contents from the repository root into the package
  3. Per our earlier discussions /asses-repo this branch and make sure the rest of our team tooling is added (linting, formatting for TS and MD files, typechecking, etc etc.)

Comment thread packages/meta/scripts/codegen.ts Outdated
writeTs(outPath, 'abi', srcJson.abi);

const roundTripped = readTsLiteral(outPath, 'abi');
if (JSON.stringify(roundTripped) !== JSON.stringify(srcJson.abi)) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These stringify checks feel a bit insane / redundant -- we just wrote the file on L96, right? How could it possibly not match? If writeTs is sane then this can never fail; same for L122 below.

Comment thread packages/meta/scripts/codegen.ts Outdated
try {
types = listDirs(artifactsPath);
} catch {
continue;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would we silently continue execution in this case? An error hear means that we just failed to update the artifacts for a path we expect to contain them, meaning that our codegen will not be correct (only some paths will be re-generated). IMO this should be an error state; we don't want to make this defensive, because the result could be publishing packages with a mixture of updates and out-of-date actual codegen'd data.

Comment thread packages/meta/scripts/codegen.ts Outdated
try {
info = JSON.parse(readFileSync(indexPath, 'utf8'));
} catch {
continue;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above, silently continuing in this case is not desirable; we shouldn't be trying to parse files that are not well-formed, and if we have malformed files in the target directory our codegen should fail loudly to avoid us publishing corrupt/incomplete packages without realising it.

Comment thread packages/meta/scripts/codegen.ts Outdated
console.log(`networks: ${stats.networks}`);
if (stats.mismatches.length > 0) {
console.error(`\nMISMATCHES (${stats.mismatches.length}):`);
for (const m of stats.mismatches) console.error(` ${m}`);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ironically, the abovementioned 'silent error swallowing' continue statements mean that this is basically guaranteed to never actually fire -- any real errors encountered are 100% ignored and the mismatches is never incremented, no error state is tracked at all, and this just basically tests 'does JSON.stringify work` :(

Comment thread packages/meta/MIGRATION.md Outdated
- Node ≥ 24
- ESM consumer (use `import`, not `require`)

If you can't be ESM yet, stay on `@maticnetwork/meta@2.x` for now or
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's worth noting that consumers can probably still bundle this ESM-native package into their app even if that app is bundled to CommonJS -- we just don't publish CommonJS code from the package; it's up to them. I don't think it's a good idea to recommend they stay on the deprecated package for this reason

Comment thread .github/workflows/build_and_deploy.yml Fixed
py-zoid added 2 commits May 12, 2026 14:17
…onsistency

Addresses the inline review comments on codegen.ts and the top-level
"keep network/ at the repo root" / "codegen from repo root into the
package" feedback.

- network/ moves back to the repo root, restoring direct-from-GitHub
  consumers and the previous Dockerfile COPY path. The npm package no
  longer owns the source-of-truth tree.
- codegen.ts now reads <repo-root>/network/networks.json as the
  canonical registry and walks each entry's <chain>/<version>/
  directory. A missing index.json, missing artifacts/ directory, empty
  artifact type directory, or non-array `abi` field is a hard error —
  silent `continue` swallowed real codegen failures and would have
  shipped packages with a mixture of fresh and stale generated TS.
- The round-trip stringify self-test is gone. writeTs writes the file
  one line earlier; re-reading + JSON.stringify-comparing is dead
  weight that only ever caught determinism of JSON.stringify, never
  any real bug.
- A new step at the end of codegen mirrors the repo-root network/
  tree into packages/meta/network/ (gitignored, materialised by
  prepack) so the @polygonlabs/meta/network/* subpath export still
  resolves to the same paths consumers of @maticnetwork/meta@2.x use.
- CONTRIBUTING.md and root README.md updated for the new layout.
Per review feedback, the old wording recommended staying on the
deprecated @maticnetwork/meta@2.x for any consumer who "can't be
ESM yet". That overstates the constraint — modern bundlers
(esbuild, webpack 5+, Vite, Rollup, Parcel) consume ESM packages
from CJS host code transparently. The only consumers actually
blocked are unbundled Node runtimes that load via `require()` and
older bundlers without ESM support; for those the HTTP endpoint
remains the documented escape hatch.
MaximusHaximus
MaximusHaximus previously approved these changes May 15, 2026
Copy link
Copy Markdown
Contributor

@MaximusHaximus MaximusHaximus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one thing re: the pnpm minimumReleaseAge, then I think this is ready to go

Comment thread pnpm-workspace.yaml Outdated
- 'packages/*'

blockExoticSubdeps: true
minimumReleaseAge: 1440
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adjust to 1 week please (per recent guidelines from security team) :)

py-zoid added 3 commits May 15, 2026 08:03
Wires up the PR-gate workflows from 0xPolygon/pipelines that every
apps-team repo is expected to consume:

- ci-trigger.yml — lint / typecheck / test via the ci composite action
- codegen-drift-check-trigger.yml — regenerates and fails on any diff
  under packages/meta/src/generated
- claude-code-review-trigger.yml — automated PR review
- claude-trigger.yml — @claude mention handler

The legacy AWS+GCP push-triggered deploy workflows stay as-is for now;
this PR only adds the missing PR-gate surface so future PRs get
linted/typechecked/drift-checked before merge.
Brings the AWS ECS deployment workflows up to the team-standard for
permissions and secrets. The push-triggered AWS+GCP deploy plumbing
itself is unchanged — that's a separate decision documented in the PR
description.

- build_and_deploy.yml: top-level `permissions: { contents: read,
  id-token: write }` for OIDC; declares its `build_params_gh_secret_keys`
  workflow_call secret explicitly and forwards it by name to the
  shared `ecs_deploy_docker_taskdef.yaml` instead of `secrets: inherit`.
- deployment.yml: same top-level `permissions:` block; passes
  `build_params_gh_secret_keys` explicitly to `build_and_deploy.yml`.

`deployment_gcp.yml` already has the correct `permissions:` block and
doesn't use `secrets: inherit`, so it's unchanged.
Required by team-standards. Every PR against master now requires
approval from @0xPolygon/product-applications. Single owner block at
the root since the team owns both the npm package and the
static.polygon.technology HTTP endpoint that ships from this repo.
py-zoid added 2 commits May 15, 2026 09:35
Lets Claude sessions running outside the apps-team-workspace fetch
the team-standards gist and find their bearings in this repo. The
new CLAUDE.md covers the dual-surface architecture (npm package +
nginx HTTP endpoint), the codegen flow (repo-root network/ → tracked
src/generated/ + gitignored network/ mirror), and points at the
existing CONTRIBUTING / MIGRATION / README docs.

.claude/settings.json grants WebFetch access to gist.githubusercontent.com
so the fetch at the top of CLAUDE.md succeeds without prompting.
Increases the install-time embargo on freshly-published packages from
1440 minutes (24 hours) to 10080 minutes (7 days). The
minimumReleaseAgeExclude allow-list still lets internal scopes
(@polygonlabs, @maticnetwork, @agglayer, @0xsequence, @0xtrails)
through immediately so day-to-day workspace development isn't
slowed down.
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
6 Security Hotspots
95.9% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@py-zoid py-zoid merged commit 05af56f into master May 15, 2026
8 of 9 checks passed
@py-zoid py-zoid deleted the feat/refactoring-with-polygonlabs-renaming branch May 15, 2026 07:38
pull Bot pushed a commit to See887777/static that referenced this pull request May 15, 2026
The 1.0.0 release fired Static Deployment on master and it failed
with `startup_failure` immediately — the called
`0xPolygon/pipelines/.github/workflows/ecs_deploy_docker_taskdef.yaml`
declares `permissions: { id-token: write, contents: write }` on its
job, but PR 0xPolygon#182 hardened the trigger with `contents: read`, which is
not a superset of what the called workflow needs.

Both deployment.yml and build_and_deploy.yml now declare
`contents: write`. id-token: write is unchanged. The token is still
scoped down from `inherit`-everything to just the two scopes the AWS
deploy actually uses.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants