chore: convert matic.js to pnpm monorepo#463
Conversation
- Move src/, test/, webpack.config.js, build_helper/, examples/ into packages/maticjs/ - Add root pnpm-workspace.yaml, .npmrc, package.json (private, devDeps only) - Add .changeset/config.json (baseBranch: master) - Add .husky/ hooks (lint-staged, commitlint, changeset pre-push check) - Add .prettierrc.json, .markdownlint-cli2.jsonc, .lintstagedrc.js from team template - Add .github/CODEOWNERS - Add MIGRATION.md scaffolds at root and packages/maticjs/ - Update .nvmrc to Node 24 - Replace old tsconfig.json with monorepo root config (noEmit, project references) - Add packages/maticjs/tsconfig.json (erasableSyntaxOnly: false, verbatimModuleSyntax: false) - Add packages/maticjs/package.json with publishConfig, repository.directory, explicit deps - Remove package-lock.json (replaced by pnpm-lock.yaml) - Remove .prettierrc (replaced by .prettierrc.json), .eslintignore, tslint.json - Add @ethereumjs/common and safe-buffer as explicit deps (used directly in source but only transitive under npm; pnpm strict isolation requires them declared) - TypeScript upgraded to ^5.9.3 — TS5 builds clean once npm node_modules is removed; earlier apparent breakage was caused by stale mixed npm/pnpm module resolution
…errors
- Add eslint.config.js using @polygonlabs/apps-team-lint@2.0.0
- Add commitlint.config.js (conventional commits)
- Add @commitlint/cli, bump markdownlint-cli2 to ^0.21.0
- Add type: module to root package.json (ESLint ESM config requirement)
- Add .idea to .gitignore
ESLint fixes in packages/maticjs/src/:
- Auto-fix consistent-type-imports, sort-imports, no-duplicates
- no-unused-vars: prefix unused abstract method params with _
- no-param-reassign: local variables throughout
- no-duplicate-enum-values: Erc721Transfer = Erc20Transfer (same ABI sig)
- ban-types: typed Callback alias; unknown instead of {}
- Remove unused imports: IBlock, ITransactionOption, ExitUtil, RootChainManager, ERROR_TYPE
- Config overrides: no-require-imports (webpack BUILD_ENV), no-default-export (semver-major)
Markdownlint: fix violations in README.md, SECURITY.md, bug-report template,
examples/README.md; move examples/ to repo root
Test infrastructure:
- Delete packages/maticjs/test/{package.json,tsconfig.json,jest.config.js,
debug.js,ether.js,config.js,.env.example} — broken nested project with
npm link, jest@27, and live-RPC dependencies
- Migrate tests/map-promise.test.ts to vitest (7 pure unit tests, no network)
- Add vitest.config.ts; add vitest to devDependencies
- Split tsconfig.json (dev+test, noEmit) from tsconfig.build.json (composite,
rootDir: src, for webpack and project references)
- Root typecheck now delegates to pnpm -r run typecheck
| if (!abiStore[bridgeType]) { | ||
| abiStore[bridgeType] = {}; | ||
| } | ||
| abiStore[bridgeType][contractName] = abi; |
Check warning
Code scanning / CodeQL
Prototype-polluting assignment Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 20 days ago
In general, to fix prototype-polluting assignments, either (1) avoid using plain objects with prototype chains for storage of untrusted-keyed data (e.g., use Map or Object.create(null)), or (2) validate or normalize keys before use to prevent special values like "__proto__", "constructor", and "prototype" from being used. Given the existing type definitions and use of plain objects for the cache, the least invasive approach is to validate bridgeType (and optionally contractName) in setABI, rejecting or ignoring dangerous keys, while keeping all existing functionality for legitimate keys.
The best targeted fix here is to add a small guard in setABI that checks bridgeType against a denylist of prototype-polluting keys and throws or silently returns if such a value is provided. This preserves the current cache structure and public API while ensuring that abiStore[bridgeType] = {} and abiStore[bridgeType][contractName] = abi can never hit __proto__ or similar. We only need to edit packages/maticjs/src/utils/abi_manager.ts, inside setABI. No new imports are required; we can use plain string comparison.
Concretely:
- Modify
setABIinpackages/maticjs/src/utils/abi_manager.tsto:- Introduce a local array or simple conditional that checks if
bridgeTypeis one of"__proto__","constructor", or"prototype". - If so, either throw an error or
returnearly. For a library utility, an early return avoids changing error behavior elsewhere, but throwing is also defensible; I’ll choose an early return as the least disruptive. - Keep the rest of the method unchanged.
- Introduce a local array or simple conditional that checks if
- Optionally, apply the same check to
contractNameif you want to be extra defensive; however, CodeQL’s taint path is explicitly onbridgeType, so the minimum change focuses on that parameter.
| @@ -63,6 +63,11 @@ | ||
| } | ||
|
|
||
| setABI(contractName: string, bridgeType: string, abi: any) { | ||
| // Prevent prototype pollution via specially crafted bridgeType keys | ||
| if (bridgeType === '__proto__' || bridgeType === 'constructor' || bridgeType === 'prototype') { | ||
| // Ignore unsafe keys to avoid mutating Object.prototype | ||
| return; | ||
| } | ||
| const abiStore = cache[this.networkName][this.version].abi; | ||
| if (!abiStore[bridgeType]) { | ||
| abiStore[bridgeType] = {}; |
0e44251 to
43315e1
Compare
Public repo pattern — no references to apps-team-workflows (private). Every workflow and action is a local copy. - Delete legacy ci.yml (npm-based) and github_doc_deploy.yml (dead since 2022) - Add .github/actions/ci/ — verbatim copy of CI composite action - Add .github/actions/upsert-changeset-comment/ — verbatim copy including compiled dist/index.js bundle (required since private repo actions cannot be called cross-visibility) - Add ci-trigger.yml — PR gate; calls ./.github/actions/ci - Add changeset-check.yml + changeset-check-trigger.yml — changeset PR gate; uses local upsert-changeset-comment action - Add npm-release.yml + npm-release-trigger.yml — release pipeline on push to master; three main→master substitutions from canonical workflow - Add claude-code-review.yml + claude-code-review-trigger.yml - Add claude.yml + claude-trigger.yml - All triggers target master branch
43315e1 to
4400396
Compare
|
|
||
| --- | ||
|
|
||
| ## Phase 2 — PR 3: `@maticnetwork/maticjs-viem` ⬜ |
Summary
Converts `0xPolygon/matic.js` from a single-package npm repo to a pnpm monorepo, bringing it up to Polygon Apps Team standards. This is the foundation PR — subsequent PRs will add the `maticjs-viem` plugin and migrate the standalone `maticjs-web3`/`maticjs-ethers` plugin repos into this workspace.
See `PLAN.md` at the repo root for the full migration roadmap.
Pre-release
A beta snapshot is available for testing: `@maticnetwork/maticjs@3.9.8-beta.1`
Changes
Monorepo structure
Tooling
Tests
Repo organisation
GitHub Actions
What didn't change
Test plan