Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions include/wally.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,18 @@ inline int descriptor_canonicalize(const DESCRIPTOR& descriptor, uint32_t flags,
return detail::check_ret(__FUNCTION__, ret);
}

template <class DESCRIPTOR>
inline int descriptor_derive_bip32_key(const DESCRIPTOR& descriptor, size_t index, uint32_t variant, uint32_t multi_index, uint32_t child_num, uint32_t flags, struct ext_key* output) {
int ret = ::wally_descriptor_derive_bip32_key(detail::get_p(descriptor), index, variant, multi_index, child_num, flags, output);
return detail::check_ret(__FUNCTION__, ret);
}

template <class DESCRIPTOR>
inline int descriptor_derive_bip32_key_alloc(const DESCRIPTOR& descriptor, size_t index, uint32_t variant, uint32_t multi_index, uint32_t child_num, uint32_t flags, struct ext_key** output) {
int ret = ::wally_descriptor_derive_bip32_key_alloc(detail::get_p(descriptor), index, variant, multi_index, child_num, flags, output);
return detail::check_ret(__FUNCTION__, ret);
}

inline int descriptor_free(struct wally_descriptor* descriptor) {
int ret = ::wally_descriptor_free(descriptor);
return detail::check_ret(__FUNCTION__, ret);
Expand Down Expand Up @@ -623,6 +635,60 @@ inline int descriptor_get_num_variants(const DESCRIPTOR& descriptor, uint32_t* v
return detail::check_ret(__FUNCTION__, ret);
}

template <class DESCRIPTOR, class BYTES_OUT>
inline int descriptor_get_taproot_control_block(const DESCRIPTOR& descriptor, uint32_t leaf_index, uint32_t multi_index, uint32_t child_num, uint32_t flags, BYTES_OUT& bytes_out, size_t* written) {
int ret = ::wally_descriptor_get_taproot_control_block(detail::get_p(descriptor), leaf_index, multi_index, child_num, flags, bytes_out.data(), bytes_out.size(), written);
return detail::check_ret(__FUNCTION__, ret);
}

template <class DESCRIPTOR>
inline int descriptor_get_taproot_control_block_len(const DESCRIPTOR& descriptor, uint32_t leaf_index, uint32_t multi_index, uint32_t child_num, uint32_t flags, size_t* written) {
int ret = ::wally_descriptor_get_taproot_control_block_len(detail::get_p(descriptor), leaf_index, multi_index, child_num, flags, written);
return detail::check_ret(__FUNCTION__, ret);
}

template <class DESCRIPTOR, class BYTES_OUT>
inline int descriptor_get_taproot_leaf_hash(const DESCRIPTOR& descriptor, uint32_t leaf_index, uint32_t multi_index, uint32_t child_num, uint32_t flags, BYTES_OUT& bytes_out) {
int ret = ::wally_descriptor_get_taproot_leaf_hash(detail::get_p(descriptor), leaf_index, multi_index, child_num, flags, bytes_out.data(), bytes_out.size());
return detail::check_ret(__FUNCTION__, ret);
}

template <class DESCRIPTOR>
inline int descriptor_get_taproot_leaf_key_index(const DESCRIPTOR& descriptor, uint32_t leaf_index, uint32_t key_index, uint32_t* value_out) {
int ret = ::wally_descriptor_get_taproot_leaf_key_index(detail::get_p(descriptor), leaf_index, key_index, value_out);
return detail::check_ret(__FUNCTION__, ret);
}

template <class DESCRIPTOR>
inline int descriptor_get_taproot_leaf_num_keys(const DESCRIPTOR& descriptor, uint32_t leaf_index, uint32_t* value_out) {
int ret = ::wally_descriptor_get_taproot_leaf_num_keys(detail::get_p(descriptor), leaf_index, value_out);
return detail::check_ret(__FUNCTION__, ret);
}

template <class DESCRIPTOR, class BYTES_OUT>
inline int descriptor_get_taproot_leaf_script(const DESCRIPTOR& descriptor, uint32_t leaf_index, uint32_t multi_index, uint32_t child_num, uint32_t flags, BYTES_OUT& bytes_out, size_t* written) {
int ret = ::wally_descriptor_get_taproot_leaf_script(detail::get_p(descriptor), leaf_index, multi_index, child_num, flags, bytes_out.data(), bytes_out.size(), written);
return detail::check_ret(__FUNCTION__, ret);
}

template <class DESCRIPTOR>
inline int descriptor_get_taproot_leaf_script_len(const DESCRIPTOR& descriptor, uint32_t leaf_index, uint32_t multi_index, uint32_t child_num, uint32_t flags, size_t* written) {
int ret = ::wally_descriptor_get_taproot_leaf_script_len(detail::get_p(descriptor), leaf_index, multi_index, child_num, flags, written);
return detail::check_ret(__FUNCTION__, ret);
}

template <class DESCRIPTOR, class BYTES_OUT>
inline int descriptor_get_taproot_merkle_root(const DESCRIPTOR& descriptor, uint32_t multi_index, uint32_t child_num, uint32_t flags, BYTES_OUT& bytes_out) {
int ret = ::wally_descriptor_get_taproot_merkle_root(detail::get_p(descriptor), multi_index, child_num, flags, bytes_out.data(), bytes_out.size());
return detail::check_ret(__FUNCTION__, ret);
}

template <class DESCRIPTOR>
inline int descriptor_get_taproot_num_leaves(const DESCRIPTOR& descriptor, uint32_t* value_out) {
int ret = ::wally_descriptor_get_taproot_num_leaves(detail::get_p(descriptor), value_out);
return detail::check_ret(__FUNCTION__, ret);
}

template <class DESCRIPTOR, class VARS_IN>
inline int descriptor_parse(const DESCRIPTOR& descriptor, const VARS_IN& vars_in, uint32_t network, uint32_t flags, struct wally_descriptor** output) {
int ret = ::wally_descriptor_parse(detail::get_p(descriptor), detail::get_p(vars_in), network, flags, output);
Expand Down
238 changes: 225 additions & 13 deletions include/wally_descriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
extern "C" {
#endif

struct ext_key;
struct wally_map;
/** An opaque type holding a parsed minscript/descriptor expression */
struct wally_descriptor;
Expand All @@ -22,25 +23,29 @@ struct wally_descriptor;
#define WALLY_MINISCRIPT_DEPTH_SHIFT 16 /** Shift to convert maximum depth to flags */

/*** miniscript-features Miniscript/Descriptor feature flags */
#define WALLY_MS_IS_RANGED 0x001 /** Allows key ranges via ``*`` */
#define WALLY_MS_IS_MULTIPATH 0x002 /** Allows multiple paths via ``<a;b;c>`` */
#define WALLY_MS_IS_PRIVATE 0x004 /** Contains at least one private key */
#define WALLY_MS_IS_UNCOMPRESSED 0x008 /** Contains at least one uncompressed key */
#define WALLY_MS_IS_RAW 0x010 /** Contains at least one raw key */
#define WALLY_MS_IS_DESCRIPTOR 0x020 /** Contains only descriptor expressions (no miniscript) */
#define WALLY_MS_IS_X_ONLY 0x040 /** Contains at least one x-only key */
#define WALLY_MS_IS_PARENTED 0x080 /** Contains at least one key key with a parent key origin */
#define WALLY_MS_IS_ELEMENTS 0x100 /** Contains Elements expressions or was parsed as Elements */
#define WALLY_MS_IS_SLIP77 0x200 /** A confidential ct() descriptor with SLIP-77 blinding */
#define WALLY_MS_IS_ELIP150 0x400 /** A confidential ct() descriptor with ELIP-150 blinding */
#define WALLY_MS_IS_ELIP151 0x800 /** A confidential ct() descriptor with ELIP-151 blinding */
#define WALLY_MS_ANY_BLINDING_KEY 0xE00 /** SLIP-77, ELIP-150 or ELIP-151 blinding key present */
#define WALLY_MS_IS_RANGED 0x0001 /** Allows key ranges via ``*`` */
#define WALLY_MS_IS_MULTIPATH 0x0002 /** Allows multiple paths via ``<a;b;c>`` */
#define WALLY_MS_IS_PRIVATE 0x0004 /** Contains at least one private key */
#define WALLY_MS_IS_UNCOMPRESSED 0x0008 /** Contains at least one uncompressed key */
#define WALLY_MS_IS_RAW 0x0010 /** Contains at least one raw key */
#define WALLY_MS_IS_DESCRIPTOR 0x0020 /** Contains only descriptor expressions (no miniscript) */
#define WALLY_MS_IS_X_ONLY 0x0040 /** Contains at least one x-only key */
#define WALLY_MS_IS_PARENTED 0x0080 /** Contains at least one key with a parent key origin */
#define WALLY_MS_IS_ELEMENTS 0x0100 /** Contains Elements expressions or was parsed as Elements */
#define WALLY_MS_IS_SLIP77 0x0200 /** A confidential ct() descriptor with SLIP-77 blinding */
#define WALLY_MS_IS_ELIP150 0x0400 /** A confidential ct() descriptor with ELIP-150 blinding */
#define WALLY_MS_IS_ELIP151 0x0800 /** A confidential ct() descriptor with ELIP-151 blinding */
#define WALLY_MS_IS_TAPROOT 0x1000 /** Contains a tr() taproot expression */
#define WALLY_MS_IS_TAPSCRIPT 0x2000 /** Contains a tr(key,{...}) tapscript tree expression */
#define WALLY_MS_ANY_BLINDING_KEY 0x0E00 /** SLIP-77, ELIP-150 or ELIP-151 blinding key present */

/*** ms-canonicalization-flags Miniscript/Descriptor canonicalization flags */
#define WALLY_MS_CANONICAL_NO_CHECKSUM 0x01 /** Do not include a checksum */

#define WALLY_MS_BLINDING_KEY_INDEX 0xffffffff /* Key index for confidential blinding key */

#define WALLY_DESCRIPTOR_TAPTREE_MAX_DEPTH 128 /* BIP-341: maximum taptree depth */

/**
* Parse an output descriptor or miniscript expression.
*
Expand Down Expand Up @@ -306,6 +311,49 @@ WALLY_CORE_API int wally_descriptor_get_key_origin_path_str(
size_t index,
char **output);


/**
* Derive a BIP32 extended key from a parsed output descriptor or miniscript expression.
*
* :param descriptor: Parsed output descriptor or miniscript expression.
* :param index: The zero-based index of the key to get, or `WALLY_MS_BLINDING_KEY_INDEX`
*| to fetch the descriptors blinding key representaton (if any).
* :param variant: The variant of descriptor to derive from. See `wally_descriptor_get_num_variants`.
* :param multi_index: The multi-path item to derive from. See `wally_descriptor_get_num_paths`.
* :param child_num: The BIP32 child number to derive, or 0 for static descriptors.
* :param flags: Use `BIP32_FLAG_KEY_PUBLIC` to return public keys from private keys,
*| and `BIP32_FLAG_SKIP_HASH` to avoid populating the derived key fingerprint.
* :param output: Destination for the resulting derived key.
*
* .. note:: The returned key may be bare (have only the public or private key populated).
*| x-only bare keys have a prefix byte of 0x00. The caller can use `wally_descriptor_get_key_features` to
*| determine the type of a given key before extracting data from it.
*
* .. note:: SLIP77 blinding keys are returned in the private key of the extended key.
*/
WALLY_CORE_API int wally_descriptor_derive_bip32_key(
const struct wally_descriptor *descriptor,
size_t index,
uint32_t variant,
uint32_t multi_index,
uint32_t child_num,
uint32_t flags,
struct ext_key *output);

/**
* Derive a BIP32 extended key from a parsed output descriptor or miniscript expression.
*
* See `wally_descriptor_derive_bip32_key`.
*/
WALLY_CORE_API int wally_descriptor_derive_bip32_key_alloc(
const struct wally_descriptor *descriptor,
size_t index,
uint32_t variant,
uint32_t multi_index,
uint32_t child_num,
uint32_t flags,
struct ext_key **output);

/**
* Get the maximum length of a script corresponding to an output descriptor.
*
Expand Down Expand Up @@ -406,6 +454,170 @@ WALLY_CORE_API int wally_descriptor_to_addresses(
char **output,
size_t num_outputs);

/**
* Get the number of taptree leaves in a taproot output descriptor.
*
* Returns WALLY_EINVAL if the descriptor is not taproot.
*
* :param descriptor: Parsed tr() output descriptor.
* :param value_out: Destination for the number of taptree leaves.
*/
WALLY_CORE_API int wally_descriptor_get_taproot_num_leaves(
const struct wally_descriptor *descriptor,
uint32_t *value_out);

/**
* Get the script for a specific taptree leaf in a taproot output descriptor.
*
* Returns WALLY_EINVAL if the descriptor is not taproot or `leaf_index`
* is out of bounds.
*
* :param descriptor: Parsed tr() output descriptor.
* :param leaf_index: Zero-based leaf index (depth-first, left-to-right order).
* :param multi_index: See `wally_descriptor_get_num_paths`.
* :param child_num: BIP32 child number, or 0 for static descriptors.
* :param flags: For future use. Must be 0.
* :param bytes_out: Destination for the compiled tapscript.
* :param len: Length of ``bytes_out`` in bytes.
* :param written: Destination for the number of bytes written to ``bytes_out``.
*/
WALLY_CORE_API int wally_descriptor_get_taproot_leaf_script(
const struct wally_descriptor *descriptor,
uint32_t leaf_index,
uint32_t multi_index,
uint32_t child_num,
uint32_t flags,
unsigned char *bytes_out,
size_t len,
size_t *written);

/**
* Get the script length for a specific taptree leaf in a taproot output descriptor.
*
* See `wally_descriptor_get_taproot_leaf_script`.
*/
WALLY_CORE_API int wally_descriptor_get_taproot_leaf_script_len(
const struct wally_descriptor *descriptor,
uint32_t leaf_index,
uint32_t multi_index,
uint32_t child_num,
uint32_t flags,
size_t *written);

/**
* Get the tapleaf hash for a specific taptree leaf in a taproot output descriptor.
*
* Returns WALLY_EINVAL if the descriptor is not taproot or `leaf_index`
* is out of bounds.
*
* :param descriptor: Parsed tr() output descriptor.
* :param leaf_index: Zero-based leaf index (depth-first, left-to-right order).
* :param multi_index: See `wally_descriptor_get_num_paths`.
* :param child_num: BIP32 child number, or 0 for static descriptors.
* :param flags: For future use. Must be 0.
* :param bytes_out: Destination for the 32-byte tapleaf hash.
* FIXED_SIZED_OUTPUT(len, bytes_out, SHA256_LEN)
*/
WALLY_CORE_API int wally_descriptor_get_taproot_leaf_hash(
const struct wally_descriptor *descriptor,
uint32_t leaf_index,
uint32_t multi_index,
uint32_t child_num,
uint32_t flags,
unsigned char *bytes_out,
size_t len);

/**
* Get the BIP-341 control block for spending via a specific taptree leaf.
*
* Returns WALLY_EINVAL if the descriptor is not taproot or `leaf_index`
* is out of bounds.
*
* :param descriptor: Parsed tr() output descriptor.
* :param leaf_index: Zero-based leaf index (depth-first, left-to-right order).
* :param multi_index: See `wally_descriptor_get_num_paths`.
* :param child_num: BIP32 child number, or 0 for static descriptors.
* :param flags: For future use. Must be 0.
* :param bytes_out: Destination for the control block bytes.
* :param len: Length of ``bytes_out`` in bytes.
* :param written: Destination for the number of bytes written to ``bytes_out``.
*/
WALLY_CORE_API int wally_descriptor_get_taproot_control_block(
const struct wally_descriptor *descriptor,
uint32_t leaf_index,
uint32_t multi_index,
uint32_t child_num,
uint32_t flags,
unsigned char *bytes_out,
size_t len,
size_t *written);

/**
* Get the BIP-341 control block for spending via a specific taptree leaf.
*
* See `wally_descriptor_get_taproot_control_block`.
*/
WALLY_CORE_API int wally_descriptor_get_taproot_control_block_len(
const struct wally_descriptor *descriptor,
uint32_t leaf_index,
uint32_t multi_index,
uint32_t child_num,
uint32_t flags,
size_t *written);

/**
* Get the number of keys in a specific taptree leaf's miniscript.
*
* Returns WALLY_EINVAL if the descriptor is not taproot or `leaf_index`
* is out of bounds.
*
* :param descriptor: Parsed tr() output descriptor.
* :param leaf_index: Zero-based leaf index (depth-first, left-to-right order).
* :param value_out: Destination for the key count.
*/
WALLY_CORE_API int wally_descriptor_get_taproot_leaf_num_keys(
const struct wally_descriptor *descriptor,
uint32_t leaf_index,
uint32_t *value_out);

/**
* Get the descriptor-level key index for a key within a specific taptree leaf.
*
* Returns WALLY_EINVAL if the descriptor is not taproot or `leaf_index`
* is out of bounds.
*
* :param descriptor: Parsed tr() output descriptor.
* :param leaf_index: Zero-based leaf index (depth-first, left-to-right order).
* :param key_index: Zero-based index of the key within the leaf's miniscript.
* :param value_out: Destination for the descriptor-level key index
*| (suitable for use with `wally_descriptor_get_key`).
*/
WALLY_CORE_API int wally_descriptor_get_taproot_leaf_key_index(
const struct wally_descriptor *descriptor,
uint32_t leaf_index,
uint32_t key_index,
uint32_t *value_out);

/**
* Get the merkle root of the taptree in a tr() descriptor.
*
* Returns WALLY_EINVAL if the descriptor does not contain a taptree.
*
* :param descriptor: Parsed tr() output descriptor.
* :param multi_index: See `wally_descriptor_get_num_paths`.
* :param child_num: BIP32 child number, or 0 for static descriptors.
* :param flags: For future use. Must be 0.
* :param bytes_out: Destination for the 32-byte merkle root.
* FIXED_SIZED_OUTPUT(len, bytes_out, SHA256_LEN)
*/
WALLY_CORE_API int wally_descriptor_get_taproot_merkle_root(
const struct wally_descriptor *descriptor,
uint32_t multi_index,
uint32_t child_num,
uint32_t flags,
unsigned char *bytes_out,
size_t len);

#ifdef __cplusplus
}
#endif
Expand Down
4 changes: 4 additions & 0 deletions include/wally_script.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ extern "C" {
#define WALLY_SCRIPTPUBKEY_P2WSH_LEN 34 /** OP_0 [SHA256] */
#define WALLY_SCRIPTPUBKEY_P2TR_LEN 34 /** OP_1 [X-ONLY-PUBKEY] */

#define WALLY_LEAF_VERSION_TAPSCRIPT 0xc0 /** BIP-342 tapscript leaf version */

#define WALLY_SCRIPTPUBKEY_OP_RETURN_MAX_LEN 83 /** OP_RETURN [80 bytes of data] */

#define WALLY_MAX_OP_RETURN_LEN 80 /* Maximum length of OP_RETURN data push */
Expand Down Expand Up @@ -171,6 +173,8 @@ extern "C" {
#define OP_NOP9 0xb8
#define OP_NOP10 0xb9

#define OP_CHECKSIGADD 0xba /* BIP-342 tapscript */

#define OP_INVALIDOPCODE 0xff
#endif /* WALLY_DISABLE_OP_CODE */

Expand Down
Loading
Loading