@@ -32,13 +32,15 @@ use crate::{
3232} ;
3333
3434mod bare;
35+ mod iter;
3536mod segwitv0;
3637mod sh;
3738mod sortedmulti;
3839mod tr;
3940
4041// Descriptor Exports
4142pub use self :: bare:: { Bare , Pkh } ;
43+ pub use self :: iter:: PkIter ;
4244pub use self :: segwitv0:: { Wpkh , Wsh , WshInner } ;
4345pub use self :: sh:: { Sh , ShInner } ;
4446pub use self :: sortedmulti:: SortedMultiVec ;
@@ -241,6 +243,29 @@ impl<Pk: MiniscriptKey> Descriptor<Pk> {
241243 Ok ( Descriptor :: Tr ( Tr :: new ( key, script) ?) )
242244 }
243245
246+ /// An iterator over all the keys referenced in the descriptor.
247+ pub fn iter_pk ( & self ) -> PkIter < ' _ , Pk > {
248+ match * self {
249+ Descriptor :: Bare ( ref bare) => PkIter :: from_miniscript_bare ( bare. as_inner ( ) ) ,
250+ Descriptor :: Pkh ( ref pk) => PkIter :: from_key ( pk. as_inner ( ) . clone ( ) ) ,
251+ Descriptor :: Wpkh ( ref pk) => PkIter :: from_key ( pk. as_inner ( ) . clone ( ) ) ,
252+ Descriptor :: Sh ( ref sh) => match * sh. as_inner ( ) {
253+ ShInner :: Wsh ( ref wsh) => match wsh. as_inner ( ) {
254+ WshInner :: SortedMulti ( ref sorted) => PkIter :: from_sortedmulti ( sorted. pks ( ) ) ,
255+ WshInner :: Ms ( ref ms) => PkIter :: from_miniscript_segwit ( ms) ,
256+ } ,
257+ ShInner :: Wpkh ( ref pk) => PkIter :: from_key ( pk. as_inner ( ) . clone ( ) ) ,
258+ ShInner :: SortedMulti ( ref sorted) => PkIter :: from_sortedmulti ( sorted. pks ( ) ) ,
259+ ShInner :: Ms ( ref ms) => PkIter :: from_miniscript_legacy ( ms) ,
260+ } ,
261+ Descriptor :: Wsh ( ref wsh) => match wsh. as_inner ( ) {
262+ WshInner :: SortedMulti ( ref sorted) => PkIter :: from_sortedmulti ( sorted. pks ( ) ) ,
263+ WshInner :: Ms ( ref ms) => PkIter :: from_miniscript_segwit ( ms) ,
264+ } ,
265+ Descriptor :: Tr ( ref tr) => PkIter :: from_tr ( tr) ,
266+ }
267+ }
268+
244269 /// For a Taproot descriptor, returns the internal key.
245270 pub fn internal_key ( & self ) -> Option < & Pk > {
246271 if let Descriptor :: Tr ( ref tr) = self {
@@ -2237,4 +2262,173 @@ pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
22372262
22382263 assert_eq ! ( xonly_pk_descriptor. to_string( ) , xonly_converted_descriptor. to_string( ) ) ;
22392264 }
2265+
2266+ #[ test]
2267+ fn test_iter_pk ( ) {
2268+ // Test Bare descriptor
2269+ let bare_desc = Descriptor :: < PublicKey > :: from_str (
2270+ "pk(020000000000000000000000000000000000000000000000000000000000000002)" ,
2271+ )
2272+ . unwrap ( ) ;
2273+ let keys: Vec < _ > = bare_desc. iter_pk ( ) . collect ( ) ;
2274+ assert_eq ! ( keys. len( ) , 1 ) ;
2275+ assert_eq ! (
2276+ keys[ 0 ] . to_string( ) ,
2277+ "020000000000000000000000000000000000000000000000000000000000000002"
2278+ ) ;
2279+
2280+ // Test Pkh descriptor
2281+ let pkh_desc = Descriptor :: < PublicKey > :: from_str (
2282+ "pkh(020000000000000000000000000000000000000000000000000000000000000002)" ,
2283+ )
2284+ . unwrap ( ) ;
2285+ let keys: Vec < _ > = pkh_desc. iter_pk ( ) . collect ( ) ;
2286+ assert_eq ! ( keys. len( ) , 1 ) ;
2287+ assert_eq ! (
2288+ keys[ 0 ] . to_string( ) ,
2289+ "020000000000000000000000000000000000000000000000000000000000000002"
2290+ ) ;
2291+
2292+ // Test Wpkh descriptor
2293+ let wpkh_desc = Descriptor :: < PublicKey > :: from_str (
2294+ "wpkh(020000000000000000000000000000000000000000000000000000000000000002)" ,
2295+ )
2296+ . unwrap ( ) ;
2297+ let keys: Vec < _ > = wpkh_desc. iter_pk ( ) . collect ( ) ;
2298+ assert_eq ! ( keys. len( ) , 1 ) ;
2299+ assert_eq ! (
2300+ keys[ 0 ] . to_string( ) ,
2301+ "020000000000000000000000000000000000000000000000000000000000000002"
2302+ ) ;
2303+
2304+ // Test Sh descriptor with a miniscript
2305+ let sh_desc = Descriptor :: < PublicKey > :: from_str (
2306+ "sh(or_d(pk(021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b),pk(0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6)))"
2307+ ) . unwrap ( ) ;
2308+ let keys: Vec < _ > = sh_desc. iter_pk ( ) . collect ( ) ;
2309+ assert_eq ! ( keys. len( ) , 2 ) ;
2310+ assert_eq ! (
2311+ keys[ 0 ] . to_string( ) ,
2312+ "021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b"
2313+ ) ;
2314+ assert_eq ! (
2315+ keys[ 1 ] . to_string( ) ,
2316+ "0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6"
2317+ ) ;
2318+
2319+ // Test Sh-Wpkh descriptor
2320+ let shwpkh_desc = Descriptor :: < PublicKey > :: from_str (
2321+ "sh(wpkh(020000000000000000000000000000000000000000000000000000000000000002))" ,
2322+ )
2323+ . unwrap ( ) ;
2324+ let keys: Vec < _ > = shwpkh_desc. iter_pk ( ) . collect ( ) ;
2325+ assert_eq ! ( keys. len( ) , 1 ) ;
2326+ assert_eq ! (
2327+ keys[ 0 ] . to_string( ) ,
2328+ "020000000000000000000000000000000000000000000000000000000000000002"
2329+ ) ;
2330+
2331+ // Test Sh-Wsh descriptor
2332+ let shwsh_desc = Descriptor :: < PublicKey > :: from_str (
2333+ "sh(wsh(or_d(pk(021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b),pk(0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6))))"
2334+ ) . unwrap ( ) ;
2335+ let keys: Vec < _ > = shwsh_desc. iter_pk ( ) . collect ( ) ;
2336+ assert_eq ! ( keys. len( ) , 2 ) ;
2337+ assert_eq ! (
2338+ keys[ 0 ] . to_string( ) ,
2339+ "021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b"
2340+ ) ;
2341+ assert_eq ! (
2342+ keys[ 1 ] . to_string( ) ,
2343+ "0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6"
2344+ ) ;
2345+
2346+ // Test Wsh descriptor
2347+ let wsh_desc = Descriptor :: < PublicKey > :: from_str (
2348+ "wsh(or_d(pk(021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b),pk(0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6)))"
2349+ ) . unwrap ( ) ;
2350+ let keys: Vec < _ > = wsh_desc. iter_pk ( ) . collect ( ) ;
2351+ assert_eq ! ( keys. len( ) , 2 ) ;
2352+ assert_eq ! (
2353+ keys[ 0 ] . to_string( ) ,
2354+ "021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b"
2355+ ) ;
2356+ assert_eq ! (
2357+ keys[ 1 ] . to_string( ) ,
2358+ "0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6"
2359+ ) ;
2360+
2361+ // Test SortedMulti descriptors
2362+ let sortedmulti_desc = Descriptor :: < PublicKey > :: from_str (
2363+ "sh(sortedmulti(2,021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b,0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))"
2364+ ) . unwrap ( ) ;
2365+ let keys: Vec < _ > = sortedmulti_desc. iter_pk ( ) . collect ( ) ;
2366+ assert_eq ! ( keys. len( ) , 3 ) ;
2367+ // Keys are sorted in the output
2368+ assert ! ( keys. iter( ) . any( |k| k. to_string( )
2369+ == "021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b" ) ) ;
2370+ assert ! ( keys. iter( ) . any( |k| k. to_string( )
2371+ == "0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6" ) ) ;
2372+ assert ! ( keys. iter( ) . any( |k| k. to_string( )
2373+ == "03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556" ) ) ;
2374+
2375+ // Test Taproot descriptor with only key path
2376+ let tr_key_only_desc = Descriptor :: < PublicKey > :: from_str (
2377+ "tr(020000000000000000000000000000000000000000000000000000000000000002)" ,
2378+ )
2379+ . unwrap ( ) ;
2380+ let keys: Vec < _ > = tr_key_only_desc. iter_pk ( ) . collect ( ) ;
2381+ assert_eq ! ( keys. len( ) , 1 ) ;
2382+ assert_eq ! (
2383+ keys[ 0 ] . to_string( ) ,
2384+ "020000000000000000000000000000000000000000000000000000000000000002"
2385+ ) ;
2386+
2387+ // Test Taproot descriptor with script path
2388+ // The internal key should be yielded first
2389+ let internal_key = "020000000000000000000000000000000000000000000000000000000000000002" ;
2390+ let script_key1 = "021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b" ;
2391+ let script_key2 = "0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6" ;
2392+
2393+ let tr_with_script_desc = Descriptor :: < PublicKey > :: from_str ( & format ! (
2394+ "tr({},{{pk({}),pk({})}})" ,
2395+ internal_key, script_key1, script_key2,
2396+ ) )
2397+ . unwrap ( ) ;
2398+
2399+ let keys: Vec < _ > = tr_with_script_desc. iter_pk ( ) . collect ( ) ;
2400+ assert_eq ! ( keys. len( ) , 3 ) ;
2401+
2402+ // Verify internal key is first
2403+ assert_eq ! ( keys[ 0 ] . to_string( ) , internal_key) ;
2404+
2405+ // Verify other keys are present (order after internal key is not guaranteed)
2406+ assert ! ( keys[ 1 ..] . iter( ) . any( |k| k. to_string( ) == script_key1) ) ;
2407+ assert ! ( keys[ 1 ..] . iter( ) . any( |k| k. to_string( ) == script_key2) ) ;
2408+
2409+ // Test Taproot descriptor with complex script tree
2410+ let tr_complex_desc = Descriptor :: < PublicKey > :: from_str ( & format ! (
2411+ "tr({},{{pk({}),{{pk({}),or_d(pk({}),pk({}))}}}})" ,
2412+ internal_key,
2413+ script_key1,
2414+ script_key2,
2415+ "03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556" ,
2416+ "0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352"
2417+ ) )
2418+ . unwrap ( ) ;
2419+
2420+ let keys: Vec < _ > = tr_complex_desc. iter_pk ( ) . collect ( ) ;
2421+ assert_eq ! ( keys. len( ) , 5 ) ;
2422+
2423+ // Verify internal key is first
2424+ assert_eq ! ( keys[ 0 ] . to_string( ) , internal_key) ;
2425+
2426+ // Verify all other keys are present
2427+ assert ! ( keys[ 1 ..] . iter( ) . any( |k| k. to_string( ) == script_key1) ) ;
2428+ assert ! ( keys[ 1 ..] . iter( ) . any( |k| k. to_string( ) == script_key2) ) ;
2429+ assert ! ( keys[ 1 ..] . iter( ) . any( |k| k. to_string( )
2430+ == "03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556" ) ) ;
2431+ assert ! ( keys[ 1 ..] . iter( ) . any( |k| k. to_string( )
2432+ == "0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352" ) ) ;
2433+ }
22402434}
0 commit comments