1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct StakerRewardsResponse {
7 pub rewards: Vec<StakerReward>,
8 pub total: Option<u64>,
9}
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct StakerReward {
14 pub stake_account: String,
16
17 pub stake_authority: String,
19
20 pub withdraw_authority: String,
22
23 pub epoch: u64,
25
26 pub mev_rewards: u64,
28
29 pub priority_fee_rewards: Option<u64>,
31
32 pub mev_claimed: bool,
34
35 pub priority_fee_claimed: Option<bool>,
37
38 pub vote_account: String,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct ValidatorRewardsResponse {
45 pub validators: Vec<ValidatorReward>,
46}
47
48#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct ValidatorReward {
51 pub vote_account: String,
53
54 pub epoch: u64,
56
57 pub mev_commission_bps: u16,
59
60 pub mev_rewards: u64,
62
63 pub priority_fee_commission_bps: Option<u16>,
65
66 pub priority_fee_rewards: Option<u64>,
68
69 pub num_stakers: Option<u64>,
71
72 pub active_stake: Option<u64>,
74}
75
76#[derive(Debug, Clone, Serialize, Deserialize)]
82pub struct ValidatorsResponse {
83 pub validators: Vec<ValidatorInfo>,
84}
85
86#[derive(Debug, Clone, Serialize, Deserialize)]
88pub struct ValidatorInfo {
89 pub vote_account: String,
91
92 pub mev_commission_bps: u16,
94
95 pub mev_rewards: u64,
97
98 pub priority_fee_commission_bps: Option<u16>,
100
101 pub priority_fee_rewards: Option<u64>,
103
104 pub running_jito: bool,
106
107 pub active_stake: u64,
109}
110
111#[derive(Debug, Clone, Serialize, Deserialize)]
113pub struct ValidatorHistory {
114 pub epoch: u64,
116
117 pub mev_commission_bps: u16,
119
120 pub mev_rewards: u64,
122
123 pub priority_fee_commission_bps: Option<u16>,
125
126 pub priority_fee_rewards: Option<u64>,
128}
129
130#[derive(Debug, Clone, Serialize, Deserialize)]
132pub struct MevRewards {
133 pub epoch: u64,
135
136 pub total_network_mev_lamports: u64,
138
139 pub jito_stake_weight_lamports: u64,
141
142 pub mev_reward_per_lamport: f64,
144}
145
146#[derive(Debug, Clone, Serialize, Deserialize)]
148pub struct DailyMevTips {
149 pub day: DateTime<Utc>,
151
152 pub count_mev_tips: u64,
154
155 pub jito_tips: f64,
157
158 pub tippers: u64,
160
161 pub validator_tips: f64,
163}
164
165#[derive(Debug, Clone, Serialize, Deserialize)]
167pub struct JitoStakeOverTime {
168 pub stake_ratio_over_time: std::collections::HashMap<String, f64>,
170}
171
172#[derive(Debug, Clone, Serialize, Deserialize)]
174pub struct MevCommissionAverageOverTime {
175 pub aggregated_mev_rewards: u64,
177
178 pub mev_rewards: Vec<TimeSeriesData<u64>>,
180
181 pub tvl: Vec<TimeSeriesData<u64>>,
183
184 pub apy: Vec<TimeSeriesData<f64>>,
186
187 pub num_validators: Vec<TimeSeriesData<u64>>,
189
190 pub supply: Vec<TimeSeriesData<f64>>,
192}
193
194#[derive(Debug, Clone, Serialize, Deserialize)]
196pub struct TimeSeriesData<T> {
197 pub data: T,
199
200 pub date: DateTime<Utc>,
202}
203
204#[derive(Debug, Clone, Serialize, Deserialize)]
206pub struct JitoSolRatio {
207 pub ratios: Vec<TimeSeriesData<f64>>,
209}
210
211#[derive(Debug, Clone, Serialize, Deserialize)]
213pub struct StakePoolStats {
214 pub epoch: u64,
216
217 pub total_lamports: u64,
219
220 pub jitosol_supply: f64,
222
223 pub exchange_ratio: f64,
225
226 pub apy: f64,
228
229 pub num_validators: u64,
231
232 pub total_mev_earned: u64,
234}
235
236#[derive(Debug, Clone, Serialize, Deserialize)]
242pub struct EpochRequest {
243 pub epoch: u64,
245}
246
247#[derive(Debug, Clone, Serialize, Deserialize)]
249pub struct RangeFilter {
250 pub start: DateTime<Utc>,
252
253 pub end: DateTime<Utc>,
255}
256
257#[derive(Debug, Clone, Serialize, Deserialize)]
259pub struct RangeRequest {
260 pub range_filter: RangeFilter,
262}
263
264#[derive(Debug, Clone, Serialize, Deserialize)]
270pub struct ValidatorHistoryAccount {
271 pub vote_account: String,
273
274 pub history: Vec<ValidatorHistoryEntry>,
276}
277
278#[derive(Debug, Clone, Serialize, Deserialize)]
280pub struct ValidatorHistoryEntry {
281 pub epoch: u64,
283
284 pub vote_credits: Option<u32>,
286
287 pub commission: Option<u8>,
289
290 pub mev_commission_bps: Option<u16>,
292
293 pub version: Option<String>,
295
296 pub client_type: Option<String>,
298
299 pub active_stake: Option<u64>,
301
302 pub stake_rank: Option<u32>,
304
305 pub is_superminority: Option<bool>,
307
308 pub ip_address: Option<String>,
310}
311
312#[derive(Debug, Clone, Serialize, Deserialize)]
314pub struct StewardConfig {
315 pub stake_pool: String,
317
318 pub authority: String,
320
321 pub scoring_params: ScoringParams,
323}
324
325#[derive(Debug, Clone, Serialize, Deserialize)]
327pub struct ScoringParams {
328 pub min_vote_credits: u32,
330
331 pub max_commission: u8,
333
334 pub performance_weight: f64,
336
337 pub commission_weight: f64,
339
340 pub stake_concentration_limit: f64,
342}
343
344#[derive(Debug, Clone, Default)]
350pub struct QueryParams {
351 pub limit: Option<u32>,
353
354 pub offset: Option<u32>,
356
357 pub epoch: Option<u64>,
359
360 pub sort_order: Option<String>,
362}
363
364impl QueryParams {
365 pub fn with_limit(limit: u32) -> Self {
367 Self {
368 limit: Some(limit),
369 ..Default::default()
370 }
371 }
372
373 pub fn with_epoch(epoch: u64) -> Self {
375 Self {
376 epoch: Some(epoch),
377 ..Default::default()
378 }
379 }
380
381 pub fn limit(mut self, limit: u32) -> Self {
383 self.limit = Some(limit);
384 self
385 }
386
387 pub fn offset(mut self, offset: u32) -> Self {
389 self.offset = Some(offset);
390 self
391 }
392
393 pub fn epoch(mut self, epoch: u64) -> Self {
395 self.epoch = Some(epoch);
396 self
397 }
398
399 pub fn to_query_string(&self) -> String {
401 let mut params = Vec::new();
402
403 if let Some(limit) = self.limit {
404 params.push(format!("limit={}", limit));
405 }
406 if let Some(offset) = self.offset {
407 params.push(format!("offset={}", offset));
408 }
409 if let Some(epoch) = self.epoch {
410 params.push(format!("epoch={}", epoch));
411 }
412 if let Some(ref sort_order) = self.sort_order {
413 params.push(format!("sort_order={}", sort_order));
414 }
415
416 if params.is_empty() {
417 String::new()
418 } else {
419 format!("?{}", params.join("&"))
420 }
421 }
422}
423
424#[derive(Debug, Clone, Serialize, Deserialize)]
430pub struct ApiErrorResponse {
431 pub error: String,
432 pub message: Option<String>,
433 pub status_code: Option<u16>,
434}