Nethermind.Arbitrum.Precompiles
2.0.1
dotnet add package Nethermind.Arbitrum.Precompiles --version 2.0.1
NuGet\Install-Package Nethermind.Arbitrum.Precompiles -Version 2.0.1
<PackageReference Include="Nethermind.Arbitrum.Precompiles" Version="2.0.1" />
<PackageVersion Include="Nethermind.Arbitrum.Precompiles" Version="2.0.1" />
<PackageReference Include="Nethermind.Arbitrum.Precompiles" />
paket add Nethermind.Arbitrum.Precompiles --version 2.0.1
#r "nuget: Nethermind.Arbitrum.Precompiles, 2.0.1"
#:package Nethermind.Arbitrum.Precompiles@2.0.1
#addin nuget:?package=Nethermind.Arbitrum.Precompiles&version=2.0.1
#tool nuget:?package=Nethermind.Arbitrum.Precompiles&version=2.0.1
Nethermind.Arbitrum.Precompiles
Auto-generated .NET ABI metadata for Arbitrum precompiles, regenerated on every PR from a pinned Arbitrum Nitro submodule.
The package exists to remove a single class of bug: ABI drift between Nethermind's .NET Arbitrum implementation and the Solidity interfaces in Nitro. Arbitrum precompiles (ArbSys, ArbGasInfo, ArbOwner, …) are EVM-callable system contracts whose method selectors, event topics, and error selectors are defined upstream in Nitro. Hand-copying these from Foundry artifacts is fragile — a forgotten regeneration after a Nitro bump silently ships stale metadata. This repo's job is to make that bug structurally impossible: bump the submodule pin, CI regenerates, drift is autocommitted (or refused on forks), and the published NuGet always matches its pinned Nitro commit.
How It Works
The repository is a small generator wrapped in a strict CI invariant.
- One generated
.g.csper precompile. Each file (e.g.,Generated/ArbSys.g.cs) exposes nested staticMethods,Functions,Events, andErrorswith constants extracted from the Solidity interface. The library project ships only generated code plus a handful of descriptor types — no runtime logic. - Foundry is the source of truth.
forge buildproduces JSON artifacts from the pinned Nitro submodule; the generator parses them and emits C#. - Hashes are pre-computed at generation time. Event
topic0strings and 4-byte error selectors are baked in via BouncyCastle'sKeccakDigest(256), so the consumer never runs Keccak at startup. - CI enforces the invariant. Every PR runs
make generateand either commits drift back (same-repo PRs) or fails with a hint (fork PRs). Generated files in git always match the pinned Nitro.
The consumer (Nethermind Arbitrum) wires these constants into its own dispatch tables, business logic, and event/error encoding. This package owns ABI metadata; the consumer owns execution.
Architecture
nitro/ (git submodule, pinned commit)
└─ contracts-local/src/precompiles/*.sol
│ forge build
▼
contracts-local/out/precompiles/*.json (Foundry artifacts: abi + methodIdentifiers)
│ dotnet run --project ...Precompiles.Generator
▼
src/Nethermind.Arbitrum.Precompiles/Generated/*.g.cs (committed)
│ dotnet pack
▼
Nethermind.Arbitrum.Precompiles (NuGet)
Three projects in one solution:
Nethermind.Arbitrum.Precompiles— published library:Generated/*.g.csplus descriptor types (AbiType,FunctionDescriptor,EventDescriptor,ErrorDescriptor).Nethermind.Arbitrum.Precompiles.Generator— console tool: reads Foundry artifacts, emits C#.Nethermind.Arbitrum.Precompiles.Test— test suite over the artifact reader, descriptor types, and generated output.
Local Development
Prerequisites: .NET SDK 10.0.100, Foundry on PATH, initialized Nitro submodule.
git submodule update --init --recursive
make generate # forge build → run C# generator
dotnet test src/Nethermind.Arbitrum.Precompiles.slnx
make help lists every target. make clean removes the generated .g.cs files; make build runs only the Foundry compile step.
Bumping Nitro
- Update the
nitro/submodule to the desired Nitro commit. - Run
make generatelocally and inspect the diff underGenerated/. - Open a PR. CI will autocommit the regenerated files if you skip step 2 (same-repo PRs only).
CI Workflows
The pipeline is split across four workflow files. Three are event-triggered; one is a reusable workflow consumed by the others via workflow_call to keep build/test logic in a single place.
| Workflow | Trigger | Purpose |
|---|---|---|
pr.yaml |
pull_request |
Regenerate classes; autocommit drift on same-repo PRs, fail with hint on fork PRs; then build + test |
main.yaml |
push to main |
Post-merge build + test sanity check |
build-test.yaml |
workflow_call |
Shared dotnet restore → build → test; consumed by the other three |
release.yaml |
workflow_dispatch |
Gated NuGet publish against a v* tag |
Two quirks worth knowing:
- Autocommit doesn't re-trigger workflows. The bot uses
GITHUB_TOKEN, which GitHub deliberately suppresses to break recursion loops. After an autocommit, theBuild and testcheck ran against the previous HEAD — click "re-run" in the UI to validate the post-autocommit commit before merging. - The required check name is compound. Because
pr.yaml'sbuild-testjob invokesbuild-test.yamlviaworkflow_call, GitHub posts the check asBuild and test / Build and test. Branch rulesets must use the compound name verbatim.
Releases
Releases are deliberate, not automatic.
- Tag a commit on
mainasvX.Y.Z. - Manually dispatch the Release workflow against that tag, choosing Staging or Production.
- The
guardjob refuses any non-refs/tags/v*ref; the version comes from the tag;dotnet packproduces.nupkg+.snupkg;dotnet nuget push --skip-duplicatemakes re-runs safe; a GitHub Release is created automatically.
| Choice | Feed | Secret |
|---|---|---|
| Staging | apiint.nugettest.org |
NUGETTEST_API_KEY |
| Production | api.nuget.org |
NUGET_API_KEY |
Consumer Usage
dotnet add package Nethermind.Arbitrum.Precompiles
Everything is a static constant under the Nethermind.Arbitrum.Precompiles.Solgen namespace.
using Nethermind.Arbitrum.Precompiles.Solgen;
uint selector = ArbSys.Methods.ArbBlockNumber; // 0xa3b1b31d
string topic0 = ArbSys.Events.L2ToL1Tx.Topic0Hex; // 0x3e7aafa7…
uint errorSel = ArbSys.Errors.InvalidBlockNumber.Selector; // 0xd5dc642d
string abiJson = ArbSys.Abi;
string nitro = ArbSys.NitroCommit;
foreach (string name in AllPrecompiles.Names) { /* … */ }
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.