Skip to content
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
ad8e096
feat: add FlashblockIndex contract
xenoliss Mar 3, 2026
ca8553c
refactor: make FlashblockIndex upgradeable and emit FlashblockIndexUp…
xenoliss Mar 3, 2026
a0a7b8c
feat: setup rust bindings crate
xenoliss Mar 3, 2026
9d223e5
refactor: move bindings into bindings/go and bindings/rust
xenoliss Mar 4, 2026
364e9ce
chore: strip binding artifacts and add justfile recipes for bindings
xenoliss Mar 4, 2026
de2e8ee
chore: update semver-lock snapshot
xenoliss Mar 4, 2026
6097477
fix: use robust PascalCase to snake_case conversion in bindings-add
xenoliss Mar 5, 2026
5ee149c
chore: remove Cargo.lock from library crate
xenoliss Mar 5, 2026
cc50730
chore: add CI step to verify Rust bindings compile
xenoliss Mar 5, 2026
a460315
chore: minor change + cleaning
xenoliss Mar 17, 2026
6dcf6aa
chore: remove FlashblockIndex contract
xenoliss Mar 17, 2026
7f575f7
chore: regenerate snapshots
xenoliss Mar 17, 2026
2274336
chore: fix snapshots/semver-lock.json
xenoliss Mar 17, 2026
9b2f9f2
chore: remove go bindings
xenoliss Mar 17, 2026
221e08b
refactor: switch Rust bindings generation to forge bind and remove Go…
xenoliss Mar 17, 2026
69d1c8e
chore: regenerate rust bindings
xenoliss Mar 18, 2026
5c18fc9
chore: add rust bindings CI debug logging
xenoliss Mar 18, 2026
a2db6be
chore: add targeted CI debug logging for rust bindings
xenoliss Mar 19, 2026
670da1e
chore: inline rust bindings CI debug step
xenoliss Mar 19, 2026
c6d34c6
chore: split rust bindings CI debug steps
xenoliss Mar 19, 2026
170a8db
chore: force rust bindings overwrite in CI debug step
xenoliss Mar 19, 2026
106c17a
chore: add rust bindings CI artifact diagnostics
xenoliss Mar 19, 2026
930bf8f
fix: hash CI artifact metadata as JSON
xenoliss Mar 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ jobs:
just semver-lock-no-build
git diff --exit-code snapshots/semver-lock.json

- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- name: Check Rust bindings
run: just bindings-check

- name: Run Forge tests
run: just test
id: test
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Artifacts and Cache
artifacts
!bindings/rust/artifacts/
forge-artifacts
target
Cargo.lock
cache
broadcast
kout-proofs
Expand Down
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion bindings/go.mod → bindings/go/go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/base/contracts/bindings
module github.com/base/contracts/bindings/go

go 1.23.0

Expand Down
File renamed without changes.
8 changes: 8 additions & 0 deletions bindings/rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "base-contracts-bindings"
version = "0.1.0"
edition = "2021"

[dependencies]
alloy-contract = "1.5.0"
alloy-sol-types = { version = "1.5.0", features = ["json"] }
1 change: 1 addition & 0 deletions bindings/rust/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

84 changes: 83 additions & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,72 @@ snapshots-no-build: snapshots-abi-storage-no-build semver-lock-no-build
snapshots: build-source snapshots-no-build



########################################################
# BINDINGS #
########################################################

# Adds a new Rust binding for a Solidity contract.
# Usage: just bindings-add src/L2/FlashblockIndex.sol
bindings-add SOL_PATH: build-source
#!/bin/bash
set -euo pipefail

sol_path="{{SOL_PATH}}"

# Extract contract name (e.g. FlashblockIndex from src/L2/FlashblockIndex.sol)
contract=$(basename "$sol_path" .sol)

# Extract module (e.g. l2 from src/L2/FlashblockIndex.sol)
module=$(echo "$sol_path" | sed 's|^src/||' | xargs dirname | tr '[:upper:]' '[:lower:]')

# Convert PascalCase to snake_case by inserting _ at lower|upper and acronym|word boundaries
snake=$(echo "$contract" | sed -E 's/([a-z0-9])([A-Z])/\1_\2/g' | sed -E 's/([A-Z]+)([A-Z][a-z])/\1_\2/g' | tr '[:upper:]' '[:lower:]')

rust_dir="bindings/rust/src/${module}"
rust_file="${rust_dir}/${snake}.rs"
mod_file="${rust_dir}/mod.rs"
artifact="bindings/rust/artifacts/${contract}.json"

# Ensure output directories exist before writing generated files.
mkdir -p "bindings/rust/artifacts" "$rust_dir"

# 1. Strip artifact
jq '{abi, bytecode: {object: .bytecode.object}, deployedBytecode: {object: .deployedBytecode.object}}' \
"forge-artifacts/${contract}.sol/${contract}.json" > "$artifact"

# 2. Create .rs file
cat > "$rust_file" << EOF
use alloy_sol_types::sol;

sol!(
#[sol(rpc, abi)]
${contract},
concat!(
env!("CARGO_MANIFEST_DIR"),
"/artifacts/${contract}.json"
)
);
EOF

# 3. Add to mod.rs (skip if already present)
if ! grep -q "mod ${snake};" "$mod_file" 2>/dev/null; then
echo "" >> "$mod_file"
echo "mod ${snake};" >> "$mod_file"
echo "pub use ${snake}::${contract};" >> "$mod_file"
fi

# 4. Add module to lib.rs (skip if already present)
if ! grep -q "pub mod ${module};" "bindings/rust/src/lib.rs" 2>/dev/null; then
echo "pub mod ${module};" >> "bindings/rust/src/lib.rs"
fi

# 5. Format generated code
cd bindings/rust && cargo fmt

echo "Added binding: ${contract} -> ${rust_file}"


########################################################
# CHECKS #
########################################################
Expand All @@ -232,6 +298,21 @@ snapshots-check-no-build: snapshots-no-build
# Checks if the snapshots are up to date.
snapshots-check: build snapshots-check-no-build

# Checks that the Rust bindings crate compiles.
bindings-check:
cd bindings/rust && cargo check

# Checks that committed Rust binding artifacts match forge-artifacts.
bindings-artifacts-check-no-build:
#!/bin/bash
set -euo pipefail
for src in bindings/rust/artifacts/*.json; do
name=$(basename "$src" .json)
jq '{abi, bytecode: {object: .bytecode.object}, deployedBytecode: {object: .deployedBytecode.object}}' \
"forge-artifacts/${name}.sol/${name}.json" > "$src"
done
git diff --exit-code bindings/rust/artifacts/

# Checks interface correctness without building.
interfaces-check-no-build:
go run ./scripts/checks/interfaces
Expand Down Expand Up @@ -338,7 +419,8 @@ check:
validate-spacers-no-build \
reinitializer-check-no-build \
interfaces-check-no-build \
lint-forge-tests-check-no-build
lint-forge-tests-check-no-build \
bindings-artifacts-check-no-build

########################################################
# DEV TOOLS #
Expand Down
Loading
Loading