Skip to content

feat: pnpm migration, contracts precompiles build & npm publish#1021

Open
nowooj wants to merge 15 commits into
cosmos:mainfrom
nowooj:feat/contracts-package
Open

feat: pnpm migration, contracts precompiles build & npm publish#1021
nowooj wants to merge 15 commits into
cosmos:mainfrom
nowooj:feat/contracts-package

Conversation

@nowooj

@nowooj nowooj commented Feb 26, 2026

Copy link
Copy Markdown

Closes: #428

Temporary published package: cosmos-evm-contracts
If you want to keep using this package name, I will transfer npm package ownership from the account that published it.


1. contracts package – precompiles build & npm publish

  • Precompiles-only build: Build .sol and ABI into dist/ from solidity/precompiles, excluding testdata and testutil
  • Publish config: files, exports, and prepublishOnly so npm publish runs the build and exposes the right entry paths
Path Change
contracts/scripts/build-precompiles.js New. Precompiles build script
contracts/package.json build:precompiles, compile, prepublishOnly, files, exports; packageManager, deps, etc.
contracts/README.md New. Installation, package structure, usage
contracts/.gitignore Add dist/
contracts/hardhat.config.js Config updates
contracts/pnpm-lock.yaml Lockfile (pnpm)

2. pnpm migration (reason)

  • Faster installs and less disk usage via a content-addressable store
  • Strict dependency resolution to avoid phantom dependencies and keep the dependency tree predictable
  • Built-in workspace support for the repo’s multiple packages (contracts/, tests/, evm-tools-compatibility, etc.)

CI, scripts, and lockfiles across the repo are updated to use pnpm accordingly.


How to verify

# Full contract compile
make contracts-all  # or use scripts/compile_smart_contracts

# Build contracts precompiles
cd contracts && pnpm install && pnpm run build:precompiles

How to publish

cd contracts

# 1) Log in to npm (once)
npm login

# 2) Publish (prepublishOnly runs build:precompiles)
pnpm publish

Author Checklist

All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.

I have...

  • tackled an existing issue or discussed with a team member
  • left instructions on how to review the changes
  • targeted the main branch

@nowooj nowooj force-pushed the feat/contracts-package branch from 92d6f00 to 3ca5e17 Compare February 26, 2026 10:40
@aljo242 aljo242 assigned aljo242 and vladjdk and unassigned aljo242 Feb 26, 2026
@nowooj nowooj force-pushed the feat/contracts-package branch 3 times, most recently from bcf6953 to 816a66c Compare March 5, 2026 08:34
@nowooj nowooj force-pushed the feat/contracts-package branch 4 times, most recently from 6887e03 to 260c1dd Compare March 6, 2026 02:53
@nowooj

nowooj commented Mar 9, 2026

Copy link
Copy Markdown
Author

Rebase on main

@nowooj nowooj force-pushed the feat/contracts-package branch from 260c1dd to 40696d7 Compare March 9, 2026 06:33
@nowooj nowooj force-pushed the feat/contracts-package branch from c3c1465 to 8ac47bb Compare April 10, 2026 08:05
@vladjdk vladjdk requested a review from a team as a code owner April 23, 2026 20:25
@vladjdk

vladjdk commented Apr 24, 2026

Copy link
Copy Markdown
Member

@greptile review

@greptile-apps

greptile-apps Bot commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR migrates the JavaScript toolchain from npm/yarn to pnpm across 115 files and introduces a new precompile build pipeline (wagmi generate → tsdown) that publishes typed ABI exports and Solidity interfaces as the cosmos-evm-contracts npm package.

  • P1: All four modified CI workflows place actions/setup-node with cache: 'pnpm' before pnpm/action-setup, which means pnpm is not installed when the node setup runs — the pnpm cache is silently skipped on every run.
  • P1: prepublishOnly calls build:precompiles (wagmi generate && tsdown) but never invokes hardhat compile; wagmi generate reads from artifacts/ and will error or produce an empty dist/ if a compile step hasn't been run separately, making pnpm publish unreliable without prior manual compilation.

Confidence Score: 4/5

Safe to merge after addressing the two P1 issues: CI workflow step ordering and the missing hardhat compile in prepublishOnly.

Two P1 findings exist: broken pnpm caching across all CI workflows (wrong step order) and a publish pipeline that can silently produce an empty/broken package without a prior compile step. The remaining findings are P2. The bulk of the migration is correct.

