ord_reqwest/
ord_client.rs1use bitcoin::OutPoint;
2use ordinals::RuneId;
3use reqwest::{Error, Response};
4use serde::{Deserialize, Serialize};
5use crate::data::rune_entry::RuneResponse;
6use crate::models::address::AddressResponse;
7use crate::models::ordinals::OutputResponse;
8
9pub struct OrdClient {
10 client: reqwest::Client,
11 base_api_url: String,
12 pub base_public_url: String,
13}
14
15#[derive(Serialize, Deserialize, Debug, Clone)]
16pub struct InscriptionResponse {
17 pub address: String,
18 pub id: String,
19}
20impl OrdClient {
21 pub fn new() -> Self {
22 let ord_base_url =
23 std::env::var("ORD_BASE_URL").unwrap_or("http://192.168.1.105:4000".to_string());
24 let ord_public_url =
25 std::env::var("ORD_PUBLIC_URL").unwrap_or("https://ordinals.com".to_string());
26 let client = reqwest::Client::builder().timeout(std::time::Duration::from_secs(10)).build().unwrap();
27 OrdClient {
28 client,
29 base_api_url: ord_base_url,
30 base_public_url: ord_public_url,
31 }
32 }
33
34 async fn do_api_call(&self, url: &str) -> Result<Response, Error> {
35 loop {
37 let response = self
38 .client
39 .get(url)
40 .header("accept", "application/json")
41 .send()
42 .await;
43 if response.is_ok() {
44 return response;
45 }
46 }
47 }
48
49 pub async fn fetch_rune_details(&self, rune_id: RuneId) -> RuneResponse {
50 let rune_url = format!("{}/rune/{}", self.base_api_url, rune_id);
52 let api_response = self.do_api_call(&rune_url).await;
54 let rune_response =
56 serde_json::from_str::<RuneResponse>(&api_response.unwrap().text().await.unwrap())
57 .unwrap();
58 rune_response
59 }
60
61 pub async fn fetch_latest_block_height(&self) -> u64 {
62 let block_height_url = format!("{}/blockheight", self.base_api_url);
64 let api_response = self.do_api_call(&block_height_url).await;
66 let block_height =
68 serde_json::from_str::<u64>(&api_response.unwrap().text().await.unwrap()).unwrap();
69 return block_height;
70 }
71 pub async fn fetch_output(&self, out_point: OutPoint) -> OutputResponse {
72 let output_url = format!("{}/output/{}:{}", self.base_api_url, out_point.txid, out_point.vout);
74 let api_response = self.do_api_call(&output_url).await;
76 let output_response =
78 serde_json::from_str::<OutputResponse>(&api_response.unwrap().text().await.unwrap())
79 .unwrap();
80 return output_response;
81 }
82 pub async fn get_address(&self, address: &str) -> AddressResponse {
83 let address_url = format!("{}/address/{}", self.base_api_url, address);
85 let api_response = self.do_api_call(&address_url).await;
87 let address_response = api_response.unwrap().text().await.unwrap();
89 let address_response: AddressResponse = serde_json::from_str(&address_response).unwrap();
90 address_response
91 }
92
93 pub async fn get_inscription(&self, inscription_id: &str) -> InscriptionResponse {
94 let inscription_url = format!("{}/inscription/{}", self.base_api_url, inscription_id);
96 let api_response = self.do_api_call(&inscription_url).await.unwrap();
98 let inscription_text = api_response.text().await.unwrap();
100 let inscription_response: InscriptionResponse = serde_json::from_str(&inscription_text).unwrap();
101 inscription_response
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use std::str::FromStr;
108
109 use bitcoin::{OutPoint, Txid};
110 use crate::models::address::AddressResponse;
111 use super::*;
112
113 #[tokio::test]
114 #[ignore]
115 async fn fetch_output() {
116 let client = OrdClient::new();
117 let out_point = OutPoint {
118 txid: Txid::from_str("3de0c436d136abfb5f1ec1996d755331f25bf8e424743b1c21e2952fea8ef002").unwrap(),
119 vout: 1
120 };
121 let output_response = client.fetch_output(out_point).await;
122 assert_eq!(output_response.value, 546);
123 assert_eq!(output_response.address, "bc1p90zah9c3hyywydpgnw0gcuk2pwwywj8u7hd0rhhr8kg0x3wl778s4d8h9t");
124 }
125
126 #[tokio::test]
127 #[ignore]
128 async fn fetch_address_details() {
129 let client = OrdClient::new();
130 let address = "bc1pk244ecgfnyurjdj43qh9ha95laff32aa5w7fmscjtt93fkresymqpf8rgz";
131 let address_response: AddressResponse = client.get_address(address).await;
132 assert!(address_response.inscriptions.len() > 0);
133 }
134
135 #[tokio::test]
136 #[ignore]
137 async fn fetch_latest_block_height() {
138 let client = OrdClient::new();
139 let block_height = client.fetch_latest_block_height().await;
140 assert!(block_height > 0);
141 }
142
143 #[tokio::test]
144 #[ignore]
145 async fn fetch_inscription_details() {
146 let client = OrdClient::new();
147 let inscription_id = "0dc34a21a53600106e9c91d7c8d4b84a62a14dbd4b58cad66272dc3bbc8dbdd7i0";
148 let inscription_details = client.get_inscription(inscription_id).await;
149 let details = inscription_details;
150 assert_eq!(details.id, inscription_id);
151 }
152}