hyperliquid_sdk_rs/utils/
mod.rs

1/// Macro for user actions that use HyperliquidSignTransaction domain
2/// All user actions must have signature_chain_id as their first field
3#[macro_export]
4macro_rules! hyperliquid_action {
5    (
6        $(#[$meta:meta])*
7        struct $name:ident {
8            pub signature_chain_id: u64,
9            $(
10                $(#[$field_meta:meta])*
11                pub $field:ident: $type:ty
12            ),* $(,)?
13        }
14        => $type_string:literal
15        => encode($($encode_field:ident),* $(,)?)
16    ) => {
17        $(#[$meta])*
18        #[derive(Debug, Clone, serde::Serialize)]
19        #[serde(rename_all = "camelCase")]
20        pub struct $name {
21            pub signature_chain_id: u64,
22            $(
23                $(#[$field_meta])*
24                pub $field: $type,
25            )*
26        }
27
28        impl $crate::types::eip712::HyperliquidAction for $name {
29            const TYPE_STRING: &'static str = $type_string;
30            const USE_PREFIX: bool = true;
31
32            fn chain_id(&self) -> Option<u64> {
33                Some(self.signature_chain_id)
34            }
35
36            fn encode_data(&self) -> Vec<u8> {
37                let mut encoded = Vec::new();
38                encoded.extend_from_slice(&Self::type_hash()[..]);
39                $(
40                    encoded.extend_from_slice(&$crate::types::eip712::encode_value(&self.$encode_field)[..]);
41                )*
42                encoded
43            }
44        }
45    };
46}
47
48/// Macro for L1 actions that use the Exchange domain
49#[macro_export]
50macro_rules! l1_action {
51    (
52        $(#[$meta:meta])*
53        struct $name:ident {
54            $(
55                $(#[$field_meta:meta])*
56                pub $field:ident: $type:ty
57            ),* $(,)?
58        }
59        => $type_string:literal
60        => encode($($encode_field:ident),* $(,)?)
61    ) => {
62        $(#[$meta])*
63        #[derive(Debug, Clone, serde::Serialize)]
64        #[serde(rename_all = "camelCase")]
65        pub struct $name {
66            $(
67                $(#[$field_meta])*
68                pub $field: $type,
69            )*
70        }
71
72        impl $crate::types::eip712::HyperliquidAction for $name {
73            const TYPE_STRING: &'static str = $type_string;
74            const USE_PREFIX: bool = false;
75
76            // L1 actions use the Exchange domain with chain ID 1337
77            fn domain(&self) -> alloy::sol_types::Eip712Domain {
78                alloy::sol_types::eip712_domain! {
79                    name: "Exchange",
80                    version: "1",
81                    chain_id: 1337u64,
82                    verifying_contract: alloy::primitives::address!("0000000000000000000000000000000000000000"),
83                }
84            }
85
86            fn encode_data(&self) -> Vec<u8> {
87                let mut encoded = Vec::new();
88                encoded.extend_from_slice(&Self::type_hash()[..]);
89                $(
90                    encoded.extend_from_slice(&$crate::types::eip712::encode_value(&self.$encode_field)[..]);
91                )*
92                encoded
93            }
94        }
95    };
96}