Skip to main content

photon_api/
lib.rs

1//! Photon API client generated from OpenAPI spec using progenitor.
2//!
3//! This crate provides a Rust client for the Photon indexer API.
4//! Types are pre-generated by progenitor and checked in; HTTP calls use reqwest directly.
5//! To regenerate after spec changes: `cargo build -p photon-api --features generate`
6
7#![allow(unused_imports, clippy::all, dead_code)]
8#![allow(mismatched_lifetime_syntaxes)]
9
10// Include the pre-generated progenitor types (checked in).
11// To regenerate after OpenAPI spec changes: cargo build -p photon-api --features generate
12include!("codegen.rs");
13
14pub mod apis {
15    use super::*;
16
17    /// Configuration for the Photon API client.
18    #[derive(Clone)]
19    pub struct Configuration {
20        pub base_path: String,
21        pub api_key: Option<String>,
22        pub client: reqwest::Client,
23    }
24
25    impl std::fmt::Debug for Configuration {
26        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27            f.debug_struct("Configuration")
28                .field("base_path", &self.base_path)
29                .finish()
30        }
31    }
32
33    impl Default for Configuration {
34        fn default() -> Self {
35            Self {
36                base_path: "https://devnet.helius-rpc.com".to_string(),
37                api_key: None,
38                client: reqwest::Client::new(),
39            }
40        }
41    }
42
43    impl Configuration {
44        /// Create a new configuration from a URL string.
45        ///
46        /// If the URL contains an `api-key` query parameter, it is extracted
47        /// and appended to every request as `?api-key=KEY`.
48        ///
49        /// ```ignore
50        /// // Without API key
51        /// let config = Configuration::new("https://rpc.example.com".to_string());
52        ///
53        /// // With API key
54        /// let config = Configuration::new("https://rpc.example.com?api-key=YOUR_KEY".to_string());
55        /// ```
56        pub fn new(url: String) -> Self {
57            let (base_path, api_key) = Self::parse_url(&url);
58            Self {
59                base_path,
60                api_key,
61                client: reqwest::Client::new(),
62            }
63        }
64
65        fn build_url(&self, endpoint: &str) -> String {
66            match &self.api_key {
67                Some(key) => format!("{}/{}?api-key={}", self.base_path, endpoint, key),
68                None => format!("{}/{}", self.base_path, endpoint),
69            }
70        }
71
72        pub(crate) fn parse_url(url: &str) -> (String, Option<String>) {
73            if let Some(query_start) = url.find('?') {
74                let base = &url[..query_start];
75                let query = &url[query_start + 1..];
76                for param in query.split('&') {
77                    if let Some(value) = param.strip_prefix("api-key=") {
78                        return (base.to_string(), Some(value.to_string()));
79                    }
80                }
81                (url.to_string(), None)
82            } else {
83                (url.to_string(), None)
84            }
85        }
86    }
87
88    pub mod configuration {
89        pub use super::Configuration;
90    }
91
92    /// Error type for API calls.
93    #[derive(Debug)]
94    pub enum Error<T> {
95        Reqwest(reqwest::Error),
96        ResponseError {
97            status: u16,
98            body: String,
99        },
100        #[doc(hidden)]
101        _Phantom(std::marker::PhantomData<T>),
102    }
103
104    impl<T> std::fmt::Display for Error<T> {
105        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
106            match self {
107                Error::Reqwest(e) => write!(f, "HTTP error: {}", e),
108                Error::ResponseError { status, body } => {
109                    write!(f, "Error response (status {}): {}", status, body)
110                }
111                Error::_Phantom(_) => unreachable!(),
112            }
113        }
114    }
115
116    /// Default API module providing function-style API calls.
117    pub mod default_api {
118        use super::*;
119
120        // ----------------------------------------------------------------
121        // Body construction helper functions
122        // ----------------------------------------------------------------
123
124        pub fn make_get_compressed_account_body(
125            params: types::PostGetCompressedAccountBodyParams,
126        ) -> types::PostGetCompressedAccountBody {
127            types::PostGetCompressedAccountBody {
128                id: types::PostGetCompressedAccountBodyId::TestAccount,
129                jsonrpc: types::PostGetCompressedAccountBodyJsonrpc::X20,
130                method: types::PostGetCompressedAccountBodyMethod::GetCompressedAccount,
131                params,
132            }
133        }
134
135        pub fn make_get_compressed_account_balance_body(
136            params: types::PostGetCompressedAccountBalanceBodyParams,
137        ) -> types::PostGetCompressedAccountBalanceBody {
138            types::PostGetCompressedAccountBalanceBody {
139                id: types::PostGetCompressedAccountBalanceBodyId::TestAccount,
140                jsonrpc: types::PostGetCompressedAccountBalanceBodyJsonrpc::X20,
141                method:
142                    types::PostGetCompressedAccountBalanceBodyMethod::GetCompressedAccountBalance,
143                params,
144            }
145        }
146
147        pub fn make_get_compressed_accounts_by_owner_v2_body(
148            params: types::PostGetCompressedAccountsByOwnerV2BodyParams,
149        ) -> types::PostGetCompressedAccountsByOwnerV2Body {
150            types::PostGetCompressedAccountsByOwnerV2Body {
151                id: types::PostGetCompressedAccountsByOwnerV2BodyId::TestAccount,
152                jsonrpc: types::PostGetCompressedAccountsByOwnerV2BodyJsonrpc::X20,
153                method: types::PostGetCompressedAccountsByOwnerV2BodyMethod::GetCompressedAccountsByOwnerV2,
154                params,
155            }
156        }
157
158        pub fn make_get_compressed_balance_by_owner_body(
159            params: types::PostGetCompressedBalanceByOwnerBodyParams,
160        ) -> types::PostGetCompressedBalanceByOwnerBody {
161            types::PostGetCompressedBalanceByOwnerBody {
162                id: types::PostGetCompressedBalanceByOwnerBodyId::TestAccount,
163                jsonrpc: types::PostGetCompressedBalanceByOwnerBodyJsonrpc::X20,
164                method:
165                    types::PostGetCompressedBalanceByOwnerBodyMethod::GetCompressedBalanceByOwner,
166                params,
167            }
168        }
169
170        pub fn make_get_compressed_mint_token_holders_body(
171            params: types::PostGetCompressedMintTokenHoldersBodyParams,
172        ) -> types::PostGetCompressedMintTokenHoldersBody {
173            types::PostGetCompressedMintTokenHoldersBody {
174                id: types::PostGetCompressedMintTokenHoldersBodyId::TestAccount,
175                jsonrpc: types::PostGetCompressedMintTokenHoldersBodyJsonrpc::X20,
176                method: types::PostGetCompressedMintTokenHoldersBodyMethod::GetCompressedMintTokenHolders,
177                params,
178            }
179        }
180
181        pub fn make_get_compressed_token_account_balance_body(
182            params: types::PostGetCompressedTokenAccountBalanceBodyParams,
183        ) -> types::PostGetCompressedTokenAccountBalanceBody {
184            types::PostGetCompressedTokenAccountBalanceBody {
185                id: types::PostGetCompressedTokenAccountBalanceBodyId::TestAccount,
186                jsonrpc: types::PostGetCompressedTokenAccountBalanceBodyJsonrpc::X20,
187                method: types::PostGetCompressedTokenAccountBalanceBodyMethod::GetCompressedTokenAccountBalance,
188                params,
189            }
190        }
191
192        pub fn make_get_validity_proof_v2_body(
193            params: types::PostGetValidityProofV2BodyParams,
194        ) -> types::PostGetValidityProofV2Body {
195            types::PostGetValidityProofV2Body {
196                id: types::PostGetValidityProofV2BodyId::TestAccount,
197                jsonrpc: types::PostGetValidityProofV2BodyJsonrpc::X20,
198                method: types::PostGetValidityProofV2BodyMethod::GetValidityProofV2,
199                params,
200            }
201        }
202
203        pub fn make_get_multiple_new_address_proofs_v2_body(
204            params: Vec<types::AddressWithTree>,
205        ) -> types::PostGetMultipleNewAddressProofsV2Body {
206            types::PostGetMultipleNewAddressProofsV2Body {
207                id: types::PostGetMultipleNewAddressProofsV2BodyId::TestAccount,
208                jsonrpc: types::PostGetMultipleNewAddressProofsV2BodyJsonrpc::X20,
209                method: types::PostGetMultipleNewAddressProofsV2BodyMethod::GetMultipleNewAddressProofsV2,
210                params,
211            }
212        }
213
214        pub fn make_get_compressed_token_accounts_by_delegate_v2_body(
215            params: types::PostGetCompressedTokenAccountsByDelegateV2BodyParams,
216        ) -> types::PostGetCompressedTokenAccountsByDelegateV2Body {
217            types::PostGetCompressedTokenAccountsByDelegateV2Body {
218                id: types::PostGetCompressedTokenAccountsByDelegateV2BodyId::TestAccount,
219                jsonrpc: types::PostGetCompressedTokenAccountsByDelegateV2BodyJsonrpc::X20,
220                method: types::PostGetCompressedTokenAccountsByDelegateV2BodyMethod::GetCompressedTokenAccountsByDelegateV2,
221                params,
222            }
223        }
224
225        pub fn make_get_compressed_token_accounts_by_owner_v2_body(
226            params: types::PostGetCompressedTokenAccountsByOwnerV2BodyParams,
227        ) -> types::PostGetCompressedTokenAccountsByOwnerV2Body {
228            types::PostGetCompressedTokenAccountsByOwnerV2Body {
229                id: types::PostGetCompressedTokenAccountsByOwnerV2BodyId::TestAccount,
230                jsonrpc: types::PostGetCompressedTokenAccountsByOwnerV2BodyJsonrpc::X20,
231                method: types::PostGetCompressedTokenAccountsByOwnerV2BodyMethod::GetCompressedTokenAccountsByOwnerV2,
232                params,
233            }
234        }
235
236        pub fn make_get_compressed_token_balances_by_owner_v2_body(
237            params: types::PostGetCompressedTokenBalancesByOwnerV2BodyParams,
238        ) -> types::PostGetCompressedTokenBalancesByOwnerV2Body {
239            types::PostGetCompressedTokenBalancesByOwnerV2Body {
240                id: types::PostGetCompressedTokenBalancesByOwnerV2BodyId::TestAccount,
241                jsonrpc: types::PostGetCompressedTokenBalancesByOwnerV2BodyJsonrpc::X20,
242                method: types::PostGetCompressedTokenBalancesByOwnerV2BodyMethod::GetCompressedTokenBalancesByOwnerV2,
243                params,
244            }
245        }
246
247        pub fn make_get_compression_signatures_for_account_body(
248            params: types::PostGetCompressionSignaturesForAccountBodyParams,
249        ) -> types::PostGetCompressionSignaturesForAccountBody {
250            types::PostGetCompressionSignaturesForAccountBody {
251                id: types::PostGetCompressionSignaturesForAccountBodyId::TestAccount,
252                jsonrpc: types::PostGetCompressionSignaturesForAccountBodyJsonrpc::X20,
253                method: types::PostGetCompressionSignaturesForAccountBodyMethod::GetCompressionSignaturesForAccount,
254                params,
255            }
256        }
257
258        pub fn make_get_compression_signatures_for_address_body(
259            params: types::PostGetCompressionSignaturesForAddressBodyParams,
260        ) -> types::PostGetCompressionSignaturesForAddressBody {
261            types::PostGetCompressionSignaturesForAddressBody {
262                id: types::PostGetCompressionSignaturesForAddressBodyId::TestAccount,
263                jsonrpc: types::PostGetCompressionSignaturesForAddressBodyJsonrpc::X20,
264                method: types::PostGetCompressionSignaturesForAddressBodyMethod::GetCompressionSignaturesForAddress,
265                params,
266            }
267        }
268
269        pub fn make_get_compression_signatures_for_owner_body(
270            params: types::PostGetCompressionSignaturesForOwnerBodyParams,
271        ) -> types::PostGetCompressionSignaturesForOwnerBody {
272            types::PostGetCompressionSignaturesForOwnerBody {
273                id: types::PostGetCompressionSignaturesForOwnerBodyId::TestAccount,
274                jsonrpc: types::PostGetCompressionSignaturesForOwnerBodyJsonrpc::X20,
275                method: types::PostGetCompressionSignaturesForOwnerBodyMethod::GetCompressionSignaturesForOwner,
276                params,
277            }
278        }
279
280        pub fn make_get_compression_signatures_for_token_owner_body(
281            params: types::PostGetCompressionSignaturesForTokenOwnerBodyParams,
282        ) -> types::PostGetCompressionSignaturesForTokenOwnerBody {
283            types::PostGetCompressionSignaturesForTokenOwnerBody {
284                id: types::PostGetCompressionSignaturesForTokenOwnerBodyId::TestAccount,
285                jsonrpc: types::PostGetCompressionSignaturesForTokenOwnerBodyJsonrpc::X20,
286                method: types::PostGetCompressionSignaturesForTokenOwnerBodyMethod::GetCompressionSignaturesForTokenOwner,
287                params,
288            }
289        }
290
291        pub fn make_get_indexer_health_body() -> types::PostGetIndexerHealthBody {
292            types::PostGetIndexerHealthBody {
293                id: types::PostGetIndexerHealthBodyId::TestAccount,
294                jsonrpc: types::PostGetIndexerHealthBodyJsonrpc::X20,
295                method: types::PostGetIndexerHealthBodyMethod::GetIndexerHealth,
296            }
297        }
298
299        pub fn make_get_indexer_slot_body() -> types::PostGetIndexerSlotBody {
300            types::PostGetIndexerSlotBody {
301                id: types::PostGetIndexerSlotBodyId::TestAccount,
302                jsonrpc: types::PostGetIndexerSlotBodyJsonrpc::X20,
303                method: types::PostGetIndexerSlotBodyMethod::GetIndexerSlot,
304            }
305        }
306
307        pub fn make_get_multiple_compressed_account_proofs_body(
308            params: Vec<types::Hash>,
309        ) -> types::PostGetMultipleCompressedAccountProofsBody {
310            types::PostGetMultipleCompressedAccountProofsBody {
311                id: types::PostGetMultipleCompressedAccountProofsBodyId::TestAccount,
312                jsonrpc: types::PostGetMultipleCompressedAccountProofsBodyJsonrpc::X20,
313                method: types::PostGetMultipleCompressedAccountProofsBodyMethod::GetMultipleCompressedAccountProofs,
314                params,
315            }
316        }
317
318        pub fn make_get_multiple_compressed_accounts_body(
319            params: types::PostGetMultipleCompressedAccountsBodyParams,
320        ) -> types::PostGetMultipleCompressedAccountsBody {
321            types::PostGetMultipleCompressedAccountsBody {
322                id: types::PostGetMultipleCompressedAccountsBodyId::TestAccount,
323                jsonrpc: types::PostGetMultipleCompressedAccountsBodyJsonrpc::X20,
324                method: types::PostGetMultipleCompressedAccountsBodyMethod::GetMultipleCompressedAccounts,
325                params,
326            }
327        }
328
329        pub fn make_get_validity_proof_body(
330            params: types::PostGetValidityProofBodyParams,
331        ) -> types::PostGetValidityProofBody {
332            types::PostGetValidityProofBody {
333                id: types::PostGetValidityProofBodyId::TestAccount,
334                jsonrpc: types::PostGetValidityProofBodyJsonrpc::X20,
335                method: types::PostGetValidityProofBodyMethod::GetValidityProof,
336                params,
337            }
338        }
339
340        pub fn make_get_queue_elements_body(
341            params: types::PostGetQueueElementsBodyParams,
342        ) -> types::PostGetQueueElementsBody {
343            types::PostGetQueueElementsBody {
344                id: types::PostGetQueueElementsBodyId::TestAccount,
345                jsonrpc: types::PostGetQueueElementsBodyJsonrpc::X20,
346                method: types::PostGetQueueElementsBodyMethod::GetQueueElements,
347                params,
348            }
349        }
350
351        pub fn make_get_queue_info_body(
352            params: types::PostGetQueueInfoBodyParams,
353        ) -> types::PostGetQueueInfoBody {
354            types::PostGetQueueInfoBody {
355                id: types::PostGetQueueInfoBodyId::TestAccount,
356                jsonrpc: types::PostGetQueueInfoBodyJsonrpc::X20,
357                method: types::PostGetQueueInfoBodyMethod::GetQueueInfo,
358                params,
359            }
360        }
361
362        pub fn make_get_account_interface_body(
363            params: types::PostGetAccountInterfaceBodyParams,
364        ) -> types::PostGetAccountInterfaceBody {
365            types::PostGetAccountInterfaceBody {
366                id: types::PostGetAccountInterfaceBodyId::TestAccount,
367                jsonrpc: types::PostGetAccountInterfaceBodyJsonrpc::X20,
368                method: types::PostGetAccountInterfaceBodyMethod::GetAccountInterface,
369                params,
370            }
371        }
372
373        pub fn make_get_multiple_account_interfaces_body(
374            params: types::PostGetMultipleAccountInterfacesBodyParams,
375        ) -> types::PostGetMultipleAccountInterfacesBody {
376            types::PostGetMultipleAccountInterfacesBody {
377                id: types::PostGetMultipleAccountInterfacesBodyId::TestAccount,
378                jsonrpc: types::PostGetMultipleAccountInterfacesBodyJsonrpc::X20,
379                method:
380                    types::PostGetMultipleAccountInterfacesBodyMethod::GetMultipleAccountInterfaces,
381                params,
382            }
383        }
384
385        // ----------------------------------------------------------------
386        // API call functions — direct reqwest, progenitor types for serde
387        // ----------------------------------------------------------------
388
389        macro_rules! api_call {
390            ($fn_name:ident, $endpoint:expr, $body_type:ty, $response_type:ty) => {
391                pub async fn $fn_name(
392                    configuration: &Configuration,
393                    body: $body_type,
394                ) -> Result<$response_type, Error<$response_type>> {
395                    let url = configuration.build_url($endpoint);
396                    let response = configuration
397                        .client
398                        .post(&url)
399                        .header(reqwest::header::ACCEPT, "application/json")
400                        .json(&body)
401                        .send()
402                        .await
403                        .map_err(Error::Reqwest)?;
404
405                    let status = response.status().as_u16();
406                    if status == 200 {
407                        response
408                            .json::<$response_type>()
409                            .await
410                            .map_err(Error::Reqwest)
411                    } else {
412                        let body = response.text().await.unwrap_or_default();
413                        Err(Error::ResponseError { status, body })
414                    }
415                }
416            };
417        }
418
419        api_call!(
420            get_compressed_account_post,
421            "getCompressedAccount",
422            types::PostGetCompressedAccountBody,
423            types::PostGetCompressedAccountResponse
424        );
425        api_call!(
426            get_compressed_account_balance_post,
427            "getCompressedAccountBalance",
428            types::PostGetCompressedAccountBalanceBody,
429            types::PostGetCompressedAccountBalanceResponse
430        );
431        api_call!(
432            get_compressed_accounts_by_owner_post,
433            "getCompressedAccountsByOwner",
434            types::PostGetCompressedAccountsByOwnerBody,
435            types::PostGetCompressedAccountsByOwnerResponse
436        );
437        api_call!(
438            get_compressed_accounts_by_owner_v2_post,
439            "getCompressedAccountsByOwnerV2",
440            types::PostGetCompressedAccountsByOwnerV2Body,
441            types::PostGetCompressedAccountsByOwnerV2Response
442        );
443        api_call!(
444            get_compressed_balance_by_owner_post,
445            "getCompressedBalanceByOwner",
446            types::PostGetCompressedBalanceByOwnerBody,
447            types::PostGetCompressedBalanceByOwnerResponse
448        );
449        api_call!(
450            get_compressed_mint_token_holders_post,
451            "getCompressedMintTokenHolders",
452            types::PostGetCompressedMintTokenHoldersBody,
453            types::PostGetCompressedMintTokenHoldersResponse
454        );
455        api_call!(
456            get_compressed_token_account_balance_post,
457            "getCompressedTokenAccountBalance",
458            types::PostGetCompressedTokenAccountBalanceBody,
459            types::PostGetCompressedTokenAccountBalanceResponse
460        );
461        api_call!(
462            get_compressed_token_accounts_by_delegate_post,
463            "getCompressedTokenAccountsByDelegate",
464            types::PostGetCompressedTokenAccountsByDelegateBody,
465            types::PostGetCompressedTokenAccountsByDelegateResponse
466        );
467        api_call!(
468            get_compressed_token_accounts_by_delegate_v2_post,
469            "getCompressedTokenAccountsByDelegateV2",
470            types::PostGetCompressedTokenAccountsByDelegateV2Body,
471            types::PostGetCompressedTokenAccountsByDelegateV2Response
472        );
473        api_call!(
474            get_compressed_token_accounts_by_owner_post,
475            "getCompressedTokenAccountsByOwner",
476            types::PostGetCompressedTokenAccountsByOwnerBody,
477            types::PostGetCompressedTokenAccountsByOwnerResponse
478        );
479        api_call!(
480            get_compressed_token_accounts_by_owner_v2_post,
481            "getCompressedTokenAccountsByOwnerV2",
482            types::PostGetCompressedTokenAccountsByOwnerV2Body,
483            types::PostGetCompressedTokenAccountsByOwnerV2Response
484        );
485        api_call!(
486            get_compressed_token_balances_by_owner_post,
487            "getCompressedTokenBalancesByOwner",
488            types::PostGetCompressedTokenBalancesByOwnerBody,
489            types::PostGetCompressedTokenBalancesByOwnerResponse
490        );
491        api_call!(
492            get_compressed_token_balances_by_owner_v2_post,
493            "getCompressedTokenBalancesByOwnerV2",
494            types::PostGetCompressedTokenBalancesByOwnerV2Body,
495            types::PostGetCompressedTokenBalancesByOwnerV2Response
496        );
497        api_call!(
498            get_compression_signatures_for_account_post,
499            "getCompressionSignaturesForAccount",
500            types::PostGetCompressionSignaturesForAccountBody,
501            types::PostGetCompressionSignaturesForAccountResponse
502        );
503        api_call!(
504            get_compression_signatures_for_address_post,
505            "getCompressionSignaturesForAddress",
506            types::PostGetCompressionSignaturesForAddressBody,
507            types::PostGetCompressionSignaturesForAddressResponse
508        );
509        api_call!(
510            get_compression_signatures_for_owner_post,
511            "getCompressionSignaturesForOwner",
512            types::PostGetCompressionSignaturesForOwnerBody,
513            types::PostGetCompressionSignaturesForOwnerResponse
514        );
515        api_call!(
516            get_compression_signatures_for_token_owner_post,
517            "getCompressionSignaturesForTokenOwner",
518            types::PostGetCompressionSignaturesForTokenOwnerBody,
519            types::PostGetCompressionSignaturesForTokenOwnerResponse
520        );
521        api_call!(
522            get_indexer_health_post,
523            "getIndexerHealth",
524            types::PostGetIndexerHealthBody,
525            types::PostGetIndexerHealthResponse
526        );
527        api_call!(
528            get_indexer_slot_post,
529            "getIndexerSlot",
530            types::PostGetIndexerSlotBody,
531            types::PostGetIndexerSlotResponse
532        );
533        api_call!(
534            get_multiple_compressed_account_proofs_post,
535            "getMultipleCompressedAccountProofs",
536            types::PostGetMultipleCompressedAccountProofsBody,
537            types::PostGetMultipleCompressedAccountProofsResponse
538        );
539        api_call!(
540            get_multiple_compressed_accounts_post,
541            "getMultipleCompressedAccounts",
542            types::PostGetMultipleCompressedAccountsBody,
543            types::PostGetMultipleCompressedAccountsResponse
544        );
545        api_call!(
546            get_multiple_new_address_proofs_v2_post,
547            "getMultipleNewAddressProofsV2",
548            types::PostGetMultipleNewAddressProofsV2Body,
549            types::PostGetMultipleNewAddressProofsV2Response
550        );
551        api_call!(
552            get_validity_proof_post,
553            "getValidityProof",
554            types::PostGetValidityProofBody,
555            types::PostGetValidityProofResponse
556        );
557        api_call!(
558            get_validity_proof_v2_post,
559            "getValidityProofV2",
560            types::PostGetValidityProofV2Body,
561            types::PostGetValidityProofV2Response
562        );
563        api_call!(
564            get_queue_elements_post,
565            "getQueueElements",
566            types::PostGetQueueElementsBody,
567            types::PostGetQueueElementsResponse
568        );
569        api_call!(
570            get_queue_info_post,
571            "getQueueInfo",
572            types::PostGetQueueInfoBody,
573            types::PostGetQueueInfoResponse
574        );
575        api_call!(
576            get_account_interface_post,
577            "getAccountInterface",
578            types::PostGetAccountInterfaceBody,
579            types::PostGetAccountInterfaceResponse
580        );
581        api_call!(
582            get_multiple_account_interfaces_post,
583            "getMultipleAccountInterfaces",
584            types::PostGetMultipleAccountInterfacesBody,
585            types::PostGetMultipleAccountInterfacesResponse
586        );
587    }
588}
589
590#[cfg(test)]
591mod tests {
592    use super::apis::{configuration::Configuration, default_api};
593
594    #[test]
595    fn test_parse_url_with_api_key() {
596        let (base, key) = Configuration::parse_url("https://rpc.example.com?api-key=MY_KEY");
597        assert_eq!(base, "https://rpc.example.com");
598        assert_eq!(key, Some("MY_KEY".to_string()));
599    }
600
601    #[test]
602    fn test_parse_url_without_api_key() {
603        let (base, key) = Configuration::parse_url("https://rpc.example.com");
604        assert_eq!(base, "https://rpc.example.com");
605        assert_eq!(key, None);
606    }
607
608    #[test]
609    fn test_parse_url_with_other_query_params() {
610        let (base, key) =
611            Configuration::parse_url("https://rpc.example.com?other=value&api-key=KEY123");
612        assert_eq!(base, "https://rpc.example.com");
613        assert_eq!(key, Some("KEY123".to_string()));
614    }
615
616    #[test]
617    fn test_new_with_api_key_in_url() {
618        let config = Configuration::new("https://rpc.example.com?api-key=SECRET".to_string());
619        assert_eq!(config.base_path, "https://rpc.example.com");
620        assert_eq!(config.api_key, Some("SECRET".to_string()));
621    }
622
623    #[test]
624    fn test_make_get_compressed_account_body() {
625        let params = super::types::PostGetCompressedAccountBodyParams {
626            address: Some(super::types::SerializablePubkey(
627                "11111111111111111111111111111111".to_string(),
628            )),
629            hash: None,
630        };
631        let body = default_api::make_get_compressed_account_body(params);
632        let json = serde_json::to_value(&body).unwrap();
633        assert_eq!(json["jsonrpc"], "2.0");
634        assert_eq!(json["method"], "getCompressedAccount");
635        assert_eq!(json["id"], "test-account");
636        assert_eq!(
637            json["params"]["address"],
638            "11111111111111111111111111111111"
639        );
640    }
641
642    #[test]
643    fn test_make_get_indexer_health_body() {
644        let body = default_api::make_get_indexer_health_body();
645        let json = serde_json::to_value(&body).unwrap();
646        assert_eq!(json["jsonrpc"], "2.0");
647        assert_eq!(json["method"], "getIndexerHealth");
648    }
649
650    #[test]
651    fn test_make_get_indexer_slot_body() {
652        let body = default_api::make_get_indexer_slot_body();
653        let json = serde_json::to_value(&body).unwrap();
654        assert_eq!(json["jsonrpc"], "2.0");
655        assert_eq!(json["method"], "getIndexerSlot");
656    }
657
658    #[test]
659    fn test_make_get_validity_proof_body() {
660        let params = super::types::PostGetValidityProofBodyParams {
661            hashes: vec![super::types::Hash("abc123".to_string())],
662            new_addresses_with_trees: vec![],
663        };
664        let body = default_api::make_get_validity_proof_body(params);
665        let json = serde_json::to_value(&body).unwrap();
666        assert_eq!(json["jsonrpc"], "2.0");
667        assert_eq!(json["method"], "getValidityProof");
668        assert_eq!(json["params"]["hashes"][0], "abc123");
669    }
670
671    #[tokio::test]
672    async fn test_api_call_sends_correct_request() {
673        use wiremock::{
674            matchers::{header, method, path, query_param},
675            Mock, MockServer, ResponseTemplate,
676        };
677
678        let mock_server = MockServer::start().await;
679
680        let response_json = serde_json::json!({
681            "jsonrpc": "2.0",
682            "result": "ok",
683            "id": "test-account"
684        });
685
686        Mock::given(method("POST"))
687            .and(path("/getIndexerHealth"))
688            .and(query_param("api-key", "TEST_KEY"))
689            .and(header("accept", "application/json"))
690            .respond_with(ResponseTemplate::new(200).set_body_json(&response_json))
691            .mount(&mock_server)
692            .await;
693
694        let config = Configuration::new(format!("{}?api-key=TEST_KEY", mock_server.uri()));
695
696        let body = default_api::make_get_indexer_health_body();
697        let result = default_api::get_indexer_health_post(&config, body).await;
698
699        result.expect("API call with api-key should succeed");
700    }
701
702    #[tokio::test]
703    async fn test_api_call_without_api_key() {
704        use wiremock::{
705            matchers::{header, method, path},
706            Mock, MockServer, ResponseTemplate,
707        };
708
709        let mock_server = MockServer::start().await;
710
711        let response_json = serde_json::json!({
712            "jsonrpc": "2.0",
713            "result": "ok",
714            "id": "test-account"
715        });
716
717        Mock::given(method("POST"))
718            .and(path("/getIndexerHealth"))
719            .and(header("accept", "application/json"))
720            .respond_with(ResponseTemplate::new(200).set_body_json(&response_json))
721            .mount(&mock_server)
722            .await;
723
724        let config = Configuration::new(mock_server.uri());
725
726        let body = default_api::make_get_indexer_health_body();
727        let result = default_api::get_indexer_health_post(&config, body).await;
728
729        result.expect("API call without api-key should succeed");
730    }
731
732    #[tokio::test]
733    async fn test_api_call_error_response() {
734        use wiremock::{
735            matchers::{method, path},
736            Mock, MockServer, ResponseTemplate,
737        };
738
739        let mock_server = MockServer::start().await;
740
741        Mock::given(method("POST"))
742            .and(path("/getIndexerHealth"))
743            .respond_with(ResponseTemplate::new(500).set_body_string("Internal Server Error"))
744            .mount(&mock_server)
745            .await;
746
747        let config = Configuration::new(mock_server.uri());
748
749        let body = default_api::make_get_indexer_health_body();
750        let result = default_api::get_indexer_health_post(&config, body).await;
751
752        match result {
753            Err(super::apis::Error::ResponseError { status, body }) => {
754                assert_eq!(status, 500);
755                assert_eq!(body, "Internal Server Error");
756            }
757            other => panic!("Expected ResponseError, got {:?}", other),
758        }
759    }
760}