feat: add Fe language support for smart contract verification#2692
feat: add Fe language support for smart contract verification#2692
Conversation
Adds compilation and verification support for the Fe programming language (argotorg/fe). Fe compiles via a CLI binary with no standard-JSON interface, outputs plain hex bytecode files, and embeds no CBOR metadata — so verification is always partial (bytecode match only). Key changes: - AuxdataStyle.FE in bytecode-utils (no-op splitAuxdata) - FeTypes (FeJsonInput, FeOutput, FeOutputContract) in compilers-types - useFeCompiler in compilers: downloads binary from GitHub releases, scaffolds a unique temp ingot dir, runs `fe build`, reads .bin outputs - FeCompilation class extending AbstractCompilation - CompilationLanguage union extended with 'Fe', IFeCompiler interface added - PreRunCompilation, AbstractCompilation, Verification updated for Fe Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Tests cover: bytecode correctness, empty CBOR auxdata positions, empty link/immutable references, version stripping, and compiler errors. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add FeLocal compiler wrapper - Wire Fe compiler through CLI, Server, VerificationService, and worker - Add 'Fe' case to createCompilationFromJsonInput - Update type unions (workerTypes, handlers, middlewares) to include FeJsonInput - Update getCompilerNameFromLanguage and createPreRunCompilationFromStoredCandidate for Fe - Add FeJsonInput to AnyJsonInput in compilers-types Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Update language enum to include 'Fe' - Update endpoint description to mention Fe - Add Fe contract example to StdJSONVerificationRequest Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…zation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rification tests - Remove FeSettings (no configurable fields in Fe alpha); add adapted-interface doc comment to FeTypes.ts explaining Fe has no official std-JSON I/O - Fix FeCompilation bytecodes to include 0x prefix (required for on-chain comparison) - validateAndNormalizeFeInput: reject bare contract names without path - Skip storeSignatures for Fe contracts (Fe emits no ABI) - New FeVerification.spec.ts: deploy + verify single-file and multi-file ingots on local hardhat - New verify.fe.spec.ts: e2e server API tests for Fe verification (single-file + multi-file) - Add deployFeContract helper to test utils - Add ServerFixture Fe compiler support + test/sources/fe fixtures Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Automatically runs ESLint --fix and Prettier on staged files before every commit. Applies to all developers and Claude instances after npm install. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix prettier formatting on feCompiler.ts, AbstractCompilation.ts, FeVerification.spec.ts, middlewares.ts, FeLocal.ts, ServerFixture.ts - Add feRepoPath to VerificationService unit test options (TS error) - Cast jsonInput.settings to VyperSettings in EtherscanVerifyApiService test to fix TS error introduced by settings union type change - Add Fe fields lookup + direct DB query test in verify.fe.spec.ts: asserts abi/storageLayout/devdoc/userdoc null, language/compiler/ compilerSettings/fullyQualifiedName correct after Fe verification Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… fields Add creationBytecode to API fields, assert runtimeMatch/creationMatch, and check all creation_code_artifacts/runtime_code_artifacts columns (sourceMap, linkReferences, immutableReferences, cborAuxdata) plus compilation_artifacts.transientStorageLayout and .sources in the direct DB query, matching the full compiled_contracts table breakdown. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
How a Fe contract is stored in
|
| Column | Value | Description |
|---|---|---|
language |
"fe" |
Lowercased from "Fe" |
compiler |
"fe" |
Fe CLI compiler |
version |
"26.0.0-alpha.10" |
Compiler version as passed in the request |
name |
"Counter" |
Contract name from contractIdentifier |
fully_qualified_name |
"src/lib.fe:Counter" |
Full path:name from contractIdentifier |
compiler_settings |
{} |
Fe alpha has no configurable settings |
compilation_artifacts |
{"abi": null, "userdoc": null, "devdoc": null, "storageLayout": null, "transientStorageLayout": null, "sources": null} |
Fe does not emit ABI, NatSpec, storage layouts, or source IDs |
creation_code_artifacts |
{"sourceMap": null, "linkReferences": null, "cborAuxdata": {}} |
Fe emits no source maps, has no library linking, and embeds no CBOR metadata |
runtime_code_artifacts |
{"sourceMap": null, "linkReferences": null, "immutableReferences": null, "cborAuxdata": {}} |
Same as creation, plus no immutables |
Match type: always "match" (partial) for both creation and runtime. Fe embeds no CBOR metadata in its bytecode, so there is no metadata hash to achieve an exact/perfect match.
All of the above is verified by "should store and return correct Fe-specific fields after verification" in services/server/test/integration/apiv2/verification/verify.fe.spec.ts, which checks every field in this table through two layers:
- API response —
GET /v2/contract/:chainId/:address?fields=compilation,abi,metadata,storageLayout,sources,creationBytecode,runtimeBytecode - Direct DB query — raw
compiled_contractsrow viaserverFixture.sourcifyDatabase
|
Very nice! I'll prioritize a few things so that we can close some gaps (Most importantly the missing JSON ABI) |
feRepo was missing from default, master, staging, and migration configs.
config.get("feRepo") throws at startup if the key is absent, so the
server would crash on launch. Matches the same pattern as vyperRepo.
Also scope lint-staged ESLint to *.ts only, matching the existing
check:eslint script (--ext .ts), so CommonJS .js config files are
not incorrectly linted.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
manuelwedler
left a comment
There was a problem hiding this comment.
Nice! Much more straight forward than I thought.
No major issues with the PR. Just some improvements that could be done.
Also, if we can have the ABI support by next week, I would wait for it to merge this PR.
| summary: Verify Contract (Standard JSON) | ||
| description: |- | ||
| Submit a contract for verification via the [Solidity standard JSON input](https://docs.soliditylang.org/en/latest/using-the-compiler.html#input-description) or [Vyper JSON input](https://docs.vyperlang.org/en/stable/compiling-a-contract.html#input-json-description). | ||
| Submit a contract for verification via the [Solidity standard JSON input](https://docs.soliditylang.org/en/latest/using-the-compiler.html#input-description), [Vyper JSON input](https://docs.vyperlang.org/en/stable/compiling-a-contract.html#input-json-description), or Fe JSON input (a Sourcify-defined format — Fe has no official compiler JSON interface). |
There was a problem hiding this comment.
Not part of this PR, but we should add a docs page for Fe support and especially describe how the json input should be created for a Fe contract.
There was a problem hiding this comment.
We don't have docs pages for other languages. Isn't the example here enough?
There was a problem hiding this comment.
yeah, probably it's enough. Some note somewhere that we support Fe would still be good. We list languages on the intro page, maybe just add it there.
Co-authored-by: Manuel Wedler <manuel@wedler.dev>
Co-authored-by: Manuel Wedler <manuel@wedler.dev>
6f67f1b to
b8936e8
Compare
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
b8936e8 to
4208d38
Compare
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The feRepo key is defined in default.js, so config.has() checks are redundant. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Tests platform detection, executable fetching, single/multi-file compilation, and error handling. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the dedicated verify.fe.spec.ts with JSON test case files in the standardized verification-cases infrastructure. This gives Fe the same thorough DB and API assertions as Solidity and Vyper tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
The Blockscout scraping test is failing which will be removed in #2672 |
|
@kuzdogan lib-sourcify tests also fail: |
FeJsonInput requires a `settings` property (Record<string, never>). The tests were missing it, causing TS2345 compilation errors. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
@manuelwedler fixed |
manuelwedler
left a comment
There was a problem hiding this comment.
Looks good to me! thanks for the changes.
@cburgdorf What's the status on the ABI output? Would still prefer to have it before a Sourcify release of this.
It was merged and will be included in the next release. I'm currently off but I can try to coordinate with the team to cut a new alpha release so you can test out the integration. |
|
You can run |
Awesome! Thanks for this! @kuzdogan let's update this PR and make the new release the minimum supported Fe version. We can also remove the assumption that abi can be null from the code. |
Summary
feCompiler.ts): downloads Fe binary per-version, scaffolds ingot project structure (fe.toml+src/), runsfe build, readsout/*.bin/out/*.runtime.binFeCompilationclass: extendsAbstractCompilation;AuxdataStyle.FE(no CBOR metadata → always partial match); no ABI/immutables/librariesFeLocalcompiler, Piscina worker support,compilation.tsanddatabase-util.tsFe casesvalidateAndNormalizeFeInput): normalizes source keys tosrc/prefix, validatescontractIdentifierformat (src/path.fe:Namerequired)contractIdentifierformat docsFeCompilation.spec.ts(6 unit tests),FeVerification.spec.ts(3 verification tests on local hardhat),verify.fe.spec.ts(2 server e2e tests)API usage
Single-file:
Multi-file ingot (contract in non-
lib.fefile):{ "contractIdentifier": "src/counter.fe:Counter", "stdJsonInput": { "language": "Fe", "sources": { "src/lib.fe": { "content": "use ingot::counter::Counter" }, "src/counter.fe": { "content": "pub contract Counter { ... }" } } } }Sources without
src/prefix are automatically normalized. Match is always partial (Fe emits no CBOR metadata hash).Test plan
cd packages/lib-sourcify && npm test— 150 tests passing (includes 6 FeCompilation + 3 FeVerification)cd services/server && npm run test-local— full integration suite/v2/verifywith a deployed Fe contractTODOs
🤖 Generated with Claude Code