use crate::{Network, NetworkTransactionBuilder, TransactionBuilder};
use alloy_consensus::SignableTransaction;
use alloy_primitives::Address;
use alloy_signer::{Signer, SignerSync};
use async_trait::async_trait;
use auto_impl::auto_impl;
use futures_utils_wasm::impl_future;
#[auto_impl(&, &mut, Box, Rc, Arc)]
pub trait NetworkWallet<N: Network>: std::fmt::Debug + Send + Sync {
fn default_signer_address(&self) -> Address;
fn has_signer_for(&self, address: &Address) -> bool;
fn signer_addresses(&self) -> impl Iterator<Item = Address>;
#[doc(alias = "sign_tx_from")]
fn sign_transaction_from(
&self,
sender: Address,
tx: N::UnsignedTx,
) -> impl_future!(<Output = alloy_signer::Result<N::TxEnvelope>>);
#[doc(alias = "sign_tx")]
fn sign_transaction(
&self,
tx: N::UnsignedTx,
) -> impl_future!(<Output = alloy_signer::Result<N::TxEnvelope>>) {
self.sign_transaction_from(self.default_signer_address(), tx)
}
fn sign_request(
&self,
request: N::TransactionRequest,
) -> impl_future!(<Output = alloy_signer::Result<N::TxEnvelope>>) {
async move {
let sender = request.from().unwrap_or_else(|| self.default_signer_address());
let tx = request.build_unsigned().map_err(alloy_signer::Error::other)?;
self.sign_transaction_from(sender, tx).await
}
}
}
#[cfg_attr(target_family = "wasm", async_trait(?Send))]
#[cfg_attr(not(target_family = "wasm"), async_trait)]
#[auto_impl(&, &mut, Box, Rc, Arc)]
#[doc(alias = "TransactionSigner")]
pub trait TxSigner<Signature> {
fn address(&self) -> Address;
#[doc(alias = "sign_tx")]
async fn sign_transaction(
&self,
tx: &mut dyn SignableTransaction<Signature>,
) -> alloy_signer::Result<Signature>;
}
#[auto_impl(&, &mut, Box, Rc, Arc)]
#[doc(alias = "TransactionSignerSync")]
pub trait TxSignerSync<Signature> {
fn address(&self) -> Address;
#[doc(alias = "sign_tx_sync")]
fn sign_transaction_sync(
&self,
tx: &mut dyn SignableTransaction<Signature>,
) -> alloy_signer::Result<Signature>;
}
pub trait FullSigner<S>: Signer<S> + TxSigner<S> {}
impl<T, S> FullSigner<S> for T where T: Signer<S> + TxSigner<S> {}
pub trait FullSignerSync<S>: SignerSync<S> + TxSignerSync<S> {}
impl<T, S> FullSignerSync<S> for T where T: SignerSync<S> + TxSignerSync<S> {}
#[cfg(test)]
mod tests {
use super::*;
struct _ObjectSafe(Box<dyn FullSigner<()>>, Box<dyn FullSignerSync<()>>);
}