11
11
#include " ../BinaryCoding.h"
12
12
#include " ../HexCoding.h"
13
13
14
+ #include < nlohmann/json.hpp>
14
15
#include < cassert>
15
16
#include < chrono>
16
17
@@ -405,17 +406,39 @@ Data serialize(const protocol::Transaction& tx) noexcept {
405
406
406
407
Proto::SigningOutput signDirect (const Proto::SigningInput& input) {
407
408
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);
410
409
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);
411
434
output.set_signature (signature.data (), signature.size ());
412
435
output.set_id (input.txid ());
413
436
output.set_id (hash.data (), hash.size ());
414
437
return output;
415
438
}
416
439
417
440
Proto::SigningOutput Signer::sign (const Proto::SigningInput& input) noexcept {
418
- if (!input.txid ().empty ()) {
441
+ if (!input.txid ().empty () || !input. raw_json (). empty () ) {
419
442
return signDirect (input);
420
443
}
421
444
@@ -455,6 +478,26 @@ Proto::SigningOutput Signer::sign(const Proto::SigningInput& input) noexcept {
455
478
456
479
Proto::SigningOutput Signer::compile (const Data& signature) const {
457
480
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
+ }
458
501
auto preImage = signaturePreimage ();
459
502
auto hash = Hash::sha256 (preImage);
460
503
auto transaction = buildTransaction (input);
@@ -468,7 +511,40 @@ Proto::SigningOutput Signer::compile(const Data& signature) const {
468
511
}
469
512
470
513
Data 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
+ }
471
528
return serialize (buildTransaction (input));
472
529
}
473
530
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
+
474
550
} // namespace TW::Tron
0 commit comments