Update Kotlin API docs to reflect new descriptor templates

This commit is contained in:
thunderbiscuit 2023-01-09 20:48:44 -05:00
parent f399b799e4
commit ff2734663e
No known key found for this signature in database
GPG Key ID: 88253696EB836462
3 changed files with 134 additions and 48 deletions

View File

@ -350,15 +350,15 @@ data class BlockTime (
* @constructor Create a BDK wallet. * @constructor Create a BDK wallet.
* *
* @param descriptor The main (or "external") descriptor. * @param descriptor The main (or "external") descriptor.
* @param changeDescriptor The change (or "internal") descriptor. * @param changeDescriptor? The change (or "internal") descriptor.
* @param network The network to act on. * @param network The network to act on.
* @param databaseConfig The database configuration. * @param databaseConfig The database configuration.
* *
* @sample org.bitcoindevkit.walletSample * @sample org.bitcoindevkit.walletSample
*/ */
class Wallet( class Wallet(
descriptor: String, descriptor: Descriptor,
changeDescriptor: String, changeDescriptor: Descriptor?,
network: Network, network: Network,
databaseConfig: DatabaseConfig, databaseConfig: DatabaseConfig,
) { ) {
@ -538,22 +538,22 @@ class DerivationPath(path: String) {}
* @sample org.bitcoindevkit.descriptorSecretKeyExtendSample * @sample org.bitcoindevkit.descriptorSecretKeyExtendSample
*/ */
class DescriptorSecretKey(network: Network, mnemonic: Mnemonic, password: String?) { class DescriptorSecretKey(network: Network, mnemonic: Mnemonic, password: String?) {
/** Build a DescriptorSecretKey from a String */ /* Build a DescriptorSecretKey from a String */
fun fromString(secretKey: String): DescriptorSecretKey {} fun fromString(secretKey: String): DescriptorSecretKey {}
/** Derive a private descriptor at a given path. */ /* Derive a private descriptor at a given path. */
fun derive(path: DerivationPath): DescriptorSecretKey {} fun derive(path: DerivationPath): DescriptorSecretKey {}
/** Extend the private descriptor with a custom path. */ /** Extend the private descriptor with a custom path. */
fun extend(path: DerivationPath): DescriptorSecretKey {} fun extend(path: DerivationPath): DescriptorSecretKey {}
/** Return the public version of the descriptor. */ /* Return the public version of the descriptor. */
fun asPublic(): DescriptorPublicKey {} fun asPublic(): DescriptorPublicKey {}
/* Return the raw private key as bytes. */ /* Return the raw private key as bytes. */
fun secretBytes(): List<UByte> fun secretBytes(): List<UByte>
/** Return the private descriptor as a string. */ /* Return the private descriptor as a string. */
fun asString(): String {} fun asString(): String {}
} }
@ -579,23 +579,79 @@ class DescriptorPublicKey(network: Network, mnemonic: String, password: String?)
} }
/** /**
* An enum describing entropy length (aka word count) in the mnemonic. * A output descriptor.
*
* @param descriptor The descriptor in string format.
* @param network The network this DescriptorPublicKey is to be used on.
*
* @sample org.bitcoindevkit.descriptorTemplates1
* @sample org.bitcoindevkit.descriptorTemplates2
*/ */
class Descriptor(descriptor: String, network: Network) {
/**
* BIP44 template. Expands to pkh(key/44'/{0,1}'/0'/{0,1}/\*)
* Since there are hardened derivation steps, this template requires a private derivable key (generally a xprv/tprv).
*/
fun newBip44(secretKey: DescriptorSecretKey, keychain: KeychainKind, network: Network) {}
/**
* BIP44 public template. Expands to pkh(key/{0,1}/\*)
* This assumes that the key used has already been derived with m/44'/0'/0' for Mainnet or m/44'/1'/0' for Testnet.
* This template requires the parent fingerprint to populate correctly the metadata of PSBTs.
*/
fun newBip44Public(publicKey: DescriptorPublicKey, fingerprint: String, keychain: KeychainKind, network: Network) {}
/**
* BIP49 template. Expands to sh(wpkh(key/49'/{0,1}'/0'/{0,1}/\*))
* Since there are hardened derivation steps, this template requires a private derivable key (generally a xprv/tprv).
*/
fun newBip49(secretKey: DescriptorSecretKey, keychain: KeychainKind, network: Network) {}
/**
* BIP49 public template. Expands to sh(wpkh(key/{0,1}/\*))
* This assumes that the key used has already been derived with m/49'/0'/0' for Mainnet or m/49'/1'/0' for Testnet.
* This template requires the parent fingerprint to populate correctly the metadata of PSBTs.
*/
fun newBip49Public(publicKey: DescriptorPublicKey, fingerprint: String, keychain: KeychainKind, network: Network) {}
/**
* BIP84 template. Expands to wpkh(key/84'/{0,1}'/0'/{0,1}/\*)
* Since there are hardened derivation steps, this template requires a private derivable key (generally a xprv/tprv).
*/
fun newBip84(secretKey: DescriptorSecretKey, keychain: KeychainKind, network: Network) {}
/**
* BIP84 public template. Expands to wpkh(key/{0,1}/\*)
* This assumes that the key used has already been derived with m/84'/0'/0' for Mainnet or m/84'/1'/0' for Testnet.
* This template requires the parent fingerprint to populate correctly the metadata of PSBTs.
*/
fun newBip84Public(publicKey: DescriptorPublicKey, fingerprint: String, keychain: KeychainKind, network: Network) {}
/** Return the public version of the output descriptor. */
fun asString(): String {}
/** Return the private version of the output descriptor if available, otherwise return the public version. */
fun asStringPrivate(): String {}
}
/**
* An enum describing entropy length (aka word count) in the mnemonic.
*/
enum class WordCount { enum class WordCount {
/** 12 words mnemonic (128 bits entropy). */ /** 12 words mnemonic (128 bits entropy). */
WORDS12, WORDS12,
/** 15 words mnemonic (160 bits entropy). */ /** 15 words mnemonic (160 bits entropy). */
WORDS15, WORDS15,
/** 18 words mnemonic (192 bits entropy). */ /** 18 words mnemonic (192 bits entropy). */
WORDS18, WORDS18,
/** 21 words mnemonic (224 bits entropy). */ /** 21 words mnemonic (224 bits entropy). */
WORDS21, WORDS21,
/** 24 words mnemonic (256 bits entropy). */ /** 24 words mnemonic (256 bits entropy). */
WORDS24, WORDS24,
} }
/** /**
@ -606,25 +662,25 @@ enum class WordCount {
* *
* @sample org.bitcoindevkit.txBuilderResultSample1 * @sample org.bitcoindevkit.txBuilderResultSample1
* @sample org.bitcoindevkit.txBuilderResultSample2 * @sample org.bitcoindevkit.txBuilderResultSample2
*/ */
data class TxBuilderResult ( data class TxBuilderResult (
var psbt: PartiallySignedBitcoinTransaction, var psbt: PartiallySignedBitcoinTransaction,
var transactionDetails: TransactionDetails var transactionDetails: TransactionDetails
) )
/** /**
* A bitcoin script. * A bitcoin script.
*/ */
class Script(rawOutputScript: List<UByte>) class Script(rawOutputScript: List<UByte>)
/** /**
* A bitcoin address. * A bitcoin address.
* *
* @param address The address in string format. * @param address The address in string format.
*/ */
class Address(address: String) { class Address(address: String) {
/* Return the ScriptPubKey. */ /* Return the ScriptPubKey. */
fun scriptPubkey(): Script fun scriptPubkey(): Script
} }
/** /**
@ -634,17 +690,17 @@ class Address(address: String) {
* @param mnemonic The mnemonic as a string of space-separated words. * @param mnemonic The mnemonic as a string of space-separated words.
* *
* @sample org.bitcoindevkit.mnemonicSample * @sample org.bitcoindevkit.mnemonicSample
*/ */
class Mnemonic(mnemonic: String) { class Mnemonic(mnemonic: String) {
/* Returns Mnemonic as string */ /* Returns Mnemonic as string */
fun asString(): String fun asString(): String
/* Parse a Mnemonic from a given string. */ /* Parse a Mnemonic from a given string. */
fun fromString(): Mnemonic fun fromString(): Mnemonic
/* /*
* Create a new Mnemonic in the specified language from the given entropy. Entropy must be a * Create a new Mnemonic in the specified language from the given entropy. Entropy must be a
* multiple of 32 bits (4 bytes) and 128-256 bits in length. * multiple of 32 bits (4 bytes) and 128-256 bits in length.
*/ */
fun fromEntropy(): Mnemonic fun fromEntropy(): Mnemonic
} }

View File

@ -243,3 +243,34 @@ fun mnemonicSample() {
println(mnemonic0.asString(), mnemonic1.asString(), mnemonic2.asString()) println(mnemonic0.asString(), mnemonic1.asString(), mnemonic2.asString())
} }
fun descriptorTemplates1() {
// Bip84 private descriptor
val recoveryPhrase: String = "scene change clap smart together mind wheel knee clip normal trial unusual"
val mnemonic = Mnemonic.fromString(recoveryPhrase)
val bip32ExtendedRootKey: DescriptorSecretKey = DescriptorSecretKey(Network.TESTNET, mnemonic, null)
val bip84ExternalDescriptor: Descriptor = Descriptor.newBip84(bip32ExtendedRootKey, KeychainKind.EXTERNAL, Network.TESTNET)
}
fun descriptorTemplates2() {
// Bip49 public descriptor
// assume we already have the xpub for m/49'/0'/1' created on an external device that only shared the xpub with the wallet
// using the template requires the parent fingerprint to populate correctly the metadata of PSBTs, which the external device would provide
// the xpub (tpub for testnet): tpubDC65ZRvk1NDddHrVAUAZrUPJ772QXzooNYmPywYF9tMyNLYKf5wpKE7ZJvK9kvfG3FV7rCsHBNXy1LVKW95jrmC7c7z4hq7a27aD2sRrAhR
// the fingerprint: d1d04177
val descriptorPublicKey: DescriptorPublicKey = DescriptorPublicKey.fromString("tpubDC65ZRvk1NDddHrVAUAZrUPJ772QXzooNYmPywYF9tMyNLYKf5wpKE7ZJvK9kvfG3FV7rCsHBNXy1LVKW95jrmC7c7z4hq7a27aD2sRrAhR")
val bip49PublicDescriptor: Descriptor = Descriptor.newBip49Public(
publicKey = descriptorPublicKey,
fingerprint = "d1d04177",
keychain = KeychainKind.EXTERNAL,
network = Network.TESTNET,
)
println(bip49PublicDescriptor.asString()) // sh(wpkh([d1d04177/49'/1'/0']tpubDC65ZRvk1NDddHrVAUAZrUPJ772QXzooNYmPywYF9tMyNLYKf5wpKE7ZJvK9kvfG3FV7rCsHBNXy1LVKW95jrmC7c7z4hq7a27aD2sRrAhR/0/*))#a7lxzefl
println(bip49PublicDescriptor.asStringPrivate()) // sh(wpkh([d1d04177/49'/1'/0']tpubDC65ZRvk1NDddHrVAUAZrUPJ772QXzooNYmPywYF9tMyNLYKf5wpKE7ZJvK9kvfG3FV7rCsHBNXy1LVKW95jrmC7c7z4hq7a27aD2sRrAhR/0/*))#a7lxzefl
// Creating it starting from the full xprv derived from a mnemonic will give you the same public descriptor
val mnemonic = Mnemonic.fromString("chaos fabric time speed sponsor all flat solution wisdom trophy crack object robot pave observe combine where aware bench orient secret primary cable detect")
val bip32ExtendedRootKey: DescriptorSecretKey = DescriptorSecretKey(Network.TESTNET, mnemonic, null)
val bip49PrivateDescriptor: Descriptor = Descriptor.newBip49(bip32ExtendedRootKey, KeychainKind.EXTERNAL, Network.TESTNET)
println(bip49PrivateDescriptor.asString()) // sh(wpkh([d1d04177/49'/1'/0']tpubDC65ZRvk1NDddHrVAUAZrUPJ772QXzooNYmPywYF9tMyNLYKf5wpKE7ZJvK9kvfG3FV7rCsHBNXy1LVKW95jrmC7c7z4hq7a27aD2sRrAhR/0/*))#a7lxzefl
}

View File

@ -1697,19 +1697,18 @@ mod test {
); );
// when using as_string on a private key, we get the same result as when using it on a public key // when using as_string on a private key, we get the same result as when using it on a public key
// these currently fails as described in #817 assert_eq!(
// assert_eq!( template_private_44.as_string(),
// template_private_44.as_string(), template_public_44.as_string()
// template_public_44.as_string() );
// ); assert_eq!(
// assert_eq!( template_private_49.as_string(),
// template_private_49.as_string(), template_public_49.as_string()
// template_public_49.as_string() );
// ); assert_eq!(
// assert_eq!( template_private_84.as_string(),
// template_private_84.as_string(), template_public_84.as_string()
// template_public_84.as_string() );
// );
} }
#[test] #[test]