This guide explains how to run a legacy wallet.dat extraction script on Termux using an Android device. The tutorial is intended for old, unencrypted Bitcoin wallet files where private key material may still be discoverable through binary scanning.
Important: this workflow is only for wallets that you own or are legally authorized to recover. A wallet.dat file may contain private keys. Anyone with access to valid private keys can move the funds.
This tutorial is not designed for modern descriptor wallets, encrypted wallets, hardware wallets, or seed-phrase based wallets. It is specifically focused on old legacy wallet recovery experiments.
1. What This Script Does
The script reads a local wallet.dat file as binary data, searches for private-key-like byte patterns, converts the detected data into WIF (Wallet Import Format), derives legacy Bitcoin addresses, checks balances through a public blockchain API, and writes the output into text files.
The generated files are:
- keys.txt — extracted WIF private keys
- balances.txt — derived addresses and detected balances
2. Scope and Limitations
This method is only useful for a narrow legacy use case. It should be treated as a recovery helper, not a guaranteed wallet recovery method.
Limitations:
- It is intended for old unencrypted wallet files.
- It may not work on encrypted wallet.dat files.
- It may miss compressed-key or non-standard wallet structures.
- It may produce false positives from random binary data.
- It checks legacy P2PKH-style addresses.
- It does not replace Bitcoin Core wallet recovery tools.
If the wallet is encrypted, this script will not decrypt it. If the wallet uses a newer format, this raw scanning method may not return useful results.
3. Install Termux
Install Termux from a trusted source. F-Droid is commonly preferred because the Play Store version of Termux may be outdated.
After installing Termux, update the package list:
pkg update pkg upgrade 4. Install Required Packages
Install Python and basic tools:
pkg install python git nano Then install the Python libraries required by the script:
pip install requests base58 ecdsa The script uses:
requestsfor API callsbase58for WIF and Bitcoin address encodingecdsafor deriving public keys from private keys
5. Enable Android Storage Access
To let Termux access files from Android internal storage, run:
termux-setup-storage After granting permission, Termux creates storage shortcuts under:
~/storage/ The shared internal storage path is usually:
~/storage/shared 6. Create a Recovery Working Directory
Create a dedicated folder for the recovery script:
mkdir -p ~/wallet-recovery cd ~/wallet-recovery This keeps the script, wallet file, and output files in one place.
7. Place wallet.dat in the Correct Directory
If your wallet.dat file is stored in the Android Download folder, copy it into the Termux working directory:
cp ~/storage/shared/Download/wallet.dat ~/wallet-recovery/ Confirm that the file exists:
ls -lh You should see:
wallet.dat 8. Create the Python Script
Create a file named extract.py:
nano extract.py Paste the following script:
import re import base58 import hashlib import requests import ecdsa WALLET_FILE = "wallet.dat" KEYS_FILE = "keys.txt" BALANCES_FILE = "balances.txt" def read_wallet_file(file_path): with open(file_path, "rb") as file: return file.read() def extract_legacy_key_candidates(data): candidates = re.findall(b"\x80[\x00-\xff]{32}", data) unique_candidates = [] for candidate in candidates: if candidate not in unique_candidates: unique_candidates.append(candidate) return unique_candidates def private_key_bytes_to_wif(key_bytes): return base58.b58encode_check(key_bytes).decode() def wif_to_legacy_address(wif): decoded = base58.b58decode_check(wif) if decoded[0] != 0x80: raise ValueError("Invalid mainnet private key prefix") private_key = decoded[1:33] signing_key = ecdsa.SigningKey.from_string( private_key, curve=ecdsa.SECP256k1 ) verifying_key = signing_key.get_verifying_key() public_key = b"\x04" + verifying_key.to_string() sha256_hash = hashlib.sha256(public_key).digest() ripemd160_hash = hashlib.new("ripemd160", sha256_hash).digest() payload = b"\x00" + ripemd160_hash checksum = hashlib.sha256(hashlib.sha256(payload).digest()).digest()[:4] return base58.b58encode(payload + checksum).decode() def get_balance(address): url = f"https://blockstream.info/api/address/{address}" response = requests.get(url, timeout=20) response.raise_for_status() data = response.json() funded = data["chain_stats"]["funded_txo_sum"] spent = data["chain_stats"]["spent_txo_sum"] return (funded - spent) / 100000000 def write_extracted_keys(keys): with open(KEYS_FILE, "w", encoding="utf-8") as output: if not keys: output.write("No private key candidates found.\n") return for key_bytes in keys: try: wif = private_key_bytes_to_wif(key_bytes) output.write(wif + "\n") except Exception as error: output.write(f"Failed to encode key: {error}\n") def check_balances_from_keys(): with open(KEYS_FILE, "r", encoding="utf-8") as file: wifs = [ line.strip() for line in file if line.strip() and not line.startswith("No private key") ] with open(BALANCES_FILE, "w", encoding="utf-8") as output: if not wifs: message = "No WIF keys available for balance checking." print(message) output.write(message + "\n") return print("\nBalance results:\n") for wif in wifs: try: address = wif_to_legacy_address(wif) balance = get_balance(address) line = f"{address} - {balance:.8f} BTC" print(line) output.write(line + "\n") except Exception as error: line = f"{wif[:6]}... failed: {error}" print(line) output.write(line + "\n") def main(): print("Reading wallet.dat...") data = read_wallet_file(WALLET_FILE) print("Scanning for legacy private key candidates...") keys = extract_legacy_key_candidates(data) print(f"Found {len(keys)} candidate key(s).") print(f"Writing WIF keys to {KEYS_FILE}...") write_extracted_keys(keys) print(f"Checking balances and writing results to {BALANCES_FILE}...") check_balances_from_keys() if __name__ == "__main__": main() 9. Run the Script
Make sure both files are in the same directory:
ls You should see:
extract.py wallet.dat Run the script:
python extract.py 10. Expected Output
If private-key candidates are found, Termux will print balance results in the terminal:
Reading wallet.dat... Scanning for legacy private key candidates... Found 2 candidate key(s). Writing WIF keys to keys.txt... Checking balances and writing results to balances.txt... Balance results: 1ExampleBitcoinAddressxxxxxxxxxxxx - 0.00000000 BTC 1AnotherBitcoinAddressxxxxxxxxxxxx - 0.01500000 BTC The script also creates two output files:
keys.txt balances.txt 11. Understanding keys.txt
The keys.txt file contains extracted WIF keys:
5ExampleWIFPrivateKeyxxxxxxxxxxxxxxxxxxxxxxxxxxxx 5AnotherExampleWIFPrivateKeyxxxxxxxxxxxxxxxxxxxx These keys are sensitive. Anyone with access to valid WIF private keys can control the related Bitcoin funds.
12. Understanding balances.txt
The balances.txt file contains the derived legacy Bitcoin address and its confirmed balance:
1ExampleBitcoinAddressxxxxxxxxxxxx - 0.00000000 BTC 1AnotherBitcoinAddressxxxxxxxxxxxx - 0.01500000 BTC The balance is calculated from confirmed on-chain data returned by the Blockstream public API.
13. Important Notes About Address Format
This script derives an uncompressed legacy P2PKH-style address from each extracted private key candidate.
This is suitable for some old wallet recovery cases, but it does not cover every possible address format. If the original wallet used compressed keys or another address type, the balance may not appear even if the private key candidate is valid.
14. Security Checklist
Before and after running the script, follow these rules:
- Work only with wallet files you own.
- Make a backup before modifying or moving any wallet file.
- Do not upload wallet.dat anywhere.
- Do not share keys.txt.
- Do not screenshot private keys.
- Do not commit recovery files to GitHub.
- Delete temporary sensitive files after recovery is complete.
To delete generated files after you are done:
rm -f keys.txt balances.txt If you copied wallet.dat into Termux and no longer need it there, remove the copied file:
rm -f wallet.dat 15. Troubleshooting
No private key candidates found: the wallet may be encrypted, compressed differently, unsupported by this scanning method, or not an old unencrypted wallet.
Network error: check your internet connection or retry later. The balance lookup depends on a public blockchain API.
Zero balance: the derived legacy address may not be the address that originally received funds, or the wallet may not contain spendable coins.
Permission denied: make sure Termux has storage permission and that wallet.dat is readable from the working directory.
16. Summary
This Termux workflow is designed for old legacy wallet.dat recovery checks where raw private-key-like data may still be present in the file. The script scans the wallet file, converts detected candidates into WIF format, derives legacy Bitcoin addresses, and checks their balances.
Because this method is heuristic, it is not guaranteed to recover every wallet. It should be used carefully, offline where possible, and only with wallet files that you own or are authorized to recover.


