shuka

About
shuka is a CLI tool for fetching verified smart contract source code from blockchain explorers and saving the full source tree locally.
It is built for workflows where manually copying verified source files from explorer pages is slow, repetitive, and error-prone.
The project keeps explorer-specific fetching, parsing, and filesystem storage separated so new explorers can be added without rewriting the whole pipeline.
Features
- Fetch verified smart contract source code by address.
- Save raw explorer responses for inspection.
- Save single-file and multi-file Solidity source trees.
- Keep explorer-specific API logic separate from parsing and storage.
Supported Explorers
| Explorer | Network | API key | Chain ID |
|---|---|---|---|
| Etherscan | Ethereum Mainnet | Required | Required |
| Battlechain | Battlechain Testnet | Not required | Not required |
Installation
Prerequisites
Install Rust and Cargo:
|
Check installation:
Install from source
Install with Cargo
Configuration
Ethereum / Etherscan v2
Ethereum uses the Etherscan v2 API and requires an API key.
Create a local .env file:
ETHEREUM_API_KEY=your_key_here
Ethereum also requires --chain-id. For Ethereum Mainnet, use:
--chain-id 1
Battlechain Testnet
Battlechain does not require:
- API key
- chain id
Usage


Fetch an Ethereum contract:
Fetch a Battlechain contract:
Choose an output directory:
Print the optional banner:
By default, output is written to:
contracts/<explorer>/<address>/
Each output directory contains:
raw_response.json- extracted source files
Architecture
shuka is intentionally organized as a small pipeline where each stage has one responsibility.
The project follows a simple pipeline:
FetchRequest
-> Explorer Adapter
-> RawExplorerResponse
-> Parser
-> ParsedSourceBundle
-> Storage
-> SaveResult
-> FetchOutcome
Module responsibilities:
- CLI parses arguments, builds
FetchRequest, and displays results. - App orchestrates the pipeline.
- Explorer adapters contain API-specific fetch logic.
- Parser transforms raw explorer responses into normalized source files.
- Storage writes files to disk and validates source paths.
- Types define shared data models.
- Error defines the unified project error type.
Important boundaries:
- Explorer adapters should not parse source files.
- Parser should not write files.
- Storage should not know explorer API details.
- CLI should stay thin.
Adding Another Explorer
Adding a new explorer usually means:
- document the API behavior
- add explorer enum support
- implement a
SourceExploreradapter - register the adapter in the app layer
- test raw response saving
- update parser logic only if the raw response shape differs
See docs/adding-another-explorer.md for the full checklist.
Parser Notes
The current parser handles Etherscan-like response envelopes and supports:
- plain Solidity source
- structured multi-file source
If a new explorer fails to parse but raw_response.json is saved correctly, the fix usually belongs in the parser, not in the explorer adapter or storage layer.
Full instructions 👉 docs/parser-notes.md