@@ -34,6 +34,7 @@ struct ProofEntry {
3434 root : String ,
3535 anchor_txid : Option < String > ,
3636 anchor_height : Option < u32 > ,
37+ witness : serde_json:: Value ,
3738}
3839
3940#[ derive( Debug , Serialize ) ]
@@ -84,9 +85,13 @@ struct LifecycleResponse {
8485}
8586
8687#[ derive( Debug , Deserialize ) ]
88+ #[ allow( dead_code) ]
8789struct LifecycleEvent {
8890 leaf_hash : String ,
8991 event_type : String ,
92+ serial_number : Option < String > ,
93+ created_at : Option < String > ,
94+ anchored : Option < bool > ,
9095}
9196
9297struct Cli {
@@ -104,8 +109,8 @@ async fn main() -> Result<()> {
104109 . timeout ( std:: time:: Duration :: from_secs ( 15 ) )
105110 . build ( ) ?;
106111
107- // get leaf hashes to export
108- let leaf_hashes = collect_leaf_hashes ( & client, & cli) . await ?;
112+ // get leaf hashes and lifecycle events
113+ let ( leaf_hashes, leaf_events ) = collect_leaf_hashes ( & client, & cli) . await ?;
109114
110115 if leaf_hashes. is_empty ( ) {
111116 eprintln ! ( "no matching leaves found" ) ;
@@ -134,6 +139,9 @@ async fn main() -> Result<()> {
134139 . await
135140 . with_context ( || format ! ( "invalid proof JSON for {}" , & hash[ ..12 ] ) ) ?;
136141
142+ // find the lifecycle event for this leaf to get witness fields
143+ let lifecycle_event = leaf_events. iter ( ) . find ( |e| e. leaf_hash == * hash) ;
144+
137145 proofs. push ( ProofEntry {
138146 leaf_hash : bundle. leaf . hash ,
139147 event_type : bundle. leaf . event_type ,
@@ -148,6 +156,13 @@ async fn main() -> Result<()> {
148156 root : bundle. root . hash ,
149157 anchor_txid : bundle. anchor . txid ,
150158 anchor_height : bundle. anchor . height ,
159+ witness : serde_json:: json!( {
160+ "wallet_hash_preimage" : cli. wallet_hash,
161+ "serial_number" : lifecycle_event. and_then( |e| e. serial_number. clone( ) ) ,
162+ "hash_function" : "BLAKE2b-256" ,
163+ "personalization" : "NordicShield_" ,
164+ "recompute" : "hash(type_byte || length_prefixed_fields) with NordicShield_ personalization" ,
165+ } ) ,
151166 } ) ;
152167 }
153168
@@ -189,7 +204,10 @@ async fn main() -> Result<()> {
189204 Ok ( ( ) )
190205}
191206
192- async fn collect_leaf_hashes ( client : & reqwest:: Client , cli : & Cli ) -> Result < Vec < String > > {
207+ async fn collect_leaf_hashes (
208+ client : & reqwest:: Client ,
209+ cli : & Cli ,
210+ ) -> Result < ( Vec < String > , Vec < LifecycleEvent > ) > {
193211 if let Some ( wh) = & cli. wallet_hash {
194212 let url = format ! ( "{}/lifecycle/{}" , cli. api_url, wh) ;
195213 let resp = client
@@ -199,14 +217,14 @@ async fn collect_leaf_hashes(client: &reqwest::Client, cli: &Cli) -> Result<Vec<
199217 . context ( "failed to fetch lifecycle" ) ?;
200218 let body: LifecycleResponse = resp. json ( ) . await . context ( "invalid lifecycle JSON" ) ?;
201219
202- let hashes : Vec < String > = body
220+ let filtered : Vec < LifecycleEvent > = body
203221 . events
204- . iter ( )
222+ . into_iter ( )
205223 . filter ( |e| cli. event_types . is_empty ( ) || cli. event_types . contains ( & e. event_type ) )
206- . map ( |e| e. leaf_hash . clone ( ) )
207224 . collect ( ) ;
225+ let hashes: Vec < String > = filtered. iter ( ) . map ( |e| e. leaf_hash . clone ( ) ) . collect ( ) ;
208226
209- Ok ( hashes)
227+ Ok ( ( hashes, filtered ) )
210228 } else {
211229 Err ( anyhow ! ( "--wallet-hash required to scope the export" ) )
212230 }
0 commit comments