celestia_rpc/tx_config.rs
1use celestia_types::state::AccAddress;
2use serde::{
3 Deserialize, Serialize,
4 ser::{SerializeStruct, Serializer},
5};
6use serde_repr::{Deserialize_repr, Serialize_repr};
7
8/// Transaction priority for gas price estimation.
9#[derive(
10 Clone,
11 Copy,
12 PartialEq,
13 Eq,
14 PartialOrd,
15 Ord,
16 Hash,
17 Debug,
18 Default,
19 Serialize_repr,
20 Deserialize_repr,
21)]
22#[repr(u8)]
23pub enum TxPriority {
24 /// Estimated gas price is the value at the end of the lowest 10% of gas prices from the last 5 blocks.
25 Low = 1,
26 /// Estimated gas price is the mean of all gas prices from the last 5 blocks.
27 #[default]
28 Medium = 2,
29 /// Estimated gas price is the price at the start of the top 10% of transactions’ gas prices from the last 5 blocks.
30 High = 3,
31}
32
33/// [`TxConfig`] specifies additional options that are be applied to the Tx.
34///
35/// If no options are provided, then the default ones will be used.
36/// Read more about the mechanisms of fees and gas usage in [`submitting data blobs`].
37///
38/// [`submitting data blobs`]: https://docs.celestia.org/developers/submit-data#fees-and-gas-limits
39#[derive(Debug, Default, Deserialize)]
40pub struct TxConfig {
41 /// Specifies the address from the keystore that will sign transactions.
42 ///
43 /// # NOTE
44 ///
45 /// Only `signer_address` or `key_name` should be passed. `signer_address` is a primary cfg.
46 /// This means If both the address and the key are specified, the address field will take priority.
47 pub signer_address: Option<AccAddress>,
48 /// Specifies the key from the keystore associated with an account that will be used to sign transactions.
49 ///
50 /// # NOTE
51 ///
52 /// This account must be available in the Keystore.
53 pub key_name: Option<String>,
54 /// Represents the amount to be paid per gas unit.
55 ///
56 /// Negative or missing `gas_price` means user want us to use the minGasPrice defined in the node.
57 pub gas_price: Option<f64>,
58 /// Represents the maximal amount to be paid per gas unit.
59 pub max_gas_price: Option<f64>,
60 /// Calculated amount of gas to be used by transaction.
61 ///
62 /// `0` or missing `gas` means that the node should calculate it itself.
63 pub gas: Option<u64>,
64 /// Transaction priority level used when estimating the gas price.
65 pub priority: Option<TxPriority>,
66 /// Specifies the account that will pay for the transaction.
67 pub fee_granter_address: Option<AccAddress>,
68}
69
70impl TxConfig {
71 /// Sets the [`gas_price`] of the transaction.
72 ///
73 /// [`gas_price`]: TxConfig::gas_price
74 pub fn with_gas_price(mut self, gas_price: f64) -> Self {
75 self.gas_price = Some(gas_price);
76 self
77 }
78
79 /// Sets the [`max_gas_price`] of the transaction.
80 ///
81 /// [`max_gas_price`]: TxConfig::max_gas_price
82 pub fn with_max_gas_price(mut self, max_gas_price: f64) -> Self {
83 self.max_gas_price = Some(max_gas_price);
84 self
85 }
86
87 /// Sets the [`gas`] of the transaction.
88 ///
89 /// [`gas`]: TxConfig::gas
90 pub fn with_gas(mut self, gas: u64) -> Self {
91 self.gas = Some(gas);
92 self
93 }
94
95 /// Sets the [`priority`] of the transaction.
96 ///
97 /// [`priority`]: TxConfig::priority
98 pub fn with_priority(mut self, priority: TxPriority) -> Self {
99 self.priority = Some(priority);
100 self
101 }
102
103 /// Sets the [`fee_granter_address`] of the transaction.
104 ///
105 /// [`fee_granter_address`]: TxConfig::fee_granter_address
106 pub fn with_fee_granter_address(mut self, fee_granter_address: AccAddress) -> Self {
107 self.fee_granter_address = Some(fee_granter_address);
108 self
109 }
110
111 /// Sets the [`signer_address`] of the transaction.
112 ///
113 /// [`signer_address`]: TxConfig::signer_address
114 pub fn with_signer_address(mut self, signer_address: AccAddress) -> Self {
115 self.signer_address = Some(signer_address);
116 self
117 }
118
119 /// Sets the [`key_name`] of the transaction.
120 ///
121 /// [`key_name`]: TxConfig::key_name
122 pub fn with_key_name(mut self, key_name: impl Into<String>) -> Self {
123 self.key_name = Some(key_name.into());
124 self
125 }
126}
127
128impl Serialize for TxConfig {
129 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
130 where
131 S: Serializer,
132 {
133 let mut state = serializer.serialize_struct("TxConfig", 6)?;
134
135 if let Some(signer_address) = &self.signer_address {
136 state.serialize_field("signer_address", signer_address)?;
137 }
138 if let Some(key_name) = &self.key_name {
139 state.serialize_field("key_name", key_name)?;
140 }
141
142 if let Some(gas_price) = &self.gas_price {
143 state.serialize_field("gas_price", gas_price)?;
144 state.serialize_field("is_gas_price_set", &true)?;
145 }
146
147 if let Some(max_gas_price) = &self.max_gas_price {
148 state.serialize_field("max_gas_price", max_gas_price)?;
149 }
150
151 if let Some(gas) = &self.gas {
152 state.serialize_field("gas", gas)?;
153 }
154
155 if let Some(priority) = &self.priority {
156 state.serialize_field("priority", priority)?;
157 }
158
159 if let Some(fee_granter_address) = &self.fee_granter_address {
160 state.serialize_field("fee_granter_address", fee_granter_address)?;
161 }
162
163 state.end()
164 }
165}