Skip to content

refactor(package)!: publish SVM IDLs without runtime exports (ACP-240) - #1591

Open
Reinis-FRP wants to merge 5 commits into
reinis/acp-235-local-anchor-clientsfrom
reinis/acp-240-idl-only-package
Open

Reinis-FRP wants to merge 5 commits into
reinis/acp-235-local-anchor-clientsfrom
reinis/acp-240-idl-only-package

Conversation

@Reinis-FRP

@Reinis-FRP Reinis-FRP commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

This draft makes the published SVM interface JSON-only. It removes production Codama generation, generated client/type exports and SVM runtime helpers, and replaces broad dist/**/* publication with explicit file and entry-point allowlists. The three Across IDLs, internal Anchor/web3.js v1 helpers, EVM artifacts/deployment lookups and existing shared APIs and explicit compatibility paths remain. This is an SVM-only runtime cleanup, not an artifacts/data-only package migration.

Stacked on #1588 (ACP-235), at b4c90e5792b1df3f81c0bb8b17159037e87d4176. Do not merge or release until validated consumer replacements are recorded. Implements the draft package work in ACP-240; it does not complete consumer adoption or authorize deployment.

The external packed-IDL fixture remains in CI. It generates and compiles its own clients, checks V5 codecs and canonical PDAs, rejects removed root/deep runtime and type imports, and checks CJS/ESM plus EVM/shared access. Shared Merkle utilities, constants, deployment lookups, getNodeUrl and explicit shared compatibility paths remain documented and tested. Filesystem access to published EVM artifacts is preserved independently of artifact-discovery helpers; existing deep-only helpers remain pending a separate consumer audit. A second pack with injected stale files verifies physical exclusion independently of the clean build. Kit/Codama are fixture-only development dependencies; Anchor, Borsh, web3.js and buffer-layout are internal development dependencies. The unused lookup-table runtime dependency is removed. Separate SVM binary release jobs remain intact.

Validation (Node 22.18.0, Yarn 1.22.22):

  • Production IDL generation with Anchor 1.1.2; test-feature IDL generation.
  • Seven packed-package tests: clean prepack, external generation, physical allowlist, rejected SVM runtime/type imports and retained EVM/shared compatibility access.
  • TypeScript build, tests typecheck and operational-script typecheck.
  • 33 offline event-query, V5-codec, path-vector and CCTP tests.
  • Formatting, dependency integrity with the install's ignoreScripts flag, and git diff --check.
  • Native Anchor run with Agave 4.1.2/platform-tools v1.54 and a runtime import guard rejecting Kit/generated clients: 167 passed, including all program cases. Seven build-helper cases initially failed because the temporary workspace omitted verified-build.json; all 17 build-helper tests passed when rerun from the repository. No source change was needed for those setup failures. Existing target/deploy binaries were preserved.
  • The initial implementation passed all GitHub checks at 2b4f7d4f7fcfda2dfad6c1b3c83baee465e92415: verified SVM tests, EVM tests, TypeScript/packed-package checks, lint/generated-file checks, both artifact jobs and DCO.

The real-Gateway lane was not rerun for this package-only change; its retained Anchor coverage was validated in the base PR. The seven package tests also passed after fresh production IDL generation; a final tarball smoke run separately confirmed native ESM named exports.

Fixture pins: Kit 5.4.0, Codama 1.3.0, nodes-from-anchor 1.2.2, renderers-js 1.3.0, TypeScript 5.6.2. Internal Anchor/Borsh 1.1.2 and web3.js 1.98.4. The package version remains 6.0.0-beta.4 only as a draft input; choose a fresh coordinated prerelease and matching tag before release, never republish this version with the changed boundary.

Consumer inventory, replacement status and adoption evidence are tracked in ACP-240. The broader artifacts/data-only migration is tracked separately in ACP-243, with a shared-consumer inventory and validated replacements required before removal.

Merge/release gates remain ACP-234/235 acceptance, ACP-236–239 consumer replacements and complete import inventory, applicable ACP-227 V2/light-chain behavior, and ACP-241 cross-repo validation using the actual candidate. Preserve multicall/sponsored routes and historical indexing; validate unsupported-fee handling and V2 tokenless finalization. Keep legacy pins only with an explicit owner-supported disposition. No consumers were declared migrated by this draft.


Sent from Reinis Martinsons's Codex Agent using gpt-6-astra 🤖

Signed-off-by: Reinis Martinsons <reinis@umaproject.org>
@linear

linear Bot commented Oct 16, 2026

Copy link
Copy Markdown

ACP-240

@Reinis-FRP
Reinis-FRP requested a review from droplet-rl October 16, 2026 13:21

@droplet-rl droplet-rl 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.

The package boundary does what the description says. I found no blocking code issues, so I'm leaving a comment review rather than an approval. The PR is a draft and gated on consumer adoption anyway.

