@@ -15,9 +15,29 @@ use miniscript::psbt::{PsbtExt, PsbtInputExt};
1515use miniscript:: { Descriptor , DescriptorPublicKey } ;
1616
1717fn main ( ) {
18- // Defining the descriptor
18+ // Defining the descriptor keys
1919 let secp256k1 = secp256k1:: Secp256k1 :: new ( ) ;
20- let s = "wsh(t:or_c(pk(027a3565454fe1b749bccaef22aff72843a9c3efefd7b16ac54537a0c23f0ec0de),v:thresh(1,pkh(032d672a1a91cc39d154d366cd231983661b0785c7f27bc338447565844f4a6813),a:pkh(03417129311ed34c242c012cd0a3e0b9bca0065f742d0dfb63c78083ea6a02d4d9),a:pkh(025a687659658baeabdfc415164528065be7bcaade19342241941e556557f01e28))))#7hut9ukn" ;
20+ let keys = vec ! [
21+ "027a3565454fe1b749bccaef22aff72843a9c3efefd7b16ac54537a0c23f0ec0de" ,
22+ "032d672a1a91cc39d154d366cd231983661b0785c7f27bc338447565844f4a6813" ,
23+ "03417129311ed34c242c012cd0a3e0b9bca0065f742d0dfb63c78083ea6a02d4d9" ,
24+ "025a687659658baeabdfc415164528065be7bcaade19342241941e556557f01e28" ,
25+ ] ;
26+ // The wsh descriptor indicates a Witness Script Hash, meaning the descriptor is for a SegWit script.
27+ // wsh(or(pk(A),thresh(1,pkh(B),pkh(C),pkh(D))))
28+
29+ // Let's break it down:
30+ // t:or_c specifies an "or" construct, which means the script can be satisfied by one of the given conditions:
31+ // pk(A) OR thresh(1,pkh(B),pkh(C),pkh(D))
32+ // Inside threshold condition atleast 1 out of all given conditions should satisfy.
33+
34+ // By constructing transactions using this wsh descriptor and signing them appropriately,
35+ // you can create flexible spending policies that enable different spending paths and conditions depending on the
36+ // transaction's inputs and outputs.
37+ let s = format ! (
38+ "wsh(t:or_c(pk({}),v:thresh(1,pkh({}),a:pkh({}),a:pkh({}))))#7hut9ukn" ,
39+ keys[ 0 ] , keys[ 1 ] , keys[ 2 ] , keys[ 3 ]
40+ ) ;
2141 let bridge_descriptor = Descriptor :: from_str ( & s) . expect ( "parse descriptor string" ) ;
2242
2343 assert ! ( bridge_descriptor. sanity_check( ) . is_ok( ) ) ;
@@ -116,10 +136,12 @@ fn main() {
116136 value : amount * 4 / 5 ,
117137 } ) ;
118138
119- // Plan the Transaction using available assets
120- // The descriptor is : or(pk(A),thresh(1,pkh(B),pkh(C),pkh(D)))
121- // For the context of planning in this example, We will only provide the key A as an asset
122- // This will satisfy the pk(A) and since we have an OR, This should be sufficient to satisfy the given policy.
139+ // Consider that out of all the keys required to sign the descriptor, we only have some handful of assets.
140+ // We can plan the PSBT with only few assets(keys or hashes) if that are enough for satisfying any policy.
141+ //
142+ // Here for example assume that we only have one key available i.e Key A(as seen from the descriptor above)
143+ // Key A is enough to satisfy the given descriptor because it is OR.
144+ // We have to add the key to `Asset` and then obtain plan with only available signature if the descriptor can be satisfied.
123145 let mut assets = Assets :: new ( ) ;
124146 assets = assets. add (
125147 DescriptorPublicKey :: from_str (
@@ -128,12 +150,14 @@ fn main() {
128150 . unwrap ( ) ,
129151 ) ;
130152
131- // Obtain the result of the plan based on provided assets
132- let result = bridge_descriptor. clone ( ) . get_plan ( & assets) ;
153+ // Obtain the Plan based on available Assets
154+ let plan = bridge_descriptor. clone ( ) . get_plan ( & assets) . unwrap ( ) ;
133155
134156 // Creating a PSBT Input
135157 let mut input = psbt:: Input :: default ( ) ;
136- result. unwrap ( ) . update_psbt_input ( & mut input) ;
158+
159+ // Update the PSBT input from the result which we have obtained from the Plan.
160+ plan. update_psbt_input ( & mut input) ;
137161 input
138162 . update_with_descriptor_unchecked ( & bridge_descriptor)
139163 . unwrap ( ) ;
@@ -158,16 +182,11 @@ fn main() {
158182
159183 // Finally construct the signature and add to psbt
160184 let sig1 = secp256k1. sign_ecdsa ( & msg, & sk1) ;
161- let pk1 = backup1_private. public_key ( & secp256k1) ;
185+ let key_a = backup1_private. public_key ( & secp256k1) ;
162186 assert ! ( secp256k1. verify_ecdsa( & msg, & sig1, & pk1. inner) . is_ok( ) ) ;
163187
164- // Second key just in case
165- let sig2 = secp256k1. sign_ecdsa ( & msg, & sk2) ;
166- let pk2 = backup2_private. public_key ( & secp256k1) ;
167- assert ! ( secp256k1. verify_ecdsa( & msg, & sig2, & pk2. inner) . is_ok( ) ) ;
168-
169188 psbt. inputs [ 0 ] . partial_sigs . insert (
170- pk1 ,
189+ key_a ,
171190 bitcoin:: ecdsa:: Signature {
172191 sig : sig1,
173192 hash_ty : hash_ty,
0 commit comments