This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
A cross-platform (Mac/Windows) desktop application to export ERC-20 token transactions from Etherscan to Excel files.
- Python 3.11+ - Primary language
- ttkbootstrap - GUI framework (modern Tkinter)
- openpyxl - Excel file handling
- requests - HTTP client for API calls
- PyInstaller - Packaging for distribution
# Create virtual environment
python3 -m venv venv
# Activate (Mac/Linux)
source venv/bin/activate
# Activate (Windows)
# venv\Scripts\activate
# Install dependencies
pip install -r requirements.txtcd src
python main.pypip install pyinstaller
cd src
pyinstaller --onefile --windowed --name "WalletExporter" main.pysrc/api/etherscan.py - API client for Etherscan v2 API
EtherscanClient: Handles all API communication with built-in rate limiting (250ms between requests = 4 req/sec)get_erc20_transactions(): Fetches paginated ERC-20 token transfers with optional timestamp filtering_format_transaction(): Converts raw API response to export-ready dictionary- Uses
EtherscanAPIErrorfor API-specific errors - Pagination: v2 API constraint is
page * offset <= 10000, uses 1000 results per page
src/export/xlsx_handler.py - Excel file operations
XlsxHandler: Creates/updates Excel files with proper formattingHEADERS: Defines 11 column output format (see Data Format below)create_new_file(): Creates new file with headers and column widthsappend_transactions(): Adds new rows without modifying existing data- Preserves formatting: frozen header row, bold headers, fixed column widths
- Use
openpyxlto read/write, always write values-only when appending
src/gui/app.py - User interface with ttkbootstrap
WalletExporterApp: Main window managing all UI components- Uses threading (
threading.Thread) for long operations to keep UI responsive Configclass saves/loads user settings (API key, wallet list)- Batch mode: stores wallet list as
[(address, file_path, selected_var), ...] - Date filtering:
get_date_range_blocks()converts date range to Unix timestamps - Disables export button during processing to prevent double-clicks
- Shows progress updates via callback from API client
src/utils/helpers.py - Utility functions
validate_eth_address(): Validates Ethereum address formatcalculate_token_value(): Converts raw token value (with decimals) to human-readable formatunix_to_datetime(): Converts Unix timestamp to datetime objectformat_date_display(): Formats datetime as "DD/MM/YYYY" for Excel
src/utils/config.py - Persistent configuration
Config: Manages saved settings (uses local file storage)- Saves/loads API key and wallet history
- User enters wallet address and API key in GUI
- GUI spawns thread calling
EtherscanClient.get_erc20_transactions() - Client fetches paginated results from Etherscan API (respects rate limits)
- For each page, transactions are formatted and filtered by date range
XlsxHandler.append_transactions()writes to Excel file without overwriting existing data- GUI updates with progress and completion status
- Transaction Hash - 70 chars wide
- Blockno - 12 chars
- UnixTimestamp - 14 chars
- DateTime (UTC) - 14 chars, formatted as DD/MM/YYYY
- From - 45 chars (wallet address)
- To - 45 chars (wallet address)
- TokenValue - 20 chars (human-readable with decimals)
- USDValueDayOfTx - 16 chars (left blank, requires external data)
- ContractAddress - 45 chars
- TokenName - 25 chars
- TokenSymbol - 12 chars
- Headers are frozen on row 1 and bolded
- Each export appends new rows below existing data
- Only values are written (never formulas or special formatting)
- Column widths remain fixed for consistency
Etherscan API v2 (not v1)
- Base URL:
https://api.etherscan.io/v2/api - Endpoint:
?module=account&action=tokentx&chainid=1&address=... - Rate limit: 5 calls/second (code uses 250ms = 4/sec for safety margin)
- Max per request: 1000 results
- Pagination limit:
page * offset <= 10000(max 10 pages at 1000 per page) - Response status:
"0"= error,"1"= success - "No transactions found" is treated as success (empty list)
API Response → Export Mapping
hash→ Transaction HashblockNumber→ BlocknotimeStamp(Unix) → UnixTimestamp, DateTime (UTC)from/to→ From/Tovalue(raw with decimals) → TokenValue (converted viatokenDecimal)contractAddress→ ContractAddresstokenName/tokenSymbol→ TokenName/TokenSymbol
cd src
# Test API client import
python -c "from api.etherscan import EtherscanClient; print('API module OK')"
# Test Excel handler
python -c "from export.xlsx_handler import XlsxHandler; print('Export module OK')"
# Test GUI import
python -c "from gui.app import WalletExporterApp; print('GUI module OK')"- API returns Unix timestamps (seconds since epoch)
- Convert to UTC:
datetime.fromtimestamp(unix_ts, tz=timezone.utc) - Format for display:
strftime("%d/%m/%Y")(DD/MM/YYYY) - Store both UnixTimestamp (raw) and DateTime (UTC) in Excel
- API returns raw token value (string) with optional
tokenDecimalfield - Default decimals: 18 (standard ERC-20)
- Conversion: divide raw value by 10^decimals
- Example: raw="1000000000000000000", decimals=18 → 1.0
- Long operations run in
threading.Thread(target=func, daemon=True) - Use callbacks to update GUI from worker threads
- Disable buttons before spawning thread, re-enable on completion
- Progress callback signature:
callback(current: int, total: int)
- Use
pathlib.Paththroughout (not string paths) - Add
src/tosys.pathin entry points to enable module imports - Works cross-platform (Windows/Mac/Linux)
- Add to
HEADERSlist inxlsx_handler.py - Add to
COLUMN_WIDTHSdict - Update
_format_transaction()inetherscan.pyto populate it from API response - Update
append_transactions()inxlsx_handler.pyif special handling needed
- Use Unix timestamps for API filtering
get_date_range_blocks()converts date objects to Unix timestamps- Filter transactions in
get_erc20_transactions()before formatting
- Catch
EtherscanAPIError(custom exception) - Show user-friendly message in GUI (never expose raw API response)
- Log to console for debugging if needed
- Status "0" + "No transactions found" message = success (empty list)