macro_rules! descriptor {
( bare ( $( $minisc:tt )* ) ) => { ... };
( sh ( wsh ( $( $minisc:tt )* ) ) ) => { ... };
( shwsh ( $( $minisc:tt )* ) ) => { ... };
( pk ( $key:expr ) ) => { ... };
( pkh ( $key:expr ) ) => { ... };
( wpkh ( $key:expr ) ) => { ... };
( sh ( wpkh ( $key:expr ) ) ) => { ... };
( shwpkh ( $key:expr ) ) => { ... };
( sh ( $( $minisc:tt )* ) ) => { ... };
( wsh ( $( $minisc:tt )* ) ) => { ... };
( tr ( $internal_key:expr ) ) => { ... };
( tr ( $internal_key:expr, $( $taptree:tt )* ) ) => { ... };
}
Expand description
Macro to write full descriptors with code
This macro expands to a Result
of
DescriptorTemplateOut
and DescriptorError
The syntax is very similar to the normal descriptor syntax, with the exception that modifiers
cannot be grouped together. For instance, a descriptor fragment like sdv:older(144)
has to be
broken up to s:d:v:older(144)
.
The pk()
, pk_k()
and pk_h()
operands can take as argument any type that implements
IntoDescriptorKey
. This means that keys can also be written inline as strings, but in that
case they must be wrapped in quotes, which is another difference compared to the standard
descriptor syntax.
ยงExample
Signature plus timelock descriptor:
let (my_descriptor, my_keys_map, networks) = bdk_wallet::descriptor!(sh(wsh(and_v(v:pk("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy"),older(50)))))?;
2-of-3 that becomes a 1-of-3 after a timelock has expired. Both descriptor_a
and descriptor_b
are equivalent: the first
syntax is more suitable for a fixed number of items known at compile time, while the other accepts a
Vec
of items, which makes it more suitable for writing dynamic descriptors.
They both produce the descriptor: wsh(thresh(2,pk(...),s:pk(...),sndv:older(...)))
let my_key_1 = bitcoin::PublicKey::from_str(
"02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c",
)?;
let my_key_2 =
bitcoin::PrivateKey::from_wif("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy")?;
let my_timelock = 50;
let (descriptor_a, key_map_a, networks) = bdk_wallet::descriptor! {
wsh (
thresh(2, pk(my_key_1), s:pk(my_key_2), s:n:d:v:older(my_timelock))
)
}?;
#[rustfmt::skip]
let b_items = vec![
bdk_wallet::fragment!(pk(my_key_1))?,
bdk_wallet::fragment!(s:pk(my_key_2))?,
bdk_wallet::fragment!(s:n:d:v:older(my_timelock))?,
];
let (descriptor_b, mut key_map_b, networks) =
bdk_wallet::descriptor!(wsh(thresh_vec(2, b_items)))?;
assert_eq!(descriptor_a, descriptor_b);
assert_eq!(key_map_a.len(), key_map_b.len());
Simple 2-of-2 multi-signature, equivalent to: wsh(multi(2, ...))
let my_key_1 = bitcoin::PublicKey::from_str(
"02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c",
)?;
let my_key_2 =
bitcoin::PrivateKey::from_wif("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy")?;
let (descriptor, key_map, networks) = bdk_wallet::descriptor! {
wsh (
multi(2, my_key_1, my_key_2)
)
}?;
Native-Segwit single-sig, equivalent to: wpkh(...)
let my_key =
bitcoin::PrivateKey::from_wif("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy")?;
let (descriptor, key_map, networks) = bdk_wallet::descriptor!(wpkh(my_key))?;