-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
143 additions
and
128 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,129 +1,7 @@ | ||
use crate::contracts::DUMMY_RPC_PROVIDER; | ||
use crate::eth::get_eth_addr_from_secret; | ||
use erc20_payment_lib_common::err_custom_create; | ||
use erc20_payment_lib_common::error::PaymentError; | ||
use futures_util::future::BoxFuture; | ||
use futures_util::FutureExt; | ||
use secp256k1::SecretKey; | ||
use std::fmt::{Debug, Display, Formatter}; | ||
use std::sync::Arc; | ||
use tokio::time::timeout; | ||
mod account; | ||
mod external; | ||
mod private; | ||
|
||
use web3::types::{Address, SignedTransaction, TransactionParameters, H160}; | ||
|
||
#[derive(Clone)] | ||
pub struct SignerAccount { | ||
pub address: Address, | ||
pub signer: Arc<Box<dyn Signer + Send + Sync>>, | ||
} | ||
|
||
impl Debug for SignerAccount { | ||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||
write!(f, "SignerAccount {{ address: {:#x} }}", self.address) | ||
} | ||
} | ||
|
||
impl Display for SignerAccount { | ||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||
write!(f, "{:#x}", self.address) | ||
} | ||
} | ||
|
||
impl SignerAccount { | ||
pub fn new(address: H160, signer: Arc<Box<dyn Signer + Send + Sync>>) -> Self { | ||
Self { address, signer } | ||
} | ||
|
||
pub async fn check_if_sign_possible(&self) -> Result<(), PaymentError> { | ||
match timeout( | ||
std::time::Duration::from_secs(5), | ||
self.signer.check_if_sign_possible(self.address), | ||
) | ||
.await | ||
{ | ||
Ok(Ok(())) => Ok(()), | ||
Ok(Err(err)) => Err(err_custom_create!("Sign returned error {err:?}")), | ||
Err(err) => Err(err_custom_create!("Sign check timed out {err:?}")), | ||
} | ||
} | ||
|
||
pub async fn sign(&self, tp: TransactionParameters) -> Result<SignedTransaction, PaymentError> { | ||
match timeout( | ||
std::time::Duration::from_secs(5), | ||
self.signer.sign(self.address, tp), | ||
) | ||
.await | ||
{ | ||
Ok(Ok(signed)) => Ok(signed), | ||
Ok(Err(err)) => Err(err_custom_create!("Sign returned error {err:?}")), | ||
Err(err) => Err(err_custom_create!("Sign check timed out {err:?}")), | ||
} | ||
} | ||
} | ||
|
||
#[derive(Debug)] | ||
pub struct SignerError { | ||
pub message: String, | ||
} | ||
|
||
pub trait Signer: Send + Sync { | ||
/// Check if signer can sign transaction for given public address | ||
fn check_if_sign_possible(&self, pub_address: H160) -> BoxFuture<'_, Result<(), SignerError>>; | ||
|
||
/// Sign transaction for given public address (look at PrivateKeySigner for example) | ||
fn sign( | ||
&self, | ||
pub_address: H160, | ||
tp: TransactionParameters, | ||
) -> BoxFuture<'_, Result<SignedTransaction, SignerError>>; | ||
} | ||
|
||
/// PrivateKeySigner is implementation of Signer trait that stores private keys in memory and use | ||
/// them to sign transactions matching them by public addresses | ||
pub struct PrivateKeySigner { | ||
secret_keys: Vec<SecretKey>, | ||
} | ||
|
||
impl PrivateKeySigner { | ||
pub fn new(secret_keys: Vec<SecretKey>) -> Self { | ||
Self { secret_keys } | ||
} | ||
|
||
fn get_private_key(&self, pub_address: H160) -> Result<&SecretKey, SignerError> { | ||
self.secret_keys | ||
.iter() | ||
.find(|sk| get_eth_addr_from_secret(sk) == pub_address) | ||
.ok_or(SignerError { | ||
message: "Failed to find private key for address: {from_addr}".to_string(), | ||
}) | ||
} | ||
} | ||
|
||
impl Signer for PrivateKeySigner { | ||
fn check_if_sign_possible(&self, pub_address: H160) -> BoxFuture<'_, Result<(), SignerError>> { | ||
async move { | ||
self.get_private_key(pub_address)?; | ||
Ok(()) | ||
} | ||
.boxed() | ||
} | ||
|
||
fn sign( | ||
&self, | ||
pub_address: H160, | ||
tp: TransactionParameters, | ||
) -> BoxFuture<'_, Result<SignedTransaction, SignerError>> { | ||
async move { | ||
let secret_key = self.get_private_key(pub_address)?; | ||
let signed = DUMMY_RPC_PROVIDER | ||
.accounts() | ||
.sign_transaction(tp, secret_key) | ||
.await | ||
.map_err(|err| SignerError { | ||
message: format!("Error when signing transaction in PrivateKeySigner {err}"), | ||
})?; | ||
Ok(signed) | ||
} | ||
.boxed() | ||
} | ||
} | ||
pub use account::*; | ||
pub use external::*; | ||
pub use private::*; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
use erc20_payment_lib_common::err_custom_create; | ||
use erc20_payment_lib_common::error::PaymentError; | ||
use std::fmt::{Debug, Display, Formatter}; | ||
use std::sync::Arc; | ||
use tokio::time::timeout; | ||
|
||
use super::Signer; | ||
use web3::types::{Address, SignedTransaction, TransactionParameters, H160}; | ||
|
||
#[derive(Clone)] | ||
pub struct SignerAccount { | ||
pub address: Address, | ||
pub signer: Arc<Box<dyn Signer + Send + Sync>>, | ||
} | ||
|
||
impl Debug for SignerAccount { | ||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||
write!(f, "SignerAccount {{ address: {:#x} }}", self.address) | ||
} | ||
} | ||
|
||
impl Display for SignerAccount { | ||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||
write!(f, "{:#x}", self.address) | ||
} | ||
} | ||
|
||
impl SignerAccount { | ||
pub fn new(address: H160, signer: Arc<Box<dyn Signer + Send + Sync>>) -> Self { | ||
Self { address, signer } | ||
} | ||
|
||
pub async fn check_if_sign_possible(&self) -> Result<(), PaymentError> { | ||
match timeout( | ||
std::time::Duration::from_secs(5), | ||
self.signer.check_if_sign_possible(self.address), | ||
) | ||
.await | ||
{ | ||
Ok(Ok(())) => Ok(()), | ||
Ok(Err(err)) => Err(err_custom_create!("Sign returned error {err:?}")), | ||
Err(err) => Err(err_custom_create!("Sign check timed out {err:?}")), | ||
} | ||
} | ||
|
||
pub async fn sign(&self, tp: TransactionParameters) -> Result<SignedTransaction, PaymentError> { | ||
match timeout( | ||
std::time::Duration::from_secs(5), | ||
self.signer.sign(self.address, tp), | ||
) | ||
.await | ||
{ | ||
Ok(Ok(signed)) => Ok(signed), | ||
Ok(Err(err)) => Err(err_custom_create!("Sign returned error {err:?}")), | ||
Err(err) => Err(err_custom_create!("Sign check timed out {err:?}")), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
use futures_util::future::BoxFuture; | ||
use std::fmt::Debug; | ||
|
||
use web3::types::{SignedTransaction, TransactionParameters, H160}; | ||
|
||
#[derive(Debug)] | ||
pub struct SignerError { | ||
pub message: String, | ||
} | ||
|
||
pub trait Signer: Send + Sync { | ||
/// Check if signer can sign transaction for given public address | ||
fn check_if_sign_possible(&self, pub_address: H160) -> BoxFuture<'_, Result<(), SignerError>>; | ||
|
||
/// Sign transaction for given public address (look at PrivateKeySigner for example) | ||
fn sign( | ||
&self, | ||
pub_address: H160, | ||
tp: TransactionParameters, | ||
) -> BoxFuture<'_, Result<SignedTransaction, SignerError>>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
use crate::contracts::DUMMY_RPC_PROVIDER; | ||
use crate::eth::get_eth_addr_from_secret; | ||
use futures_util::future::BoxFuture; | ||
use futures_util::FutureExt; | ||
use secp256k1::SecretKey; | ||
|
||
use super::{Signer, SignerError}; | ||
use web3::types::{SignedTransaction, TransactionParameters, H160}; | ||
|
||
/// PrivateKeySigner is implementation of Signer trait that stores private keys in memory and use | ||
/// them to sign transactions matching them by public addresses | ||
pub struct PrivateKeySigner { | ||
secret_keys: Vec<SecretKey>, | ||
} | ||
|
||
impl PrivateKeySigner { | ||
pub fn new(secret_keys: Vec<SecretKey>) -> Self { | ||
Self { secret_keys } | ||
} | ||
|
||
fn get_private_key(&self, pub_address: H160) -> Result<&SecretKey, SignerError> { | ||
self.secret_keys | ||
.iter() | ||
.find(|sk| get_eth_addr_from_secret(sk) == pub_address) | ||
.ok_or(SignerError { | ||
message: "Failed to find private key for address: {from_addr}".to_string(), | ||
}) | ||
} | ||
} | ||
|
||
impl Signer for PrivateKeySigner { | ||
fn check_if_sign_possible(&self, pub_address: H160) -> BoxFuture<'_, Result<(), SignerError>> { | ||
async move { | ||
self.get_private_key(pub_address)?; | ||
Ok(()) | ||
} | ||
.boxed() | ||
} | ||
|
||
fn sign( | ||
&self, | ||
pub_address: H160, | ||
tp: TransactionParameters, | ||
) -> BoxFuture<'_, Result<SignedTransaction, SignerError>> { | ||
async move { | ||
let secret_key = self.get_private_key(pub_address)?; | ||
let signed = DUMMY_RPC_PROVIDER | ||
.accounts() | ||
.sign_transaction(tp, secret_key) | ||
.await | ||
.map_err(|err| SignerError { | ||
message: format!("Error when signing transaction in PrivateKeySigner {err}"), | ||
})?; | ||
Ok(signed) | ||
} | ||
.boxed() | ||
} | ||
} |