Skip to content

Conversation

Sjors
Copy link
Member

@Sjors Sjors commented Mar 21, 2025

Since we're probably not going to support bip39 mnemonics in the wallet itself, but it's an often requested feature, this PR provides a simple Rust utility to import one.

This puts the utility in share so it's included in releases. Alternatively we could make a separate repo akin to HWI. Or perhaps Rust Bitcoin could ship it as an example.

Usage (first bip39 test vector):

cd share/wallet
cargo run -- import bip39

Specify network: 'main' (default) or 'test' (testnet and signet)
main
Enter bip39 mnemonic:
abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about
Enter passphrase (optional):
TREZOR
Parsed 12 word mnemonic.
Import into your wallet as follows:

importdescriptors '[{"desc": "pkh(xprv9s21ZrQH143K3h3fDYiay8mocZ3afhfULfb5GX8kCBdno77K4HiA15Tg23wpbeF1pLfs1c5SPmYHrEpTuuRhxMwvKDwqdKiGJS9XFKzUsAF/44h/0h/0h/<0;1>/*)#y6qw5vhg", "timestamp": "now", "active": true}, {"desc": "sh(wpkh(xprv9s21ZrQH143K3h3fDYiay8mocZ3afhfULfb5GX8kCBdno77K4HiA15Tg23wpbeF1pLfs1c5SPmYHrEpTuuRhxMwvKDwqdKiGJS9XFKzUsAF/49h/0h/0h/<0;1>/*))#u20wznzk", "timestamp": "now", "active": true}, {"desc": "wpkh(xprv9s21ZrQH143K3h3fDYiay8mocZ3afhfULfb5GX8kCBdno77K4HiA15Tg23wpbeF1pLfs1c5SPmYHrEpTuuRhxMwvKDwqdKiGJS9XFKzUsAF/84h/0h/0h/<0;1>/*)#53uwn79v", "timestamp": "now", "active": true}, {"desc": "tr(xprv9s21ZrQH143K3h3fDYiay8mocZ3afhfULfb5GX8kCBdno77K4HiA15Tg23wpbeF1pLfs1c5SPmYHrEpTuuRhxMwvKDwqdKiGJS9XFKzUsAF/86h/0h/0h/<0;1>/*)#r9yp5mw9", "timestamp": "now", "active": true}]'

Pro tip: use -blockfilterindex for an ultra fast rescanblockchain experience.

Dependencies:

Fixes #19151

Could be expanded to import codex32, see #27351.

@DrahtBot
Copy link
Contributor

DrahtBot commented Mar 21, 2025

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Code Coverage & Benchmarks

For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/32115.

Reviews

See the guideline for information on the review process.

Type Reviewers
Concept NACK dergoegge

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

@darosior
Copy link
Member

This puts the utility in share so it's included in releases

Does this mean the Guix build will now have to bootstrap a Rust compiler?

@Sjors
Copy link
Member Author

Sjors commented Mar 21, 2025

@darosior no, the user has to cargo run it themselves. It's similar to the RPC auth script we ship, which also doesn't include Python itself: https://github.com/bitcoin/bitcoin/tree/master/share/rpcauth

(unlike e.g. the HWI project which ships a standalone binary that including Python, mainly useful for Windows users I think)

Copy link
Member

@maflcko maflcko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or perhaps Rust Bitcoin could ship it as an example.

Yeah, right now it looks like this is just a few lines of docs and example code with the bulk being several imported rust-bitcoin dependencies. So I wonder what the benefits are to include it here, instead of somewhere closer where the majority of its (implicit) code sits.

Comment on lines +14 to +16
Bitcoin Core does not support bip39. The mnemonic will not be stored in the
wallet, so be sure to back it up. Only standard derivation paths are supported
(BIP44, BIP49, BIP84 and BIP86).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit confusing. What does "back it up" mean? The wallet, the mnemonic? Also, I am not sure about the risks that users are exposed to now. I've only read the first section of https://github.com/bitcoin/bips/wiki/Comments:BIP-0039 and it mentions loss of funds. So I think it would be better to educate the users about how wallet incompatibilities can silently lead to loss of funds, instead of implying that a backup of the mnemonic is sufficient for recovery.

Copy link
Member Author

@Sjors Sjors Mar 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mnemonic. Some wallets let you see the mnemonic, others don't (e.g. Ledger only shows it on first use, Bitkey doesn't show it all). But we can't show it, because the master hd key is a hash of the mnemonic, so there's no way back.

If the original wallet uses different derivation paths then Bitcoin Core won't find funds, but they're not lost. Using the same key material between two wallets is a bad idea in general, so we could advice against that.

The docs should probably also mention that HWI can be used to create a watch-only wallet.

https://support.ledger.com/article/360007223753-zd

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mnemonic.

Unless I am missing something, that'll lead to loss of funds, because importdescriptors does not fail if there are already descriptors in the wallet, and it doesn't guarantee that all prior descriptors are inactive. So a users could (after they ran through the steps here) silently and accidentally use a prior active descriptor and then fail to recover the funds there, because they only backed up the mnemonic.

If the original wallet uses different derivation paths then Bitcoin Core won't find funds, but they're not lost.

I am not sure if it matters much for the user if they lost the funds because Bitcoin Core didn't find them, or if they lost them in another way. It seems plausible that someone does an import, then sees some funds from some matching paths, but fails to see the missing funds from mismatching paths. (Likely the user will only fail to notice this if the missing funds are only a small portion, but it still seems like a silent foot-gun to me)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assumed you were talking about losing from from the imported wallet, but I think you're talking about funds in a pre-existing Bitcoin Core wallet.

does not fail if there are already descriptors in the wallet

The instructions say that the wallet should be blank. Perhaps the script should make the RPC calls so that it can actually verify this, but using RPC increases complexity and presumably requires importing network or shell code.

@Sjors
Copy link
Member Author

Sjors commented Mar 24, 2025

closer where the majority of its (implicit) code sits

The importdescriptors RPC is highly specific to Bitcoin Core, and all that code lives here.

The script itself seems trivial to maintain, especially if someone who actually knows Rust cleans it up a bit.

The problem is in the dependencies.

several imported rust-bitcoin dependencies

We only need a small (?) subset of this, but I'm not familiar enough with Rust to constrain the imports. And perhaps a few changes to rust-bitcoin are needed to prevent pulling in the kitchen sink.

It would be nice if Rust had a way to vendor only the classes and methods that are actually called, so you can see all the rust code involved and review changes.

If it's just a few hundred lines then we can actually review it. But if the sub-sub-depedency rabbit hole is too large, then it's probably too much burden for the project. In that case implementing it in c++ might be better, since we have most (all?) of the dependencies already, see #19151 (comment).

I don't think we should tell users to just google for utilities like this. Nor should we link to some project that we're not reviewing. And if we don't tell users where it is, then only people who've heard of rust-bitcoin will use it. I wouldn't consider that a fix of #19151.

@dergoegge
Copy link
Member

Concept NACK

Shipping rust code in share/ that users have to compile themselves seems like the wrong approach. Imo, bip39 should either be supported properly (available to all users without jumping through hoops) or not at all.

The amount of users that would compile this themselves is marginal making the upside of this pretty small. Technical users like that would have no trouble finding this in the e.g. rust-bitcoin examples or elsewhere.

@Sjors Sjors closed this Mar 24, 2025
@1440000bytes

This comment was marked as abuse.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

support BIP39 mnemonic in descriptors
7 participants