Skip to main content

builder_relayer_client_rust/builder/
create.rs

1use 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
11// Define EIP-712 structs using alloy::sol!
12pub 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    // derive safe address
57    let safe_address = derive_safe(factory, owner_addr)?;
58
59    // Sign
60    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}