Skip to content

Commit

Permalink
feat(aptos): add aptos signer.rs
Browse files Browse the repository at this point in the history
  • Loading branch information
Milerius committed Oct 31, 2023
1 parent 1a34b2f commit 1abb8aa
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 7 deletions.
18 changes: 17 additions & 1 deletion rust/tw_aptos/src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,27 @@ use std::fmt::{Display, Formatter};
use std::str::FromStr;
use move_core_types::account_address::{AccountAddress, AccountAddressParseError};
use tw_coin_entry::coin_entry::CoinAddress;
use tw_coin_entry::error::AddressError;
use tw_coin_entry::error::{AddressError, AddressResult};
use tw_keypair::ed25519;
use tw_memory::Data;
use tw_hash::sha3::sha3_256;


pub trait AptosAddress: FromStr<Err = AddressError> + Into<Address> {
/// Tries to parse an address from the string representation.
/// Returns `Ok(None)` if the given `s` string is empty.
#[inline]
fn from_str_optional(s: &str) -> AddressResult<Option<Self>> {
if s.is_empty() {
return Ok(None);
}

Self::from_str(s).map(Some)
}
}

impl AptosAddress for Address {}

#[repr(u8)]
pub enum Scheme {
Ed25519 = 0,
Expand Down
7 changes: 2 additions & 5 deletions rust/tw_aptos/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use tw_keypair::ed25519::sha512::KeyPair;
use tw_proto::Aptos::Proto;
use tw_proto::TxCompiler::Proto as CompilerProto;
use crate::address::Address;
use crate::signer::{AptosContext, Signer, StandardAptosContext};
use crate::transaction_builder;


Expand Down Expand Up @@ -61,11 +62,7 @@ impl CoinEntry for AptosEntry {

#[inline]
fn sign(&self, _coin: &dyn CoinContext, input: Self::SigningInput<'_>) -> Self::SigningOutput {
let mut builder = transaction_builder::TransactionFactory::new_from_protobuf(input.clone());
let sender = Address::from_str(&input.sender).unwrap().inner();
let key_pair = KeyPair::try_from(input.private_key.to_vec().as_slice()).unwrap();
let raw_tx = builder.sender(sender).sequence_number(input.sequence_number as u64).build().sign(key_pair).unwrap();
todo!()
Signer::<StandardAptosContext>::sign_proto(input)
}

#[inline]
Expand Down
2 changes: 2 additions & 0 deletions rust/tw_aptos/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ pub mod address;
pub mod aptos_move_packages;
pub mod constants;
pub mod entry;

pub mod signer;
pub mod transaction;
pub mod transaction_builder;
pub mod transaction_payload;
48 changes: 48 additions & 0 deletions rust/tw_aptos/src/signer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use std::borrow::Cow;
use std::marker::PhantomData;
use std::str::FromStr;
use tw_coin_entry::error::SigningResult;
use tw_coin_entry::signing_output_error;
use tw_keypair::ed25519;
use tw_proto::Aptos::Proto;
use tw_proto::Aptos::Proto::TransactionAuthenticator;
use crate::address::{Address, AptosAddress};
use crate::transaction_builder;

pub trait AptosContext {
type Address: AptosAddress;
}

#[derive(Default)]
pub struct StandardAptosContext;

impl AptosContext for StandardAptosContext {
type Address = Address;
}

pub struct Signer<Context: AptosContext> {
_phantom: PhantomData<Context>,
}

impl<Context: AptosContext> Signer<Context> {
#[inline]
pub fn sign_proto(input: Proto::SigningInput<'_>) -> Proto::SigningOutput<'static> {
Self::sign_proto_impl(input)
.unwrap_or_else(|e| signing_output_error!(Proto::SigningOutput, e))
}

fn sign_proto_impl(
input: Proto::SigningInput<'_>,
) -> SigningResult<Proto::SigningOutput<'static>> {
let key_pair = ed25519::sha512::KeyPair::try_from(input.private_key.as_ref())?;
let mut builder = transaction_builder::TransactionFactory::new_from_protobuf(input.clone());
let sender = Address::from_str(&input.sender)?;
let raw_tx = builder.sender(sender.inner()).sequence_number(input.sequence_number as u64).build().sign(key_pair)?;
Ok(Proto::SigningOutput {
raw_txn: raw_tx.raw_txn_bytes().clone().into(),
encoded: raw_tx.encoded().clone().into(),
authenticator: Some((*raw_tx.authenticator()).clone().into()),
..Proto::SigningOutput::default()
})
}
}
18 changes: 17 additions & 1 deletion rust/tw_aptos/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
// terms governing use, modification, and redistribution, is contained in the
// file LICENSE at the root of the source code distribution tree.

use std::borrow::Cow;
use move_core_types::account_address::AccountAddress;
use serde::Serialize;
use tw_coin_entry::error::SigningResult;
use tw_keypair::ed25519::sha512::{KeyPair, PublicKey};
use tw_keypair::traits::{KeyPairTrait, SigningKeyTrait};
use tw_number::Sign;
use tw_proto::Aptos::Proto;
use crate::transaction_payload::{EntryFunction, TransactionPayload};

#[derive(Clone, Serialize)]
Expand All @@ -20,10 +23,23 @@ pub enum TransactionAuthenticator {
}
}

impl From<TransactionAuthenticator> for Proto::TransactionAuthenticator<'_> {
fn from(from: TransactionAuthenticator) -> Self {
Proto::TransactionAuthenticator {
signature: Cow::from(from.get_signature()),
public_key: Cow::from(from.get_public_key()),
}
}
}

impl TransactionAuthenticator {
pub fn get_signature(&self) -> Vec<u8> {
match self { TransactionAuthenticator::Ed25519 { public_key: _public_key, signature } => { signature.clone() } }
}

pub fn get_public_key(&self) -> Vec<u8> {
match self { TransactionAuthenticator::Ed25519 { public_key, signature: _signature } => { public_key.clone() } }
}
}

/// RawTransaction is the portion of a transaction that a client signs.
Expand Down Expand Up @@ -105,7 +121,7 @@ impl RawTransaction {
pub fn sign(
self,
key_pair: KeyPair,
) -> Result<SignedTransaction, String> {
) -> SigningResult<SignedTransaction> {
let mut serialized = bcs::to_bytes(&self).unwrap();
let mut to_sign = tw_hash::sha3::sha3_256("APTOS::RawTransaction".as_bytes());
to_sign.extend_from_slice(serialized.as_slice());
Expand Down

0 comments on commit 1abb8aa

Please sign in to comment.