bdk-ffi icon indicating copy to clipboard operation
bdk-ffi copied to clipboard

DescriptorSecretKey.extend() method requires a wildcard be applied to the root extended key

Open thunderbiscuit opened this issue 1 year ago • 1 comments

Our current implementation of the .extend() method carries over the wildcard choice made initially by the DescriptorSecretKey type. This means that if the DescriptorSecretKey was created without a wildcard, there is no way to extend it with a wildcard.

Example:

val rootDescriptorSecretKey = DescriptorSecretKey.fromString(
    "tprv8ghw3FWfWTeLCEXcr8f8Q8Lz4QPCELYv3jhBXjAm7XagA6R5hreeWLTJeLBfMj7Ni6Q3PdV1o8NbvNBHE59W97EkRJSU4JkvTQjaNUmQubE"
)
val keysAtNewPath = rootDescriptorSecretKey.extend(DerivationPath("m/1212"))
val descriptorTest1 = Descriptor(
    descriptor = "wpkh(${keysAtNewPath.asString()})",
    network = Network.TESTNET
)
println("Issue #324 descriptor is ${descriptorTest1.asStringPrivate()}")
// Issue #324 descriptor is wpkh(tprv8ghw3FWfWTeLCEXcr8f8Q8Lz4QPCELYv3jhBXjAm7XagA6R5hreeWLTJeLBfMj7Ni6Q3PdV1o8NbvNBHE59W97EkRJSU4JkvTQjaNUmQubE/1212)#8qetj2j9

We cannot apply the wildcard to the DerivationPath type, and so the only way to have a wilcard for this path is to create the root key with a wild card in the first place:

val rootDescriptorSecretKey = DescriptorSecretKey.fromString(
    "tprv8ghw3FWfWTeLCEXcr8f8Q8Lz4QPCELYv3jhBXjAm7XagA6R5hreeWLTJeLBfMj7Ni6Q3PdV1o8NbvNBHE59W97EkRJSU4JkvTQjaNUmQubE/*"
)
val keysAtNewPath = rootDescriptorSecretKey.extend(DerivationPath("m/1212"))
val descriptorTest1 = Descriptor(
    descriptor = "wpkh(${keysAtNewPath.asString()})",
    network = Network.TESTNET
)
println("Issue #324 descriptor is ${descriptorTest1.asStringPrivate()}")

// Issue #324 descriptor is wpkh(tprv8ghw3FWfWTeLCEXcr8f8Q8Lz4QPCELYv3jhBXjAm7XagA6R5hreeWLTJeLBfMj7Ni6Q3PdV1o8NbvNBHE59W97EkRJSU4JkvTQjaNUmQubE/1212/*)#lgncmkah

This little quirk of the API comes from the fact that in the FFI we extend the DescriptorSecretKey "directly", whereas the .extend() method in rust-bitcoin belongs to the DerivationPath type. This little bug (not really a bug but just a weird behaviour?) doesn't have an easy answer, because it might involve reshaping our API and the way we extend keys with custom paths.

Opening this issue for discussion.

thunderbiscuit avatar Mar 10 '23 15:03 thunderbiscuit

Adding an argument for the wildcard sounds like a good way to adjust and allow for the functionality we need.

thunderbiscuit avatar Mar 10 '23 20:03 thunderbiscuit