koios_sdk/api/
script.rs

1use crate::{
2    error::Result,
3    models::{
4        requests::ScriptHashesRequest,
5        script::{ScriptInfo, ScriptList, ScriptRedeemer},
6        UtxoInfo,
7    },
8    types::{Extended, ScriptHash},
9    Client,
10};
11
12impl Client {
13    /// Get list of script information for given script hashes
14    ///
15    /// # Arguments
16    ///
17    /// * `script_hashes` - List of script hashes to query
18    ///
19    /// # Examples
20    ///
21    /// ```no_run
22    /// use koios_sdk::Client;
23    ///
24    /// #[tokio::main]
25    /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
26    ///     let client = Client::new()?;
27    ///     let script_hashes = vec![
28    ///         "67f33146617a5e61936081db3b2117cbf59bd2123748f58ac9678656".to_string()
29    ///     ];
30    ///     let info = client.get_script_info(&script_hashes).await?;
31    ///     println!("Script info: {:?}", info);
32    ///     Ok(())
33    /// }
34    /// ```
35    pub async fn get_script_info(&self, script_hashes: &[String]) -> Result<Vec<ScriptInfo>> {
36        let request = ScriptHashesRequest::new(script_hashes.to_vec());
37        self.post("/script_info", &request).await
38    }
39
40    /// Get list of all existing native script hashes along with their creation transaction hashes
41    ///
42    /// # Examples
43    ///
44    /// ```no_run
45    /// use koios_sdk::Client;
46    ///
47    /// #[tokio::main]
48    /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
49    ///     let client = Client::new()?;
50    ///     let scripts = client.get_native_script_list().await?;
51    ///     println!("Native scripts: {:?}", scripts);
52    ///     Ok(())
53    /// }
54    /// ```
55    pub async fn get_native_script_list(&self) -> Result<Vec<ScriptList>> {
56        self.get("/native_script_list").await
57    }
58
59    /// Get list of all existing Plutus script hashes along with their creation transaction hashes
60    ///
61    /// # Examples
62    ///
63    /// ```no_run
64    /// use koios_sdk::Client;
65    ///
66    /// #[tokio::main]
67    /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
68    ///     let client = Client::new()?;
69    ///     let scripts = client.get_plutus_script_list().await?;
70    ///     println!("Plutus scripts: {:?}", scripts);
71    ///     Ok(())
72    /// }
73    /// ```
74    pub async fn get_plutus_script_list(&self) -> Result<Vec<ScriptList>> {
75        self.get("/plutus_script_list").await
76    }
77
78    /// Get list of all redeemers for a given script hash
79    ///
80    /// # Arguments
81    ///
82    /// * `script_hash` - Script hash to query
83    ///
84    /// # Examples
85    ///
86    /// ```no_run
87    /// use koios_sdk::Client;
88    /// use koios_sdk::types::ScriptHash;
89    ///
90    /// #[tokio::main]
91    /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
92    ///     let client = Client::new()?;
93    ///     let script_hash = ScriptHash::new(
94    ///         "67f33146617a5e61936081db3b2117cbf59bd2123748f58ac9678656"
95    ///     );
96    ///     let redeemers = client.get_script_redeemers(&script_hash).await?;
97    ///     println!("Script redeemers: {:?}", redeemers);
98    ///     Ok(())
99    /// }
100    /// ```
101    pub async fn get_script_redeemers(
102        &self,
103        script_hash: &ScriptHash,
104    ) -> Result<Vec<ScriptRedeemer>> {
105        self.get(&format!(
106            "/script_redeemers?_script_hash={}",
107            script_hash.value()
108        ))
109        .await
110    }
111
112    /// Get list of all UTXOs for a given script hash
113    ///
114    /// # Arguments
115    ///
116    /// * `script_hash` - Script hash to query
117    /// * `extended` - Optional flag to include extended information
118    ///
119    /// # Examples
120    ///
121    /// ```no_run
122    /// use koios_sdk::Client;
123    /// use koios_sdk::types::{ScriptHash, Extended};
124    ///
125    /// #[tokio::main]
126    /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
127    ///     let client = Client::new()?;
128    ///     let script_hash = ScriptHash::new(
129    ///         "67f33146617a5e61936081db3b2117cbf59bd2123748f58ac9678656"
130    ///     );
131    ///     let utxos = client.get_script_utxos(&script_hash, Some(Extended::new(true))).await?;
132    ///     println!("Script UTXOs: {:?}", utxos);
133    ///     Ok(())
134    /// }
135    /// ```
136    pub async fn get_script_utxos(
137        &self,
138        script_hash: &ScriptHash,
139        extended: Option<Extended>,
140    ) -> Result<Vec<UtxoInfo>> {
141        let mut endpoint = format!("/script_utxos?_script_hash={}", script_hash.value());
142
143        if let Some(ext) = extended {
144            endpoint.push_str(&format!("&_extended={}", ext.value()));
145        }
146
147        self.get(&endpoint).await
148    }
149}
150
151#[cfg(test)]
152mod tests {
153    use super::*;
154    use serde_json::json;
155    use wiremock::matchers::{method, path, query_param};
156    use wiremock::{Mock, MockServer, ResponseTemplate};
157
158    #[tokio::test]
159    async fn test_get_plutus_script_list() {
160        let mock_server = MockServer::start().await;
161        let client = Client::builder()
162            .base_url(mock_server.uri())
163            .build()
164            .unwrap();
165
166        let mock_response = json!([{
167            "script_hash": "67f33146617a5e61936081db3b2117cbf59bd2123748f58ac9678656",
168            "creation_tx_hash": "6ed09ba58a56c6e946668038ba4d3cef8eb97a20cbf76c5970e1402e8a8d6541",
169            "type": "plutusv1",
170            "size": 42
171        }]);
172
173        Mock::given(method("GET"))
174            .and(path("/plutus_script_list"))
175            .respond_with(ResponseTemplate::new(200).set_body_json(&mock_response))
176            .mount(&mock_server)
177            .await;
178
179        let response = client.get_plutus_script_list().await.unwrap();
180        assert_eq!(response.len(), 1);
181        assert_eq!(
182            response[0].script_hash,
183            "67f33146617a5e61936081db3b2117cbf59bd2123748f58ac9678656"
184        );
185    }
186
187    #[tokio::test]
188    async fn test_get_script_redeemers() {
189        let mock_server = MockServer::start().await;
190        let client = Client::builder()
191            .base_url(mock_server.uri())
192            .build()
193            .unwrap();
194
195        let script_hash = "67f33146617a5e61936081db3b2117cbf59bd2123748f58ac9678656";
196        let mock_response = json!([{
197            "script_hash": script_hash,
198            "redeemers": [{
199                "tx_hash": "6ed09ba58a56c6e946668038ba4d3cef8eb97a20cbf76c5970e1402e8a8d6541",
200                "tx_index": 0,
201                "unit_mem": 1000,
202                "unit_steps": 500,
203                "fee": "500000",
204                "purpose": "spend",
205                "datum_hash": "ab01cd23",
206                "datum_value": null
207            }]
208        }]);
209
210        Mock::given(method("GET"))
211            .and(path("/script_redeemers"))
212            .and(query_param("_script_hash", script_hash))
213            .respond_with(ResponseTemplate::new(200).set_body_json(&mock_response))
214            .mount(&mock_server)
215            .await;
216
217        let response = client
218            .get_script_redeemers(&ScriptHash::new(script_hash))
219            .await
220            .unwrap();
221        assert_eq!(response.len(), 1);
222        assert_eq!(response[0].script_hash, script_hash);
223    }
224
225    // Add more tests for other endpoints...
226}