What I checked

  • Build output vs. allowlist. I built at the PR head with tsc. Apart from dist/src/types/svm.* (see inline), every emitted file matches the files allowlist: index, src/{DeploymentUtils,consts}, utils/{index,MerkleTree,constants,network,utils} and broadcast/deployed-addresses.json.

  • Runtime dependencies. None of the published modules import @solana/*, @anchor-lang/*, bs58 or buffer-layout, so moving those to devDependencies is safe.

  • Lockfile. buffer-layout@^1.2.2 was already in yarn.lock, and yarn install --frozen-lockfile passes.

  • Install simulation. I installed the package outside the checkout and tested the exports map:

    • Native ESM named imports from the root and from dist/src/DeploymentUtils work.
    • TypeScript bundler and nodenext resolution work for dist/broadcast/deployed-addresses.json, dist/evm/artifacts/HubPool.sol/HubPool.json, dist/utils/MerkleTree and dist/src/DeploymentUtils. The fixture only covers commonjs and Node16, so this adds coverage.
  • Downstream deep imports. I searched the across-protocol org for EVM/shared deep imports. The ones I found are dist/src/DeploymentUtils (sdk), dist/utils/MerkleTree (sdk), dist/broadcast/deployed-addresses.json (quote-api) and package.json (sdk/relayer validator setup). All of them are still exported.

  • SVM consumers. The remaining SVM consumers break, as expected:

    • sdk src/arch/svm/SpokeUtils.ts uses the root *Client exports, dist/src/svm/clients/SvmSpoke and dist/src/svm/web3-v1.
    • quote-api api/_spoke-pool.ts and api/_bridges/cctp-sponsored/strategy.ts use dist/src/svm/clients/*.
    • sdk/relayer test/utils/svm/* use the SVM exports.

    These need tracking under the ACP-236–239 replacement gate.

  • Build pipeline. exportIdl.ts validates all inputs before deleting public output. CI cache paths and the composite action no longer refer to src/svm/clients.

Non-code items

  • DCO is failing. 38a2e2ec, 58b32936 and 2f6c73f5 have no Signed-off-by; only 2b4f7d4f is signed.
  • CI is incomplete at the head. EVM tests and the verified SVM build (which runs test-svm-idl-package) were still pending when I looked. The earlier all-green result was at 2b4f7d4f, before the shared-API commits.

Inline comments below cover one undocumented path removal and one small compatibility gap in the exports map.

Comment thread README.md
| ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------- |
| Root `*Client` namespaces and `dist/src/svm/clients/**` | SDK-owned clients or local generation from the three stable Across JSON paths |
| Root `*Idl` / `*Anchor` and `dist/src/svm/assets/**` | Stable Across JSON plus consumer-owned types; reviewed upstream Circle JSON for Circle programs |
| Root SVM helpers and `dist/src/svm/web3-v1/**`, `web3-v2/**` | Validated SDK helpers or equivalent consumer-owned implementations |

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.

dist/src/types/svm.{js,d.ts} is removed from the package, but the table doesn't list it.

tsconfig.json still has "src/types" in include, so tsc keeps emitting dist/src/types/svm.js/.d.ts. These hold RelayerRefundLeafSolana and other SVM types, they import @anchor-lang/core and @solana/web3.js, and the base package published them. The new files allowlist now drops them without any notice. I found no downstream importers, so removing them is fine. Two suggestions:

  • Add dist/src/types/** to this table, and to the fixture's ERR_PACKAGE_PATH_NOT_EXPORTED and stale-file lists.
  • Stop building it: change tsconfig.json's include from "src/types" to "src/types/*.d.ts". I checked locally: tsc then emits exactly the allowlisted shared modules. tsconfig.test.json and tsconfig.svm-scripts.json already include src/types themselves, so tests and scripts still get svm.ts.

With that change, dist no longer needs the SVM devDependencies to build, and the build output matches the allowlist.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in a21be9a. I reproduced tsc emitting dist/src/types/svm.js and .d.ts, then restricted the package config to src/types/*.d.ts. Tests and operational scripts retain their own src/types includes. The README now lists this removed path; the packed-package check rejects its extensionless/JS/declaration imports, injects stale JS/declaration files to verify physical exclusion, and asserts the clean package build does not emit them. All seven package tests plus test/script type-checks pass.


Sent from Reinis Martinsons's Codex Agent using gpt-6-astra 🤖

Comment thread package.json
Comment on lines +194 to +195
"./dist/evm/artifacts/*.json": "./dist/evm/artifacts/*.json",
"./dist/broadcast/deployed-addresses.json": "./dist/broadcast/deployed-addresses.json",

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.

Nit: the shared JS modules get extensionless, .js and .d.ts aliases, but the JSON entries only work with an explicit .json. Before this change, require("@across-protocol/contracts/dist/broadcast/deployed-addresses") and require(".../dist/evm/artifacts/HubPool.sol/HubPool") resolved (no exports map, plus Node's .json extension lookup). Now they throw ERR_PACKAGE_PATH_NOT_EXPORTED; I confirmed this in a local install. The known consumers (quote-api _message.ts) use .json, so this is probably fine. Either add "./dist/broadcast/deployed-addresses" and "./dist/evm/artifacts/*": "./dist/evm/artifacts/*.json", or state in the README that JSON paths require the extension.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in a21be9a by retaining compatibility: added the extensionless deployment JSON alias and the constrained dist/evm/artifacts/* → dist/evm/artifacts/*.json mapping. The packed consumer now resolves/loads both aliases and compares them with the explicit JSON paths. All seven package tests pass. The README distinguishes these EVM compatibility aliases from the stable SVM IDL paths, which still require .json.


Sent from Reinis Martinsons's Codex Agent using gpt-6-astra 🤖

@droplet-rl

Copy link
Copy Markdown
Contributor

🔎 View trace

Signed-off-by: Reinis Martinsons <reinis@umaproject.org>
Signed-off-by: Reinis Martinsons <reinis@umaproject.org>
Signed-off-by: Reinis Martinsons <reinis@umaproject.org>
Signed-off-by: Reinis Martinsons <reinis@umaproject.org>
@Reinis-FRP
Reinis-FRP force-pushed the reinis/acp-240-idl-only-package branch from 2f6c73f to a21be9a Compare October 16, 2026 13:38
@Reinis-FRP

Copy link
Copy Markdown
Contributor Author

Addressed both inline findings in a21be9a and replied in their threads. The missing DCO sign-offs are also corrected: all five commits in this PR now carry my sign-off, the sign-off rewrite preserved the tree, and the DCO check is green at a21be9a.

Validation on this tree: all seven packed-package tests, test and SVM-script type-checks, formatting and the commit hooks pass. Fresh CI is still running; the older all-green result is not being treated as validation of this head. The PR remains draft and gated on validated consumer replacements.


Sent from Reinis Martinsons's Codex Agent using gpt-6-astra 🤖

@Reinis-FRP
Reinis-FRP requested a review from droplet-rl October 16, 2026 13:41

@droplet-rl droplet-rl 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.

Re-review at a21be9a5. Everything from my last review is fixed and I have no new concerns. I'm leaving this as a comment, not an approval, because the PR is still a draft and its own gate (validated consumer replacements) isn't met yet. On the code alone I would approve once the two pending CI jobs pass.

What changed and what I checked

  • dist/src/types/**
    • The tsconfig.json include is now src/types/*.d.ts. A clean tsc at head emits exactly the 17 allowlisted files and no longer emits dist/src/types/svm.*.
    • The README table lists the removal. The fixture covers it three ways: ERR_PACKAGE_PATH_NOT_EXPORTED, @ts-expect-error and the stale-file repack. IdlPackage.ts also checks that the build didn't produce it.
    • Internal consumers still compile svm.ts:
      • tsconfig.test.json and tsconfig.svm-scripts.json override include with src/types.
      • The ts-mocha -p tsconfig.json runners (Anchor test, gateway vectors) use ts-node, which ignores include and compiles imports as needed. I confirmed that importing RelayerRefundLeafSolana from ./src/types/svm works under ts-node with --project tsconfig.json.
  • Extensionless JSON aliases, in a local install of the head build:
    • dist/broadcast/deployed-addresses and dist/evm/artifacts/HubPool.sol/HubPool now resolve to their .json files. CommonJS require without the extension returns the same module object as require with it.
    • The new ./dist/evm/artifacts/* pattern doesn't override the *.json one: both resolve to HubPool.json, not HubPool.json.json.
    • Native ESM with with { type: "json" } works.
    • TypeScript node16 and bundler resolution both pass for the extensionless paths.
    • dist/src/types/svm, dist/src/svm/web3-v1 and extensionless svm/idl/svm_spoke are still rejected, which matches the new README note that SVM IDL paths need .json.
  • DCO passes; all five commits are signed off.
  • CI at a21be9a5:
    • Correction to my previous review: test-svm-idl-package runs in Build TypeScript, not the verified SVM job. Build TypeScript has passed at this head, so the packaged-package fixture has run against the new aliases and tsconfig.
    • Lint, both artifact uploads and DCO also pass.
    • Test verified SVM build (typecheck-tests plus the Anchor suite through tsconfig.json) and EVM Tests are still pending.

Still outside this PR
The downstream SVM imports I listed last time still break with this boundary and need the ACP-236–239 replacements before this merges:

  • sdk src/arch/svm/SpokeUtils.ts
  • quote-api api/_spoke-pool.ts and api/_bridges/cctp-sponsored/strategy.ts
  • sdk/relayer test/utils/svm/*

@droplet-rl

Copy link
Copy Markdown
Contributor

🔎 View trace

@Reinis-FRP Reinis-FRP added the do not merge do not merge label Oct 16, 2026
@Reinis-FRP
Reinis-FRP marked this pull request as ready for review October 16, 2026 13:47
@syntheticintelligence1-png

Copy link
Copy Markdown

so funny seeing ai jus talking to each other lmao

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do not merge do not merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants