BLO-131: Contracts & SDK v3#288
Conversation
There was a problem hiding this comment.
We can't remove this file: it is the authoritative source of this information, referenced from here: https://docs.immutable.com/learn/products/contracts/
Drop Hardhat, typechain, bundled ethers clients, postinstall, and per-ABI JSON subpaths. Publish TypeScript ABIs and addresses from dist/ and Solidity sources via contracts/*. Keep PascalCase ABI export names aligned with v2.2.18 for ABI-only consumers. Co-authored-by: Cursor <cursoragent@cursor.com>
Resolve package.json in favor of v3.0.0 Foundry/npm layout. Combine .npmignore rules from main (mocks, assets, diagrams) with v3 dev exclusions. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep the lean npm package (dist + contracts exports) while restoring the full Solidity sources, lib submodules, and remappings required by forge test. Align foundry.toml with main, add recursive submodule checkout in CI, and cache Foundry build output without lib/ (submodules + forge install supply deps). Verified locally: forge build, forge test (867 passed), yarn build, npm pack.
|
All alerts resolved. Learn more about Socket for GitHub. This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored. |
Remove invalid `contents` input from JS-DevTools/npm-publish@v4 (package files come from package.json `files` and .npmignore). Split PR CI into forge-test (recursive submodules) and package-check only; run full forge build and npm publish on release. Bump checkout and setup-node to v6. Co-authored-by: Cursor <cursoragent@cursor.com>
Narrow published files to dist and contract sources only, exclude mocks and non-Solidity assets, and drop declaration maps from the package. Replace tsup with tsc, add ESM subpath exports, and restore solhint in CI. Co-authored-by: Cursor <cursoragent@cursor.com>
Set rootDir for TS 6, drop rimraf/prettier, inline clean, bump @types/node and solhint, and align CI with .nvmrc. Co-authored-by: Cursor <cursoragent@cursor.com>
Rename Foundry job to match required status, restore README/slither jobs, add v3 skip stubs for removed Hardhat/eslint, and harden npm publish workflow. Co-authored-by: Cursor <cursoragent@cursor.com>
Match main branch workflow: apt remove python3-typing-extensions before pip install. Co-authored-by: Cursor <cursoragent@cursor.com>
| "contracts/**/*.sol", | ||
| "!contracts/mocks", | ||
| "dist" | ||
| "!contracts/mocks/**" |
There was a problem hiding this comment.
Negation pattern in files has undefined npm behavior
Medium Severity
The !contracts/mocks/** negation in the "files" array relies on behavior that npm explicitly documents as having "undefined consequences." Multiple npm versions (v7+) have had bugs where files negation is silently ignored, which would cause mock/test contracts to leak into the published tarball. The .npmignore has a backup exclusion, but the PR description incorrectly states .npmignore is ignored when "files" is set, risking future removal of that safety net.
Reviewed by Cursor Bugbot for commit 1e11e98. Configure here.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
There are 4 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 2ee3fba. Configure here.
| package: package.json | ||
| tag: latest | ||
| provenance: true | ||
| strategy: all |
There was a problem hiding this comment.
Release tag ignores package version
High Severity
The publish workflow no longer validates the GitHub release tag or updates the package.json version before npm publish. This can cause the published package's version on NPM to diverge from the GitHub release tag, potentially confusing consumers.
Reviewed by Cursor Bugbot for commit 2ee3fba. Configure here.
| - name: Attest build provenance | ||
| uses: actions/attest-build-provenance@v3 | ||
| with: | ||
| subject-path: ./*.tgz |
There was a problem hiding this comment.
Provenance attestation after publish
Medium Severity
The Attest build provenance step now runs after Publish to NPM. This reverses the previous workflow's order, allowing packages to be published without their build provenance attestation, which was a critical supply-chain security requirement.
Reviewed by Cursor Bugbot for commit 2ee3fba. Configure here.
| function beforeAuthorizedTransfer(address token, uint256 tokenId) external; | ||
| function beforeAuthorizedTransferWithAmount(address token, uint256 tokenId, uint256 amount) external; | ||
| function afterAuthorizedTransferWithAmount(address token, uint256 tokenId) external; | ||
| } No newline at end of file |
There was a problem hiding this comment.
Unused local transfer interface
Low Severity
The new ITransferValidator.sol under v3/interfaces/ is not imported anywhere; ImmutableSignedZoneV3.sol still imports Limit Break’s ITransferValidator. The duplicate ships in the npm tarball without participating in compilation.
Reviewed by Cursor Bugbot for commit 2ee3fba. Configure here.


Summary
This PR releases
@imtbl/contracts@3.0.0: a breaking major that turns the package into a lean ABI + addresses + Solidity sources artifact for viem / wagmi / ethers v6, with no runtime npm dependencies and no Hardhat/ethers v5/typechain in the published tarball.The Solidity preset tree remains in the repo for Forge development and is still published (excluding mocks). What v3 removes is the old npm/TypeScript toolchain (Hardhat deploy scripts, generated ABI tree, ethers v5 clients, wagmi codegen, bundled third-party contract deps).
What's changed in v3 (vs
main)Toolchain: Hardhat → Foundry (development and CI)
main)chore/v3)hardhat compile,hardhat test,hardhat coverageforge build,forge test,forge coveragehardhat.config.ts, Hardhat plugins (typechain, waffle, foundry bridge)foundry.toml,remappings.txt, git submodulesdeploy/(Hardhat +deploy/utils.ts)forge script/forge create(seeBUILD.md)clients/clients/packageforge fmt--compile-force-framework forgetsconly →dist/Deleted files (tooling):
hardhat.config.ts,wagmi.config.ts,tsup.config.ts,.eslintrc.js,.eslintignore,.prettierrc,.prettierignore, rootindex.ts(wagmi re-exports),CHANGELOG.md.npm package surface (breaking for consumers)
main)2.2.18(line)3.0.0typecommonjsmodule(ESM).nvmrc18.17.nvmrc22.12.0)dependencies@openzeppelin/contracts, Seaport fork aliases, Axelar, solmate, etc.)peerDependencies@openzeppelin/contracts(consumers supply OZ when compiling.sol)postinstallrimrafon Seaportfoundry.tomldist/+ entirecontracts/+ hugeabi/treedist/+contracts/**/*.solexcludingcontracts/mocks/**Removed from the published package:
abi/— generated JSON ABIs,abi/index.ts, per-contract JSON subpaths (~1.1 MB of ABI payload in v2)clients/— ethers v5 helpers (erc20.ts,erc721.ts,erc721-mint-by-id.ts, config overrides)contract_address.json— replaced by typed constants insrc/addresses.tsAdded / changed exports:
@imtbl/contracts—ImmutableERC721Abi,ImmutableERC721MintByIdAbi,ImmutableERC1155Abi,GuardedMulticaller2Abi,PaymentSplitterAbi, plus address maps (IMMUTABLE_SEAPORT,CHAIN_ID, bridge/wallet/zone addresses, etc.)@imtbl/contracts/abis— ABI-only subpath@imtbl/contracts/addresses— address constants only@imtbl/contracts/contracts/*— Solidity sources for import/remapping in consumer projectsABI naming (breaking): v2 re-exported camelCase names from
abi/generated.ts(e.g.immutableErc721Abi). v3 uses PascalCase names aligned with v2.2.18 public API (ImmutableERC721Abi, etc.). Subpath imports change from@imtbl/contracts/abi/...to@imtbl/contracts/abisor root.No longer shipped: typechain types, wagmi hooks from this package, ethers v5
clients,import contract_address.json.Solidity in the repo vs in the tarball
contracts/(Forge needs submodules; restored indc7c7dcafter an intermediate lean pass).mainincontracts/: one addition —contracts/trading/seaport16/zones/immutable-signed-zone/v3/interfaces/ITransferValidator.sol.contracts/mocks/**) remain in the repo for tests but are not published to npm.CI (
.github/workflows/test.yml)Real jobs:
forge testwith submodule init + Foundry cache (name matches branch protection)yarn build+npm pack --dry-runpython3-typing-extensionsconflict)Legacy stub jobs (pass immediately until branch protection is updated for v3):
Publish workflow (
.github/workflows/publish.yaml)forge buildbefore pack,yarn build, publish with pinned action SHA,tag: latest, npm provenance attestation on.tgz.Breaking changes for npm consumers
@imtbl/contracts@2.2.18until you migrate, or adopt v3 explicitly.contract_address.jsonwithIMMUTABLE_*/CHAIN_IDfrom@imtbl/contractsor@imtbl/contracts/addresses.clients/*andabi/*JSON imports with viem/wagmi/ethers v6 + exported ABIs.@openzeppelin/contracts(and your own Seaport/Axelar remappings) when compiling published.solfiles."type": "module") and Node ≥20.Follow-ups (post-merge)
@imtbl/contractsNote
Medium Risk
Medium risk because this is a breaking release that changes the published npm surface (ESM, Node version, exports) and rewires CI/release workflows; it should not affect on-chain Solidity logic beyond one added interface file.
Overview
Updates
@imtbl/contractsto v3.0.0 as a lean ESM package that publishes TypeScript ABIs + typed deployed address constants + Solidity sources, and removes the old TypeScript/Hardhat consumer surface (generatedabi/,clients/, Hardhat deploy scripts/config, wagmi codegen, eslint/prettier configs, andcontract_address.json).Switches the development and CI toolchain to Foundry-first: workflows now run
forge build/forge test, add Foundry build caching, add a package build/pack check, and keep stub “legacy” jobs for old branch protection. Packaging is tightened viaexports,files, and.npmignore(excludingcontracts/mocks/**), Node is bumped via.nvmrc/engines, and docs are updated to reflect the new consumption and migration guidance.Reviewed by Cursor Bugbot for commit 2ee3fba. Bugbot is set up for automated code reviews on this repo. Configure here.