From fab0535832d87f8194cf49acc897ac6b004c38c4 Mon Sep 17 00:00:00 2001 From: Miroslav Kovar Date: Wed, 10 May 2023 11:23:05 +0200 Subject: [PATCH 1/2] Proxy client Signed-off-by: Miroslav Kovar --- Cargo.toml | 1 + indy-vdr-proxy-client/Cargo.toml | 12 +++ indy-vdr-proxy-client/src/error.rs | 56 ++++++++++++ indy-vdr-proxy-client/src/lib.rs | 136 +++++++++++++++++++++++++++++ 4 files changed, 205 insertions(+) create mode 100644 indy-vdr-proxy-client/Cargo.toml create mode 100644 indy-vdr-proxy-client/src/error.rs create mode 100644 indy-vdr-proxy-client/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index e3bc9415..b8d4c2f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ resolver = "2" members = [ "libindy_vdr", "indy-vdr-proxy", + "indy-vdr-proxy-client", ] [profile.release] diff --git a/indy-vdr-proxy-client/Cargo.toml b/indy-vdr-proxy-client/Cargo.toml new file mode 100644 index 00000000..7244abb5 --- /dev/null +++ b/indy-vdr-proxy-client/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "indy-vdr-proxy-client" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +reqwest = { version = "0.11.17", default-features = false, features = ["json"] } +indy-vdr = { file = "../libindy_vdr" } +serde_json = "1.0.96" +url = "2.3.1" diff --git a/indy-vdr-proxy-client/src/error.rs b/indy-vdr-proxy-client/src/error.rs new file mode 100644 index 00000000..da521e8e --- /dev/null +++ b/indy-vdr-proxy-client/src/error.rs @@ -0,0 +1,56 @@ +use std::error::Error; +use std::fmt; + +pub enum VdrProxyClientError { + HttpClientError(reqwest::Error), + ParseError(url::ParseError), + NonSuccessStatusCode(u16, String), +} + +impl fmt::Display for VdrProxyClientError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + VdrProxyClientError::HttpClientError(err) => write!(f, "HTTP request failed: {}", err), + VdrProxyClientError::ParseError(err) => write!(f, "URL parsing failed: {}", err), + VdrProxyClientError::NonSuccessStatusCode(_, msg) => { + write!(f, "Non-success status code: {}", msg) + } + } + } +} + +impl fmt::Debug for VdrProxyClientError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + VdrProxyClientError::HttpClientError(err) => { + write!(f, "HTTP request failed: {:?}", err) + } + VdrProxyClientError::ParseError(err) => write!(f, "URL parsing failed: {:?}", err), + VdrProxyClientError::NonSuccessStatusCode(code, body) => { + write!(f, "Non-success status code: {} {}", code, body) + } + } + } +} + +impl Error for VdrProxyClientError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + match self { + VdrProxyClientError::HttpClientError(err) => Some(err), + VdrProxyClientError::ParseError(err) => Some(err), + VdrProxyClientError::NonSuccessStatusCode(_, _) => None, + } + } +} + +impl From for VdrProxyClientError { + fn from(err: reqwest::Error) -> VdrProxyClientError { + VdrProxyClientError::HttpClientError(err) + } +} + +impl From for VdrProxyClientError { + fn from(err: url::ParseError) -> VdrProxyClientError { + VdrProxyClientError::ParseError(err) + } +} diff --git a/indy-vdr-proxy-client/src/lib.rs b/indy-vdr-proxy-client/src/lib.rs new file mode 100644 index 00000000..5fc3129f --- /dev/null +++ b/indy-vdr-proxy-client/src/lib.rs @@ -0,0 +1,136 @@ +pub mod error; + +use error::VdrProxyClientError; +use reqwest::{Client, Response, Url}; + +pub use indy_vdr::ledger::RequestBuilder; +pub use indy_vdr::pool::PreparedRequest; + +pub struct VdrProxyClient { + client: Client, + url: Url, +} + +async fn map_resp(response: Response) -> Result { + let status = response.status(); + if !status.is_success() { + let text = response.text().await.unwrap_or_default(); + return Err(VdrProxyClientError::NonSuccessStatusCode( + status.as_u16(), + text, + )); + } + response + .text() + .await + .map_err(VdrProxyClientError::HttpClientError) +} + +impl VdrProxyClient { + pub fn new(url: &str) -> Result { + let url = Url::parse(url)?; + let client = Client::new(); + Ok(VdrProxyClient { client, url }) + } + + async fn get_request(&self, url: Url) -> Result { + let response = self.client.get(url).send().await?; + map_resp(response).await + } + + async fn post_request( + &self, + url: Url, + request: PreparedRequest, + ) -> Result { + let response = self + .client + .post(url) + .json(&request.req_json) + .send() + .await + .map_err(VdrProxyClientError::HttpClientError)?; + map_resp(response).await + } + + pub async fn post(&self, request: PreparedRequest) -> Result { + let url = self.url.join("submit")?; + self.post_request(url, request).await + } + + pub async fn get_nym(&self, did: &str) -> Result { + let url = self.url.join(&format!("nym/{}", did))?; + self.get_request(url).await + } + + pub async fn get_attrib(&self, did: &str, attrib: &str) -> Result { + let url = self.url.join(&format!("attrib/{}/{}", did, attrib))?; + self.get_request(url).await + } + + pub async fn get_schema(&self, schema_id: &str) -> Result { + let url = self.url.join(&format!("schema/{}", schema_id))?; + self.get_request(url).await + } + + pub async fn get_cred_def(&self, cred_def_id: &str) -> Result { + let url = self.url.join(&format!("cred_def/{}", cred_def_id))?; + self.get_request(url).await + } + + pub async fn get_rev_reg(&self, rev_reg_def_id: &str) -> Result { + let url = self.url.join(&format!("rev_reg/{}", rev_reg_def_id))?; + self.get_request(url).await + } + + pub async fn get_rev_reg_def( + &self, + rev_reg_def_id: &str, + ) -> Result { + let url = self.url.join(&format!("rev_reg_def/{}", rev_reg_def_id))?; + self.get_request(url).await + } + + pub async fn get_rev_reg_delta( + &self, + rev_reg_def_id: &str, + ) -> Result { + let url = self + .url + .join(&format!("rev_reg_delta/{}", rev_reg_def_id))?; + self.get_request(url).await + } + + pub async fn get_txn_author_agreement(&self) -> Result { + let url = self.url.join("taa")?; + self.get_request(url).await + } + + pub async fn get_genesis_txs(&self) -> Result { + let url = self.url.join("genesis")?; + self.get_request(url).await + } + + pub async fn get_acceptance_methods_list(&self) -> Result { + let url = self.url.join("aml")?; + self.get_request(url).await + } + + pub async fn get_auth_rules(&self) -> Result { + let url = self.url.join("auth")?; + self.get_request(url).await + } + + pub async fn get_proxy_status(&self) -> Result { + self.get_request(self.url.clone()).await + } + + pub async fn get_ledger_txn( + &self, + subledger: &str, + seq_no: u64, + ) -> Result { + let url = self.url.join(&format!("txn/{}/{}", subledger, seq_no))?; + self.get_request(url).await + } +} From c978eb1e2e126dbc6e022818ab0b3eba421d083e Mon Sep 17 00:00:00 2001 From: Miroslav Kovar Date: Thu, 10 Aug 2023 21:14:51 +0200 Subject: [PATCH 2/2] Fix build Signed-off-by: Miroslav Kovar --- indy-vdr-proxy-client/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indy-vdr-proxy-client/Cargo.toml b/indy-vdr-proxy-client/Cargo.toml index 7244abb5..d9b6b097 100644 --- a/indy-vdr-proxy-client/Cargo.toml +++ b/indy-vdr-proxy-client/Cargo.toml @@ -7,6 +7,6 @@ edition = "2021" [dependencies] reqwest = { version = "0.11.17", default-features = false, features = ["json"] } -indy-vdr = { file = "../libindy_vdr" } +indy-vdr = { path = "../libindy_vdr" } serde_json = "1.0.96" url = "2.3.1"