Derive Ethereum private keys from BIP39 seed phrases, scan derived addresses for on-chain activity, and export the results.
eth-key-seed-scan takes BIP39 seed phrases as input, derives private keys and addresses across multiple BIP44 derivation paths, checks each address against the Ethereum blockchain for balances and transaction history, and exports the keys, addresses, and activity data to CSV or Excel.
In short: seed phrase in, private keys and wallet activity out.
- Key derivation -- Each seed phrase is expanded into private keys using BIP44 HD wallet derivation across configurable paths (e.g.
m/44'/60'/0'/0/x). - On-chain scanning -- Each derived address is checked against the Etherscan API for balance and transaction history.
- Gap limit filtering -- Scanning stops after a configurable number of consecutive unused addresses, matching the behavior of wallets like MetaMask.
- Export -- Results are written to CSV or formatted Excel, including addresses, private keys (optional), balances, and transaction dates.
- BIP44 key derivation -- derives private keys from seed phrases across multiple standard and custom derivation paths
- On-chain activity detection -- checks balances, transaction counts, and first/last transaction dates via Etherscan
- Gap limit algorithm -- stops scanning after N consecutive empty addresses, matching HD wallet discovery behavior
- Async with retries -- concurrent API requests with rate limiting, timeouts, and exponential backoff
- CSV and Excel export -- timestamped output with configurable column ordering and clickable Etherscan links
- Seed validation diagnostics -- word-level BIP39 analysis with spelling suggestions for invalid phrases
- Private key controls -- keys can be included, masked, or excluded from output entirely
- Python 3.9+
- Etherscan API key (free tier available at etherscan.io)
- Dependencies (installed via
requirements.txt):- web3, eth-account, mnemonic
- aiohttp, pandas, click
- openpyxl, xlsxwriter, python-dotenv
- Clone the repository:
git clone https://github.com/mskiny/ETH_Seed_Scanner.git
cd ETH_Seed_Scanner- Create and activate a virtual environment:
python -m venv venv
source venv/bin/activate # Linux / macOS
.\venv\Scripts\Activate # Windows PowerShell- Install dependencies:
pip install -r requirements.txt- Create a
.envfile with your Etherscan API key:
ETHERSCAN_API_KEY=your_etherscan_api_key
A default config/config.json ships with the repository. If the file is missing at runtime, it will be auto-created with sensible defaults.
# Derive keys and scan a single seed phrase
python -m app.main --seed "your twelve word seed phrase goes here..." --format excel
# Batch scan multiple seed phrases from a file
python -m app.main --seed-file seeds.env --format excel
# View all CLI options
python -m app.main --helpOn Windows, you can also use the provided PowerShell script:
.\run_scanner.ps1 --seed-file seeds.env --format excelEdit config/config.json to customize behavior:
{
"api_keys": {
"etherscan": ""
},
"scan_settings": {
"derivation_paths": [
"m/44'/60'/0'/0/x",
"m/44'/60'/x'/0/0",
"m/44'/60'/0'/x"
],
"gap_limit": 20,
"batch_size": 5,
"threads": 4,
"check_balance": true,
"check_transactions": true,
"include_private_keys": false
},
"output_settings": {
"fields": [
"path", "index", "used", "balance", "transaction_count",
"first_tx_date", "last_tx_date", "etherscan_url",
"address", "private_key", "seed_phrase"
],
"mask_private_keys": true,
"show_only_used_addresses": false,
"output_dir": "results",
"output_path": "results/scan",
"format": "csv"
}
}| Setting | Description | Default |
|---|---|---|
derivation_paths |
BIP44 path patterns to derive keys from (x is replaced by index) |
3 standard paths |
gap_limit |
Consecutive unused addresses before stopping | 20 |
batch_size |
Addresses per API batch | 5 |
include_private_keys |
Include derived private keys in output | false |
fields |
Column order in output files | See above |
mask_private_keys |
Replace private keys with [MASKED] |
true |
show_only_used_addresses |
Exclude addresses with no on-chain activity | false |
The Etherscan API key can be set in config.json or via the ETHERSCAN_API_KEY environment variable (.env file). The environment variable takes precedence.
# Single seed phrase, CSV output
python -m app.main --seed "word1 word2 ... word12" --format csv
# Batch scan from file, Excel output with timestamps
python -m app.main --seed-file seeds.env --format excel --timestamp
# Debug logging
python -m app.main --seed-file seeds.env --debug
# Custom config file
python -m app.main --seed-file seeds.env --config path/to/config.jsonPlain comma-separated values. Compatible with any spreadsheet application or data pipeline.
Formatted .xlsx file with:
- Bold headers with gray background
- Auto-sized columns
- Date formatting for transaction date columns
- Yes/No display for the
usedcolumn - Clickable Etherscan hyperlinks
- Column ordering based on the
fieldsconfiguration
Use --format excel to select Excel output.
The scanner uses a gap limit algorithm matching HD wallet discovery in MetaMask and similar software:
- For each derivation path, keys are derived and addresses checked sequentially starting at index 0.
- Scanning continues until
gap_limitconsecutive unused addresses are found after the last active address. - All addresses up to and including the gap window are included in the output.
Example with gap_limit=20: if addresses at indices 0, 3, and 5 have on-chain activity, the scanner includes addresses 0 through 25 (index 5 + 20 gap).
Output files contain the following columns (order configurable via fields in config):
| Column | Description |
|---|---|
path |
BIP44 derivation path used to derive the key |
index |
Index position within the derivation path |
used |
Whether the address has balance or transaction history |
balance |
Current balance in ETH |
transaction_count |
Total number of transactions |
first_tx_date |
Date of the first transaction (YYYY-MM-DD) |
last_tx_date |
Date of the most recent transaction (YYYY-MM-DD) |
etherscan_url |
Link to view the address on Etherscan |
address |
Ethereum address derived from the key |
private_key |
Private key (if include_private_keys is enabled) |
seed_phrase |
Source seed phrase |
- Never share output files containing private keys or seed phrases.
- Set
include_private_keys: falsewhen generating reports intended for distribution. - Store seed phrase files securely and avoid transmitting them over insecure channels.
- Consider running in an air-gapped or otherwise isolated environment when handling high-value wallets.
- The
.gitignoreis configured to exclude.env,seeds.env, and result files from version control.
Contributions are welcome. Please open a pull request with a clear description of the change.
This project is licensed under the MIT License. See the LICENSE file for details.