builder_relayer_client_rust/builder/
create.rs1use crate::builder::derive::derive_safe;
2use crate::errors::Result;
3use crate::types::{
4 SafeCreateTransactionArgs, SignatureParams, TransactionRequest, TransactionType,
5};
6use crate::utils::split_and_pack_sig;
7use alloy::primitives::Address;
8use async_trait::async_trait;
9use std::str::FromStr;
10
11pub const SAFE_FACTORY_NAME: &str = "Polymarket Contract Proxy Factory";
13
14pub mod internal {
15 alloy::sol! {
16 #[derive(Debug)]
17 struct CreateProxy {
18 address paymentToken;
19 uint256 payment;
20 address paymentReceiver;
21 }
22
23 #[derive(Debug)]
24 struct EIP712Domain {
25 string name;
26 uint256 chainId;
27 address verifyingContract;
28 }
29 }
30}
31pub use internal::{CreateProxy, EIP712Domain};
32
33#[async_trait]
34pub trait AbstractSignerForCreate {
35 fn address(&self) -> Address;
36 async fn sign_typed_create_proxy(
37 &self,
38 safe_factory: &str,
39 chain_id: u64,
40 payment_token: &str,
41 payment: &str,
42 payment_receiver: &str,
43 ) -> Result<String>;
44}
45
46pub async fn build_safe_create_transaction_request(
47 signer: &dyn AbstractSignerForCreate,
48 safe_factory: &str,
49 args: SafeCreateTransactionArgs,
50) -> Result<TransactionRequest> {
51 let factory = Address::from_str(safe_factory)
52 .map_err(|_| crate::errors::RelayClientError::InvalidAddress)?;
53 let owner_addr = Address::from_str(&args.from)
54 .map_err(|_| crate::errors::RelayClientError::InvalidAddress)?;
55
56 let safe_address = derive_safe(factory, owner_addr)?;
58
59 let sig_hex = signer
61 .sign_typed_create_proxy(
62 safe_factory,
63 args.chain_id,
64 &args.payment_token,
65 &args.payment,
66 &args.payment_receiver,
67 )
68 .await?;
69
70 let packed_sig = split_and_pack_sig(&sig_hex);
71
72 Ok(TransactionRequest {
73 r#type: TransactionType::SafeCreate,
74 from: args.from.clone(),
75 to: safe_factory.to_string(),
76 proxy_wallet: Some(safe_address.to_string()),
77 data: "0x".to_string(),
78 nonce: Some(args.payment.clone()),
79 signature: packed_sig,
80 signature_params: SignatureParams {
81 payment_token: Some(args.payment_token.clone()),
82 payment: Some(args.payment.clone()),
83 payment_receiver: Some(args.payment_receiver.clone()),
84 ..Default::default()
85 },
86 metadata: None,
87 })
88}