How to recover a wallet seed phrase or passphrase

using Ian Coleman’s BIP39 Mnemonic Code Converter.

Imagine if you try to restore your cryptocurrency wallet from a seed phrase, but the wallet software says it is an invalid phrase. This happened to me. I had some Bitcoin BTC and a little Ripple XRP in a ledger wallet. I erased the ledger by entering an incorrect PIN 3 times. When I tried to recover from my seed phrase, the ledger said, “Recovery phrase is not valid”.

I was shocked and dismayed to discover that I might have just lost all my bitcoin. It took 3 weeks before I recovered my wallet. I ended up writing a small modification to Ian Coleman’s BIP39 tool, which enabled me to recover my seed phrase. Luckily, my incorrect phrase only had 1 word wrong which made it easily recoverable. I want to share my findings to help anybody else who may need to recover a seed phrase.

At the bottom of the page I have also added code to help recover a passphrase.

In my search for help with this problem, I found two potentially useful tools, Ian Coleman’s BIP39 Mnemonic Code Converter, and Chris Gurnee’s btcrecover software.

Here is the web version of Ian Coleman’s BIP39 tool:

https://iancoleman.io/bip39/


Here is Chris Gurnee’s btcrecover software:

https://github.com/gurnec/btcrecover/

The btcrecover software can recover a bitcoin seed phrase from an incorrect seed phrase, which has one or two wrong words. Unfortunately at the time of this writing it does not yet support bitcoin segwit addresses, and my bitcoin was in a segwit address. Nor does it support Ripple XRP. However it is informative and interesting to read through btcrecover's issue discussions on github. Since it is open source, the option is available to edit its source code to add whatever features anyone needs. However, I decided to focus my efforts on Ian Coleman’s BIP39 tool instead, because it already supports a large number of coins.

Ian Coleman’s BIP39 tool allows you to enter a seed phrase, and it can generate from that seed phrase the associated keys and addresses for a variety of different coins. If your wallet that you are trying to recover follows the BIP39 standard, and uses standard derivation paths, then the addresses generated by Ian Coleman’s BIP39 tool will probably match the addresses generated by your wallet. Before you can use the BIP39 tool to recover your wallet, you need to make sure that it does indeed generate the same addresses from the same seed phrase that your wallet software does. To verify this, you’ll need to make a new seed phrase for testing purposes, and have that seed phrase in your wallet, and in the BIP39 tool. Then compare the address generated by the wallet to the address generated by the BIP39 tool, for the type of coin whose address you have in the wallet you want to recover.

So, for instance, supposing that the wallet that you want to recover has a Ripple address, then you have to make sure that the BIP39 tool generates the same Ripple addresses from seed phrases as your wallet software does. So you can use your wallet software to make a new wallet for testing purposes, write down its seed phrase, then get the Ripple address from your new wallet. Then enter the same recovery seed phrase into the BIP39 tool, select XRP - Ripple as the coin, and see if it shows the same Ripple address as your new wallet made. If it does, then you can use the BIP39 tool to make guesses at the seed phrase you are trying to recover. Just type in guesses at your seed phrase, and compare the Ripple addresses it generates to your known Ripple address from the wallet you want to recover. If you get a match, you are in luck.

If you have a Bitcoin segwit address, then in the BIP39 tool, try selecting BTC - Bitcoin as the coin, and in the Derivation Path section, try selecting the BIP49 tab or the BIP141 tab.

If you have trouble getting the BIP39 tool to generate addresses that match your wallet, you may have to experiment with the settings. The explanation on this page may help:

https://forkdrop.io/using-ian-colemans-bip-39-tool

Once you have the settings, which enable the BIP39 tool to generate the same address as your wallet for the type of coins to recover, then you are ready to start guessing phrases. After you enter each guess, you'll look under the Derived Addresses section to see if the address holding your coins appears. This type of manual guessing may be all you need if you have a good idea about possible guesses to try.

However, if you don’t have any luck with manual guessing and get tired of it, then the guessing process can be automated. I wrote some code that you will have to copy/paste into Ian Coleman’s code, to automate the guessing process. The code that I wrote will try all possible phrases, which are different from your incorrect phrase by one word. If your phrase only has one word wrong, this will find it. If your phrase has more than one word wrong, then you could modify the small section of my code to search for more words wrong as needed. My own phrase was only off by one word, so this code was sufficient for my own recovery.

