diff --git a/cli/src/command_executor.rs b/cli/src/command_executor.rs index f5fde3bf7a..bd9ee18994 100644 --- a/cli/src/command_executor.rs +++ b/cli/src/command_executor.rs @@ -7,7 +7,6 @@ use unescape::unescape; use std::cell::RefCell; use std::collections::BTreeMap; use std::collections::HashMap; -use std::error::Error; use linefeed::{Reader, ReadResult}; @@ -868,7 +867,7 @@ impl CommandExecutor { } } Err(err) => { - println_err!("{}", err.description().to_string()); + println_err!("{}", err.to_string()); println!("Please enter value for {}:", param); } } diff --git a/cli/src/utils/logger.rs b/cli/src/utils/logger.rs index abea13a26f..8d46073cc2 100644 --- a/cli/src/utils/logger.rs +++ b/cli/src/utils/logger.rs @@ -2,7 +2,6 @@ extern crate log4rs; extern crate log; extern crate libc; -use std::error::Error; use indy; pub struct IndyCliLogger; @@ -10,7 +9,7 @@ pub struct IndyCliLogger; impl IndyCliLogger { pub fn init(path: &str) -> Result<(), String> { log4rs::init_file(path, Default::default()) - .map_err(|err| format!("Cannot init Indy CLI logger: {}", err.description()))?; + .map_err(|err| format!("Cannot init Indy CLI logger: {}", err.to_string()))?; indy::logger::set_logger(log::logger()) .map_err(|_| "Cannot init Libindy logger".to_string()) diff --git a/libindy/Cargo.lock b/libindy/Cargo.lock index c60a2a5c1c..faa618b837 100644 --- a/libindy/Cargo.lock +++ b/libindy/Cargo.lock @@ -538,18 +538,6 @@ name = "elastic-array-plus" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "env_logger" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "env_logger" version = "0.7.1" @@ -849,7 +837,7 @@ dependencies = [ "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "derivative 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "etcommon-rlp 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1995,7 +1983,6 @@ dependencies = [ "checksum ed25519-dalek 1.0.0-pre.2 (registry+https://github.com/rust-lang/crates.io-index)" = "845aaacc16f01178f33349e7c992ecd0cee095aa5e577f0f4dee35971bd36455" "checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" "checksum elastic-array-plus 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "562cc8504a01eb20c10fb154abd7c4baeb9beba2329cf85838ee2bd48a468b18" -"checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" "checksum env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" "checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" "checksum etcommon-hexutil 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "20b4d1933bf88b806ba2d9189880b1b4ef205e42df9573b65716f2a50818024c" diff --git a/libindy/Cargo.toml b/libindy/Cargo.toml index 47c8037771..40caecc6aa 100644 --- a/libindy/Cargo.toml +++ b/libindy/Cargo.toml @@ -27,9 +27,9 @@ only_high_cases = [] fatal_warnings = [] [dependencies] -env_logger = "0.6.2" +env_logger = "0.7" etcommon-rlp = "0.2.4" -failure = "0.1.6" +failure = "0.1.7" hex = "0.3.2" libc = "0.2.66" log = "0.4.8" @@ -55,7 +55,7 @@ regex = "1.2.1" indy-api-types = { path = "./indy-api-types"} indy-utils = { path = "./indy-utils"} indy-wallet = { path = "./indy-wallet"} -quote = "=1.0.2" +quote = "=1.0.7" [dependencies.uuid] version = "0.7.4" diff --git a/libindy/mac.build.sh b/libindy/mac.build.sh index 3611fb3fda..24782655bb 100755 --- a/libindy/mac.build.sh +++ b/libindy/mac.build.sh @@ -41,10 +41,7 @@ if [[ "$OSTYPE" == "darwin"* ]]; then export CARGO_INCREMENTAL=1 export RUST_LOG=indy=trace export RUST_TEST_THREADS=1 - for version in `ls -t /usr/local/Cellar/openssl/`; do - export OPENSSL_DIR=/usr/local/Cellar/openssl/$version - break - done + export OPENSSL_DIR=/usr/local/opt/`ls /usr/local/opt/ | grep openssl | sort | tail -1` cargo build export LIBRARY_PATH=$(pwd)/target/debug cd ../cli diff --git a/vcx/libvcx/src/api/connection.rs b/vcx/libvcx/src/api/connection.rs index 52188862cd..b0a80e1363 100644 --- a/vcx/libvcx/src/api/connection.rs +++ b/vcx/libvcx/src/api/connection.rs @@ -803,13 +803,13 @@ pub extern fn vcx_connection_send_message(command_handle: CommandHandle, msg: *const c_char, send_msg_options: *const c_char, cb: Option) -> u32 { - info!("vcx_message_send >>>"); + info!("vcx_connection_send_message >>>"); check_useful_c_callback!(cb, VcxErrorKind::InvalidOption); check_useful_c_str!(msg, VcxErrorKind::InvalidOption); check_useful_c_str!(send_msg_options, VcxErrorKind::InvalidOption); - trace!("vcx_message_send(command_handle: {}, connection_handle: {}, msg: {}, send_msg_options: {})", + trace!("vcx_connection_send_message(command_handle: {}, connection_handle: {}, msg: {}, send_msg_options: {})", command_handle, connection_handle, msg, send_msg_options); spawn(move || { diff --git a/vcx/libvcx/src/api/disclosed_proof.rs b/vcx/libvcx/src/api/disclosed_proof.rs index 4abbccb1f9..ae5b54cdfa 100644 --- a/vcx/libvcx/src/api/disclosed_proof.rs +++ b/vcx/libvcx/src/api/disclosed_proof.rs @@ -9,7 +9,7 @@ use error::prelude::*; use indy_sys::CommandHandle; /* - The API represents an Prover side in credential presentation process. + APIs in this module are called by a prover throughout the request-proof-and-verify process. Assumes that pairwise connection between Verifier and Prover is already established. # State diff --git a/vcx/libvcx/src/api/proof.rs b/vcx/libvcx/src/api/proof.rs index 203fc2722f..45fd176054 100644 --- a/vcx/libvcx/src/api/proof.rs +++ b/vcx/libvcx/src/api/proof.rs @@ -9,7 +9,7 @@ use error::prelude::*; use indy_sys::CommandHandle; /* - The API represents an Verifier side in credential presentation process. + APIs in this module are called by a verifier throughout the request-proof-and-verify process. Assumes that pairwise connection between Verifier and Prover is already established. # State @@ -557,11 +557,6 @@ pub extern fn vcx_proof_get_request_msg(command_handle: CommandHandle, } -/// Todo: This api should remove the connection_handle!! It is not being used within the code. I assume -/// the only reason it still has it as an input was to not break it for existing users. vcx_get_proof_msg -/// is the updated api that we should use. -/// Get Proof message -/// /// #Params /// command_handle: command handle to map callback to user context. /// @@ -573,10 +568,14 @@ pub extern fn vcx_proof_get_request_msg(command_handle: CommandHandle, /// /// #Returns /// Error code as a u32 +#[deprecated( + since = "1.15.0", + note = "Use vcx_get_proof_msg() instead. This api is similar, but requires an extra parameter (connection_handle) which is unnecessary and unused in the internals." +)] #[no_mangle] pub extern fn vcx_get_proof(command_handle: CommandHandle, proof_handle: u32, - _connection_handle: u32, + _unused_connection_handle: u32, cb: Option) -> u32 { info!("vcx_get_proof >>>"); diff --git a/vcx/libvcx/src/api/schema.rs b/vcx/libvcx/src/api/schema.rs index bae11b08e6..f55512e19a 100644 --- a/vcx/libvcx/src/api/schema.rs +++ b/vcx/libvcx/src/api/schema.rs @@ -9,7 +9,7 @@ use utils::threadpool::spawn; use error::prelude::*; use indy_sys::CommandHandle; -/// Create a new Schema object and publish correspondent record on the ledger +/// Create a new Schema object and publish corresponding record on the ledger /// /// #Params /// command_handle: command handle to map callback to user context. @@ -18,13 +18,16 @@ use indy_sys::CommandHandle; /// /// schema_name: Name of schema /// -/// version: version of schema +/// version: Version of schema. A semver-compatible value like "1.0" is encouraged. /// -/// schema_data: list of attributes that will make up the schema (the number of attributes should be less or equal than 125) +/// schema_data: A list of attributes that will make up the schema, represented +/// as a string containing a JSON array. The number of attributes should be +/// less or equal to 125, because larger arrays cause various downstream problems. +/// This limitation is an annoyance that we'd like to remove. /// /// # Example schema_data -> "["attr1", "attr2", "attr3"]" /// -/// payment_handle: future use (currently uses any address in the wallet) +/// payment_handle: Reserved for future use (currently uses any address in the wallet) /// /// cb: Callback that provides Schema handle and error status of request. /// diff --git a/vcx/libvcx/src/connection.rs b/vcx/libvcx/src/connection.rs index ff55285bb8..631e9a3b55 100644 --- a/vcx/libvcx/src/connection.rs +++ b/vcx/libvcx/src/connection.rs @@ -1242,7 +1242,7 @@ impl From<(Connection, ActorDidExchangeState)> for ConnectionV3 { } } -use v3::messages::a2a::{A2AMessage, MessageId}; +use v3::messages::a2a::A2AMessage; use v3::messages::connection::did_doc::DidDoc; pub fn get_messages(handle: u32) -> VcxResult> { @@ -1294,24 +1294,6 @@ pub fn send_message_to_self_endpoint(message: A2AMessage, did_doc: &DidDoc) -> V ConnectionV3::send_message_to_self_endpoint(&message, did_doc) } -pub fn add_pending_messages(handle: u32, messages: HashMap) -> VcxResult<()> { - CONNECTION_MAP.get(handle, |connection| { - match connection { - Connections::V1(_) => Err(VcxError::from(VcxErrorKind::InvalidConnectionHandle)), - Connections::V3(ref connection) => connection.add_pending_messages(messages.clone()) - } - }) -} - -pub fn remove_pending_message(handle: u32, id: &MessageId) -> VcxResult<()> { - CONNECTION_MAP.get(handle, |connection| { - match connection { - Connections::V1(_) => Err(VcxError::from(VcxErrorKind::InvalidConnectionHandle)), - Connections::V3(ref connection) => connection.remove_pending_message(id.clone()) - } - }) -} - pub fn is_v3_connection(connection_handle: u32) -> VcxResult { CONNECTION_MAP.get(connection_handle, |connection| { match connection { diff --git a/vcx/libvcx/src/messages/payload.rs b/vcx/libvcx/src/messages/payload.rs index 2869297769..e762b49586 100644 --- a/vcx/libvcx/src/messages/payload.rs +++ b/vcx/libvcx/src/messages/payload.rs @@ -168,7 +168,7 @@ pub enum PayloadTypes { #[derive(Clone, Deserialize, Serialize, Debug, PartialEq)] pub struct PayloadTypeV1 { - name: String, + pub name: String, ver: String, fmt: String, } diff --git a/vcx/libvcx/src/utils/mod.rs b/vcx/libvcx/src/utils/mod.rs index 520f7c9130..baeb665516 100644 --- a/vcx/libvcx/src/utils/mod.rs +++ b/vcx/libvcx/src/utils/mod.rs @@ -23,6 +23,7 @@ macro_rules! secret { ($val:expr) => {{ "_" }}; } +#[cfg(test)] macro_rules! map ( { $($key:expr => $value:expr),+ } => { { diff --git a/vcx/libvcx/src/v3/handlers/connection/connection.rs b/vcx/libvcx/src/v3/handlers/connection/connection.rs index f888d07406..4a9dc01f2b 100644 --- a/vcx/libvcx/src/v3/handlers/connection/connection.rs +++ b/vcx/libvcx/src/v3/handlers/connection/connection.rs @@ -4,7 +4,7 @@ use error::prelude::*; use v3::handlers::connection::states::{DidExchangeSM, Actor, ActorDidExchangeState}; use v3::handlers::connection::messages::DidExchangeMessages; use v3::handlers::connection::agent::AgentInfo; -use v3::messages::a2a::{A2AMessage, MessageId}; +use v3::messages::a2a::A2AMessage; use v3::messages::connection::invite::Invitation; use std::collections::HashMap; @@ -126,16 +126,11 @@ impl Connection { pub fn update_state_with_message(&mut self, message: &str) -> VcxResult<()> { trace!("Connection: update_state_with_message: {}", message); - let agent_info = self.agent_info().clone(); - - let message: Message = ::serde_json::from_str(&message) + let message: A2AMessage = ::serde_json::from_str(&message) .map_err(|err| VcxError::from_msg(VcxErrorKind::InvalidOption, format!("Cannot updated state with messages: Message deserialization failed: {:?}", err)))?; - let a2a_message = self.decode_message(&message)?; - self.handle_message(a2a_message.into())?; - - agent_info.update_message_status(message.uid)?; + self.handle_message(message.into())?; Ok(()) } @@ -183,16 +178,8 @@ impl Connection { AgentInfo::send_message_anonymously(message, did_doc) } - pub fn send_generic_message(&self, message: &str, _message_options: &str) -> VcxResult { - trace!("Connection::send_generic_message >>> message: {:?}", message); - - let message = match ::serde_json::from_str::(message) { - Ok(A2AMessage::Generic(message)) => { - BasicMessage::create() - .set_content(message.to_string()) - .set_time() - .to_a2a_message() - } + fn parse_generic_message(message: &str, _message_options: &str) -> A2AMessage { + match ::serde_json::from_str::(message) { Ok(a2a_message) => a2a_message, Err(_) => { BasicMessage::create() @@ -200,8 +187,13 @@ impl Connection { .set_time() .to_a2a_message() } - }; + } + } + + pub fn send_generic_message(&self, message: &str, _message_options: &str) -> VcxResult { + trace!("Connection::send_generic_message >>> message: {:?}", message); + let message = Connection::parse_generic_message(message, _message_options); self.send_message(&message).map(|_| String::new()) } @@ -220,16 +212,6 @@ impl Connection { Ok(()) } - pub fn add_pending_messages(&self, messages: HashMap) -> VcxResult<()> { - trace!("Connection::add_pending_messages >>> messages: {:?}", messages); - self.connection_sm.add_pending_messages(messages) - } - - pub fn remove_pending_message(&self, id: MessageId) -> VcxResult<()> { - trace!("Connection::remove_pending_message >>> id: {:?}", id); - self.connection_sm.remove_pending_message(id) - } - pub fn send_discovery_features(&mut self, query: Option, comment: Option) -> VcxResult<()> { trace!("Connection::send_discovery_features_query >>> query: {:?}, comment: {:?}", query, comment); self.handle_message(DidExchangeMessages::DiscoverFeatures((query, comment))) @@ -284,4 +266,40 @@ struct SideConnectionInfo { service_endpoint: String, #[serde(skip_serializing_if = "Option::is_none")] protocols: Option>, +} + +#[cfg(test)] +mod tests { + use v3::messages::a2a::A2AMessage; + use v3::handlers::connection::connection::Connection; + + #[test] + fn test_parse_generic_message_plain_string_should_be_parsed_as_basic_msg() -> Result<(), String> { + let message = "Some plain text message"; + let result = Connection::parse_generic_message(message, ""); + match result { + A2AMessage::BasicMessage(basic_msg) => { + assert_eq!(basic_msg.content, message); + Ok(()) + } + other => Err(format!("Result is not BasicMessage, but: {:?}", other)) + } + } + + #[test] + fn test_parse_generic_message_json_msg_should_be_parsed_as_generic() -> Result<(), String> { + let message = json!({ + "@id": "some id", + "@type": "some type", + "content": "some content" + }).to_string(); + let result = Connection::parse_generic_message(&message, ""); + match result { + A2AMessage::Generic(value) => { + assert_eq!(value.to_string(), message); + Ok(()) + } + other => Err(format!("Result is not Generic, but: {:?}", other)) + } + } } \ No newline at end of file diff --git a/vcx/libvcx/src/v3/handlers/connection/mod.rs b/vcx/libvcx/src/v3/handlers/connection/mod.rs index ce20949bc7..2209298fce 100644 --- a/vcx/libvcx/src/v3/handlers/connection/mod.rs +++ b/vcx/libvcx/src/v3/handlers/connection/mod.rs @@ -138,27 +138,6 @@ pub mod tests { ::connection::update_message_status(alice.connection_handle, uid).unwrap(); } - // Pending Message - { - faber.activate(); - - let message = _ack(); - ::connection::send_message(faber.connection_handle, message.to_a2a_message()).unwrap(); - - alice.activate(); - - let messages = ::connection::get_messages(alice.connection_handle).unwrap(); - assert_eq!(1, messages.len()); - let uid = messages.keys().next().unwrap().clone(); - - ::connection::add_pending_messages(alice.connection_handle, map!( message.id.clone() => uid )).unwrap(); - - ::connection::remove_pending_message(alice.connection_handle, &message.id).unwrap(); - - let messages = ::connection::get_messages(alice.connection_handle).unwrap(); - assert_eq!(0, messages.len()); - } - // Download Messages { use messages::get_message::{download_messages, MessageByConnection, Message}; diff --git a/vcx/libvcx/src/v3/handlers/connection/states.rs b/vcx/libvcx/src/v3/handlers/connection/states.rs index bd49646d58..d87589348c 100644 --- a/vcx/libvcx/src/v3/handlers/connection/states.rs +++ b/vcx/libvcx/src/v3/handlers/connection/states.rs @@ -13,13 +13,11 @@ use v3::messages::ack::Ack; use v3::messages::connection::did_doc::DidDoc; use v3::messages::discovery::query::Query; use v3::messages::discovery::disclose::{Disclose, ProtocolDescriptor}; -use v3::messages::a2a::MessageId; use v3::messages::a2a::protocol_registry::ProtocolRegistry; use std::collections::HashMap; use error::prelude::*; -use v3::utils::pending_message::PendingMessage; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct DidExchangeSM { @@ -672,32 +670,6 @@ impl DidExchangeSM { ActorDidExchangeState::Invitee(_) => Actor::Invitee } } - - pub fn add_pending_messages(&self, messages: HashMap) -> VcxResult<()> { - match self.state { - ActorDidExchangeState::Inviter(DidExchangeState::Completed(ref _state)) | - ActorDidExchangeState::Invitee(DidExchangeState::Completed(ref _state)) => { - for (key, value) in messages { - PendingMessage::add(&key.0, &value).ok(); - } - } - _ => {} - }; - Ok(()) - } - - pub fn remove_pending_message(&self, id: MessageId) -> VcxResult<()> { - match self.state { - ActorDidExchangeState::Inviter(DidExchangeState::Completed(ref _state)) | - ActorDidExchangeState::Invitee(DidExchangeState::Completed(ref _state)) => { - if let Some(uid_) = PendingMessage::get(&id.0) { - self.agent_info.update_message_status(uid_.to_string()).ok(); - } - } - _ => {} - }; - Ok(()) - } } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] diff --git a/vcx/libvcx/src/v3/handlers/issuance/holder.rs b/vcx/libvcx/src/v3/handlers/issuance/holder.rs index ad9c505ff5..bb7aca47ed 100644 --- a/vcx/libvcx/src/v3/handlers/issuance/holder.rs +++ b/vcx/libvcx/src/v3/handlers/issuance/holder.rs @@ -60,8 +60,10 @@ impl HolderSM { match self.find_message_to_handle(messages) { Some((uid, msg)) => { + let state = self.handle_message(msg.into())?; connection::update_message_status(conn_handle, uid)?; - self.handle_message(msg.into()) + Ok(state) + } None => Ok(self) } @@ -119,7 +121,6 @@ impl HolderSM { Ok((cred_request, req_meta, cred_def_json)) => { let cred_request = cred_request .set_thread_id(&thread_id); - connection::remove_pending_message(connection_handle, &state_data.offer.id)?; connection::send_message(connection_handle, cred_request.to_a2a_message())?; HolderState::RequestSent((state_data, req_meta, cred_def_json, connection_handle).into()) } diff --git a/vcx/libvcx/src/v3/handlers/issuance/issuer.rs b/vcx/libvcx/src/v3/handlers/issuance/issuer.rs index 23e4f92294..8008f43641 100644 --- a/vcx/libvcx/src/v3/handlers/issuance/issuer.rs +++ b/vcx/libvcx/src/v3/handlers/issuance/issuer.rs @@ -13,7 +13,7 @@ use issuer_credential::encode_attributes; use v3::messages::status::Status; use std::collections::HashMap; use connection::{send_message, get_messages}; -use connection::update_message_status; +use connection; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct IssuerSM { @@ -54,8 +54,9 @@ impl IssuerSM { match self.find_message_to_handle(messages) { Some((uid, msg)) => { - update_message_status(conn_handle, uid)?; - self.handle_message(msg.into()) + let state = self.handle_message(msg.into())?; + connection::update_message_status(conn_handle, uid)?; + Ok(state) } None => Ok(self) } diff --git a/vcx/libvcx/src/v3/handlers/issuance/mod.rs b/vcx/libvcx/src/v3/handlers/issuance/mod.rs index 192eb0e1bd..84c5c6bdbd 100644 --- a/vcx/libvcx/src/v3/handlers/issuance/mod.rs +++ b/vcx/libvcx/src/v3/handlers/issuance/mod.rs @@ -3,10 +3,8 @@ pub mod states; pub mod messages; pub mod holder; -use std::collections::HashMap; use error::prelude::*; -use messages::get_message::Message; -use v3::messages::a2a::{A2AMessage, MessageId}; +use v3::messages::a2a::A2AMessage; use v3::handlers::issuance::issuer::IssuerSM; use v3::handlers::issuance::messages::CredentialIssuanceMessage; use v3::handlers::issuance::holder::HolderSM; @@ -51,10 +49,9 @@ impl Issuer { pub fn update_status(&mut self, msg: Option) -> VcxResult<()> { match msg { Some(msg) => { - let message: Message = ::serde_json::from_str(&msg) + let message: A2AMessage = ::serde_json::from_str(&msg) .map_err(|err| VcxError::from_msg(VcxErrorKind::InvalidOption, format!("Cannot deserialize Message: {:?}", err)))?; - let message = connection::decode_message(self.issuer_sm.get_connection_handle(), message)?; self.step(message.into()) } None => { @@ -97,10 +94,9 @@ impl Holder { pub fn update_state(&mut self, msg: Option) -> VcxResult<()> { match msg { Some(msg) => { - let message: Message = ::serde_json::from_str(&msg) + let message: A2AMessage = ::serde_json::from_str(&msg) .map_err(|err| VcxError::from_msg(VcxErrorKind::InvalidOption, format!("Cannot update state: Message deserialization failed: {:?}", err)))?; - let message = connection::decode_message(self.holder_sm.get_connection_handle(), message)?; self.step(message.into()) } None => { @@ -138,34 +134,30 @@ impl Holder { pub fn get_credential_offer_message(connection_handle: u32, msg_id: &str) -> VcxResult { let message = connection::get_message_by_id(connection_handle, msg_id.to_string())?; - let (id, credential_offer): (MessageId, CredentialOffer) = match message { - A2AMessage::CredentialOffer(credential_offer) => (credential_offer.id.clone(), credential_offer), - msg => return Err(VcxError::from_msg(VcxErrorKind::InvalidMessages, format!("Message of different type was received: {:?}", msg))) + let credential_offer: CredentialOffer = match message { + A2AMessage::CredentialOffer(credential_offer) => credential_offer, + msg => { + return Err(VcxError::from_msg(VcxErrorKind::InvalidMessages, + format!("Message of different type was received: {:?}", msg))); + } }; - connection::add_pending_messages(connection_handle, map! { id => msg_id.to_string() })?; - Ok(credential_offer) } pub fn get_credential_offer_messages(conn_handle: u32) -> VcxResult> { let messages = connection::get_messages(conn_handle)?; - let (uids, msgs): (HashMap, Vec) = messages + let msgs: Vec = messages .into_iter() - .filter_map(|(uid, a2a_message)| { + .filter_map(|(_, a2a_message)| { match a2a_message { A2AMessage::CredentialOffer(credential_offer) => { - Some((uid, credential_offer.id.clone(), credential_offer)) + Some(credential_offer) } _ => None } - }).fold((HashMap::new(), vec![]), |(mut uids, mut msgs), (uid, id, msg)| { - uids.insert(id, uid); - msgs.push(msg); - (uids, msgs) - }); - - connection::add_pending_messages(conn_handle, uids)?; + }) + .collect(); Ok(msgs) } diff --git a/vcx/libvcx/src/v3/handlers/proof_presentation/prover/prover.rs b/vcx/libvcx/src/v3/handlers/proof_presentation/prover/prover.rs index ab83ffc179..1ced5ace26 100644 --- a/vcx/libvcx/src/v3/handlers/proof_presentation/prover/prover.rs +++ b/vcx/libvcx/src/v3/handlers/proof_presentation/prover/prover.rs @@ -1,25 +1,18 @@ -use messages::get_message::Message; use error::prelude::*; use utils::libindy::anoncreds; use std::convert::TryInto; -use std::collections::HashMap; use v3::handlers::proof_presentation::prover::states::ProverSM; use v3::handlers::proof_presentation::prover::messages::ProverMessages; -use v3::messages::a2a::{A2AMessage, MessageId}; +use v3::messages::a2a::A2AMessage; use v3::messages::proof_presentation::presentation_proposal::PresentationPreview; use v3::messages::proof_presentation::presentation_request::PresentationRequest; use connection; use messages::proofs::proof_message::ProofMessage; -use std::sync::Mutex; use v3::messages::proof_presentation::presentation::Presentation; -lazy_static! { - pub static ref PENDING_PRESENTATION_REQUESTS: Mutex> = Default::default(); -} - #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Prover { prover_sm: ProverSM @@ -93,16 +86,10 @@ impl Prover { pub fn update_state_with_message(&mut self, message: &str) -> VcxResult<()> { trace!("Prover::update_state_with_message >>> message: {:?}", message); - let message: Message = ::serde_json::from_str(&message) + let a2a_message: A2AMessage = ::serde_json::from_str(&message) .map_err(|err| VcxError::from_msg(VcxErrorKind::InvalidOption, format!("Cannot updated state with message: Message deserialization failed: {:?}", err)))?; - let connection_handle = self.prover_sm.connection_handle()?; - - let uid = message.uid.clone(); - let a2a_message = connection::decode_message(connection_handle, message)?; - self.handle_message(a2a_message.into())?; - connection::update_message_status(connection_handle, uid)?; Ok(()) } @@ -117,36 +104,32 @@ impl Prover { let message = connection::get_message_by_id(connection_handle, msg_id.to_string())?; - let (id, presentation_request): (MessageId, PresentationRequest) = match message { - A2AMessage::PresentationRequest(presentation_request) => (presentation_request.id.clone(), presentation_request), - msg => return Err(VcxError::from_msg(VcxErrorKind::InvalidMessages, format!("Message of different type was received: {:?}", msg))) + let presentation_request: PresentationRequest = match message { + A2AMessage::PresentationRequest(presentation_request) => presentation_request, + msg => { + return Err(VcxError::from_msg(VcxErrorKind::InvalidMessages, + format!("Message of different type was received: {:?}", msg))); + } }; - connection::add_pending_messages(connection_handle, map! { id => msg_id.to_string() })?; - Ok(presentation_request) } pub fn get_presentation_request_messages(connection_handle: u32, match_name: Option<&str>) -> VcxResult> { trace!("Prover::get_presentation_request_messages >>> connection_handle: {:?}, match_name: {:?}", connection_handle, match_name); - let (uids, presentation_requests): (HashMap, Vec) = + let presentation_requests: Vec = connection::get_messages(connection_handle)? .into_iter() - .filter_map(|(uid, message)| { + .filter_map(|(_, message)| { match message { A2AMessage::PresentationRequest(presentation_request) => { - Some((uid, presentation_request.id.clone(), presentation_request)) + Some(presentation_request) } _ => None, } - }).fold((HashMap::new(), Vec::new()), |(mut uids, mut messages), (uid, id, presentation_request)| { - uids.insert(id, uid); - messages.push(presentation_request); - (uids, messages) - }); - - connection::add_pending_messages(connection_handle, uids)?; + }) + .collect(); Ok(presentation_requests) } diff --git a/vcx/libvcx/src/v3/handlers/proof_presentation/prover/states.rs b/vcx/libvcx/src/v3/handlers/proof_presentation/prover/states.rs index 875916f116..9ab01cc64e 100644 --- a/vcx/libvcx/src/v3/handlers/proof_presentation/prover/states.rs +++ b/vcx/libvcx/src/v3/handlers/proof_presentation/prover/states.rs @@ -15,6 +15,8 @@ use disclosed_proof::DisclosedProof; use error::prelude::*; +/// A state machine that tracks the evolution of states for a Prover during +/// the Present Proof protocol. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct ProverSM { source_id: String, @@ -269,7 +271,6 @@ impl ProverSM { match state.presentation_request.service.clone() { None => { connection::send_message(connection_handle, state.presentation.to_a2a_message())?; - connection::remove_pending_message(connection_handle, &state.presentation_request.id)?; ProverState::PresentationSent((state, connection_handle).into()) } Some(service) => { @@ -342,7 +343,6 @@ impl ProverSM { Some(service) => connection::send_message_to_self_endpoint(problem_report.to_a2a_message(), &service.into())? } - connection::remove_pending_message(connection_handle, &presentation_request.id)?; Ok(()) } @@ -356,7 +356,6 @@ impl ProverSM { Some(service) => connection::send_message_to_self_endpoint(proposal.to_a2a_message(), &service.into())? } - connection::remove_pending_message(connection_handle, &presentation_request.id)?; Ok(()) } diff --git a/vcx/libvcx/src/v3/handlers/proof_presentation/verifier/verifier.rs b/vcx/libvcx/src/v3/handlers/proof_presentation/verifier/verifier.rs index 8d731ebbcb..f94afe97b4 100644 --- a/vcx/libvcx/src/v3/handlers/proof_presentation/verifier/verifier.rs +++ b/vcx/libvcx/src/v3/handlers/proof_presentation/verifier/verifier.rs @@ -1,13 +1,12 @@ use error::prelude::*; use std::convert::TryInto; -use messages::get_message::Message; - use connection; use v3::messages::proof_presentation::presentation_request::*; use v3::messages::proof_presentation::presentation::Presentation; use v3::handlers::proof_presentation::verifier::states::VerifierSM; use v3::handlers::proof_presentation::verifier::messages::VerifierMessages; +use v3::messages::a2a::A2AMessage; use messages::proofs::proof_request::ProofRequestMessage; use messages::proofs::proof_message::ProofMessage; @@ -74,16 +73,10 @@ impl Verifier { pub fn update_state_with_message(&mut self, message: &str) -> VcxResult<()> { trace!("Verifier::update_state_with_message >>> message: {:?}", message); - let message: Message = ::serde_json::from_str(&message) + let message: A2AMessage = ::serde_json::from_str(&message) .map_err(|err| VcxError::from_msg(VcxErrorKind::InvalidOption, format!("Cannot update state with message: Message deserialization failed: {:?}", err)))?; - let connection_handle = self.verifier_sm.connection_handle()?; - - let uid = message.uid.clone(); - let a2a_message = connection::decode_message(connection_handle, message)?; - - self.handle_message(a2a_message.into())?; - connection::update_message_status(connection_handle, uid)?; + self.handle_message(message.into())?; Ok(()) } diff --git a/vcx/libvcx/src/v3/messages/a2a/mod.rs b/vcx/libvcx/src/v3/messages/a2a/mod.rs index c8ecc94a95..0dbf2d5555 100644 --- a/vcx/libvcx/src/v3/messages/a2a/mod.rs +++ b/vcx/libvcx/src/v3/messages/a2a/mod.rs @@ -72,7 +72,7 @@ pub enum A2AMessage { BasicMessage(BasicMessage), /// Any Raw Message - Generic(String), + Generic(Value), } impl<'de> Deserialize<'de> for A2AMessage { @@ -81,7 +81,7 @@ impl<'de> Deserialize<'de> for A2AMessage { let message_type: MessageType = match serde_json::from_value(value["@type"].clone()) { Ok(message_type) => message_type, - Err(_) => return Ok(A2AMessage::Generic(value.to_string())) + Err(_) => return Ok(A2AMessage::Generic(value)) }; match (message_type.family, message_type.type_.as_str()) { @@ -192,7 +192,7 @@ impl<'de> Deserialize<'de> for A2AMessage { } (_, other_type) => { warn!("Unexpected @type field structure: {}", other_type); - Ok(A2AMessage::Generic(value.to_string())) + Ok(A2AMessage::Generic(value)) } } } @@ -229,7 +229,7 @@ impl Serialize for A2AMessage { A2AMessage::Query(msg) => set_a2a_message_type(msg, MessageFamilies::DiscoveryFeatures, A2AMessage::QUERY), A2AMessage::Disclose(msg) => set_a2a_message_type(msg, MessageFamilies::DiscoveryFeatures, A2AMessage::DISCLOSE), A2AMessage::BasicMessage(msg) => set_a2a_message_type(msg, MessageFamilies::Basicmessage, A2AMessage::BASIC_MESSAGE), - A2AMessage::Generic(msg) => ::serde_json::to_value(msg), + A2AMessage::Generic(msg) => Ok(msg.clone()) }.map_err(ser::Error::custom)?; value.serialize(serializer) diff --git a/vcx/libvcx/src/v3/mod.rs b/vcx/libvcx/src/v3/mod.rs index 1fcf96add1..0ee8195526 100644 --- a/vcx/libvcx/src/v3/mod.rs +++ b/vcx/libvcx/src/v3/mod.rs @@ -9,13 +9,12 @@ pub const SERIALIZE_VERSION: &'static str = "2.0"; pub mod test { use rand; use rand::Rng; - use utils::devsetup::config_with_wallet_handle; + use utils::devsetup::*; use messages::agent_utils::connect_register_provision; use utils::libindy::wallet::*; - use v3::messages::a2a::A2AMessage; use indy_sys::WalletHandle; use utils::plugins::init_plugin; - use messages::get_message::Message; + use messages::payload::PayloadV1; pub fn source_id() -> String { String::from("test source id") @@ -105,13 +104,27 @@ pub mod test { } } - fn download_message(did: String) -> ::messages::get_message::Message { + #[derive(Debug)] + pub struct Message { + uid: String, + message: String, + } + + fn download_message(did: String, type_: &str) -> Message { let mut messages = ::messages::get_message::download_messages(Some(vec![did]), Some(vec![String::from("MS-103")]), None).unwrap(); assert_eq!(1, messages.len()); - let mut messages = messages.pop().unwrap(); - assert_eq!(1, messages.msgs.len()); - let message = messages.msgs.pop().unwrap(); - message + let messages = messages.pop().unwrap(); + + for message in messages.msgs.into_iter(){ + let payload: PayloadV1 = serde_json::from_str(&message.decrypted_payload.clone().unwrap()).unwrap(); + if payload.type_.name == type_ { + return Message{ + uid: message.uid, + message: payload.msg + } + } + } + panic!("Message not found") } pub struct Faber { @@ -131,9 +144,9 @@ pub mod test { let wallet_name = "faber_wallet"; let config = json!({ - "agency_url": "http://localhost:8080", - "agency_did": "VsKV7grR1BUE29mG2Fm2kX", - "agency_verkey": "Hezce2UWMZ3wUhVkh2LfKSs8nDzWwzs2Win7EzNN3YaR", + "agency_url": AGENCY_ENDPOINT, + "agency_did": AGENCY_DID, + "agency_verkey": AGENCY_VERKEY, "wallet_name": wallet_name, "wallet_key": "123", "payment_method": "null", @@ -216,19 +229,6 @@ pub mod test { assert_eq!(expected_state, ::connection::get_state(self.connection_handle)); } - pub fn update_state_with_message(&self, expected_state: u32) -> A2AMessage { - self.activate(); - let did = ::connection::get_pw_did(self.connection_handle).unwrap(); - let message = download_message(did); - - let a2a_message = ::connection::decode_message(self.connection_handle, message.clone()).unwrap(); - - ::connection::update_state_with_message(self.connection_handle, message).unwrap(); - assert_eq!(expected_state, ::connection::get_state(self.connection_handle)); - - a2a_message - } - pub fn ping(&self) { self.activate(); ::connection::send_ping(self.connection_handle, None).unwrap(); @@ -324,9 +324,9 @@ pub mod test { let wallet_name = "alice_wallet"; let config = json!({ - "agency_url": "http://localhost:8080", - "agency_did": "VsKV7grR1BUE29mG2Fm2kX", - "agency_verkey": "Hezce2UWMZ3wUhVkh2LfKSs8nDzWwzs2Win7EzNN3YaR", + "agency_url": C_AGENCY_ENDPOINT, + "agency_did": C_AGENCY_DID, + "agency_verkey": C_AGENCY_VERKEY, "wallet_name": wallet_name, "wallet_key": "123", "payment_method": "null", @@ -368,21 +368,10 @@ pub mod test { assert_eq!(expected_state, ::connection::get_state(self.connection_handle)); } - pub fn download_message(&self) -> Message { + pub fn download_message(&self, message_type: &str) -> Message { self.activate(); let did = ::connection::get_pw_did(self.connection_handle).unwrap(); - download_message(did) - } - - pub fn update_state_with_message(&self, expected_state: u32) -> A2AMessage { - let message = self.download_message(); - - let a2a_message = ::connection::decode_message(self.connection_handle, message.clone()).unwrap(); - - ::connection::update_state_with_message(self.connection_handle, message).unwrap(); - assert_eq!(expected_state, ::connection::get_state(self.connection_handle)); - - a2a_message + download_message(did, message_type) } pub fn accept_offer(&mut self) { @@ -531,21 +520,11 @@ pub mod test { alice.send_presentation(); faber.verify_presentation(); alice.ensure_presentation_verified(); - - // Decline Presentation - faber.request_presentation(); - alice.decline_presentation_request(); - faber.update_proof_state(0, 2); - - // Propose Presentation - faber.request_presentation(); - alice.propose_presentation(); - faber.update_proof_state(0, 2); } #[cfg(feature = "aries")] #[test] - fn aries_demo_update_state_with_message_flow() { + fn aries_demo_handle_connection_related_messages() { PaymentPlugin::load(); let _pool = Pool::open(); @@ -563,18 +542,16 @@ pub mod test { let invite = faber.create_invite(); alice.accept_invite(&invite); - faber.update_state_with_message(3); - alice.update_state_with_message(4); - faber.update_state_with_message(4); + faber.update_state(3); + alice.update_state(4); + faber.update_state(4); // Ping faber.ping(); - let message = alice.update_state_with_message(4); - assert_match!(A2AMessage::Ping(_), message); + alice.update_state(4); - let message = faber.update_state_with_message(4); - assert_match!(A2AMessage::PingResponse(_), message); + faber.update_state(4); let faber_connection_info = faber.connection_info(); assert!(faber_connection_info["their"]["protocols"].as_array().is_none()); @@ -582,54 +559,12 @@ pub mod test { // Discovery Features faber.discovery_features(); - let message = alice.update_state_with_message(4); - assert_match!(A2AMessage::Query(_), message); + alice.update_state(4); - let message = faber.update_state_with_message(4); - assert_match!(A2AMessage::Disclose(_), message); + faber.update_state(4); let faber_connection_info = faber.connection_info(); assert!(faber_connection_info["their"]["protocols"].as_array().unwrap().len() > 0); - - /* - Create with message id flow - */ - - // Credential issuance - faber.offer_credential(); - - // Alice creates Credential object with message id - { - let message = alice.download_message(); - let (credential_handle, _credential_offer) = ::credential::credential_create_with_msgid("test", alice.connection_handle, &message.uid).unwrap(); - alice.credential_handle = credential_handle; - - ::credential::send_credential_request(alice.credential_handle, alice.connection_handle).unwrap(); - assert_eq!(2, ::credential::get_state(alice.credential_handle).unwrap()); - } - - faber.send_credential(); - alice.accept_credential(); - - // Credential Presentation - faber.request_presentation(); - - // Alice creates Presentation object with message id - { - let message = alice.download_message(); - let (presentation_handle, _presentation_request) = ::disclosed_proof::create_proof_with_msgid("test", alice.connection_handle, &message.uid).unwrap(); - alice.presentation_handle = presentation_handle; - - let credentials = alice.get_credentials_for_presentation(); - - ::disclosed_proof::generate_proof(alice.presentation_handle, credentials.to_string(), String::from("{}")).unwrap(); - assert_eq!(3, ::disclosed_proof::get_state(alice.presentation_handle).unwrap()); - - ::disclosed_proof::send_proof(alice.presentation_handle, alice.connection_handle).unwrap(); - assert_eq!(2, ::disclosed_proof::get_state(alice.presentation_handle).unwrap()); - } - - faber.verify_presentation(); } #[cfg(feature = "aries")] @@ -652,9 +587,9 @@ pub mod test { let invite = faber.create_invite(); alice.accept_invite(&invite); - faber.update_state_with_message(3); - alice.update_state_with_message(4); - faber.update_state_with_message(4); + faber.update_state(3); + alice.update_state(4); + faber.update_state(4); /* Create with message id flow @@ -665,7 +600,7 @@ pub mod test { // Alice creates Credential object with message id { - let message = alice.download_message(); + let message = alice.download_message("credential-offer"); let (credential_handle, _credential_offer) = ::credential::credential_create_with_msgid("test", alice.connection_handle, &message.uid).unwrap(); alice.credential_handle = credential_handle; @@ -681,7 +616,7 @@ pub mod test { // Alice creates Presentation object with message id { - let message = alice.download_message(); + let message = alice.download_message("presentation-request"); let (presentation_handle, _presentation_request) = ::disclosed_proof::create_proof_with_msgid("test", alice.connection_handle, &message.uid).unwrap(); alice.presentation_handle = presentation_handle; @@ -717,9 +652,9 @@ pub mod test { let invite = faber.create_invite(); alice.accept_invite(&invite); - faber.update_state_with_message(3); - alice.update_state_with_message(4); - faber.update_state_with_message(4); + faber.update_state(3); + alice.update_state(4); + faber.update_state(4); /* Create with message flow @@ -730,12 +665,9 @@ pub mod test { // Alice creates Credential object with Offer { - let message = alice.download_message(); + let message = alice.download_message("credential-offer"); - let msg: serde_json::Value = ::serde_json::from_str(&message.decrypted_payload.unwrap()).unwrap(); - let offer = msg["@msg"].as_str().unwrap(); - - alice.credential_handle = ::credential::credential_create_with_offer("test", &offer).unwrap(); + alice.credential_handle = ::credential::credential_create_with_offer("test", &message.message).unwrap(); ::connection::update_message_status(alice.connection_handle, message.uid).unwrap(); @@ -751,12 +683,9 @@ pub mod test { // Alice creates Presentation object with Proof Request { - let message = alice.download_message(); - - let msg: serde_json::Value = ::serde_json::from_str(&message.decrypted_payload.unwrap()).unwrap(); - let request = msg["@msg"].as_str().unwrap(); + let message = alice.download_message("presentation-request"); - alice.presentation_handle = ::disclosed_proof::create_proof("test", &request).unwrap(); + alice.presentation_handle = ::disclosed_proof::create_proof("test", &message.message).unwrap(); ::connection::update_message_status(alice.connection_handle, message.uid).unwrap(); diff --git a/vcx/libvcx/src/v3/utils/mod.rs b/vcx/libvcx/src/v3/utils/mod.rs index c7b41d1a41..834c22cadd 100644 --- a/vcx/libvcx/src/v3/utils/mod.rs +++ b/vcx/libvcx/src/v3/utils/mod.rs @@ -1,2 +1 @@ -pub mod encryption_envelope; -pub mod pending_message; \ No newline at end of file +pub mod encryption_envelope; \ No newline at end of file diff --git a/vcx/libvcx/src/v3/utils/pending_message.rs b/vcx/libvcx/src/v3/utils/pending_message.rs deleted file mode 100644 index 8ab550a9c2..0000000000 --- a/vcx/libvcx/src/v3/utils/pending_message.rs +++ /dev/null @@ -1,22 +0,0 @@ -use utils::libindy::wallet; -use error::VcxResult; - -pub struct PendingMessage; - -impl PendingMessage { - const TYPE: &'static str = "PENDING_MESSAGE"; - - pub fn add(id: &str, message: &str) -> VcxResult<()> { - wallet::add_record(Self::TYPE, id, &message, None) - } - - pub fn get(id: &str) -> Option { - match wallet::get_record(Self::TYPE, id, "{}") { - Ok(record) => { - let record: serde_json::Value = serde_json::from_str(&record).ok()?; - record["value"].as_str().map(String::from) - } - _ => None - } - } -} \ No newline at end of file diff --git a/vcx/wrappers/ios/vcx/ConnectMeVcx.h b/vcx/wrappers/ios/vcx/ConnectMeVcx.h index 31e4c718b9..7a3799cd44 100644 --- a/vcx/wrappers/ios/vcx/ConnectMeVcx.h +++ b/vcx/wrappers/ios/vcx/ConnectMeVcx.h @@ -89,12 +89,20 @@ extern void VcxWrapperCommonNumberStringCallback(vcx_command_handle_t xcommand_h connectionType:(NSString *)connectionType completion:(void (^)(NSError *error, NSString *inviteDetails))completion; +- (void)connectionGetState:(NSInteger)connectionHandle + completion:(void (^)(NSError *error, NSInteger state))completion; + +- (void)connectionUpdateState:(NSInteger) connectionHandle + completion:(void (^)(NSError *error, NSInteger state))completion; + - (void)connectionSerialize:(NSInteger)connectionHandle completion:(void (^)(NSError *error, NSString *serializedConnection))completion; - (void)connectionDeserialize:(NSString *)serializedConnection completion:(void (^)(NSError *error, NSInteger connectionHandle))completion; +- (int)connectionRelease:(NSInteger) connectionHandle; + - (void)deleteConnection:(VcxHandle)connectionHandle withCompletion:(void (^)(NSError *error))completion; @@ -147,6 +155,8 @@ extern void VcxWrapperCommonNumberStringCallback(vcx_command_handle_t xcommand_h - (void)credentialDeserialize:(NSString *)serializedCredential completion:(void (^)(NSError *error, NSInteger credentialHandle))completion; +- (int)credentialRelease:(NSInteger) credentialHandle; + - (void)exportWallet:(NSString *)exportPath encryptWith:(NSString *)encryptionKey completion:(void (^)(NSError *error, NSInteger exportHandle))completion; @@ -172,6 +182,9 @@ extern void VcxWrapperCommonNumberStringCallback(vcx_command_handle_t xcommand_h recordId:(NSString *)recordId completion:(void (^)(NSError *error))completion; +- (void) proofGetRequests:(NSInteger)connectionHandle + completion:(void (^)(NSError *error, NSString *requests))completion; + - (void) proofRetrieveCredentials:(vcx_proof_handle_t)proofHandle withCompletion:(void (^)(NSError *error, NSString *matchingCredentials))completion; @@ -189,6 +202,12 @@ withSelectedCredentials:(NSString *)selectedCredentials withConnectionHandle:(vcx_connection_handle_t)connection_handle withCompletion:(void (^)(NSError *error))completion; +- (void)proofGetState:(NSInteger)proofHandle + completion:(void (^)(NSError *error, NSInteger state))completion; + +- (void)proofUpdateState:(NSInteger) proofHandle + completion:(void (^)(NSError *error, NSInteger state))completion; + - (void) proofReject: (vcx_proof_handle_t)proof_handle withConnectionHandle:(vcx_connection_handle_t)connection_handle withCompletion: (void (^)(NSError *error))completion; @@ -216,6 +235,8 @@ withConnectionHandle:(vcx_connection_handle_t)connection_handle - (void) proofDeserialize:(NSString *) serializedProof withCompletion:(void (^)(NSError *error, vcx_proof_handle_t proofHandle)) completion; +- (int)proofRelease:(NSInteger) proofHandle; + - (int)vcxShutdown:(BOOL *)deleteWallet; - (void)createPaymentAddress:(NSString *)seed diff --git a/vcx/wrappers/ios/vcx/ConnectMeVcx.m b/vcx/wrappers/ios/vcx/ConnectMeVcx.m index 21a86016c6..80f3d9bd5c 100644 --- a/vcx/wrappers/ios/vcx/ConnectMeVcx.m +++ b/vcx/wrappers/ios/vcx/ConnectMeVcx.m @@ -386,6 +386,36 @@ - (void)connectionConnect: (NSInteger) connectionHandle } } +- (void)connectionGetState:(NSInteger)connectionHandle + completion:(void (^)(NSError *error, NSInteger state))completion { + vcx_error_t ret; + vcx_command_handle_t handle = [[VcxCallbacks sharedInstance] createCommandHandleFor:completion]; + ret = vcx_connection_get_state(handle, connectionHandle, VcxWrapperCommonNumberCallback); + + if( ret != 0 ) + { + [[VcxCallbacks sharedInstance] deleteCommandHandleFor: handle]; + + dispatch_async(dispatch_get_main_queue(), ^{ + completion([NSError errorFromVcxError: ret], 0); + }); + } +} + +- (void)connectionUpdateState:(NSInteger) connectionHandle + completion:(void (^)(NSError *error, NSInteger state))completion { + vcx_error_t ret; + vcx_command_handle_t handle = [[VcxCallbacks sharedInstance] createCommandHandleFor:completion]; + ret = vcx_connection_update_state(handle, connectionHandle, VcxWrapperCommonNumberCallback); + if( ret != 0 ) + { + [[VcxCallbacks sharedInstance] deleteCommandHandleFor: handle]; + dispatch_async(dispatch_get_main_queue(), ^{ + completion([NSError errorFromVcxError: ret], 0); + }); + } +} + - (void)connectionSerialize:(NSInteger)connectionHandle completion:(void (^)(NSError *error, NSString *serializedConnection))completion{ vcx_error_t ret; @@ -420,6 +450,10 @@ - (void)connectionDeserialize:(NSString *)serializedConnection } } +- (int)connectionRelease:(NSInteger) connectionHandle { + return vcx_connection_release(connectionHandle); +} + - (void)deleteConnection:(VcxHandle)connectionHandle withCompletion:(void (^)(NSError *error))completion { @@ -704,6 +738,10 @@ - (void)credentialDeserialize:(NSString *)serializedCredential } } +- (int)credentialRelease:(NSInteger) credentialHandle { + return vcx_credential_release(credentialHandle); +} + - (void)exportWallet:(NSString *)exportPath encryptWith:(NSString *)encryptionKey completion:(void (^)(NSError *error, NSInteger exportHandle))completion { @@ -828,6 +866,23 @@ - (void)updateRecordWallet:(NSString *)recordType } } +- (void)proofGetRequests:(NSInteger)connectionHandle + completion:(void (^)(NSError *error, NSString *requests))completion{ + vcx_error_t ret; + vcx_command_handle_t handle = [[VcxCallbacks sharedInstance] createCommandHandleFor:completion]; + + ret = vcx_disclosed_proof_get_requests(handle,connectionHandle, VcxWrapperCommonStringCallback); + + if( ret != 0 ) + { + [[VcxCallbacks sharedInstance] deleteCommandHandleFor: handle]; + + dispatch_async(dispatch_get_main_queue(), ^{ + completion([NSError errorFromVcxError: ret],nil); + }); + } +} + - (void) proofCreateWithMsgId:(NSString *)sourceId withConnectionHandle:(vcx_connection_handle_t)connectionHandle withMsgId:(NSString *)msgId @@ -905,6 +960,36 @@ - (void) proofSend:(vcx_proof_handle_t)proof_handle } } +- (void)proofGetState:(NSInteger)proofHandle + completion:(void (^)(NSError *error, NSInteger state))completion { + vcx_error_t ret; + vcx_command_handle_t handle = [[VcxCallbacks sharedInstance] createCommandHandleFor:completion]; + ret = vcx_disclosed_proof_get_state(handle, proofHandle, VcxWrapperCommonNumberCallback); + + if( ret != 0 ) + { + [[VcxCallbacks sharedInstance] deleteCommandHandleFor: handle]; + + dispatch_async(dispatch_get_main_queue(), ^{ + completion([NSError errorFromVcxError: ret], 0); + }); + } +} + +- (void)proofUpdateState:(NSInteger) proofHandle + completion:(void (^)(NSError *error, NSInteger state))completion { + vcx_error_t ret; + vcx_command_handle_t handle = [[VcxCallbacks sharedInstance] createCommandHandleFor:completion]; + ret = vcx_disclosed_proof_update_state(handle, proofHandle, VcxWrapperCommonNumberCallback); + if( ret != 0 ) + { + [[VcxCallbacks sharedInstance] deleteCommandHandleFor: handle]; + dispatch_async(dispatch_get_main_queue(), ^{ + completion([NSError errorFromVcxError: ret], 0); + }); + } +} + - (void) proofReject: (vcx_proof_handle_t)proof_handle withConnectionHandle:(vcx_connection_handle_t)connection_handle withCompletion: (void (^)(NSError *error))completion { vcx_error_t ret; @@ -1045,6 +1130,9 @@ - (void) proofDeserialize:(NSString *) serializedProof } } +- (int)proofRelease:(NSInteger) proofHandle { + return vcx_disclosed_proof_release(proofHandle); +} - (void)createPaymentAddress:(NSString *)seed withCompletion:(void (^)(NSError *error, NSString *address))completion { diff --git a/vcx/wrappers/ios/vcx/include/libvcx.h b/vcx/wrappers/ios/vcx/include/libvcx.h index d98dda1777..aec6ec1f56 100644 --- a/vcx/wrappers/ios/vcx/include/libvcx.h +++ b/vcx/wrappers/ios/vcx/include/libvcx.h @@ -294,7 +294,7 @@ vcx_error_t vcx_connection_get_redirect_details(vcx_command_handle_t command_han vcx_error_t vcx_disclosed_proof_update_state(vcx_command_handle_t command_handle, vcx_proof_handle_t proof_handle, void (*cb)(vcx_command_handle_t xcommand_handle, vcx_error_t err, vcx_state_t state)); /** Check for any proof requests from the connection. */ -vcx_error_t vcx_disclosed_proof_get_requests(vcx_command_handle_t command_handle, vcx_connection_handle_t connection_handle, void (*cb)(vcx_command_handle_t xcommand_handle, vcx_error_t err, const char *offers)); +vcx_error_t vcx_disclosed_proof_get_requests(vcx_command_handle_t command_handle, vcx_connection_handle_t connection_handle, void (*cb)(vcx_command_handle_t xcommand_handle, vcx_error_t err, const char *requests)); /** Retrieves the state of the disclosed_proof. */ vcx_error_t vcx_disclosed_proof_get_state(vcx_command_handle_t command_handle, vcx_proof_handle_t proof_handle, void (*cb)(vcx_command_handle_t xcommand_handle, vcx_error_t err, vcx_state_t state)); diff --git a/vcx/wrappers/python3/demo/alice_create_with_message_flow.py b/vcx/wrappers/python3/demo/alice_create_with_message_flow.py new file mode 100644 index 0000000000..b7053ad822 --- /dev/null +++ b/vcx/wrappers/python3/demo/alice_create_with_message_flow.py @@ -0,0 +1,49 @@ +import asyncio +import json + +from alice import init, connect, accept_offer, create_proof +from demo_utils import download_message, update_message_as_read + +from vcx import logging +from vcx.api.credential import Credential +from vcx.api.disclosed_proof import DisclosedProof + + + +async def main(): + await init() + connection_to_faber = None + while True: + answer = input( + "Would you like to do? \n " + "0 - establish connection \n " + "1 - check for credential offer \n " + "2 - check for proof request \n " + "else finish \n") \ + .lower().strip() + if answer == '0': + connection_to_faber = await connect() + elif answer == '1': + print("Check agency for a credential offer") + pw_did = await connection_to_faber.get_my_pw_did() + uid, offer, _ = await download_message(pw_did, 'credential-offer') + credential = await Credential.create('credential', json.loads(offer)) + await accept_offer(connection_to_faber, credential) + await update_message_as_read(pw_did, uid) + elif answer == '2': + print("Check agency for a proof request") + pw_did = await connection_to_faber.get_my_pw_did() + uid, request, _ = await download_message(pw_did, 'presentation-request') + print("#23 Create a Disclosed proof object from proof request") + proof = await DisclosedProof.create('proof', json.loads(request)) + await create_proof(connection_to_faber, proof) + await update_message_as_read(pw_did, uid) + else: + pass + # break + print("Finished") + + +if __name__ == '__main__': + loop = asyncio.get_event_loop() + loop.run_until_complete(main()) diff --git a/vcx/wrappers/python3/demo/alice_create_with_message_id_flow.py b/vcx/wrappers/python3/demo/alice_create_with_message_id_flow.py new file mode 100644 index 0000000000..e62a32a7ca --- /dev/null +++ b/vcx/wrappers/python3/demo/alice_create_with_message_id_flow.py @@ -0,0 +1,50 @@ +import asyncio + +from alice import connect, accept_offer, create_proof, init +from demo_utils import download_message + +from vcx.api.credential import Credential +from vcx.api.disclosed_proof import DisclosedProof + + +# logging.basicConfig(level=0) + +async def main(): + await init() + connection_to_faber = None + while True: + answer = input( + "Would you like to do? \n " + "0 - establish connection \n " + "1 - check for credential offer \n " + "2 - check for proof request \n " + "else finish \n") \ + .lower().strip() + if answer == '0': + connection_to_faber = await connect() + elif answer == '1': + print("Check agency for a credential offer") + pw_did = await connection_to_faber.get_my_pw_did() + uid, offer, _ = await download_message(pw_did, 'credential-offer') + print(uid) + credential = await Credential.create_with_msgid('credential', connection_to_faber, uid) + print("Offer") + print(credential.cred_offer) + await accept_offer(connection_to_faber, credential) + elif answer == '2': + print("Check agency for a proof request") + pw_did = await connection_to_faber.get_my_pw_did() + uid, request, _ = await download_message(pw_did, 'presentation-request') + print("#23 Create a Disclosed proof object from proof request") + proof = await DisclosedProof.create_with_msgid('proof', connection_to_faber, uid) + await create_proof(connection_to_faber, proof) + else: + pass + # break + print(answer) + print("Finished") + + +if __name__ == '__main__': + loop = asyncio.get_event_loop() + loop.run_until_complete(main()) diff --git a/vcx/wrappers/python3/demo/demo_utils.py b/vcx/wrappers/python3/demo/demo_utils.py index 25894d414c..11642ad5d2 100644 --- a/vcx/wrappers/python3/demo/demo_utils.py +++ b/vcx/wrappers/python3/demo/demo_utils.py @@ -268,6 +268,23 @@ async def create_postgres_wallet(provisionConfig): print("Postgres wallet provisioned") +async def download_message(pw_did: str, msg_type: str): + messages = await vcx_messages_download("MS-103", None, pw_did) + messages = json.loads(messages.decode())[0]['msgs'] + print(messages) + message = [message for message in messages if json.loads(message["decryptedPayload"])["@type"]["name"] == msg_type][0] + decryptedPayload = message["decryptedPayload"] + return message["uid"], json.loads(decryptedPayload)["@msg"], json.dumps(message) + + +async def update_message_as_read(pw_did: str, uid: str): + messages_to_update = [{ + "pairwiseDID": pw_did, + "uids": [uid] + }] + await vcx_messages_update_status(json.dumps(messages_to_update)) + + def load_payment_library(): payment_plugin = cdll.LoadLibrary('libnullpay' + file_ext()) payment_plugin.nullpay_init()