Created
January 14, 2021 13:00
-
-
Save AdamISZ/d9db8d8abc611fa4c25618f02823123b to your computer and use it in GitHub Desktop.
Script to recover pre-segwit Joinmarket wallet keys from the seedphrase only without Bitcoin Core
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
from optparse import OptionParser | |
from jmbase import jmprint | |
from jmclient import load_program_config, LegacyWallet, VolatileStorage, get_network | |
def get_parser(): | |
description = ( | |
'Use this script to extract keys and addresses from pre-segwit ' | |
'Joinmarket wallets if you do not have access to Bitcoin Core. Specify ' | |
'number of mixdepths (default 5) with -m and number of addresses per ' | |
'mixdepth with -N (default 20). So to print 100 addresses in each of ' | |
'6 mixdepths use `python recover-old-keys.py -m 6 -N 100. Enter seed ' | |
' when prompted. ' | |
'PLEASE BE CAUTIOUS WHEN PRINTING PRIVATE KEYS!') | |
parser = OptionParser(usage='usage: %prog [options]', | |
description=description) | |
parser.add_option('-m', | |
'--mixdepths', | |
action='store', | |
type='int', | |
dest='mixdepths', | |
help="Mixdepth(s) to use in the wallet. Default=6", | |
default=6) | |
parser.add_option('-N', | |
'--num-addresses', | |
action='store', | |
type='int', | |
dest='num_addresses', | |
help="Number of addresses to print keys for per mixdepth, default=20", | |
default=20) | |
return parser | |
def wallet_dumpprivkeys(wallet, m, N): | |
"""returns a list of strings, each string is formatted: | |
hdpath, address, private key in wif - this is CSV. | |
""" | |
csvstrings = [] | |
for i in range(m): | |
for j in range(2): | |
for k in range(N): | |
hdpath = "m/0/"+"/".join([str(x) for x in [i, j, k]]) | |
path = wallet.path_repr_to_path(hdpath) | |
wif = wallet.get_wif_path(path) | |
addr = wallet.get_address_from_path(path) | |
csvstrings.append(",".join([hdpath, addr, wif])+"\n") | |
return "\n".join(csvstrings) | |
def recover_keys_main(): | |
"""returned is a string (output or error) | |
""" | |
parser = get_parser() | |
(options, args) = parser.parse_args() | |
if options.mixdepths < 1: | |
parser.error("Must have at least one mixdepth.") | |
sys.exit(0) | |
while True: | |
proposed_seed = input("Enter 12 word seed: ") | |
word_count = len(proposed_seed.split()) | |
if word_count == 12: | |
break | |
jmprint("Wrong seed length, should be 12 words.") | |
entropy = LegacyWallet.entropy_from_mnemonic(proposed_seed) | |
storage = VolatileStorage() | |
LegacyWallet.initialize(storage, get_network(), max_mixdepth=5, entropy=entropy) | |
wallet = LegacyWallet(storage) | |
return wallet_dumpprivkeys(wallet, options.mixdepths, options.num_addresses) | |
if __name__ == "__main__": | |
load_program_config() | |
jmprint(recover_keys_main(), "success") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment