diff --git a/uniffi_aries_vcx/core/Cargo.toml b/uniffi_aries_vcx/core/Cargo.toml index 14b97124cf..e46a3272de 100644 --- a/uniffi_aries_vcx/core/Cargo.toml +++ b/uniffi_aries_vcx/core/Cargo.toml @@ -30,4 +30,4 @@ shared_vcx = { path = "../../shared_vcx" } url = "2.3.1" [build-dependencies] -uniffi = { version = "0.23.0", features = [ "build", "cli" ] } +uniffi = { version = "0.23.0", features = ["build", "cli"] } diff --git a/uniffi_aries_vcx/core/src/handlers/connection.rs b/uniffi_aries_vcx/core/src/handlers/connection.rs index 391fdb05eb..e6d5ab6c79 100644 --- a/uniffi_aries_vcx/core/src/handlers/connection.rs +++ b/uniffi_aries_vcx/core/src/handlers/connection.rs @@ -237,4 +237,20 @@ impl Connection { Ok(()) }) } + + pub fn send_message( + &self, + profile_holder: Arc, + message: String, + ) -> VcxUniFFIResult<()> { + let message = serde_json::from_str(&message)?; + let handler = self.handler.lock()?.clone(); + + block_on(async { + handler + .send_message(profile_holder.inner.wallet(), &message, &HttpClient) + .await?; + Ok(()) + }) + } } diff --git a/uniffi_aries_vcx/core/src/handlers/holder.rs b/uniffi_aries_vcx/core/src/handlers/holder.rs new file mode 100644 index 0000000000..a3b295cb29 --- /dev/null +++ b/uniffi_aries_vcx/core/src/handlers/holder.rs @@ -0,0 +1,250 @@ +use std::sync::{Arc, Mutex}; + +use aries_vcx::{ + handlers::issuance::holder::Holder as VcxHolder, + protocols::issuance::holder::state_machine::HolderState as VcxHolderState, +}; + +use crate::{core::profile::ProfileHolder, errors::error::VcxUniFFIResult, runtime::block_on}; +pub struct Holder { + handler: Mutex, +} + +#[derive(Debug, PartialEq, Eq)] +pub enum HolderState { + Initial, + ProposalSet, + OfferReceived, + RequestSet, + Finished, + Failed, +} + +impl From for HolderState { + fn from(x: VcxHolderState) -> Self { + match x { + VcxHolderState::Initial => HolderState::Initial, + VcxHolderState::ProposalSet => HolderState::ProposalSet, + VcxHolderState::OfferReceived => HolderState::OfferReceived, + VcxHolderState::RequestSet => HolderState::RequestSet, + VcxHolderState::Finished => HolderState::Finished, + VcxHolderState::Failed => HolderState::Failed, + } + } +} + +pub fn create(source_id: String) -> VcxUniFFIResult> { + block_on(async { + let handler = Mutex::new(VcxHolder::create(&source_id)?); + Ok(Arc::new(Holder { handler })) + }) +} + +pub fn create_from_offer(source_id: String, offer_message: String) -> VcxUniFFIResult> { + let offer_message = serde_json::from_str(&offer_message)?; + block_on(async { + let handler = Mutex::new(VcxHolder::create_from_offer(&source_id, offer_message)?); + Ok(Arc::new(Holder { handler })) + }) +} + +pub fn create_with_proposal( + source_id: String, + propose_credential: String, +) -> VcxUniFFIResult> { + let propose_credential = serde_json::from_str(&propose_credential)?; + + block_on(async { + let handler = Mutex::new(VcxHolder::create_with_proposal( + &source_id, + propose_credential, + )?); + Ok(Arc::new(Holder { handler })) + }) +} + +impl Holder { + pub fn set_proposal(&self, credential_proposal: String) -> VcxUniFFIResult<()> { + let mut handler = self.handler.lock()?; + + handler.set_proposal(serde_json::from_str(&credential_proposal)?)?; + Ok(()) + } + + pub fn prepare_credential_request( + &self, + profile: Arc, + my_pw_did: String, + ) -> VcxUniFFIResult<()> { + let mut handler = self.handler.lock()?; + let mut holder = handler.clone(); + + block_on(async { + holder + .prepare_credential_request( + profile.inner.wallet(), + profile.inner.ledger_read(), + profile.inner.anoncreds(), + my_pw_did, + ) + .await?; + *handler = holder; + + Ok(()) + }) + } + + pub fn get_msg_credential_request(&self) -> VcxUniFFIResult { + let handler = self.handler.lock()?; + + Ok(serde_json::to_string( + &handler.clone().get_msg_credential_request()?, + )?) + } + + pub fn decline_offer(&self, comment: Option) -> VcxUniFFIResult { + let mut handler = self.handler.lock()?; + let mut holder = handler.clone(); + let problem_report_result = &holder.decline_offer(comment.as_deref())?; + *handler = holder; + + Ok(serde_json::to_string(problem_report_result)?) + } + + pub fn process_credential( + &self, + profile: Arc, + credential: String, + ) -> VcxUniFFIResult<()> { + let credential = serde_json::from_str(&credential)?; + let mut handler = self.handler.lock()?; + let mut holder = handler.clone(); + + block_on(async { + holder + .process_credential( + profile.inner.wallet(), + profile.inner.ledger_read(), + profile.inner.anoncreds(), + credential, + ) + .await?; + *handler = holder; + Ok(()) + }) + } + + pub fn is_terminal_state(&self) -> VcxUniFFIResult { + let handler = self.handler.lock()?; + + Ok(handler.is_terminal_state()) + } + + pub fn get_state(&self) -> VcxUniFFIResult { + let handler = self.handler.lock()?; + + Ok(HolderState::from(handler.get_state())) + } + + pub fn get_source_id(&self) -> VcxUniFFIResult { + let handler = self.handler.lock()?; + + Ok(handler.get_source_id()) + } + + pub fn get_credential(&self) -> VcxUniFFIResult { + let handler = self.handler.lock()?; + let credential = handler.get_credential()?; + Ok(credential.0) + } + + pub fn get_attributes(&self) -> VcxUniFFIResult { + let handler = self.handler.lock()?; + + Ok(handler.get_attributes()?) + } + + pub fn get_attachment(&self) -> VcxUniFFIResult { + let handler = self.handler.lock()?; + + Ok(handler.get_attachment()?) + } + + pub fn get_offer(&self) -> VcxUniFFIResult { + let handler = self.handler.lock()?; + + Ok(serde_json::to_string(&(handler.get_offer()?))?) + } + + pub fn get_tails_location(&self) -> VcxUniFFIResult { + let handler = self.handler.lock()?; + + Ok(handler.get_tails_location()?) + } + + pub fn get_tails_hash(&self) -> VcxUniFFIResult { + let handler = self.handler.lock()?; + + Ok(handler.get_tails_hash()?) + } + + pub fn get_rev_reg_id(&self) -> VcxUniFFIResult { + let handler = self.handler.lock()?; + + Ok(handler.get_rev_reg_id()?) + } + + pub fn get_cred_id(&self) -> VcxUniFFIResult { + let handler = self.handler.lock()?; + + Ok(handler.get_cred_id()?) + } + + pub fn get_thread_id(&self) -> VcxUniFFIResult { + let handler = self.handler.lock()?; + + Ok(handler.get_thread_id()?) + } + + pub fn is_revokable(&self, profile: Arc) -> VcxUniFFIResult { + let handler = self.handler.lock()?.clone(); + + block_on(async { Ok(handler.is_revokable(profile.inner.ledger_read()).await?) }) + } + + pub fn is_revoked(&self, profile: Arc) -> VcxUniFFIResult { + let handler = self.handler.lock()?.clone(); + + block_on(async { + Ok(handler + .is_revoked( + profile.inner.wallet(), + profile.inner.ledger_read(), + profile.inner.anoncreds(), + ) + .await?) + }) + } + + pub fn get_cred_rev_id(&self, profile: Arc) -> VcxUniFFIResult { + let handler = self.handler.lock()?.clone(); + + block_on(async { + Ok(handler + .get_cred_rev_id(profile.inner.wallet(), profile.inner.anoncreds()) + .await?) + }) + } + + pub fn get_problem_report(&self) -> VcxUniFFIResult { + let handler = self.handler.lock()?; + + Ok(serde_json::to_string(&handler.get_problem_report()?)?) + } + + pub fn get_final_message(&self) -> VcxUniFFIResult> { + let handler = self.handler.lock()?; + + Ok(Some(serde_json::to_string(&handler.get_final_message()?)?)) + } +} diff --git a/uniffi_aries_vcx/core/src/handlers/mod.rs b/uniffi_aries_vcx/core/src/handlers/mod.rs index b3b606b40c..b1ff1075cd 100644 --- a/uniffi_aries_vcx/core/src/handlers/mod.rs +++ b/uniffi_aries_vcx/core/src/handlers/mod.rs @@ -1 +1,2 @@ pub mod connection; +pub mod holder; diff --git a/uniffi_aries_vcx/core/src/lib.rs b/uniffi_aries_vcx/core/src/lib.rs index c647641b7c..a6bad31599 100644 --- a/uniffi_aries_vcx/core/src/lib.rs +++ b/uniffi_aries_vcx/core/src/lib.rs @@ -8,7 +8,7 @@ pub mod runtime; use aries_vcx::{ aries_vcx_core::wallet::indy::WalletConfig, protocols::connection::pairwise_info::PairwiseInfo, }; -use handlers::connection::*; +use handlers::{connection::*, holder::*}; use crate::{ core::{profile::*, unpack_message::*}, diff --git a/uniffi_aries_vcx/core/src/vcx.udl b/uniffi_aries_vcx/core/src/vcx.udl index 412455643e..2df09828e8 100644 --- a/uniffi_aries_vcx/core/src/vcx.udl +++ b/uniffi_aries_vcx/core/src/vcx.udl @@ -68,6 +68,83 @@ interface Connection { void send_ack(ProfileHolder profile); }; +interface Holder { + [Throws=VcxUniFFIError] + void set_proposal(string credential_proposal); + + [Throws=VcxUniFFIError] + void prepare_credential_request(ProfileHolder profile, string my_pw_did); + + [Throws=VcxUniFFIError] + string get_msg_credential_request(); + + [Throws=VcxUniFFIError] + string decline_offer(string? comment); + + [Throws=VcxUniFFIError] + void process_credential(ProfileHolder profile, string credential); + + [Throws=VcxUniFFIError] + boolean is_terminal_state(); + + [Throws=VcxUniFFIError] + HolderState get_state(); + + [Throws=VcxUniFFIError] + string get_source_id(); + + [Throws=VcxUniFFIError] + string get_credential(); + + [Throws=VcxUniFFIError] + string get_attributes(); + + [Throws=VcxUniFFIError] + string get_attachment(); + + [Throws=VcxUniFFIError] + string get_offer(); + + [Throws=VcxUniFFIError] + string get_tails_location(); + + [Throws=VcxUniFFIError] + string get_tails_hash(); + + [Throws=VcxUniFFIError] + string get_rev_reg_id(); + + [Throws=VcxUniFFIError] + string get_cred_id(); + + [Throws=VcxUniFFIError] + string get_thread_id(); + + [Throws=VcxUniFFIError] + boolean is_revokable(ProfileHolder profile); + + [Throws=VcxUniFFIError] + boolean is_revoked(ProfileHolder profile); + + [Throws=VcxUniFFIError] + string get_cred_rev_id(ProfileHolder profile); + + [Throws=VcxUniFFIError] + string get_problem_report(); + + [Throws=VcxUniFFIError] + string? get_final_message(); +}; + +enum HolderState { + "Initial", + "ProposalSet", + "OfferReceived", + "RequestSet", + "Finished", + "Failed" +}; + [Error] enum VcxUniFFIError { "AriesVcxError", @@ -88,4 +165,13 @@ namespace vcx { [Throws=VcxUniFFIError] UnpackMessage unpack_message(ProfileHolder profile, string packed_msg); + + [Throws=VcxUniFFIError] + Holder create(string source_id); + + [Throws=VcxUniFFIError] + Holder create_from_offer(string source_id, string offer_message); + + [Throws=VcxUniFFIError] + Holder create_with_proposal(string source_id, string propose_credential); };