.github/workflows/slither.yml and all three compatibility workflows (step ordering), and contracts/package.json (prepublishOnly missing compile).

Important Files Changed

Filename Overview
.github/workflows/slither.yml Adds pnpm support for Slither CI; step ordering bug — setup-node with cache:'pnpm' runs before pnpm/action-setup, breaking cache.
.github/workflows/tests-compatibility-hardhat.yml Migrates to pnpm; same step-ordering issue as slither.yml — pnpm/action-setup must precede actions/setup-node for caching to work.
contracts/package.json Adds build:precompiles pipeline, publish config, and pnpm migration; prepublishOnly missing hardhat compile step could ship an empty/broken package.
contracts/wagmi.config.ts New file; dynamically walks precompile sources and wires wagmi hardhat plugin — correct pattern, but depends on pre-existing artifacts/.
contracts/tsdown.config.ts New file; compiles wagmi-generated .ts to ESM/CJS/DTS and copies .sol files; output dir overlaps with entry glob (minor idempotency risk).
scripts/compile_smart_contracts/compile_smart_contracts.py Migrates npm→pnpm and adds abi.json-aware extraction for Go precompiles; correct and well-scoped cleanup logic.
contracts/hardhat.config.js Adds Solidity 0.8.28 compiler version for @account-abstraction/contracts; straightforward and correct.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[pnpm install] --> B[hardhat compile\nnot in script!]
    B --> C[artifacts/ dir]
    C --> D[wagmi generate]
    D --> E[dist/abi/precompiles/*.ts]
    E --> F[tsdown]
    F --> G[dist/abi/precompiles/*.js / *.cjs / *.d.ts]
    F --> H[dist/solidity/precompiles/*.sol]
    G --> I[pnpm publish]
    H --> I
    style B fill:#f88,stroke:#c00
    style I fill:#8f8,stroke:#080
Loading

Reviews (1): Last reviewed commit: "fix: solidity path" | Re-trigger Greptile

Comment on lines +22 to +30
- name: Setup Node.js and pnpm
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'pnpm'
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 9

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.

P1 pnpm/action-setup must precede actions/setup-node

actions/setup-node@v4 with cache: 'pnpm' requires pnpm to already be installed so it can locate the cache store path. With the current order, pnpm is not available yet when setup-node runs, so the pnpm cache is silently skipped on every CI run. The same ordering bug exists in all three compatibility workflows (tests-compatibility-hardhat.yml, tests-compatibility-viem.yml, tests-compatibility-web3js.yml).

Swap the steps: run pnpm/action-setup@v4 first, then actions/setup-node@v4.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Comment thread contracts/package.json
Comment on lines +9 to +11
"@types/node": "^22.0.0",
"@wagmi/cli": "^2.2.0",
"hardhat": "^3.1.10",

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.

P1 prepublishOnly skips the Hardhat compilation step

build:precompiles runs wagmi generate && tsdown. wagmi generate reads from artifacts/ (pre-built Hardhat artifacts), but hardhat compile is not called anywhere in prepublishOnly. If someone runs pnpm publish without having already compiled the contracts, wagmi generate will fail to find artifacts — either erroring out or producing an empty dist/, resulting in a broken or empty published package. Adding pnpm exec hardhat compile && before wagmi generate in build:precompiles would make the publish self-contained.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Comment on lines +1 to +27
import { defineConfig } from "tsdown";

export default defineConfig({
entry: ["./dist/abi/**/*.ts", "!./dist/abi/**/*.d.ts"],
format: ["esm", "cjs"],
outDir: "dist/abi/precompiles",
dts: true,
unbundle: true,
clean: false,
outExtensions: ({ format }) => ({
js: format === 'cjs' ? '.cjs' : '.js',
dts: '.d.ts',
}),
platform: 'neutral',
copy: [
{
from: [
"solidity/precompiles/**/*.sol",
"!solidity/precompiles/**/testdata/**",
"!solidity/precompiles/**/testutil/**",
],
to: "dist",
flatten: false,
verbose: true,
},
],
});

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.

P2 Output directory overlaps with input entry glob