To apply my modifications, first you’ll need to download Ian Coleman’s source code from github.

https://github.com/iancoleman/bip39

Click the “Clone or Download” button.

Click “Download ZIP”.

Save the Zip file to your hard drive and extract it.

Find the ‘src’ directory.

In the ‘src’ directory, you’ll see a file ‘index.html’ and two subdirectories, ‘js’ and ‘css’. If you double click ‘index.html’ the web page will open in your browser, running from your hard drive. Note that since this runs offline, it would be highly advisable to do your recovery attempt on an offline computer. Typing even a partially correct seed into an Internet connected computer puts your funds at risk of theft.

To apply my modifications, go in the ‘js’ directory, and use a text editor to open the file ‘index.js’.

There are two sections of code to copy/paste.

First, find the function generateClicked(). It looks like this:

function generateClicked() {
        if (isUsingOwnEntropy()) {
            return;
        }
        clearDisplay();
        showPending();
        setTimeout(function() {
            setMnemonicLanguage();
            var phrase = generateRandomPhrase();
            if (!phrase) {
                return;
            }
            phraseChanged();
        }, 50);
    }

  

Delete the whole function or comment it out, and copy/paste in its place, all of the code from this text file:

section1.txt

After you have done that, modify these two variables to contain your own values:

var addressToFind = "1ArKbbf28DSmcEajJgKk7ETWvbNmUFnHmP" ;
    var myIncorrectPhrase = ["example", "sea", "sea", "clown", "round", "hybrid", 
          "depend", "book", "farm", "devote", "winner", "lunch", "code", "impose",
           "about", "comfort", "retire", "balance", "maximum", "match", "message", "letter", "pony", "horse"];

In place of 1ArKbbf28DSmcEajJgKk7ETWvbNmUFnHmP, put the address from your wallet that you are trying to recover. In place of the phrase words, put the words from your own incorrect phrase. If your phrase is less than 24 words, delete the extra words.

Next, look further down to find the function addAddressToList. The top part of it looks like this:

