anvil/eth/beacon/
response.rs

1//! Beacon API response types
2
3use axum::{
4    Json,
5    http::StatusCode,
6    response::{IntoResponse, Response},
7};
8use serde::{Deserialize, Serialize};
9
10/// Generic Beacon API response wrapper
11///
12/// This follows the beacon chain API specification where responses include
13/// the actual data plus metadata about execution optimism and finalization.
14#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct BeaconResponse<T> {
16    /// The response data
17    pub data: T,
18    /// Whether the response references an unverified execution payload
19    ///
20    /// For Anvil, this is always `false` since there's no real consensus layer
21    #[serde(default, skip_serializing_if = "Option::is_none")]
22    pub execution_optimistic: Option<bool>,
23    /// Whether the response references finalized history
24    ///
25    /// For Anvil, this is always `false` since there's no real consensus layer
26    #[serde(default, skip_serializing_if = "Option::is_none")]
27    pub finalized: Option<bool>,
28}
29
30impl<T> BeaconResponse<T> {
31    /// Creates a new beacon response with the given data
32    ///
33    /// For Anvil context, `execution_optimistic` and `finalized` are always `false`
34    pub fn new(data: T) -> Self {
35        Self { data, execution_optimistic: None, finalized: None }
36    }
37
38    /// Creates a beacon response with custom execution_optimistic and finalized flags
39    pub fn with_flags(data: T, execution_optimistic: bool, finalized: bool) -> Self {
40        Self { data, execution_optimistic: Some(execution_optimistic), finalized: Some(finalized) }
41    }
42}
43
44impl<T: Serialize> IntoResponse for BeaconResponse<T> {
45    fn into_response(self) -> Response {
46        (StatusCode::OK, Json(self)).into_response()
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53
54    #[test]
55    fn test_beacon_response_defaults() {
56        let response = BeaconResponse::new("test data");
57        assert_eq!(response.data, "test data");
58        assert!(response.execution_optimistic.is_none());
59        assert!(response.finalized.is_none());
60    }
61
62    #[test]
63    fn test_beacon_response_serialization() {
64        let response = BeaconResponse::with_flags(vec![1, 2, 3], false, false);
65        let json = serde_json::to_value(&response).unwrap();
66
67        assert_eq!(json["data"], serde_json::json!([1, 2, 3]));
68        assert_eq!(json["execution_optimistic"], false);
69        assert_eq!(json["finalized"], false);
70    }
71}