Using the latest version of zcashd, I made a fresh wallet and ran the zcashd-wallet-tool to back it up. I then generated a z-address and sent significant funds to it — the t-addresses in this wall have never been used.
After this, the wallet.dat was irrevocably lost.
TASK: I need to regenerate that first z-addr (privkey) from the emergency recovery phrase. How?
The problem is that the backup created by zcashd (via zcashd-wallet-tool) does not include an HDseed or z addrs in it by default — only the emergency recovery phrase(erp). And as far as I can tell, the wallet tool does not have any ability to regenerate a wallet.dat via the erp (or do anything else beyond dumping keys…?). I made a new wallet.dat and imported the backup created by the zcashd-wallet-tool, but that didn’t correctly import the seed and allow the correct deterministic generation of zaddrs. Similarly, there’s zero as far as I can tell in the zcashd or zcash-cli help on how to do this. Github and Google also miss.
Let’s set aside the frankly terrifying lack of in-tool guidance on how to actually use the recovery phrase zcashd actually forces you to generate (UX problem) for now: how in the hell do I correctly regenerate the wallet.dat from the provided ERP (or at correctly deterministically generate the right private key for the very first z-addr from it)?
You can use it in YWallet or ZWL or NH. We all use Zip-32.
I’ll give it a shot and report back. Thank you!
If you need the secret key, you have to use YWallet. The other wallets don’t show it.
Any wallet with a lightweight node will help you. All of them have recovery by seed phrase.
It doesn’t seem to work — the light wallets do generate deterministic zaddrs (I tested using ZWL and YWL to confirm they match) but the generated zaddrs are different from what the actual zcashd/zcash-clip z_getnewaddress generated. I know this because I had the correct address copy pasted in another window.
So the question becomes: what is the difference between how the light wallets generate their first zaddr from the recovery phrase, and how the official zcash-cli first address is generated?
I think this problem returns us to the original post: it is zcashd that is spitting out the recovery phrase. So how do we make zcashd to actually process the recovery phrase? I mean, this is a core, blocking feature of the reference wallet. It has to work, right?
I think it’s time to call for help from those who have these answers: @str4d @nuttycom @pacu
I’ll try to clarify the current status. It’s a little complicated, because of how zcashd was previously using its HD seed phrase:
- We have work in-progress to implement zcashd restore from the seed phrase, using ZIP-316. This is a bit complicated by the aforesaid handling of the legacy HD seed, but we’re working on it.
z_getnewaddress did not previously generate addresses in accordance with ZIP 32 derivation from the seed phrase: instead, it derived addresses from the raw seed bytes. It now generates addresses from the seed phrase, at a high account number as is described in ZIP 316. This was an issue with how derivation was originally done from the HD seed; essentially, zcashd didn’t previously follow BIP 39 properly.
z_getnewaddress is deprecated as of v5.0.0 to help smooth the transition to unified addresses: https://github.com/zcash/zcash/blob/master/doc/release-notes/release-notes-5.0.0.md#deprecated. However, we will support restoration of addresses previously generated from the legacy HD seed prior to the 5.0.0 upgrade, because the seed phrase can be converted (via a nonstandard process) back to that legacy seed.
- If you generate a unified address by using
z_getnewaccount to obtain account 0 and then
z_getaddressforaccount 0 '["sapling"]', and then use
z_listunifiedreceivers to extract the Sapling component, this address should correspond to the default Sapling address generated by mobile wallets that have followed ZIP 32.
- If you used
z_getnewaddress to generate a Sapling address, and attempt to import the seed phrase from zcashd into a mobile wallet, that address will not be automatically discovered because it is derived under the BIP 44
account path level at account
0x7FFFFFFF to avoid collision with the Sapling addresses for unified account
0. The reason for this is that each address generated by
z_getnewaddress must be treated as a separate pool of funds from the perspective of the wallet; this is also part of the reason that
z_getnewaddress is deprecated in favor of the ZIP 316 account model, where each account represents a separate pool of funds.
Sorry for all the edits, just trying to clarify the current situation.
Thank you for the detailed response. Unfortunately, I couldn’t follow the part of your answer, exactly, on how to recover the wallet/key.
Let me reiterate and simplify in the hopes you can just give me the direct zcash-cli commands for how to recover the funds:
Wallet was created via latest official zcashd release and backed up with zcashd-wallet-tool. ERP and file is saved as recommended.
a single zaddr is generated and used to receive a ztx. Nothing else in the wallet was changed.
Wallet.dat got Thanos-snapped. Gone, reduced to electrons.
So I need to recover the funds. The only relevant information in the backup file I can see is the emergency recovery phrase.
So how do I use it to recover the funds? The
z_getaddressforaccount 0 '["sapling"]' stuff isn’t really clear on how I actually recover use the recovery phrase, or what parameters I feed it in the absence of the original wallet.dat
That’s good, you’ve done everything needed to ensure your funds are recoverable.
As @nuttycom said, we are still implementing the emergency recovery to a new wallet. The problem you experienced with importing the backup file is not due to an incompatibility in the key generation, it’s because the zcashd wallet can only use HD keys generated from one seed at a time. In your situation, a new wallet had already been generated with a different seed. The tool that Ying Tong and @nuttycom are implementing will solve this problem for zcashd.
Note that there were updates to ZIP 32 to support unified addresses; however, they should be compatible with the existing behaviour of light wallets for Sapling keys. However, as @nuttycom said, the keys that zcashd generated using
z_getnewaddress will have been generated in the “legacy” Sapling key tree and it is possible that the light wallet libraries are not looking there. We’ll investigate and get this working in cooperation with the wallet developers.
I apologize for the disruption and delay in being able to access your funds. As long as you have the emergency recovery phrase, they are definitely not lost.
@daira is correct: light wallets will not be looking under account
0x7FFFFFFF when performing restoration from the seed phrase.
It’s great to hear the funds aren’t lost. Am I right in understanding there’s nothing I can do until the new tool gets released? Is there an ETA on that? Because it’s a significant amount of money for me. Thank you.
That’s correct. Your funds are safe, and the tool is currently undergoing unit testing. We’ll let you know as soon as it is available.
Just FYI, users can specify a custom value for the account index in YWallet.
Edit: The path still doesn’t match because we don’t have the last part. We derive m/32’/133’/0x7FFFFFFF’ but zcashd uses m/32’/133’/0x7FFFFFFF’/0’
zcashd-wallet-tool not only spits out the seed but also creates an export file:
Enter the filename for the wallet export file, using only characters
a-z, A-Z and 0-9 (default 'export20220726').
If @Erp-help has this file would they be able to import it by just regular
zcash-cli RPCs? That is, if wallet.dat were lost but export+seed were not, would going through the export file route be faster? (That file is saved in
-exportdir specified in the
If @Erp-help has this file would they be able to import it by just regular
The ERP is written in this file, but all that (currently) gets imported are the T-addresses — The ERP itself is commented out.
We derive m/32’/133’/0x7FFFFFFF’ but zcashd uses m/32’/133’/0x7FFFFFFF’/0’
I wonder: could you export the derived key from YWL in this manner, import it into zcashd, and then (not sure I see a command for it) get zcashd to generate the account 0 from this specific key?
Could I just enter the right derivation path into https://iancoleman.io/bip39/ to get the correct privkey? What are the appropriate parameters?