1111#include " ../BinaryCoding.h"
1212#include " ../HexCoding.h"
1313
14+ #include < nlohmann/json.hpp>
1415#include < cassert>
1516#include < chrono>
1617
@@ -405,17 +406,39 @@ Data serialize(const protocol::Transaction& tx) noexcept {
405406
406407Proto::SigningOutput signDirect (const Proto::SigningInput& input) {
407408 const auto key = PrivateKey (Data (input.private_key ().begin (), input.private_key ().end ()), TWCurveSECP256k1);
408- auto hash = parse_hex (input.txid ());
409- const auto signature = key.sign (hash);
410409 auto output = Proto::SigningOutput ();
410+
411+ Data hash;
412+ if (!input.txid ().empty ()) {
413+ hash = parse_hex (input.txid ());
414+ } else if (!input.raw_json ().empty ()) {
415+ try {
416+ auto parsed = nlohmann::json::parse (input.raw_json ());
417+ if (parsed.contains (" txID" ) && parsed[" txID" ].is_string ()) {
418+ hash = parse_hex (parsed[" txID" ].get <std::string>());
419+ } else {
420+ // If txID is not present, return an error
421+ output.set_error (Common::Proto::Error_invalid_params);
422+ output.set_error_message (" No txID found in raw JSON" );
423+ return output;
424+ }
425+ } catch (const std::exception& e) {
426+ // If parsing fails, return an error
427+ output.set_error (Common::Proto::Error_invalid_params);
428+ output.set_error_message (e.what ());
429+ return output;
430+ }
431+ }
432+
433+ const auto signature = key.sign (hash);
411434 output.set_signature (signature.data (), signature.size ());
412435 output.set_id (input.txid ());
413436 output.set_id (hash.data (), hash.size ());
414437 return output;
415438}
416439
417440Proto::SigningOutput Signer::sign (const Proto::SigningInput& input) noexcept {
418- if (!input.txid ().empty ()) {
441+ if (!input.txid ().empty () || !input. raw_json (). empty () ) {
419442 return signDirect (input);
420443 }
421444
@@ -455,6 +478,26 @@ Proto::SigningOutput Signer::sign(const Proto::SigningInput& input) noexcept {
455478
456479Proto::SigningOutput Signer::compile (const Data& signature) const {
457480 Proto::SigningOutput output;
481+ if (!input.raw_json ().empty ()) {
482+ // If raw JSON is provided, we use it directly
483+ try {
484+ auto parsed = nlohmann::json::parse (input.raw_json ());
485+ // Add signature to JSON and set to output
486+ parsed[" signature" ] = nlohmann::json::array ({hex (signature)});
487+ output.set_json (parsed.dump ());
488+ output.set_signature (signature.data (), signature.size ());
489+ // Extract txID and set to output
490+ if (parsed.contains (" txID" ) && parsed[" txID" ].is_string ()) {
491+ auto txID = parse_hex (parsed[" txID" ].get <std::string>());
492+ output.set_id (txID.data (), txID.size ());
493+ }
494+ return output;
495+ } catch (const std::exception& e) {
496+ output.set_error (Common::Proto::Error_invalid_params);
497+ output.set_error_message (e.what ());
498+ return output;
499+ }
500+ }
458501 auto preImage = signaturePreimage ();
459502 auto hash = Hash::sha256 (preImage);
460503 auto transaction = buildTransaction (input);
@@ -468,7 +511,40 @@ Proto::SigningOutput Signer::compile(const Data& signature) const {
468511}
469512
470513Data Signer::signaturePreimage () const {
514+ if (!input.raw_json ().empty ()) {
515+ // If raw JSON is provided, we use raw_data_hex directly
516+ try {
517+ auto parsed = nlohmann::json::parse (input.raw_json ());
518+ if (parsed.contains (" raw_data_hex" ) && parsed[" raw_data_hex" ].is_string ()) {
519+ return parse_hex (parsed[" raw_data_hex" ].get <std::string>());
520+ }
521+ // If raw_data_hex is not present, return an empty Data
522+ return {};
523+ } catch (...) {
524+ // Ignore parsing errors, return an empty Data
525+ return {};
526+ }
527+ }
471528 return serialize (buildTransaction (input));
472529}
473530
531+ Data Signer::signaturePreimageHash () const {
532+ if (!input.raw_json ().empty ()) {
533+ // If raw JSON is provided, we use txID directly
534+ try {
535+ auto parsed = nlohmann::json::parse (input.raw_json ());
536+ if (parsed.contains (" txID" ) && parsed[" txID" ].is_string ()) {
537+ return parse_hex (parsed[" txID" ].get <std::string>());
538+ }
539+ // If txID is not present, return an empty Data
540+ return {};
541+ } catch (...) {
542+ // Ignore parsing errors, return an empty Data
543+ return {};
544+ }
545+ }
546+ auto preImage = signaturePreimage ();
547+ return Hash::sha256 (preImage);
548+ }
549+
474550} // namespace TW::Tron
0 commit comments