builder_relayer_client_rust/
signer.rs1use crate::builder::create::{
2 AbstractSignerForCreate, CreateProxy, EIP712Domain, SAFE_FACTORY_NAME,
3};
4use crate::errors::{RelayClientError, Result};
5use alloy::primitives::{Address, B256, Signature, U256, keccak256};
6use alloy::signers::Signer;
7use alloy::signers::local::PrivateKeySigner;
8use alloy::sol_types::SolStruct;
9use async_trait::async_trait;
10use std::str::FromStr;
11
12#[async_trait]
14pub trait AbstractSigner: Send + Sync {
15 fn address(&self) -> Address;
16 async fn sign_hash(&self, hash: B256) -> Result<Signature>;
17 async fn sign_eip712_digest(&self, digest: B256) -> Result<Signature>;
18}
19
20#[derive(Clone)]
22pub struct DummySigner {
23 wallet: PrivateKeySigner,
24}
25
26impl DummySigner {
27 pub fn new(priv_key_hex: &str) -> Result<Self> {
28 let wallet = PrivateKeySigner::from_str(priv_key_hex)
29 .map_err(|_| RelayClientError::SignerUnavailable)?;
30 Ok(Self { wallet })
31 }
32}
33
34#[async_trait]
35impl AbstractSigner for DummySigner {
36 fn address(&self) -> Address {
37 self.wallet.address()
38 }
39
40 async fn sign_hash(&self, hash: B256) -> Result<Signature> {
41 self.wallet
42 .sign_hash(&hash)
43 .await
44 .map_err(|e| RelayClientError::SigningError(e.to_string()))
45 }
46
47 async fn sign_eip712_digest(&self, digest: B256) -> Result<Signature> {
48 self.sign_hash(digest).await
51 }
52}
53
54#[async_trait]
55impl AbstractSignerForCreate for DummySigner {
56 fn address(&self) -> Address {
57 self.wallet.address()
58 }
59
60 async fn sign_typed_create_proxy(
61 &self,
62 safe_factory: &str,
63 chain_id: u64,
64 payment_token: &str,
65 payment: &str,
66 payment_receiver: &str,
67 ) -> Result<String> {
68 let domain = EIP712Domain {
69 name: SAFE_FACTORY_NAME.to_string(),
70 chainId: U256::from(chain_id),
71 verifyingContract: Address::from_str(safe_factory)
72 .map_err(|_| RelayClientError::InvalidAddress)?,
73 };
74
75 let create_proxy = CreateProxy {
76 paymentToken: Address::from_str(payment_token)
77 .map_err(|_| RelayClientError::InvalidAddress)?,
78 payment: U256::from_str(payment).unwrap_or(U256::ZERO),
79 paymentReceiver: Address::from_str(payment_receiver)
80 .map_err(|_| RelayClientError::InvalidAddress)?,
81 };
82
83 let domain_separator = domain.eip712_hash_struct();
84 let struct_hash = create_proxy.eip712_hash_struct();
85
86 let mut digest_input = Vec::with_capacity(2 + 32 + 32);
87 digest_input.extend_from_slice(&[0x19, 0x01]);
88 digest_input.extend_from_slice(&domain_separator.0);
89 digest_input.extend_from_slice(&struct_hash.0);
90
91 let digest = keccak256(&digest_input);
92
93 let sig = self.sign_hash(digest).await?;
94 Ok(format!("0x{}", hex::encode(sig.as_bytes())))
95 }
96}