Skip to content

Commit f298a44

Browse files
committed
descriptor: allow caller to fetch node features for keys
This is required e.g. to differentiate x-only keys.
1 parent fa9b984 commit f298a44

File tree

9 files changed

+53
-16
lines changed

9 files changed

+53
-16
lines changed

include/wally.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,12 @@ inline int descriptor_get_key_child_path_str_len(const DESCRIPTOR& descriptor, s
522522
return ret;
523523
}
524524

525+
template <class DESCRIPTOR>
526+
inline int descriptor_get_key_features(const DESCRIPTOR& descriptor, size_t index, uint32_t* value_out) {
527+
int ret = ::wally_descriptor_get_key_features(detail::get_p(descriptor), index, value_out);
528+
return ret;
529+
}
530+
525531
template <class DESCRIPTOR>
526532
inline int descriptor_get_network(const DESCRIPTOR& descriptor, uint32_t* value_out) {
527533
int ret = ::wally_descriptor_get_network(detail::get_p(descriptor), value_out);

include/wally_descriptor.h

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -202,16 +202,27 @@ WALLY_CORE_API int wally_descriptor_get_num_keys(
202202
* :param output: Destination for the resulting string representation.
203203
*| The string returned should be freed using `wally_free_string`.
204204
*
205-
* .. note:: Keys may be BIP32 xpub/xpriv, WIF or hex pubkeys. The caller
206-
*| can use `wally_descriptor_get_features` to determine which key types
207-
*| are present.
208-
*
205+
* .. note:: Keys may be BIP32 xpub/xpriv, WIF or hex pubkeys, and may be
206+
*| x-only. The caller can use `wally_descriptor_get_key_features` to
207+
*| determine the type of a given key.
209208
*/
210209
WALLY_CORE_API int wally_descriptor_get_key(
211210
const struct wally_descriptor *descriptor,
212211
size_t index,
213212
char **output);
214213

214+
/**
215+
* Get the features of a key in a parsed output descriptor or miniscript expression.
216+
*
217+
* :param descriptor: Parsed output descriptor or miniscript expression.
218+
* :param index: The zero-based index of the key to get.
219+
* :param value_out: Destination for the resulting :ref:`miniscript-features`.
220+
*/
221+
WALLY_CORE_API int wally_descriptor_get_key_features(
222+
const struct wally_descriptor *descriptor,
223+
size_t index,
224+
uint32_t *value_out);
225+
215226
/**
216227
* Get the length of a keys child path string in a parsed output descriptor or miniscript expression.
217228
*

src/descriptor.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2934,6 +2934,19 @@ int wally_descriptor_get_key(const struct wally_descriptor *descriptor,
29342934
return WALLY_OK;
29352935
}
29362936

2937+
int wally_descriptor_get_key_features(const struct wally_descriptor *descriptor,
2938+
size_t index, uint32_t *value_out)
2939+
{
2940+
const ms_node *node = descriptor_get_key(descriptor, index);
2941+
2942+
if (value_out)
2943+
*value_out = 0;
2944+
if (!node || !value_out)
2945+
return WALLY_EINVAL;
2946+
*value_out = node->flags;
2947+
return WALLY_OK;
2948+
}
2949+
29372950
int wally_descriptor_get_key_child_path_str_len(
29382951
const struct wally_descriptor *descriptor, size_t index, size_t *written)
29392952
{

src/swig_java/swig.i

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,7 @@ static jobjectArray create_jstringArray(JNIEnv *jenv, char **p, size_t len) {
564564
%returns_string(wally_descriptor_get_key);
565565
%returns_string(wally_descriptor_get_key_child_path_str);
566566
%returns_size_t(wally_descriptor_get_key_child_path_str_len);
567+
%returns_size_t(wally_descriptor_get_key_features);
567568
%returns_size_t(wally_descriptor_get_num_keys);
568569
%returns_size_t(wally_descriptor_get_num_paths);
569570
%returns_size_t(wally_descriptor_get_num_variants);

src/test/test_descriptor.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -325,24 +325,24 @@ def test_key_iteration(self):
325325
P = POLICY
326326

327327
# Valid args
328-
for flags, descriptor, expected, child_path in [
328+
for flags, descriptor, expected, child_path, expected_features in [
329329
# Bip32 xpub
330-
(0, f'pkh({k1})', k1, ''),
331-
(0, f'pkh({k1}/*)', k1, '*'),
332-
(0, f'pkh({k1}/0/1/2/*)', k1, '0/1/2/*'),
333-
(0, f'pkh({k1}/<0;1>/*)', k1, '<0;1>/*'),
330+
(0, f'pkh({k1})', k1, '', 0),
331+
(0, f'pkh({k1}/*)', k1, '*', MS_IS_RANGED),
332+
(0, f'pkh({k1}/0/1/2/*)', k1, '0/1/2/*', MS_IS_RANGED),
333+
(0, f'pkh({k1}/<0;1>/*)', k1, '<0;1>/*', MS_IS_RANGED|MS_IS_MULTIPATH),
334334
# Bip32 xpub (as policy)
335-
(P, 'pkh(@0/*)', k1, '*'),
336-
(P, 'pkh(@0/**)', k1, '<0;1>/*'),
337-
(P, 'pkh(@0/<0;1>/*)', k1, '<0;1>/*'),
335+
(P, 'pkh(@0/*)', k1, '*', MS_IS_RANGED),
336+
(P, 'pkh(@0/**)', k1, '<0;1>/*', MS_IS_RANGED|MS_IS_MULTIPATH),
337+
(P, 'pkh(@0/<0;1>/*)', k1, '<0;1>/*', MS_IS_RANGED|MS_IS_MULTIPATH),
338338
# BIP32 xprv
339-
(0, f'pkh({k2})', k2, ''),
339+
(0, f'pkh({k2})', k2, '', MS_IS_PRIVATE),
340340
# WIF
341-
(0, f'pkh({wif})', wif, ''),
341+
(0, f'pkh({wif})', wif, '', MS_IS_RAW|MS_IS_PRIVATE),
342342
# Hex pubkey, compressed
343-
(0, f'pk({pk})', pk, ''),
343+
(0, f'pk({pk})', pk, '', MS_IS_RAW),
344344
# Hex pubkey, uncompressed
345-
(0, f'pk({pk_u})', pk_u, ''),
345+
(0, f'pk({pk_u})', pk_u, '', MS_IS_RAW|MS_IS_UNCOMPRESSED),
346346
]:
347347
d = c_void_p()
348348
keys = policy_keys if flags & P else None
@@ -356,6 +356,8 @@ def test_key_iteration(self):
356356
self.assertEqual((ret, path_len), (WALLY_OK, len(child_path)))
357357
ret, path_str = wally_descriptor_get_key_child_path_str(d, 0)
358358
self.assertEqual((ret, path_str), (WALLY_OK, child_path))
359+
ret, features = wally_descriptor_get_key_features(d, 0)
360+
self.assertEqual((ret, features), (WALLY_OK, expected_features))
359361
wally_descriptor_free(d)
360362

361363

src/test/util.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ class wally_psbt(Structure):
316316
('wally_descriptor_get_key', c_int, [c_void_p, c_size_t, c_char_p_p]),
317317
('wally_descriptor_get_key_child_path_str', c_int, [c_void_p, c_size_t, c_char_p_p]),
318318
('wally_descriptor_get_key_child_path_str_len', c_int, [c_void_p, c_size_t, c_size_t_p]),
319+
('wally_descriptor_get_key_features', c_int, [c_void_p, c_size_t, c_uint32_p]),
319320
('wally_descriptor_get_network', c_int, [c_void_p, c_uint32_p]),
320321
('wally_descriptor_get_num_keys', c_int, [c_void_p, c_uint32_p]),
321322
('wally_descriptor_get_num_paths', c_int, [c_void_p, c_uint32_p]),

src/wasm_package/src/functions.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/wasm_package/src/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ export function descriptor_get_depth(descriptor: Ref_wally_descriptor): number;
125125
export function descriptor_get_features(descriptor: Ref_wally_descriptor): number;
126126
export function descriptor_get_key(descriptor: Ref_wally_descriptor, index: number): string;
127127
export function descriptor_get_key_child_path_str_len(descriptor: Ref_wally_descriptor, index: number): number;
128+
export function descriptor_get_key_features(descriptor: Ref_wally_descriptor, index: number): number;
128129
export function descriptor_get_network(descriptor: Ref_wally_descriptor): number;
129130
export function descriptor_get_num_keys(descriptor: Ref_wally_descriptor): number;
130131
export function descriptor_get_num_paths(descriptor: Ref_wally_descriptor): number;

tools/wasm_exports.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ EXPORTED_FUNCTIONS="['_malloc','_free','_bip32_key_free' \
8484
,'_wally_descriptor_get_key' \
8585
,'_wally_descriptor_get_key_child_path_str' \
8686
,'_wally_descriptor_get_key_child_path_str_len' \
87+
,'_wally_descriptor_get_key_features' \
8788
,'_wally_descriptor_get_network' \
8889
,'_wally_descriptor_get_num_keys' \
8990
,'_wally_descriptor_get_num_paths' \

0 commit comments

Comments
 (0)