LtbLightning / bdk-flutter

Bitcoin Development Kit - Flutter Package
MIT License
63 stars 28 forks source link

Create descriptor from xpub #30

Closed BullishNode closed 1 year ago

BullishNode commented 1 year ago

If possible, it would be ideal if createDescriptors() could take an xpub as an input instead of just xpriv.

The goal is to then create a watch-only wallet or air-gapped wallet using a given xpub.

BullishNode commented 1 year ago

I believe this feature is added by release of bdk-flutter 0.2.0 @BitcoinZavior ?

thunderbiscuit commented 1 year ago

This is not answering your question directly but I can provide a bit of context into what is coming down in the next release of bdk-ffi (which I think might be reflected in bdk-flutter 0.3.0), because it's likely to change the API a little bit (for the better!).

With bitcoindevkit/bdk-ffi#260 we're bringing in BDK's descriptor templates (one of the most requested things we've had over the past few months), and a Descriptor type, which you'll be able to create using either any of the standard templates (Bip44, Bip49, Bip84, as well as their public versions Bip44Public, Bip49Public, and Bip84Public), or simply by providing a string. This Descriptor type is what you'll then use to build the Wallet object (instead of just a string). Here is a preview of what it would look like at the call-site in Kotlin (Dart would probably be fairly similar I think):

// example 1: create private descriptor from template
val mnemonic: Mnemonic = Mnemonic(WordCount.WORDS12)
val rootSecretKey: DescriptorSecretKey = DescriptorSecretKey(
    network = Network.TESTNET,
    mnemonic = mnemonic,
    password = null
)
val descriptor = Descriptor.newBip84(rootSecretKey, KeychainKind.EXTERNAL, Network.TESTNET)
println("Xprv: ${descriptor.asStringPrivate()}")
// Xprv: wpkh(tprv8ZgxMBicQKsPdNEsNU8zL8sStkjL5rgXxcTHKDcuCJY4VD4hjRroDnx86Ty6R1FeLG4RYW4hUbjHtcASqpVYJExvi86TPvxzYdwgx3PE3ZG/84'/0'/0'/0/*)#a47490pe
println("Xpub: ${descriptor.asString()}")
// Xpub: wpkh([dc9e85c5/84'/0'/0']tpubDCj2SEEQpVo4RSD4X2vujJqaYiLge26xsg6DcR7wWBycc6LAVodhbEj9UncxnLLbc1EdehfUA3FUfZpnspQ7S8g24CpHr1D5TnRGZVAE4F2/0/*)#82trdexc

// example 2: create public descriptor from template
val xpub = "tpubDCj2SEEQpVo4RSD4X2vujJqaYiLge26xsg6DcR7wWBycc6LAVodhbEj9UncxnLLbc1EdehfUA3FUfZpnspQ7S8g24CpHr1D5TnRGZVAE4F2"
val fingerprint = "dc9e85c5"
val extendedPublicKey: DescriptorPublicKey = DescriptorPublicKey.fromString(xpub)
val descriptor = Descriptor.newBip84Public(extendedPublicKey, fingerprint, KeychainKind.EXTERNAL, Network.BITCOIN)
println("Xpub: ${descriptor.asString()}")
// Xpub: wpkh([dc9e85c5/84'/0'/0']tpubDCj2SEEQpVo4RSD4X2vujJqaYiLge26xsg6DcR7wWBycc6LAVodhbEj9UncxnLLbc1EdehfUA3FUfZpnspQ7S8g24CpHr1D5TnRGZVAE4F2/0/*)#82trdexc

This means we'll be able to create all types of descriptors just like we used to using plain strings, but also prevent footguns by providing standard descriptor structures for the most common ones.