The problem
Your CI pipeline deploys to Base mainnet at 11 PM. Gas is 10x normal. You burn $200 in fees. Nobody noticed until the gas bill arrived.
This actually happened during Base's gas spike in May 2024, when prices hit 0.5 Gwei — 83x the normal rate. Teams without a gas gate in CI deployed contracts and paid hundreds in unnecessary fees.
The solution: l2gas
npx @psicossz/l2gas
No installation required. Zero dependencies. Just Node 18+.
╔══════════════════════════════════════════════════════════════╗
║ ⚡ L2GAS v1.1.0 | REAL-TIME L2 GAS & TRANSFER COSTS ║
╚══════════════════════════════════════════════════════════════╝
Chain Tech Gas (Gwei) Transfer ($) Block
──────────────────────────────────────────────────────────────────
Base OP Stack 0.006 Gwei $0.000315 #52066208
Arbitrum One Nitro 0.020 Gwei $0.001057 #510900717
Optimism OP Stack 0.001 Gwei $0.000053 #157661493
Polygon PoS PoS 304.3 Gwei $0.002556 #94811082
Linea zkEVM 0.263 Gwei $0.013839 #32207812
Scroll zkEVM 0.0001 Gwei $0.000006 #35249012
zkSync Era zkRollup 0.045 Gwei $0.002376 #72300380
──────────────────────────────────────────────────────────────────
All 7 chains queried in parallel in under 2 seconds, directly from public RPC endpoints — no API key, no rate limits, no third-party service.
Add it to your GitHub Actions pipeline
The --threshold flag exits with code 1 if any chain exceeds the Gwei limit, which natively blocks a CI step:
# .github/workflows/deploy.yml
jobs:
gas-check:
runs-on: ubuntu-latest
steps:
- name: Check gas before deploying
run: npx @psicossz/l2gas base arbitrum --threshold=0.05
# Exit code 1 = gas too high = deploy blocked automatically
deploy:
needs: gas-check # Won't run if gas-check fails
runs-on: ubuntu-latest
steps:
- run: echo "Gas OK — deploying to Base mainnet..."
Or use the reusable workflow for a cleaner setup:
jobs:
gas-check:
uses: psicossz29-netizen/l2gas-cli/.github/workflows/l2gas-check.yml@main
with:
chains: 'base arbitrum'
max-gwei: '0.05'
fail-on-exceed: true
deploy:
needs: gas-check
if: needs.gas-check.outputs.gas-ok == 'true'
runs-on: ubuntu-latest
steps:
- run: echo "Deploying..."
Use it as a library too
npm install @psicossz/l2gas
const { getChainGas, getAllChainsGas } = require('@psicossz/l2gas');
// Single chain
const base = await getChainGas('base');
console.log(base.gasPriceGwei); // 0.006
console.log(base.transferCostUsd); // 0.000315
// All chains in parallel
const all = await getAllChainsGas();
// Specific chains
const subset = await getAllChainsGas(['base', 'arbitrum', 'optimism']);
JSON output for scripting
l2gas --json | jq '.chains[] | select(.gasPriceGwei > 0.1)'
{
"version": "1.1.0",
"timestamp": "2026-10-02T06:00:00.000Z",
"chains": [
{
"chain": "Base",
"chainId": 8453,
"layer": "OP Stack",
"gasPriceGwei": 0.006,
"transferCostUsd": 0.000315,
"blockNumber": 52066208,
"status": "ONLINE"
}
]
}
Watch mode
l2gas --watch # Refreshes every 30 seconds
l2gas base --watch # Watch a single chain
How it works internally
The interesting part: it uses zero npm dependencies. The entire implementation relies on:
-
fetch()(native, Node 18+) for RPC calls -
AbortSignal.timeout(8000)for per-chain timeouts -
Promise.all()for parallel querying -
BigIntarithmetic for precise Wei calculations
// Core logic — this is really all it takes
async function getChainGas(chainKey) {
const [gasPriceHex, block] = await Promise.all([
rpcFetch(config.rpc, 'eth_gasPrice'),
rpcFetch(config.rpc, 'eth_getBlockByNumber', ['latest', false])
]);
const gasPriceWei = BigInt(gasPriceHex);
const transferCostWei = gasPriceWei * 21000n;
const transferCostUsd = (Number(transferCostWei) / 1e18) * ETH_PRICE_USD;
return { gasPriceGwei: Number(gasPriceWei) / 1e9, transferCostUsd };
}
Supported chains (v1.1.0)
| Chain | Tech | ChainId | RPC |
|---|---|---|---|
| Base | OP Stack | 8453 | mainnet.base.org |
| Arbitrum One | Nitro | 42161 | arb1.arbitrum.io/rpc |
| Optimism | OP Stack | 10 | mainnet.optimism.io |
| Polygon PoS | PoS | 137 | polygon-bor-rpc.publicnode.com |
| Linea | zkEVM | 59144 | rpc.linea.build |
| Scroll | zkEVM | 534352 | rpc.scroll.io |
| zkSync Era | zkRollup | 324 | mainnet.era.zksync.io |
Install
# Global CLI
npm install -g @psicossz/l2gas
# No install (latest version always)
npx @psicossz/l2gas
# As a library
npm install @psicossz/l2gas
GitHub: psicossz29-netizen/l2gas-cli
npm: @psicossz/l2gas
If it saves you from a gas spike disaster, a ⭐ on the repo goes a long way 🙏
Next version (v1.2.0): --alert flag to send a Slack/Discord/Telegram webhook when gas drops below your threshold — so your pipeline can auto-resume when conditions are right.
Top comments (0)