@@ -91,6 +91,15 @@ pub(crate) struct Commitments {
9191 commitments : Vec < String > ,
9292}
9393
94+ /// The return value for a transaction metadata query.
95+ #[ skip_serializing_none]
96+ #[ derive( Serialize ) ]
97+ pub ( crate ) struct TransactionWithMetadata < T : Serialize , N : Network > {
98+ transaction : T ,
99+ block_hash : Option < N :: BlockHash > ,
100+ block_height : Option < u32 > ,
101+ }
102+
94103/// The return value for a `sync_status` query.
95104#[ skip_serializing_none]
96105#[ derive( Copy , Clone , Serialize ) ]
@@ -292,25 +301,54 @@ impl<N: Network, C: ConsensusStorage<N>, R: Routing<N>> Rest<N, C, R> {
292301 }
293302
294303 /// GET /<network>/transaction/{transactionID}
304+ /// GET /<network>/transaction/{transactionID}?metadata={true}
295305 pub ( crate ) async fn get_transaction (
296306 State ( rest) : State < Self > ,
297307 Path ( tx_id) : Path < N :: TransactionID > ,
308+ metadata : Query < Metadata > ,
298309 ) -> Result < ErasedJson , RestError > {
299310 // Ledger returns a generic anyhow::Error, so checking the message is the only way to parse it.
300- Ok ( ErasedJson :: pretty ( rest. ledger . get_transaction ( tx_id) . map_err ( |err| {
311+ let transaction = rest. ledger . get_transaction ( tx_id) . map_err ( |err| {
301312 if err. to_string ( ) . contains ( "Missing" ) { RestError :: not_found ( err) } else { RestError :: from ( err) }
302- } ) ?) )
313+ } ) ?;
314+ // Check if metadata is requested and return the transaction with metadata if so.
315+ if metadata. metadata . unwrap_or ( false ) {
316+ // Get the block hash and height for the transaction, if it exists.
317+ let block_hash = rest. ledger . find_block_hash ( & tx_id) . ok ( ) . flatten ( ) ;
318+ let block_height = block_hash. and_then ( |hash| rest. ledger . get_height ( & hash) . ok ( ) ) ;
319+ Ok ( ErasedJson :: pretty ( TransactionWithMetadata :: < _ , N > { transaction, block_hash, block_height } ) )
320+ } else {
321+ Ok ( ErasedJson :: pretty ( transaction) )
322+ }
303323 }
304324
305325 /// GET /<network>/transaction/confirmed/{transactionID}
326+ /// GET /<network>/transaction/confirmed/{transactionID}?metadata={true}
306327 pub ( crate ) async fn get_confirmed_transaction (
307328 State ( rest) : State < Self > ,
308329 Path ( tx_id) : Path < N :: TransactionID > ,
330+ metadata : Query < Metadata > ,
309331 ) -> Result < ErasedJson , RestError > {
310332 // Ledger returns a generic anyhow::Error, so checking the message is the only way to parse it.
311- Ok ( ErasedJson :: pretty ( rest. ledger . get_confirmed_transaction ( tx_id) . map_err ( |err| {
333+ let transaction = rest. ledger . get_confirmed_transaction ( tx_id) . map_err ( |err| {
312334 if err. to_string ( ) . contains ( "Missing" ) { RestError :: not_found ( err) } else { RestError :: from ( err) }
313- } ) ?) )
335+ } ) ?;
336+ // Check if metadata is requested and return the transaction with metadata if so.
337+ if metadata. metadata . unwrap_or ( false ) {
338+ // Get the block hash and height for the confirmed transaction.
339+ let block_hash = rest
340+ . ledger
341+ . find_block_hash ( & tx_id) ?
342+ . ok_or_else ( || anyhow ! ( "Block hash not found for transaction {tx_id}" ) ) ?;
343+ let block_height = rest. ledger . get_height ( & block_hash) ?;
344+ Ok ( ErasedJson :: pretty ( TransactionWithMetadata :: < _ , N > {
345+ transaction,
346+ block_hash : Some ( block_hash) ,
347+ block_height : Some ( block_height) ,
348+ } ) )
349+ } else {
350+ Ok ( ErasedJson :: pretty ( transaction) )
351+ }
314352 }
315353
316354 /// GET /<network>/transaction/unconfirmed/{transactionID}
0 commit comments