function addAddressToList(indexText, address, pubkey, privkey) {
    var row = $(addressRowTemplate.html());
    // Elements
    var indexCell = row.find(".index span");
    var addressCell = row.find(".address span");
    var pubkeyCell = row.find(".pubkey span");

…….

Do not delete it, but insert a few blank lines inside the top of the function, and then copy/paste the 5 lines of code from this text file into the top part of the function:

section2.txt

After you have done that, the top part of the function should look something like this:

function addAddressToList(indexText, address, pubkey, privkey) {

    if (addressToFind == address) {
       alert("address found:" + addressToFind + "\n  Your seed mnemonic is: \n" + testPhrase);
        finishedSearching = true;
       clearTimeout(myTestTimer)
   }   

    var row = $(addressRowTemplate.html());
    // Elements
    var indexCell = row.find(".index span");
    var addressCell = row.find(".address span");
    var pubkeyCell = row.find(".pubkey span");

….

So that you understand what is happening here, the function addAddressToList adds the addresses to the Derived Addresses section at the bottom of the web page after the addresses have been computed from the input phrase. This modification takes the addresses which are about to be added to the page, and compares them to the address from your wallet which you entered in the other section of code. If they match, then your seed phrase has been found, and it pops up a message box to let you know.

After making all these changes to ‘index.js’ in your text editor, save the file. Now open the file ‘index.html’ in your browser, or reload the page if you already had it open. Select all the settings on the page, (the coin, and the tab in the derivation path), which you found to enable the BIP39 page to generate the same addresses as your wallet software. Remember, these settings are critical. If you forget to set them, then the addresses generated won’t match your address even if it tried the correct seed. Then click the ‘Generate’ button. It should pop up with an ok/cancel dialog box. Press ‘cancel’ to begin the recovery. (‘Ok’ does the normal behavior for the generate button).

Chrome is the tested browser

A note about browsers: the performance of this code varies depending on which browser it runs in. I did all my testing with the Chrome browser. I tried briefly in a different browser and it was slower or did not work right because the timing delay was not long enough for the other browser. I suggest using Chrome when running this. If you use a different browser, you may need to increase the number of milliseconds in the call to setTimeout.

Two Words Wrong

If you have two words wrong in your seed phrase, the following section1 can be used instead of the section1 given above.

two_words_section1.txt

Use the same section2.txt as linked above.

Be forewarned that it may take many months to iterate through all combinations, and is provided here only because it has been requested. If you want some assurance that the code actually will iterate through all combinations, you can temporarily edit the function myIncrement() to replace 2048 with 4, in both places that 2048 appears. So change

if (index2_Bip39WordList >= 2048) {

To

if (index2_Bip39WordList >= 4) {

Do this both places that 2048 appears in the function. The sample phrase consists of the first 4 words in the word list, repeated 3 times to make a 12 word phrase, so that this method of testing would work. You can verify that it finds the two wrong words in the sample phrase this way, then change 4 back to 2048 when you put your own incorrect phrase in.


Passphrase Recovery

If you know your seed phrase but have a passphrase for which you have forgotten some details, you can attempt recovery with this tool. The instructions are the same as for a seed phrase above, except that instead of guessing at your seed phrase, you will be guessing at your passphrase. You can put your known seed phrase in the BIP39 Mnemonic textbox, and try typing guesses into textbox just underneath it, labeled BIP39 Passphrase (optional) .

As detailed in the instructions above, you need to find the settings which enable Ian Coleman’s BIP39 tool to generate the same addresses as your wallet software. With the correct settings applied to the page, and with your seed entered in the correct place, after you type each guess at your passphrase you would compare the generated addresses against your known wallet address that you are trying to recover. This guessing process can be automated following the steps below.

In the instructions above, I provided two sections of code to copy paste into the source code of index.js. For passphrase recovery, the instructions are the same, but the two sections of code are different. Instead of section1.txt above, copy paste all of the code from this text file over the function generateClicked():

passphrase.section1.txt

Instead of section2.txt above, copy paste all of the code from this text file inside the function addAddressToList(), in the same way as described above.

passphrase.section2.txt

After doing that, the first section of text needs more editing. In place of 1ArKbbf28DSmcEajJgKk7ETWvbNmUFnHmP, put the address from your wallet that you are trying to recover.

Then you will need to edit the token lists section, which looks like this:

TokenLists[0] = new Array ("Brown", "brown", "BROWN");
TokenLists[1] =  new Array ("\-", "\.", "\_", "");
TokenLists[2] =  new Array ("Cow", "cow", "COW");
TokenLists[3] =  new Array ("0", "1", "2", "3", "4", "5", "6", "7", "8", "9");
TokenLists[4] =  new Array ("@", "\%", "\^", "\'", "\)", "\(", "\&", "\*", "\$", "\#");

The automated guessing will iterate through all possible combinations of listed tokens. Each TokenLists array is a position. All tokens in that array will be tried in that position. An empty string is a valid token to try in a position. Beware that javascript strings require a backslash in front of special characters. Just put a backslash in front of anything which isn’t a letter or number and you’ll be okay. You may have as many or as few tokens as you wish in each TokenLists[] array. You may have as many or as few TokenLists[] arrays as you wish. Just uncomment the commented out ones, or keep adding them with increasing sequential numbers, for example: TokenLists[10] = new Array ("…  etc.

Note that in javascript, // in front of a line turns the line into a comment. To uncomment a line, remove the // in front.

After making all these changes to ‘index.js’ in your text editor, save the file. Now open the file ‘index.html’ in your browser, or reload the page if you already had it open. Select all the settings on the page, (the coin, and the tab in the derivation path), which you found to enable the BIP39 page to generate the same addresses as your wallet software. Remember, these settings are critical. If you forget to set them, then the addresses generated won’t match your address even if it tried the correct passphrase. Put your known seed into the correct textbox. Then click the ‘Generate’ button. It should pop up with an ok/cancel dialog box. Press ‘cancel’ to begin the recovery. (‘Ok’ does the normal behavior for the generate button).

Contact Info

If you try to use this tool and can’t get it to work, please let me know. Maybe I can offer suggestions or help. If you have a successful recovery, I’d be glad hear about it. I have a disposable email address in case of spam.

Random25371@vly3.com

License

Ian Coleman’s license applies to his code. For my code, you may do whatever you want with it, but it is provided “as is” without any warranty. You may modify and redistribute my code without attribution of credit.