Rust tool to import bip39 mnemonic #32115

pull Sjors wants to merge 1 commits into bitcoin:master from Sjors:2024/03/bip39 changing 4 files +382 −0
  1. Sjors commented at 4:47 pm on March 21, 2025: member

    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):

     0cd share/wallet
     1cargo run -- import bip39
     2
     3Specify network: 'main' (default) or 'test' (testnet and signet)
     4main
     5Enter bip39 mnemonic:
     6abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about
     7Enter passphrase (optional):
     8TREZOR
     9Parsed 12 word mnemonic.
    10Import into your wallet as follows:
    11
    12importdescriptors '[{"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.

  2. DrahtBot commented at 4:47 pm on March 21, 2025: contributor

    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.

  3. darosior commented at 5:29 pm on March 21, 2025: 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?

  4. Sjors commented at 6:24 pm on March 21, 2025: member

    @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)

  5. Rust tool to import bip39 mnemonic a069dbb03d
  6. in share/wallet/src/main.rs:84 in 76d5d7d6f1 outdated
    79+                                 "{root_xprv}/44h/{network_der}/0h/<0;1>/*")).expect("valid pkh() descriptor"));
    80+    let bip49_desc = import_desc(Descriptor::new_sh_wpkh(format!(
    81+                                 "{root_xprv}/49h/{network_der}/0h/<0;1>/*")).expect("valid sh(wpkh()) descriptor"));
    82+    let bip84_desc = import_desc(Descriptor::new_wpkh(format!(
    83+                                 "{root_xprv}/84h/{network_der}/0h/<0;1>/*")).expect("valid wpkh() descriptor"));
    84+    let bip96_desc = import_desc(Descriptor::new_tr(format!(
    


    sipa commented at 7:10 pm on March 21, 2025:
    86, no?

    Sjors commented at 7:22 pm on March 21, 2025:
    Indeed, fixed.
  7. Sjors force-pushed on Mar 21, 2025
  8. in share/wallet/README.md:16 in a069dbb03d
    11+
    12+Use `import bip39` to import from a [bip39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) mnemonic.
    13+
    14+Bitcoin Core does not support bip39. The mnemonic will not be stored in the
    15+wallet, so be sure to back it up. Only standard derivation paths are supported
    16+(BIP44, BIP49, BIP84 and BIP86).
    


    maflcko commented at 7:53 am on March 22, 2025:
    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.

    Sjors commented at 9:05 am on March 24, 2025:

    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


    maflcko commented at 9:35 am on March 24, 2025:

    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)


    Sjors commented at 10:21 am on March 24, 2025:

    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.

  9. maflcko commented at 7:59 am on March 22, 2025: member

    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.

  10. Sjors commented at 9:25 am on March 24, 2025: member

    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.

  11. dergoegge commented at 9:52 am on March 24, 2025: 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.

  12. Sjors closed this on Mar 24, 2025

  13. 1440000bytes commented at 7:58 pm on March 24, 2025: none

    Concept ACK

    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.

    Agree. This could be a useful tool for bitcoin core users.


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2025-03-28 15:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me