@@ -464,7 +464,8 @@ void protocol_electrum::handle_blockchain_transaction_get(const code& ec,
464464 }
465465
466466 const auto & query = archive ();
467- const auto tx = query.get_transaction (query.to_tx (hash), true );
467+ const auto link = query.to_tx (hash);
468+ const auto tx = query.get_transaction (link, true );
468469 if (!tx)
469470 {
470471 send_code (error::not_found);
@@ -474,9 +475,41 @@ void protocol_electrum::handle_blockchain_transaction_get(const code& ec,
474475 const auto size = tx->serialized_size (true );
475476 if (verbose)
476477 {
477- // TODO: inject contextual tx properties.
478+ auto value = value_from (bitcoind (*tx));
479+ if (!value.is_object ())
480+ {
481+ send_code (error::server_error);
482+ return ;
483+ }
484+
485+ if (const auto header = query.to_strong (link); !header.is_terminal ())
486+ {
487+ using namespace system ;
488+ const auto top = query.get_top_confirmed ();
489+ const auto height = query.get_height (header);
490+ const auto block_hash = query.get_header_key (header);
491+
492+ uint32_t timestamp{};
493+ if (height.is_terminal () || (block_hash == null_hash) ||
494+ !query.get_timestamp (timestamp, header))
495+ {
496+ send_code (error::server_error);
497+ return ;
498+ }
499+
500+ // Floor manages race between getting confirmed top and height.
501+ const auto confirmations = add1 (floored_subtract (top, height.value ));
502+
503+ auto & transaction = value.as_object ();
504+ transaction[" in_active_chain" ] = true ;
505+ transaction[" blockhash" ] = encode_hash (block_hash);
506+ transaction[" confirmations" ] = confirmations;
507+ transaction[" blocktime" ] = timestamp;
508+ transaction[" time" ] = timestamp;
509+ }
510+
478511 // Verbose means whatever bitcoind returns for getrawtransaction, lolz.
479- send_result (value_from ( bitcoind (*tx) ), two * size, BIND (complete, _1));
512+ send_result (std::move (value ), two * size, BIND (complete, _1));
480513 }
481514 else
482515 {
0 commit comments