diff --git a/rust/chains/tw_pactus/src/compiler.rs b/rust/chains/tw_pactus/src/compiler.rs index 3c32c3a2d6c..4a74297f7b4 100644 --- a/rust/chains/tw_pactus/src/compiler.rs +++ b/rust/chains/tw_pactus/src/compiler.rs @@ -2,13 +2,18 @@ // // Copyright © 2017 Trust Wallet. +use std::borrow::Cow; + use tw_coin_entry::coin_context::CoinContext; use tw_coin_entry::coin_entry::{PublicKeyBytes, SignatureBytes}; use tw_coin_entry::error::prelude::*; use tw_coin_entry::signing_output_error; +use tw_keypair::ed25519; use tw_proto::Pactus::Proto; use tw_proto::TxCompiler::Proto as CompilerProto; +use crate::transaction::Transaction; + pub struct PactusCompiler; impl PactusCompiler { @@ -23,9 +28,18 @@ impl PactusCompiler { fn preimage_hashes_impl( _coin: &dyn CoinContext, - _input: Proto::SigningInput<'_>, + input: Proto::SigningInput<'_>, ) -> SigningResult> { - todo!() + let trx = Transaction::from_proto(&input)?; + let data = trx.to_bytes(); + + let output = CompilerProto::PreSigningOutput { + data_hash: Cow::Owned(trx.id()), + data: data.into(), + ..CompilerProto::PreSigningOutput::default() + }; + + Ok(output) } #[inline] @@ -41,10 +55,30 @@ impl PactusCompiler { fn compile_impl( _coin: &dyn CoinContext, - _input: Proto::SigningInput<'_>, - _signatures: Vec, - _public_keys: Vec, + input: Proto::SigningInput<'_>, + signatures: Vec, + public_keys: Vec, ) -> SigningResult> { - todo!() + let signature_bytes = signatures + .first() + .or_tw_err(SigningErrorType::Error_signatures_count)?; + let public_key_bytes = public_keys + .first() + .or_tw_err(SigningErrorType::Error_signatures_count)?; + + let public_key = ed25519::sha512::PublicKey::try_from(public_key_bytes.as_slice())?; + let signature = ed25519::Signature::try_from(signature_bytes.as_slice())?; + + let mut trx = Transaction::from_proto(&input)?; + trx.set_signatory(public_key.to_owned(), signature.to_owned()); + + let data = trx.to_bytes(); + + let output = Proto::SigningOutput { + encoded: data.into(), + ..Proto::SigningOutput::default() + }; + + Ok(output) } } diff --git a/rust/chains/tw_pactus/src/transaction.rs b/rust/chains/tw_pactus/src/transaction.rs index 71dedbb45d5..8f0057109f4 100644 --- a/rust/chains/tw_pactus/src/transaction.rs +++ b/rust/chains/tw_pactus/src/transaction.rs @@ -99,7 +99,7 @@ impl Transaction { pub fn from_proto(input: &Pactus::Proto::SigningInput) -> SigningResult { match &input.transaction { - None => return SigningError::err(SigningErrorType::Error_invalid_params), + None => SigningError::err(SigningErrorType::Error_invalid_params), Some(trx) => { let payload = match &trx.payload { Pactus::Proto::mod_TransactionMessage::OneOfpayload::transfer(pld) => { @@ -121,7 +121,7 @@ impl Transaction { } }; - return Ok(Transaction { + Ok(Transaction { flags: 0, version: VERSION_LATEST, lock_time: trx.lock_time, @@ -130,21 +130,25 @@ impl Transaction { payload, public_key: None, signature: None, - }); + }) } - }; + } } pub fn sign(&mut self, private_key: &PrivateKey) -> SigningResult<()> { let sign_bytes = self.sign_bytes(); let signature = private_key.sign(sign_bytes)?; - self.public_key = Some(private_key.public()); - self.signature = Some(signature); + self.set_signatory(private_key.public(), signature); Ok(()) } + pub fn set_signatory(&mut self, public_key: PublicKey, signature: Signature) { + self.public_key = Some(public_key); + self.signature = Some(signature); + } + pub fn id(&self) -> Vec { blake2_b(&self.sign_bytes(), 32).unwrap_or_default() }