Skip to main content

gelato_sdk/
types.rs

1use ethers_core::types::{Bytes, H160, H256, U256, U64};
2use once_cell::sync::Lazy;
3use serde::{Deserialize, Serialize};
4use serde_repr::{Deserialize_repr, Serialize_repr};
5
6/// Magic value used to specify the chain-native token
7static NATIVE_TOKEN: Lazy<FeeToken> = Lazy::new(|| {
8    FeeToken(
9        "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
10            .parse()
11            .unwrap(),
12    )
13});
14
15/// A gelato fee token is an ERC20 address, which defaults to `0xee..ee`. This
16/// magic value indicates "eth" or the native asset of the chain. This FeeToken
17/// must be allowlisted by Gelato validators
18#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq)]
19pub struct FeeToken(H160);
20
21impl std::ops::Deref for FeeToken {
22    type Target = H160;
23
24    fn deref(&self) -> &Self::Target {
25        &self.0
26    }
27}
28
29impl Default for FeeToken {
30    fn default() -> Self {
31        *NATIVE_TOKEN
32    }
33}
34
35impl From<H160> for FeeToken {
36    fn from(token: H160) -> Self {
37        Self(token)
38    }
39}
40
41/// Gelato payment type
42/// <https://docs.gelato.network/developer-products/gelato-relay-sdk/payment-types>
43#[derive(Debug, Copy, Clone, Serialize_repr, Deserialize_repr, PartialEq, Eq)]
44#[repr(u8)]
45pub enum PaymentType {
46    /// The target smart contract will pay Gelato Relay's smart contract as the
47    /// call is forwarded. Payment can be done in feeToken, where it is
48    /// expected to be a whitelisted payment token.
49    Synchronous = 0,
50    /// The sponsor must hold a balance in one of Gelato's Gas Tank smart
51    /// contracts. The balance could even be held on a different chainId than
52    /// the one the transaction is being relayed on (as defined by
53    /// sponsorChainId).
54    ///
55    /// An event is emitted to tell Gelato how much to charge in the future,
56    /// which shall be acknowledged in an off-chain accounting system. A
57    /// sponsor signature is expected in order to ensure that the sponsor
58    /// agrees on being charged up to a maxFee amount
59    AsyncGasTank = 1,
60    /// Similar to Type 1, but sponsor is expected to hold a balance with
61    /// Gelato on the same chainId where the transaction is executed. Fee
62    /// deduction happens during the transaction. A sponsor signature is
63    /// expected in order to ensure that the sponsor agrees on being charged up
64    /// to a maxFee amount.
65    SyncGasTank = 2,
66    /// In this scenario a sponsor pre-approves the appropriate Gelato Relay's
67    /// smart contract to spend tokens up so some maximum allowance value.
68    /// During execution of the transaction, Gelato will credit due fees using
69    /// `IERC20(feeToken).transferFrom(...)` in order to pull fees from his/her
70    /// account. A sponsor signature is expected in order to ensure that the
71    /// sponsor agrees on being charged up to a maxFee amount.
72    SyncPullFee = 3,
73}
74
75/// Request for forwarding tx to gas-tank based relay service.
76#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
77#[serde(rename_all = "camelCase")]
78pub struct ForwardRequest {
79    /// must be exactly "ForwardRequest"
80    pub type_id: &'static str,
81    /// Chain id
82    pub chain_id: usize,
83    /// Address of dApp's smart contract to call.
84    pub target: H160,
85    /// Payload for `target`.
86    pub data: Bytes,
87    /// paymentToken for Gelato Executors
88    pub fee_token: H160,
89    ///Type identifier for Gelato's payment. Can be 1, 2 or 3.
90    pub payment_type: usize, // 1 = gas tank
91    /// Maximum fee sponsor is willing to pay Gelato Executors
92    pub max_fee: U64,
93    /// Gas limit
94    pub gas: U64,
95    /// EOA address that pays Gelato Executors.
96    pub sponsor: H160,
97    /// Chain ID of where sponsor holds a Gas Tank balance with Gelato
98    /// Usually the same as `
99    pub sponsor_chain_id: usize,
100    /// Smart contract nonce for sponsor to sign.
101    /// Can be 0 if enforceSponsorNonce is always false.
102    pub nonce: usize,
103    /// Whether or not to enforce replay protection using sponsor's nonce.
104    /// Defaults to false, as repla
105    pub enforce_sponsor_nonce: bool,
106    /// Whether or not ordering matters for concurrently submitted transactions.
107    /// Defaults to `true` if not provided.
108    pub enforce_sponsor_nonce_ordering: Option<bool>,
109    /// EIP-712 signature over the forward request
110    pub sponsor_signature: ethers_core::types::Signature,
111}
112
113/// A Relay Request
114#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
115#[serde(rename_all = "camelCase")]
116pub struct RelayRequest {
117    /// The address of the contract to be called
118    pub dest: H160,
119    /// The calldata
120    pub data: Bytes,
121    /// The fee token
122    pub token: FeeToken,
123    /// The amount of fee
124    pub relayer_fee: U64,
125}
126
127/// An Estimated Fee Request
128#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
129#[serde(rename_all = "camelCase")]
130pub struct EstimatedFeeRequest {
131    /// Payment token
132    pub payment_token: FeeToken,
133    /// Gas limit
134    pub gas_limit: U64,
135    /// Whether this is high priority
136    pub is_high_priority: bool,
137}
138
139/// Response to relay request, contains an ID for the task
140#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
141#[serde(rename_all = "camelCase")]
142pub struct RelayResponse {
143    /// The task ID
144    pub task_id: H256,
145}
146
147/// Response to estimated fee request. Contains the estimated fee
148#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
149#[serde(rename_all = "camelCase")]
150pub(crate) struct EstimatedFeeResponse {
151    /// The oracle-recommended fee, as a decimal string
152    estimated_fee: String,
153}
154
155impl EstimatedFeeResponse {
156    pub(crate) fn estimated_fee(&self) -> usize {
157        self.estimated_fee.parse().unwrap()
158    }
159}
160
161/// Response to Relay chains request. Contains a list of chain ids supported
162#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
163#[serde(rename_all = "camelCase")]
164pub(crate) struct RelayChainsResponse {
165    /// The supported chain ids
166    relays: Vec<String>,
167}
168
169impl RelayChainsResponse {
170    pub(crate) fn relays(&self) -> impl Iterator<Item = usize> + '_ {
171        self.relays.iter().map(|s| s.parse().unwrap())
172    }
173}
174
175/// Response to the GetTaskStatus api call. Contains an array of task statuses
176#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
177#[serde(rename_all = "camelCase")]
178pub struct TaskStatusResponse {
179    data: Vec<TransactionStatus>,
180}
181
182impl std::ops::Deref for TaskStatusResponse {
183    type Target = Vec<TransactionStatus>;
184
185    fn deref(&self) -> &Self::Target {
186        &self.data
187    }
188}
189
190impl IntoIterator for TaskStatusResponse {
191    type Item = TransactionStatus;
192
193    type IntoIter = <Vec<TransactionStatus> as IntoIterator>::IntoIter;
194
195    fn into_iter(self) -> Self::IntoIter {
196        self.data.into_iter()
197    }
198}
199
200/// A Task Status object
201#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
202#[serde(rename_all = "camelCase")]
203pub struct TransactionStatus {
204    /// Service name
205    pub service: String,
206    /// Chain name
207    pub chain: String,
208    /// Task id
209    pub task_id: H256,
210    /// Task state
211    pub task_state: TaskState,
212    /// Created at date/time string
213    #[serde(rename = "created_at")]
214    pub created_at: String, // date
215    /// Info from last check
216    pub last_check: Option<CheckOrDate>,
217    /// Execution info
218    pub execution: Option<Execution>,
219    /// Last execution date/time string
220    pub last_execution: String, // date
221}
222
223/// Execution details
224#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
225#[serde(rename_all = "camelCase")]
226pub struct Execution {
227    /// Transaction status
228    pub status: String,
229    /// Transaction hash
230    pub transaction_hash: H256,
231    /// Block number
232    pub block_number: usize,
233    /// Creation date/time string
234    #[serde(rename = "created_at")]
235    pub created_at: String,
236}
237
238/// Either check details, or a date/time string
239#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
240#[serde(untagged, rename_all = "camelCase")]
241pub enum CheckOrDate {
242    /// Date
243    Date(String),
244    /// Check
245    Check(Check),
246}
247
248/// Check info for a
249#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
250#[serde(rename_all = "camelCase")]
251pub struct Check {
252    /// Task state at this check
253    pub task_state: TaskState,
254    /// Message string
255    pub message: Option<String>,
256    /// Creation date/time string
257    #[serde(rename = "created_at")]
258    pub created_at: Option<String>,
259}
260
261/// Transaction payload information
262#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
263#[serde(rename_all = "camelCase")]
264pub struct Payload {
265    /// Transaction target
266    pub to: H160,
267    /// Transaction input data
268    pub data: Bytes,
269    /// Fee data
270    pub fee_data: FeeData,
271}
272
273/// eip1559 fee data
274#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
275#[serde(rename_all = "camelCase")]
276pub struct FeeData {
277    /// Gas Price
278    pub gas_price: U256,
279    /// Max fee per gas
280    pub max_fee_per_gas: U256,
281    /// Max priority fee per gas
282    pub max_priority_fee_per_gas: U256,
283}
284
285/// Task states
286#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
287pub enum TaskState {
288    /// CheckPending
289    CheckPending,
290    /// ExecPending
291    ExecPending,
292    /// ExecSuccess
293    ExecSuccess,
294    /// ExecReverted
295    ExecReverted,
296    /// WaitingForConfirmation
297    WaitingForConfirmation,
298    /// Blacklisted
299    Blacklisted,
300    /// Cancelled
301    Cancelled,
302    /// NotFound
303    NotFound,
304}