Static analysis linter for GenLayer Intelligent Contracts.
Catch bugs before deploy. Like ESLint, but for GenLayer contracts.
pip install genlayer-linter# Lint a single file
genlayer-lint contract.py
# Lint a directory
genlayer-lint ./contracts/
# Include INFO-level findings
genlayer-lint ./contracts/ --verbose
# JSON output
genlayer-lint contract.py --json
# List all rules
genlayer-lint --list-rules| ID | Rule | Severity | Description |
|---|---|---|---|
| GL001 | public-init | ❌ Error | __init__ must be private (@gl.private) |
| GL002 | assert-in-prod | Don't use assert — use if/raise |
|
| GL003 | missing-payable | ❌ Error | Methods accessing msg.value need @gl.payable |
| GL004 | eval-exec | ❌ Error | eval()/exec() is a security risk |
| GL005 | web-no-error-handling | gl.get_from_web() needs try/except |
|
| GL006 | missing-return-type | ℹ️ Info | Public methods need return type hints |
| GL007 | hardcoded-url | ℹ️ Info | Hardcoded URLs should be configurable |
| GL008 | missing-docstring | ℹ️ Info | Public classes/methods need docstrings |
📄 contracts/weather_bet.py
──────────────────────────────────────────────────
❌ [GL001] contracts/weather_bet.py:5:4: Public __init__ in class `WeatherBet` — must be private
💡 Add @gl.private decorator to __init__
⚠️ [GL002] contracts/weather_bet.py:12:8: assert in production code — disabled with python -O
💡 Replace with: if not condition: raise ValueError('message')
ℹ️ [GL006] contracts/weather_bet.py:18:4: Public method `resolve` missing return type hint
💡 Add return type annotation (e.g., -> dict, -> None)
==================================================
📊 Summary
❌ Errors: 1
⚠️ Warnings: 1
ℹ️ Info: 1
❌ Found 1 error(s) — fix before deploying!
from genlayer_linter import analyze_file, analyze_directory
# Lint a single file
findings = analyze_file("contract.py")
for f in findings:
print(f"{f.severity.value}: {f.message} (line {f.line})")
# Lint a directory
results = analyze_directory("./contracts/")
for filepath, findings in results.items():
print(f"{filepath}: {len(findings)} issues")GenLayer contracts have unique patterns that generic linters don't catch:
__init__must be private (prefixed with_or decorated)- Methods accepting
msg.valuemust be marked@gl.payable assertis dangerous — can be disabled withpython -O- Network calls (
gl.get_from_web()) need error handling - Equivalence principle requires deterministic code paths
This linter catches these issues before you deploy to testnet.
- Python 3.12+
- GenLayer Bradbury Testnet contracts
MIT