1use std::collections::HashSet;
2
3use chrono::{DateTime, Utc};
4use jsonrpsee::{
5 core::{RpcResult, SubscriptionResult},
6 proc_macros::rpc,
7};
8use serde::{Deserialize, Serialize};
9use solana_sdk::{clock::Slot, pubkey::Pubkey};
10
11use crate::CompoundProof;
12
13#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
16pub struct BloberData {
17 #[serde(with = "pubkey_with_str")]
18 pub blober: Pubkey,
19 pub payer: Pubkey,
20 pub network_id: u64,
21}
22
23#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
25pub struct TimeRange {
26 pub start: Option<DateTime<Utc>>,
28 pub end: Option<DateTime<Utc>>,
30}
31
32impl TimeRange {
33 pub fn to_db_defaults(&self) -> (DateTime<Utc>, DateTime<Utc>) {
36 #[allow(clippy::unwrap_used, reason = "Hardcoding 0 will never panic")]
37 let default_start = DateTime::<Utc>::from_timestamp_micros(0).unwrap();
38
39 (
40 self.start.unwrap_or(default_start),
41 self.end.unwrap_or(Utc::now()),
42 )
43 }
44}
45
46#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
48pub struct PubkeyFromStr(#[serde(with = "pubkey_with_str")] pub Pubkey);
49
50impl From<PubkeyFromStr> for Pubkey {
51 fn from(value: PubkeyFromStr) -> Self {
52 value.0
53 }
54}
55
56impl From<Pubkey> for PubkeyFromStr {
57 fn from(value: Pubkey) -> Self {
58 PubkeyFromStr(value)
59 }
60}
61
62#[rpc(server, client)]
64pub trait IndexerRpc {
65 #[method(name = "get_blobs")]
69 async fn get_blobs(&self, blober: PubkeyFromStr, slot: u64) -> RpcResult<Option<Vec<Vec<u8>>>>;
70
71 #[method(name = "get_blobs_by_blober")]
74 async fn get_blobs_by_blober(
75 &self,
76 blober: PubkeyFromStr,
77 time_range: Option<TimeRange>,
78 ) -> RpcResult<Vec<Vec<u8>>>;
79
80 #[method(name = "get_blobs_by_payer")]
83 async fn get_blobs_by_payer(
84 &self,
85 payer: PubkeyFromStr,
86 network_name: String,
87 time_range: Option<TimeRange>,
88 ) -> RpcResult<Vec<Vec<u8>>>;
89
90 #[method(name = "get_blobs_by_network")]
93 async fn get_blobs_by_network(
94 &self,
95 network_name: String,
96 time_range: TimeRange,
97 ) -> RpcResult<Vec<Vec<u8>>>;
98
99 #[method(name = "get_blobs_by_namespace")]
102 async fn get_blobs_by_namespace_for_payer(
103 &self,
104 namespace: String,
105 payer: Option<PubkeyFromStr>,
106 time_range: TimeRange,
107 ) -> RpcResult<Vec<Vec<u8>>>;
108
109 #[method(name = "get_payers_by_network")]
112 async fn get_payers_by_network(&self, network_name: String) -> RpcResult<Vec<PubkeyFromStr>>;
113
114 #[method(name = "get_proof")]
117 async fn get_proof(&self, blober: PubkeyFromStr, slot: u64)
118 -> RpcResult<Option<CompoundProof>>;
119
120 #[method(name = "get_proof_for_blob")]
123 async fn get_proof_for_blob(
124 &self,
125 blob_address: PubkeyFromStr,
126 ) -> RpcResult<Option<CompoundProof>>;
127
128 #[subscription(
132 name = "subscribe_blob_finalization" => "listen_subscribe_blob_finalization",
133 unsubscribe = "unsubscribe_blob_finalization",
134 item = (Pubkey, Slot)
135 )]
136 async fn subscribe_blob_finalization(
137 &self,
138 blobers: HashSet<PubkeyFromStr>,
139 ) -> SubscriptionResult;
140}
141
142pub mod pubkey_with_str {
143 use std::str::FromStr;
144
145 use serde::{Deserialize, Deserializer, de};
146 use solana_sdk::pubkey::Pubkey;
147
148 pub fn deserialize<'de, D>(deserializer: D) -> Result<Pubkey, D::Error>
149 where
150 D: Deserializer<'de>,
151 {
152 String::deserialize(deserializer)
153 .and_then(|key| Pubkey::from_str(&key).map_err(de::Error::custom))
154 }
155
156 pub fn serialize<S>(pubkey: &Pubkey, serializer: S) -> Result<S::Ok, S::Error>
157 where
158 S: serde::Serializer,
159 {
160 serializer.serialize_str(&pubkey.to_string())
161 }
162}