Skip to main content

polyoxide_relay/
types.rs

1use alloy::sol;
2use serde::{Deserialize, Serialize};
3
4/// Wallet type for the relayer API
5#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
6pub enum WalletType {
7    /// Safe wallet - requires explicit deployment before first transaction
8    #[default]
9    Safe,
10    /// Proxy wallet - auto-deploys on first transaction (Magic Link users)
11    Proxy,
12}
13
14impl WalletType {
15    pub fn as_str(&self) -> &'static str {
16        match self {
17            WalletType::Safe => "SAFE",
18            WalletType::Proxy => "PROXY",
19        }
20    }
21}
22
23sol! {
24    #[derive(Debug, PartialEq, Eq)]
25    struct SafeTransaction {
26        address to;
27        uint8 operation;
28        bytes data;
29        uint256 value;
30    }
31
32    #[derive(Debug, PartialEq, Eq)]
33    struct SafeTransactionArgs {
34        address from_address;
35        uint256 nonce;
36        uint256 chain_id;
37        SafeTransaction[] transactions;
38    }
39
40    #[derive(Debug, PartialEq, Eq)]
41    struct SafeTx {
42        address to;
43        uint256 value;
44        bytes data;
45        uint8 operation;
46        uint256 safeTxGas;
47        uint256 baseGas;
48        uint256 gasPrice;
49        address gasToken;
50        address refundReceiver;
51        uint256 nonce;
52    }
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize)]
56pub struct TransactionRequest {
57    #[serde(rename = "type")]
58    pub type_: String,
59    pub from: String,
60    pub to: String,
61    #[serde(rename = "proxyWallet")]
62    pub proxy_wallet: String,
63    pub data: String,
64    pub signature: String,
65    // Add signature params if needed
66}
67
68#[derive(Debug, Clone, Serialize, Deserialize)]
69pub struct RelayerTransactionResponse {
70    #[serde(rename = "transactionID")]
71    pub transaction_id: String,
72    #[serde(rename = "transactionHash")]
73    pub transaction_hash: Option<String>,
74}
75
76pub fn deserialize_nonce<'de, D>(deserializer: D) -> Result<u64, D::Error>
77where
78    D: serde::Deserializer<'de>,
79{
80    use serde::de;
81
82    struct NonceVisitor;
83
84    impl<'de> de::Visitor<'de> for NonceVisitor {
85        type Value = u64;
86
87        fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
88            formatter.write_str("a u64 or string representing a u64")
89        }
90
91        fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> {
92            Ok(v)
93        }
94
95        fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
96        where
97            E: de::Error,
98        {
99            v.parse().map_err(de::Error::custom)
100        }
101    }
102
103    deserializer.deserialize_any(NonceVisitor)
104}
105
106#[derive(Debug, Clone, Serialize, Deserialize)]
107pub struct NonceResponse {
108    #[serde(deserialize_with = "deserialize_nonce")]
109    pub nonce: u64,
110}
111
112#[derive(Debug, Clone, Serialize, Deserialize)]
113pub struct TransactionStatusResponse {
114    pub state: String,
115    #[serde(rename = "transactionHash")]
116    pub transaction_hash: Option<String>,
117}