koios_sdk/api/address.rs
1use crate::{
2 error::Result,
3 models::{
4 address::{AddressAsset, AddressInfo, AddressTransaction},
5 requests::{
6 AddressTransactionsRequest, CredentialTransactionsRequest, CredentialUtxosRequest,
7 PaymentAddressesRequest, PaymentAddressesWithExtendedRequest,
8 },
9 UtxoInfo,
10 },
11 Client,
12};
13use urlencoding::encode;
14
15impl Client {
16 /// Get address info - balance, associated stake address (if any) and UTxO set for given addresses
17 ///
18 /// # Arguments
19 ///
20 /// * `addresses` - List of addresses to query
21 ///
22 /// # Examples
23 ///
24 /// ```no_run
25 /// use koios_sdk::Client;
26 ///
27 /// #[tokio::main]
28 /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
29 /// let client = Client::new()?;
30 /// let addresses = vec![
31 /// "addr1qxqs59lphg8g6qndelq8xwqn60ag3aeyfcp33c2kdp46a09re5df3pzwwmyq946axfcejy5n4x0y99wqpgtp2gd0k09qsgy6pz".to_string()
32 /// ];
33 /// let address_info = client.get_address_info(&addresses).await?;
34 /// println!("Address info: {:?}", address_info);
35 /// Ok(())
36 /// }
37 /// ```
38 pub async fn get_address_info(&self, addresses: &[String]) -> Result<Vec<AddressInfo>> {
39 let encoded_addresses: Vec<String> = addresses
40 .iter()
41 .map(|addr| encode(addr).into_owned())
42 .collect();
43 let request = PaymentAddressesRequest::new(encoded_addresses);
44 self.post("/address_info", &request).await
45 }
46
47 /// Get UTxO set for given addresses
48 ///
49 /// # Arguments
50 ///
51 /// * `addresses` - List of addresses to query
52 /// * `extended` - Optional flag to include extended information
53 ///
54 /// # Examples
55 ///
56 /// ```no_run
57 /// use koios_sdk::Client;
58 ///
59 /// #[tokio::main]
60 /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
61 /// let client = Client::new()?;
62 /// let addresses = vec![
63 /// "addr1qxqs59lphg8g6qndelq8xwqn60ag3aeyfcp33c2kdp46a09re5df3pzwwmyq946axfcejy5n4x0y99wqpgtp2gd0k09qsgy6pz".to_string()
64 /// ];
65 /// let utxos = client.get_address_utxos(&addresses, Some(true)).await?;
66 /// println!("Address UTXOs: {:?}", utxos);
67 /// Ok(())
68 /// }
69 /// ```
70 pub async fn get_address_utxos(
71 &self,
72 addresses: &[String],
73 extended: Option<bool>,
74 ) -> Result<Vec<UtxoInfo>> {
75 let encoded_addresses: Vec<String> = addresses
76 .iter()
77 .map(|addr| encode(addr).into_owned())
78 .collect();
79 let request = PaymentAddressesWithExtendedRequest::new(encoded_addresses, extended);
80 self.post("/address_utxos", &request).await
81 }
82
83 /// Get UTxO details for requested payment credentials
84 ///
85 /// # Arguments
86 ///
87 /// * `payment_credentials` - List of payment credentials to query
88 /// * `extended` - Optional flag to include extended information
89 ///
90 /// # Examples
91 ///
92 /// ```no_run
93 /// use koios_sdk::Client;
94 ///
95 /// #[tokio::main]
96 /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
97 /// let client = Client::new()?;
98 /// let credentials = vec![
99 /// "025b0a8f85cb8a46e1dda3fae5d22f07e2d56abb4019a2129c5d6c52".to_string()
100 /// ];
101 /// let utxos = client.get_credential_utxos(&credentials, Some(true)).await?;
102 /// println!("Credential UTXOs: {:?}", utxos);
103 /// Ok(())
104 /// }
105 /// ```
106 pub async fn get_credential_utxos(
107 &self,
108 payment_credentials: &[String],
109 extended: Option<bool>,
110 ) -> Result<Vec<UtxoInfo>> {
111 let encoded_credentials: Vec<String> = payment_credentials
112 .iter()
113 .map(|cred| encode(cred).into_owned())
114 .collect();
115 let request = CredentialUtxosRequest::new(encoded_credentials, extended);
116 self.post("/credential_utxos", &request).await
117 }
118
119 /// Get the transaction hash list of input address array, optionally filtering after specified block height
120 ///
121 /// # Arguments
122 ///
123 /// * `addresses` - List of addresses to query
124 /// * `after_block_height` - Optional block height to filter from
125 ///
126 /// # Examples
127 ///
128 /// ```no_run
129 /// use koios_sdk::Client;
130 ///
131 /// #[tokio::main]
132 /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
133 /// let client = Client::new()?;
134 /// let addresses = vec![
135 /// "addr1qxqs59lphg8g6qndelq8xwqn60ag3aeyfcp33c2kdp46a09re5df3pzwwmyq946axfcejy5n4x0y99wqpgtp2gd0k09qsgy6pz".to_string()
136 /// ];
137 /// let txs = client.get_address_transactions(&addresses, Some(42000000)).await?;
138 /// println!("Address transactions: {:?}", txs);
139 /// Ok(())
140 /// }
141 /// ```
142 pub async fn get_address_transactions(
143 &self,
144 addresses: &[String],
145 after_block_height: Option<u64>,
146 ) -> Result<Vec<AddressTransaction>> {
147 let encoded_addresses: Vec<String> = addresses
148 .iter()
149 .map(|addr| encode(addr).into_owned())
150 .collect();
151 let request = AddressTransactionsRequest::new(encoded_addresses, after_block_height);
152 self.post("/address_txs", &request).await
153 }
154
155 /// Get the transaction hash list of input payment credential array, optionally filtering after specified block height
156 ///
157 /// # Arguments
158 ///
159 /// * `payment_credentials` - List of payment credentials to query
160 /// * `after_block_height` - Optional block height to filter from
161 ///
162 /// # Examples
163 ///
164 /// ```no_run
165 /// use koios_sdk::Client;
166 ///
167 /// #[tokio::main]
168 /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
169 /// let client = Client::new()?;
170 /// let credentials = vec![
171 /// "025b0a8f85cb8a46e1dda3fae5d22f07e2d56abb4019a2129c5d6c52".to_string()
172 /// ];
173 /// let txs = client.get_credential_transactions(&credentials, Some(42000000)).await?;
174 /// println!("Credential transactions: {:?}", txs);
175 /// Ok(())
176 /// }
177 /// ```
178 pub async fn get_credential_transactions(
179 &self,
180 payment_credentials: &[String],
181 after_block_height: Option<u64>,
182 ) -> Result<Vec<AddressTransaction>> {
183 let encoded_credentials: Vec<String> = payment_credentials
184 .iter()
185 .map(|cred| encode(cred).into_owned())
186 .collect();
187 let request = CredentialTransactionsRequest::new(encoded_credentials, after_block_height);
188 self.post("/credential_txs", &request).await
189 }
190
191 /// Get the list of all the assets (policy, name and quantity) for given addresses
192 ///
193 /// # Arguments
194 ///
195 /// * `addresses` - List of addresses to query
196 ///
197 /// # Examples
198 ///
199 /// ```no_run
200 /// use koios_sdk::Client;
201 ///
202 /// #[tokio::main]
203 /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
204 /// let client = Client::new()?;
205 /// let addresses = vec![
206 /// "addr1qxqs59lphg8g6qndelq8xwqn60ag3aeyfcp33c2kdp46a09re5df3pzwwmyq946axfcejy5n4x0y99wqpgtp2gd0k09qsgy6pz".to_string()
207 /// ];
208 /// let assets = client.get_address_assets(&addresses).await?;
209 /// println!("Address assets: {:?}", assets);
210 /// Ok(())
211 /// }
212 /// ```
213 pub async fn get_address_assets(&self, addresses: &[String]) -> Result<Vec<AddressAsset>> {
214 let encoded_addresses: Vec<String> = addresses
215 .iter()
216 .map(|addr| encode(addr).into_owned())
217 .collect();
218 let request = PaymentAddressesRequest::new(encoded_addresses);
219 self.post("/address_assets", &request).await
220 }
221}
222
223#[cfg(test)]
224mod tests {
225 use super::*;
226 use serde_json::json;
227 use wiremock::matchers::{method, path};
228 use wiremock::{Mock, MockServer, ResponseTemplate};
229
230 #[tokio::test]
231 async fn test_get_address_info() {
232 let mock_server = MockServer::start().await;
233 let client = Client::builder()
234 .base_url(mock_server.uri())
235 .build()
236 .unwrap();
237
238 let address = "addr1qxqs59lphg8g6qndelq8xwqn60ag3aeyfcp33c2kdp46a09re5df3pzwwmyq946axfcejy5n4x0y99wqpgtp2gd0k09qsgy6pz";
239 let mock_response = json!([{
240 "address": address,
241 "balance": "42000000",
242 "stake_address": "stake1u9ylzsgxaa6xctf4juup682ar3juj85n8tx3hthnljg47zctvm3rc",
243 "script_address": false,
244 "utxo_set": []
245 }]);
246
247 Mock::given(method("POST"))
248 .and(path("/address_info"))
249 .respond_with(ResponseTemplate::new(200).set_body_json(&mock_response))
250 .mount(&mock_server)
251 .await;
252
253 let response = client
254 .get_address_info(&[address.to_string()])
255 .await
256 .unwrap();
257 assert_eq!(response.len(), 1);
258 assert_eq!(response[0].address, address);
259 }
260
261 // Add more tests for other endpoints...
262}