Skip to main content

jito_bundle/
types.rs

1use serde::{Deserialize, Serialize};
2
3/// Generic JSON-RPC request payload wrapper.
4#[derive(Debug, Serialize)]
5pub struct JsonRpcRequest<T: Serialize> {
6    /// JSON-RPC protocol version.
7    pub jsonrpc: &'static str,
8    /// Request id used for matching responses.
9    pub id: u64,
10    /// RPC method name.
11    pub method: &'static str,
12    /// Method-specific parameters.
13    pub params: T,
14}
15
16/// Generic JSON-RPC response payload wrapper.
17#[derive(Debug, Deserialize)]
18pub struct JsonRpcResponse<T> {
19    /// JSON-RPC protocol version.
20    pub jsonrpc: String,
21    /// Response id corresponding to request id.
22    pub id: u64,
23    /// Success result payload when present.
24    pub result: Option<T>,
25    /// Error payload when present.
26    pub error: Option<JsonRpcError>,
27}
28
29/// JSON-RPC error object.
30#[derive(Debug, Deserialize)]
31pub struct JsonRpcError {
32    /// JSON-RPC error code.
33    pub code: i64,
34    /// Human-readable error message.
35    pub message: String,
36}
37
38/// Jito tip-floor API response entry.
39#[derive(Debug, Deserialize, Clone)]
40pub struct JitoTipFloorResponse {
41    /// Response timestamp.
42    pub time: String,
43    /// 25th percentile landed tip (SOL units).
44    pub landed_tips_25th_percentile: f64,
45    /// 50th percentile landed tip (SOL units).
46    pub landed_tips_50th_percentile: f64,
47    /// 75th percentile landed tip (SOL units).
48    pub landed_tips_75th_percentile: f64,
49    /// 95th percentile landed tip (SOL units).
50    pub landed_tips_95th_percentile: f64,
51    /// 99th percentile landed tip (SOL units).
52    pub landed_tips_99th_percentile: f64,
53    /// EMA 50th percentile landed tip (SOL units).
54    pub ema_landed_tips_50th_percentile: f64,
55}
56
57/// High-level bundle landing status.
58#[derive(Clone)]
59pub enum BundleStatus {
60    /// Bundle is still pending.
61    Pending,
62    /// Bundle landed with optional slot.
63    Landed { slot: Option<u64> },
64    /// Bundle failed with optional error details.
65    Failed { error: Option<String> },
66    /// Status could not be determined.
67    Unknown,
68}
69
70impl std::fmt::Debug for BundleStatus {
71    /// Formats bundle status in a compact human-readable form.
72    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73        match self {
74            BundleStatus::Pending => write!(f, "Pending"),
75            BundleStatus::Landed { slot } => write!(f, "Landed(slot: {slot:?})"),
76            BundleStatus::Failed { error } => write!(f, "Failed(error: {error:?})"),
77            BundleStatus::Unknown => write!(f, "Unknown"),
78        }
79    }
80}
81
82/// Result returned after bundle submission.
83#[derive(Debug, Clone)]
84pub struct BundleResult {
85    /// Returned bundle id.
86    pub bundle_id: String,
87    /// Transaction signatures from submitted bundle.
88    pub signatures: Vec<String>,
89    /// Explorer URL for bundle status.
90    pub explorer_url: String,
91}
92
93/// Parameters for Helius `simulateBundle` call.
94#[derive(Debug, Serialize)]
95#[serde(rename_all = "camelCase")]
96pub struct SimulateBundleParams {
97    /// Base64-encoded transactions in bundle order.
98    pub encoded_transactions: Vec<String>,
99}
100
101/// Top-level Helius `simulateBundle` result.
102#[derive(Debug, Deserialize)]
103#[serde(rename_all = "camelCase")]
104pub struct SimulateBundleApiResult {
105    /// Simulation context metadata.
106    pub context: SimulateBundleContext,
107    /// Simulation output payload.
108    pub value: SimulateBundleValue,
109}
110
111/// Simulation context metadata.
112#[derive(Debug, Deserialize)]
113#[serde(rename_all = "camelCase")]
114pub struct SimulateBundleContext {
115    /// API version that handled simulation.
116    pub api_version: String,
117    /// Slot used for simulation context.
118    pub slot: u64,
119}
120
121/// Full simulation output.
122#[derive(Debug, Deserialize)]
123#[serde(rename_all = "camelCase")]
124pub struct SimulateBundleValue {
125    /// Overall simulation summary.
126    pub summary: SimulateBundleSummary,
127    /// Per-transaction simulation results.
128    pub transaction_results: Vec<TransactionSimulationResult>,
129}
130
131/// Overall simulation summary state.
132#[derive(Debug, Deserialize)]
133#[serde(rename_all = "camelCase")]
134pub enum SimulateBundleSummary {
135    /// All transactions simulated successfully.
136    Succeeded,
137    /// Simulation failed with details.
138    Failed(SimulateBundleFailure),
139}
140
141/// Failure payload returned by Helius simulation.
142#[derive(Debug, Deserialize)]
143#[serde(rename_all = "camelCase")]
144pub struct SimulateBundleFailure {
145    /// Raw simulation error object.
146    pub error: serde_json::Value,
147    /// Optional failing transaction signature.
148    pub tx_signature: Option<String>,
149}
150
151impl SimulateBundleFailure {
152    /// Extracts a readable error message from Helius failure payload.
153    pub fn error_message(&self) -> String {
154        if let Some(tx_failure) = self.error.get("TransactionFailure")
155            && let Some(arr) = tx_failure.as_array()
156            && let Some(msg) = arr.get(1).and_then(|v| v.as_str())
157        {
158            return msg.to_string();
159        }
160        self.error.to_string()
161    }
162}
163
164/// Per-transaction simulation result entry.
165#[derive(Debug, Deserialize)]
166#[serde(rename_all = "camelCase")]
167pub struct TransactionSimulationResult {
168    /// Transaction-level error when present.
169    pub err: Option<serde_json::Value>,
170    /// Program logs emitted during execution.
171    pub logs: Option<Vec<String>>,
172    /// Compute units consumed by transaction.
173    pub units_consumed: Option<u64>,
174    /// Optional program return data.
175    pub return_data: Option<ReturnData>,
176    /// Optional pre-execution account states.
177    pub pre_execution_accounts: Option<Vec<AccountState>>,
178    /// Optional post-execution account states.
179    pub post_execution_accounts: Option<Vec<AccountState>>,
180}
181
182/// Account snapshot in simulation response.
183#[derive(Debug, Deserialize)]
184#[serde(rename_all = "camelCase")]
185pub struct AccountState {
186    /// Base58-encoded account pubkey.
187    pub pubkey: String,
188    /// Account lamports balance.
189    pub lamports: u64,
190    /// Account data payload.
191    pub data: Vec<String>,
192    /// Base58-encoded owner program id.
193    pub owner: String,
194    /// Whether account is executable.
195    pub executable: bool,
196    /// Account rent epoch.
197    pub rent_epoch: u64,
198}
199
200/// Program return data from simulation.
201#[derive(Debug, Deserialize)]
202#[serde(rename_all = "camelCase")]
203pub struct ReturnData {
204    /// Program id that returned the data.
205    pub program_id: String,
206    /// Encoded return data payload.
207    pub data: Vec<String>,
208}