CI & Dev Loops
End-to-end guidance for running the Stylus-first shim workflow in continuous integration and during local development. Scope is limited to section’s precompile shims and reseeding/validation flow (no VM precompile injection).
Objective
- Provide reproducible validation of ArbSys (
0x…64) and ArbGasInfo (0x…6c) during builds. - Prefer Stylus gas data when a public RPC is reachable; otherwise fall back to project configuration or a safe default.
 - Keep executions hermetic within Hardhat; shim mode is sufficient.
 
Prerequisites
- 
Node.js ≥ 18 (global
fetch) and a recent Hardhat. - 
Tasks and scripts present in the project (or exposed by the plugin):
arb:reseed-shimsscripts/predeploy-precompiles.jsscripts/check-gasinfo-local.jsscripts/validate-precompiles.js
 - 
Optional public Stylus RPC for live reseed:
https://sepolia-rollup.arbitrum.io/rpc(subject to rate limits)
 
Common environment variables:
STYLUS_RPC— remote source of gas prices (preferred)NITRO_RPC— optional compatibility sourceARB_PRECOMPILES_CONFIG— path override to JSON configNODE_OPTIONS=--dns-result-order=ipv4first— prefer IPv4 resolutionNODE_NO_HTTP2=1— disable HTTP/2 negotiation (stability on some runners)
CI blueprint
Deterministic mode (no network dependency)
Purpose: fully offline, reproducible runs. Gas tuple is read from precompiles.config.json.
Steps
- Start a persistent Hardhat node on a fixed port (e.g., 8549).
 - Predeploy shim bytecode at the canonical addresses.
 - Reseed from project config (no 
STYLUS_RPC). - Validate using the provided scripts.
 
Command sketch
# start node (background)
npx hardhat node --port 8549 &
# predeploy shims
npx hardhat --config hardhat.config.js run --network localhost scripts/predeploy-precompiles.js
# reseed from config (no RPC flags)
npx hardhat --config hardhat.config.js arb:reseed-shims --network localhost
# validations
npx hardhat --config hardhat.config.js run --network localhost scripts/check-gasinfo-local.js
npx hardhat --config hardhat.config.js run --network localhost scripts/validate-precompiles.js
Pass criteria
- 
check-gasinfo-local.jsprints a 6-value tuple from configuration. - 
validate-precompiles.jsprints:ArbSys arbChainID returned: 42161(or configured chainId)ArbGasInfo getL1BaseFeeEstimate returned: …- Contract calls complete; 
getCurrentTxL1GasFeesmirrors the estimate in shim mode. 
 
Live Stylus mode (optional network dependency)
Purpose: align the local tuple with a live Stylus testnet.
Steps
- Export network tuning flags to improve fetch stability on CI runners.
 - Start a persistent Hardhat node.
 - Predeploy shims.
 - Reseed with 
--stylus(source isSTYLUS_RPCor configuredstylusRpc). - Validate.
 
Command sketch
export NODE_OPTIONS=--dns-result-order=ipv4first
export NODE_NO_HTTP2=1
export STYLUS_RPC=https://sepolia-rollup.arbitrum.io/rpc
npx hardhat node --port 8549 &
npx hardhat --config hardhat.config.js run --network localhost scripts/predeploy-precompiles.js
npx hardhat --config hardhat.config.js arb:reseed-shims --network localhost --stylus
npx hardhat --config hardhat.config.js run --network localhost scripts/check-gasinfo-local.js
npx hardhat --config hardhat.config.js run --network localhost scripts/validate-precompiles.js
Pass criteria Same as deterministic mode; the tuple should reflect live network values.
GitHub Actions example (minimal)
name: shim-validate
on:
  push:
    branches: [ main ]
  pull_request:
jobs:
  validate:
    runs-on: ubuntu-latest
    env:
      NODE_OPTIONS: --dns-result-order=ipv4first
      NODE_NO_HTTP2: 1
      # Set to enable live Stylus reseed; omit for deterministic mode
      # STYLUS_RPC: https://sepolia-rollup.arbitrum.io/rpc
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - name: Start hardhat node
        run: npx hardhat node --port 8549 &
      - name: Predeploy shims
        run: npx hardhat --config hardhat.config.js run --network localhost scripts/predeploy-precompiles.js
      - name: Reseed (Stylus if STYLUS_RPC set; else config)
        run: |
          if [ -n "${STYLUS_RPC}" ]; then
            npx hardhat --config hardhat.config.js arb:reseed-shims --network localhost --stylus
          else
            npx hardhat --config hardhat.config.js arb:reseed-shims --network localhost
          fi
      - name: Readback tuple
        run: npx hardhat --config hardhat.config.js run --network localhost scripts/check-gasinfo-local.js
      - name: Validate probe
        run: npx hardhat --config hardhat.config.js run --network localhost scripts/validate-precompiles.js
Notes: secret RPC endpoints (if used) should be stored as repository or environment secrets and mapped to STYLUS_RPC.
Local developer loop
Two patterns are typical.
In-process (single command run)
Suitable for quick smoke checks. The one-shot installer can predeploy and verify within the same Hardhat process:
npx hardhat --config hardhat.config.js run scripts/install-and-check-shims.js
5.2 Persistent node (recommended for iteration)
# Terminal A
npx hardhat node --port 8549
# Terminal B
export NODE_OPTIONS=--dns-result-order=ipv4first
export NODE_NO_HTTP2=1
export STYLUS_RPC=https://sepolia-rollup.arbitrum.io/rpc
npx hardhat --config hardhat.config.js run --network localhost scripts/predeploy-precompiles.js
npx hardhat --config hardhat.config.js arb:reseed-shims --network localhost --stylus
npx hardhat --config hardhat.config.js run --network localhost scripts/check-gasinfo-local.js
npx hardhat --config hardhat.config.js run --network localhost scripts/validate-precompiles.js
Build artifacts and logs
- 
Reseed logs indicate the chosen source and resulting tuple:
ℹ️ fetched from Stylus: […]ℹ️ using JSON/config (shim order): […]ℹ️ using plugin fallback: […]
 - 
Validation logs include:
- Detected handlers and addresses
 - Raw precompile call results
 - Contract deployment address
 - Contract call outcomes
 
 
Persisting these logs in CI as workflow artifacts is recommended for traceability.
Failure modes & mitigation
| Symptom | Likely cause | Mitigation | 
|---|---|---|
HH108: Cannot connect to the network localhost | Hardhat node not running on expected port | Start npx hardhat node --port 8549; confirm networks.localhost.url matches the port | 
RPC fetch failed … during reseed | Public RPC blocked, DNS/HTTP2 issues | Export NODE_OPTIONS=--dns-result-order=ipv4first and NODE_NO_HTTP2=1; retry; fall back to config | 
ArbGasInfoShim not installed … | Predeploy step skipped | Run scripts/predeploy-precompiles.js or the one-shot installer | 
Tuple readback fails (e.g., 0x/decode error) | Querying the wrong chain/port | Point the provider at the Hardhat node that hosts the shim | 
getCurrentTxL1GasFees differs from expectation | Shim mode maps to slot 1 (estimate) by design | Behavior is intentional to guarantee deterministic tests | 
Security & hygiene
- Public RPC endpoints may rate-limit; deterministic mode avoids non-determinism.
 - Secrets for private RPCs belong in CI secret storage and must not be committed.
 - Console logs should avoid leaking credentialed endpoints.
 
Optional extensions
- A local cache file (e.g., 
.cache/stylus-prices.json) can be written after a successful live reseed and used as a high-priority offline source. - A scheduled job can periodically refresh the cache to keep default shim tuples aligned with the testnet.