entry is "./dist/abi/**/*.ts" and outDir is "dist/abi/precompiles". Since wagmi generate places the generated .ts source files inside dist/abi/precompiles/, tsdown's output goes into the same tree it's compiling from. With clean: false, a second run of tsdown will also pick up .ts files produced by tsdown in a previous run (if any leaked through). Consider emitting generated TypeScript to a staging location (e.g. dist/.src/abi/) and outputting compiled artifacts to dist/abi/precompiles/, keeping source and build outputs separate.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Comment thread contracts/package.json
Comment on lines 14 to +26
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"build:precompiles": "wagmi generate && tsdown",
"prepublishOnly": "pnpm run build:precompiles"
},
"files": [
"dist",
"README.md"
],
"exports": {
"./*.sol": "./dist/*.sol",
"./*": {
"types": "./dist/*.d.ts",

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.

P2 Wildcard exports patterns for .sol files are ignored by Solidity tooling

The "./*.sol" export entry maps package subpaths to dist/*.sol. However, Solidity tooling (Hardhat, Foundry) does not use the Node.js exports field for import resolution — Hardhat uses require() resolution and Foundry uses remappings.txt. The .sol export entry will be silently ignored by those tools, making the README's Hardhat import example (import "cosmos-evm-contracts/precompiles/bank/IBank.sol") work only if the resolver falls through to bare node_modules file paths. Consider verifying the Hardhat and Foundry import paths against actual resolved paths after pnpm install.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@vladjdk vladjdk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@nowooj few conflicts and Greptile issues to resolve.

@nowooj nowooj force-pushed the feat/contracts-package branch from ace00fa to 0b8280a Compare May 22, 2026 01:26

@aljo242 aljo242 left a comment

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.

ci has not run: all workflows are action_required -- fork pr, needs maintainer approval to trigger.

wagmi.config.ts include path is malformed: join("solidity", "precompiles", module, "${contract}.sol", "*.json") treats ${contract}.sol as a directory segment. hardhat artifacts don't live there -- wagmi will silently produce no output and the published package will have empty ABIs.

exports field doesn't match output structure: the catch-all ./* maps to root dist/*.js / dist/*.d.ts, but tsdown outputs to dist/abi/precompiles/. import paths like cosmos-evm-contracts/abi/precompiles/bank/IBank (as documented in the README) won't resolve.

files field missing .generated/: wagmi writes to .generated/ during build, but only dist and precompiles are listed in files. if cleanup runs between build and publish, generated ABI files won't be included in the package.

nowooj added 9 commits May 29, 2026 11:51
chore: refine exports structure for TypeScript compatibility

chore: enhance exports for Solidity files

refactor: enhance TypeScript configuration for precompiles

feat: add dual ESM/CJS build for ABI exports

refactor: streamline build process for precompiles

chore: make contracts-all
@nowooj nowooj force-pushed the feat/contracts-package branch from 0b8280a to f2719c5 Compare May 29, 2026 02:51
@nowooj nowooj force-pushed the feat/contracts-package branch from 5dbb144 to d8d837e Compare May 29, 2026 05:27
@nowooj

nowooj commented May 29, 2026

Copy link
Copy Markdown
Author

ci has not run: all workflows are action_required -- fork pr, needs maintainer approval to trigger.

wagmi.config.ts include path is malformed: join("solidity", "precompiles", module, "${contract}.sol", "*.json") treats ${contract}.sol as a directory segment. hardhat artifacts don't live there -- wagmi will silently produce no output and the published package will have empty ABIs.

exports field doesn't match output structure: the catch-all ./* maps to root dist/*.js / dist/*.d.ts, but tsdown outputs to dist/abi/precompiles/. import paths like cosmos-evm-contracts/abi/precompiles/bank/IBank (as documented in the README) won't resolve.

files field missing .generated/: wagmi writes to .generated/ during build, but only dist and precompiles are listed in files. if cleanup runs between build and publish, generated ABI files won't be included in the package.

Thanks for the review.

  • The wagmi.config.ts include path seems correct. The build generated all expected ABI files, so the Hardhat artifact glob is resolving as intended.
  • I updated the generated ABI module path to remove the extra abi/ segment.
    • The intended import path is now: cosmos-evm-contracts/precompiles/bank/IBank
    • The Solidity interface path remains: cosmos-evm-contracts/precompiles/bank/IBank.sol
  • I don’t think .generated/ should be included in files; it is only an intermediate wagmi staging directory. This was changed after Greptile’s earlier review so publish no longer depends on generated ABI sources directly. The package should publish dist, precompiles, and README.md.

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.

Declare the common Types.sol as a library.

3 participants