diff --git a/Cargo.lock b/Cargo.lock index dc7349f3fd..92d5eb8d19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2760,6 +2760,7 @@ dependencies = [ "log", "num-traits", "once_cell", + "public_key", "rand 0.8.5", "serde", "serde_derive", diff --git a/aries/agents/rust/mediator/src/aries_agent/client/mod.rs b/aries/agents/rust/mediator/src/aries_agent/client/mod.rs index 5a19a21108..d55e98322d 100644 --- a/aries/agents/rust/mediator/src/aries_agent/client/mod.rs +++ b/aries/agents/rust/mediator/src/aries_agent/client/mod.rs @@ -39,7 +39,7 @@ impl Agent { oob_invite: OOBInvitation, ) -> Result<(InviteeConnection, EncryptionEnvelope), String> { // Generate keys - let (pw_did, pw_vk) = self + let did_data = self .wallet .create_and_store_my_did(None, None) .await @@ -48,7 +48,10 @@ impl Agent { let mock_ledger = MockLedger {}; // not good. to be dealt later let client_conn = InviteeConnection::::new_invitee( "foo".into(), - PairwiseInfo { pw_did, pw_vk }, + PairwiseInfo { + pw_did: did_data.did().into(), + pw_vk: did_data.verkey().base58(), + }, ) .accept_invitation(&mock_ledger, AnyInvitation::Oob(oob_invite.clone())) .await diff --git a/aries/agents/rust/mediator/src/aries_agent/mod.rs b/aries/agents/rust/mediator/src/aries_agent/mod.rs index d4b0dd58f7..72fcded050 100644 --- a/aries/agents/rust/mediator/src/aries_agent/mod.rs +++ b/aries/agents/rust/mediator/src/aries_agent/mod.rs @@ -92,12 +92,12 @@ impl Agent { routing_keys: Vec, service_endpoint: url::Url, ) -> Result<(), AriesVcxCoreError> { - let (_, vk) = self.wallet.create_and_store_my_did(None, None).await?; + let did_data = self.wallet.create_and_store_my_did(None, None).await?; let service = AriesService { id: "#inline".to_owned(), type_: "did-communication".to_owned(), priority: 0, - recipient_keys: vec![vk], + recipient_keys: vec![did_data.verkey().base58()], routing_keys, service_endpoint, }; @@ -170,7 +170,7 @@ impl Agent { .thread .map(|t| t.thid) .unwrap_or(request.id); - let (did, vk) = self + let did_data = self .wallet .create_and_store_my_did(None, None) .await @@ -188,8 +188,8 @@ impl Agent { self.wallet.as_ref(), thread_id, old_vk.clone(), - did, - vk.clone(), + did_data.did().into(), + did_data.verkey().base58(), self.service.as_ref().unwrap().service_endpoint.clone(), self.service.as_ref().unwrap().routing_keys.clone(), ) @@ -209,7 +209,8 @@ impl Agent { let auth_pubkey = their_keys .first() .ok_or("No recipient key for client :/ ?".to_owned())?; - self.create_account(auth_pubkey, &vk, &their_diddoc).await?; + self.create_account(auth_pubkey, &did_data.verkey().base58(), &their_diddoc) + .await?; Ok(packed_response_envelope) } diff --git a/aries/agents/rust/mediator/src/didcomm_handlers/connection.rs b/aries/agents/rust/mediator/src/didcomm_handlers/connection.rs index d58e8e40e1..0bdee9ec62 100644 --- a/aries/agents/rust/mediator/src/didcomm_handlers/connection.rs +++ b/aries/agents/rust/mediator/src/didcomm_handlers/connection.rs @@ -1,3 +1,4 @@ +use aries_vcx_core::wallet::base_wallet::BaseWallet; use messages::msg_fields::protocols::connection::Connection; use super::{unhandled_aries_message, utils::prelude::*, ArcAgent}; diff --git a/aries/agents/rust/mediator/src/didcomm_handlers/forward.rs b/aries/agents/rust/mediator/src/didcomm_handlers/forward.rs index 3a8b308a4c..2cd4074813 100644 --- a/aries/agents/rust/mediator/src/didcomm_handlers/forward.rs +++ b/aries/agents/rust/mediator/src/didcomm_handlers/forward.rs @@ -1,3 +1,4 @@ +use aries_vcx_core::wallet::base_wallet::BaseWallet; use messages::msg_fields::protocols::{notification::ack::Ack, routing::Forward}; use super::{utils::prelude::*, ArcAgent}; diff --git a/aries/agents/rust/mediator/src/didcomm_handlers/mediator_coord.rs b/aries/agents/rust/mediator/src/didcomm_handlers/mediator_coord.rs index 55812e559d..713bb3f0a7 100644 --- a/aries/agents/rust/mediator/src/didcomm_handlers/mediator_coord.rs +++ b/aries/agents/rust/mediator/src/didcomm_handlers/mediator_coord.rs @@ -1,3 +1,4 @@ +use aries_vcx_core::wallet::base_wallet::BaseWallet; use messages::msg_fields::protocols::coordinate_mediation::{ CoordinateMediation, MediateGrant, MediateGrantContent, MediateGrantDecorators, }; diff --git a/aries/agents/rust/mediator/src/didcomm_handlers/mod.rs b/aries/agents/rust/mediator/src/didcomm_handlers/mod.rs index 6e6092e7ce..f58a6259a4 100644 --- a/aries/agents/rust/mediator/src/didcomm_handlers/mod.rs +++ b/aries/agents/rust/mediator/src/didcomm_handlers/mod.rs @@ -1,5 +1,6 @@ use std::fmt::Debug; +use aries_vcx_core::wallet::base_wallet::BaseWallet; use axum::{body::Bytes, extract::State, Json}; use messages::AriesMessage; use serde::{Deserialize, Serialize}; diff --git a/aries/agents/rust/mediator/src/didcomm_handlers/pickup.rs b/aries/agents/rust/mediator/src/didcomm_handlers/pickup.rs index 85e683faeb..7bb2571041 100644 --- a/aries/agents/rust/mediator/src/didcomm_handlers/pickup.rs +++ b/aries/agents/rust/mediator/src/didcomm_handlers/pickup.rs @@ -1,3 +1,4 @@ +use aries_vcx_core::wallet::base_wallet::BaseWallet; use messages::msg_fields::protocols::pickup::Pickup; use super::utils::prelude::*; diff --git a/aries/agents/rust/mediator/tests/mediator-coord-protocol.rs b/aries/agents/rust/mediator/tests/mediator-coord-protocol.rs index 062b36df37..2681477a96 100644 --- a/aries/agents/rust/mediator/tests/mediator-coord-protocol.rs +++ b/aries/agents/rust/mediator/tests/mediator-coord-protocol.rs @@ -1,6 +1,6 @@ mod common; -use aries_vcx_core::wallet::base_wallet::BaseWallet; +use aries_vcx_core::wallet::base_wallet::DidWallet; use messages::{ msg_fields::protocols::coordinate_mediation::{ keylist_update::{KeylistUpdateItem, KeylistUpdateItemAction}, @@ -69,14 +69,14 @@ async fn test_mediate_keylist_update_add() -> Result<()> { let (agent, mut aries_transport, our_verkey, their_diddoc) = gen_mediator_connected_agent().await?; // prepare request message - let (_, new_vk) = agent + let did_data = agent .get_wallet_ref() .create_and_store_my_did(None, None) .await?; let keylist_update_request = KeylistUpdate::builder() .content(KeylistUpdateContent { updates: vec![KeylistUpdateItem { - recipient_key: new_vk, + recipient_key: did_data.verkey().base58(), action: KeylistUpdateItemAction::Add, }], }) @@ -120,14 +120,14 @@ async fn test_mediate_keylist_query() -> Result<()> { let (agent, mut aries_transport, our_verkey, their_diddoc) = gen_mediator_connected_agent().await?; // prepare request message: add key - let (_, new_vk) = agent + let did_data = agent .get_wallet_ref() .create_and_store_my_did(None, None) .await?; let keylist_update_request = KeylistUpdate::builder() .content(KeylistUpdateContent { updates: vec![KeylistUpdateItem { - recipient_key: new_vk, + recipient_key: did_data.verkey().base58(), action: KeylistUpdateItemAction::Add, }], }) @@ -188,14 +188,14 @@ async fn test_mediate_keylist_update_remove() -> Result<()> { let (agent, mut aries_transport, our_verkey, their_diddoc) = gen_mediator_connected_agent().await?; // prepare request message: add key - let (_, new_vk) = agent + let did_data = agent .get_wallet_ref() .create_and_store_my_did(None, None) .await?; let keylist_update_request = KeylistUpdate::builder() .content(KeylistUpdateContent { updates: vec![KeylistUpdateItem { - recipient_key: new_vk.clone(), + recipient_key: did_data.verkey().base58(), action: KeylistUpdateItemAction::Add, }], }) @@ -220,7 +220,7 @@ async fn test_mediate_keylist_update_remove() -> Result<()> { let keylist_update_request = KeylistUpdate::builder() .content(KeylistUpdateContent { updates: vec![KeylistUpdateItem { - recipient_key: new_vk, + recipient_key: did_data.verkey().base58(), action: KeylistUpdateItemAction::Remove, }], }) diff --git a/aries/aries_vcx/src/common/keys.rs b/aries/aries_vcx/src/common/keys.rs index a97cf8befa..fa58b779a0 100644 --- a/aries/aries_vcx/src/common/keys.rs +++ b/aries/aries_vcx/src/common/keys.rs @@ -42,10 +42,7 @@ pub async fn rotate_verkey_apply( )); } - wallet - .replace_did_keys_apply(did) - .await - .map_err(|err| err.into()) + Ok(wallet.replace_did_key_apply(did).await?) } pub async fn rotate_verkey( @@ -53,8 +50,8 @@ pub async fn rotate_verkey( indy_ledger_write: &impl IndyLedgerWrite, did: &str, ) -> VcxResult<()> { - let trustee_temp_verkey = wallet.replace_did_keys_start(did).await?; - rotate_verkey_apply(wallet, indy_ledger_write, did, &trustee_temp_verkey).await + let trustee_verkey = wallet.replace_did_key_start(did, None).await?; + rotate_verkey_apply(wallet, indy_ledger_write, did, &trustee_verkey.base58()).await } pub async fn get_verkey_from_ledger( diff --git a/aries/aries_vcx/src/common/ledger/transactions.rs b/aries/aries_vcx/src/common/ledger/transactions.rs index 0d3271a912..2d1dcf247d 100644 --- a/aries/aries_vcx/src/common/ledger/transactions.rs +++ b/aries/aries_vcx/src/common/ledger/transactions.rs @@ -83,14 +83,21 @@ pub async fn add_new_did( submitter_did: &str, role: Option<&str>, ) -> VcxResult<(String, String)> { - let (did, verkey) = wallet.create_and_store_my_did(None, None).await?; + let did_data = wallet.create_and_store_my_did(None, None).await?; let res = indy_ledger_write - .publish_nym(wallet, submitter_did, &did, Some(&verkey), None, role) + .publish_nym( + wallet, + submitter_did, + did_data.did(), + Some(&did_data.verkey().base58()), + None, + role, + ) .await?; check_response(&res)?; - Ok((did, verkey)) + Ok((did_data.did().into(), did_data.verkey().base58())) } pub async fn get_service(ledger: &impl IndyLedgerRead, did: &String) -> VcxResult { diff --git a/aries/aries_vcx/src/common/signing.rs b/aries/aries_vcx/src/common/signing.rs index acca48c4c9..3ce8a053f5 100644 --- a/aries/aries_vcx/src/common/signing.rs +++ b/aries/aries_vcx/src/common/signing.rs @@ -4,6 +4,7 @@ use messages::msg_fields::protocols::connection::{ response::{ConnectionSignature, ResponseContent}, ConnectionData, }; +use public_key::{Key, KeyType}; use time; use crate::{errors::error::prelude::*, utils::base64::URL_SAFE_LENIENT}; @@ -27,7 +28,9 @@ async fn get_signature_data( let mut sig_data = now.to_be_bytes().to_vec(); sig_data.extend(data.as_bytes()); - let signature = wallet.sign(key, &sig_data).await?; + let signature = wallet + .sign(&Key::from_base58(key, KeyType::Ed25519)?, &sig_data) + .await?; Ok((signature, sig_data)) } @@ -64,7 +67,14 @@ pub async fn decode_signed_connection_response( let sig_data = base64url_decode(&response.connection_sig.sig_data)?; - if !wallet.verify(their_vk, &sig_data, &signature).await? { + if !wallet + .verify( + &Key::from_base58(their_vk, KeyType::Ed25519)?, + &sig_data, + &signature, + ) + .await? + { return Err(AriesVcxError::from_msg( AriesVcxErrorKind::InvalidJson, "ConnectionResponse signature is invalid for original Invite recipient key", diff --git a/aries/aries_vcx/src/protocols/connection/pairwise_info.rs b/aries/aries_vcx/src/protocols/connection/pairwise_info.rs index 40b1fc0791..8c2b8e92fb 100644 --- a/aries/aries_vcx/src/protocols/connection/pairwise_info.rs +++ b/aries/aries_vcx/src/protocols/connection/pairwise_info.rs @@ -10,7 +10,10 @@ pub struct PairwiseInfo { impl PairwiseInfo { pub async fn create(wallet: &impl BaseWallet) -> VcxResult { - let (pw_did, pw_vk) = wallet.create_and_store_my_did(None, None).await?; - Ok(PairwiseInfo { pw_did, pw_vk }) + let did_data = wallet.create_and_store_my_did(None, None).await?; + Ok(PairwiseInfo { + pw_did: did_data.did().into(), + pw_vk: did_data.verkey().base58(), + }) } } diff --git a/aries/aries_vcx/src/protocols/did_exchange/state_machine/helpers.rs b/aries/aries_vcx/src/protocols/did_exchange/state_machine/helpers.rs index 97ffe3f21f..1cefcb1f8d 100644 --- a/aries/aries_vcx/src/protocols/did_exchange/state_machine/helpers.rs +++ b/aries/aries_vcx/src/protocols/did_exchange/state_machine/helpers.rs @@ -150,7 +150,7 @@ pub async fn jws_sign_attach( let b64_protected = base64::engine::Engine::encode(&URL_SAFE_NO_PAD, protected_header.to_string()); let sign_input = format!("{}.{}", b64_protected, attach_base64).into_bytes(); - let signed = wallet.sign(&verkey.base58(), &sign_input).await?; + let signed = wallet.sign(&verkey, &sign_input).await?; let signature_base64 = base64::engine::Engine::encode(&URL_SAFE_NO_PAD, signed); let jws = { diff --git a/aries/aries_vcx/src/utils/encryption_envelope.rs b/aries/aries_vcx/src/utils/encryption_envelope.rs index 751b63fb08..8c3eae98e0 100644 --- a/aries/aries_vcx/src/utils/encryption_envelope.rs +++ b/aries/aries_vcx/src/utils/encryption_envelope.rs @@ -5,6 +5,7 @@ use messages::{ msg_fields::protocols::routing::{Forward, ForwardContent}, AriesMessage, }; +use public_key::{Key, KeyType}; use uuid::Uuid; use crate::errors::error::prelude::*; @@ -70,9 +71,17 @@ impl EncryptionEnvelope { "Encrypting for pairwise; sender_vk: {:?}, recipient_key: {}", sender_vk, recipient_key ); - let recipient_keys = json!([recipient_key.clone()]).to_string(); + + let recipient_keys = vec![Key::from_base58(&recipient_key, KeyType::Ed25519)?]; + wallet - .pack_message(sender_vk, &recipient_keys, data) + .pack_message( + sender_vk + .map(|key| Key::from_base58(key, KeyType::Ed25519)) + .transpose()?, + recipient_keys, + data, + ) .await .map_err(|err| err.into()) } @@ -115,10 +124,14 @@ impl EncryptionEnvelope { .build(); let message = json!(AriesMessage::from(message)).to_string(); - let receiver_keys = json!(vec![routing_key]).to_string(); + + let receiver_keys = vec![routing_key] + .into_iter() + .map(|item| Key::from_base58(item, KeyType::Ed25519)) + .collect::>()?; wallet - .pack_message(None, &receiver_keys, message.as_bytes()) + .pack_message(None, receiver_keys, message.as_bytes()) .await .map_err(|err| err.into()) } @@ -246,11 +259,12 @@ pub mod unit_tests { use test_utils::devsetup::build_setup_profile; use super::*; + use crate::aries_vcx_core::wallet::base_wallet::DidWallet; #[tokio::test] async fn test_pack_unpack_anon() { let setup = build_setup_profile().await; - let (_, recipient_key) = setup + let did_data = setup .wallet .create_and_store_my_did(None, None) .await @@ -262,7 +276,7 @@ pub mod unit_tests { &setup.wallet, data_original.as_bytes(), None, - recipient_key, + did_data.verkey().base58(), [].to_vec(), ) .await @@ -280,12 +294,12 @@ pub mod unit_tests { #[tokio::test] async fn test_pack_unpack_auth() { let setup = build_setup_profile().await; - let (_, sender_key) = setup + let sender_data = setup .wallet .create_and_store_my_did(None, None) .await .unwrap(); - let (_, recipient_key) = setup + let recipient_data = setup .wallet .create_and_store_my_did(None, None) .await @@ -296,16 +310,20 @@ pub mod unit_tests { let envelope = EncryptionEnvelope::create2( &setup.wallet, data_original.as_bytes(), - Some(&sender_key), - recipient_key, + Some(&sender_data.verkey().base58()), + recipient_data.verkey().base58(), [].to_vec(), ) .await .unwrap(); - let data_unpacked = EncryptionEnvelope::auth_unpack(&setup.wallet, envelope.0, &sender_key) - .await - .unwrap(); + let data_unpacked = EncryptionEnvelope::auth_unpack( + &setup.wallet, + envelope.0, + &sender_data.verkey().base58(), + ) + .await + .unwrap(); assert_eq!(data_original, data_unpacked); } @@ -313,17 +331,17 @@ pub mod unit_tests { #[tokio::test] async fn test_pack_unpack_with_routing() { let setup = build_setup_profile().await; - let (_, sender_key) = setup + let sender_data = setup .wallet .create_and_store_my_did(None, None) .await .unwrap(); - let (_, recipient_key) = setup + let recipient_data = setup .wallet .create_and_store_my_did(None, None) .await .unwrap(); - let (_, routing_key1) = setup + let routing_data = setup .wallet .create_and_store_my_did(None, None) .await @@ -334,9 +352,9 @@ pub mod unit_tests { let envelope = EncryptionEnvelope::create2( &setup.wallet, data_original.as_bytes(), - Some(&sender_key), - recipient_key, - [routing_key1].to_vec(), + Some(&sender_data.verkey().base58()), + recipient_data.verkey().base58(), + [routing_data.verkey().base58()].to_vec(), ) .await .unwrap(); @@ -359,17 +377,17 @@ pub mod unit_tests { #[tokio::test] async fn test_pack_unpack_unexpected_key_detection() { let setup = build_setup_profile().await; - let (_, sender_key_alice) = setup + let alice_data = setup .wallet .create_and_store_my_did(None, None) .await .unwrap(); - let (_, sender_key_bob) = setup + let bob_data = setup .wallet .create_and_store_my_did(None, None) .await .unwrap(); - let (_, recipient_key) = setup + let recipient_data = setup .wallet .create_and_store_my_did(None, None) .await @@ -380,15 +398,19 @@ pub mod unit_tests { let envelope = EncryptionEnvelope::create2( &setup.wallet, data_original.as_bytes(), - Some(&sender_key_bob), // bob trying to impersonate alice - recipient_key, + Some(&bob_data.verkey().base58()), // bob trying to impersonate alice + recipient_data.verkey().base58(), [].to_vec(), ) .await .unwrap(); - let err = - EncryptionEnvelope::auth_unpack(&setup.wallet, envelope.0, &sender_key_alice).await; + let err = EncryptionEnvelope::auth_unpack( + &setup.wallet, + envelope.0, + &alice_data.verkey().base58(), + ) + .await; assert!(err.is_err()); assert_eq!( err.unwrap_err().kind(), diff --git a/aries/aries_vcx/tests/test_mysql_wallet.rs b/aries/aries_vcx/tests/test_mysql_wallet.rs index ce87185976..dd0c428822 100644 --- a/aries/aries_vcx/tests/test_mysql_wallet.rs +++ b/aries/aries_vcx/tests/test_mysql_wallet.rs @@ -7,7 +7,7 @@ mod dbtests { use aries_vcx::global::settings; use aries_vcx_core::wallet::{ - base_wallet::BaseWallet, + base_wallet::DidWallet, indy::{ wallet::{close_wallet, create_and_open_wallet, wallet_configure_issuer}, IndySdkWallet, WalletConfig, @@ -46,7 +46,7 @@ mod dbtests { let wallet_handle = create_and_open_wallet(&config_wallet).await?; let _config_issuer = wallet_configure_issuer(wallet_handle, enterprise_seed).await?; - let (_, _) = IndySdkWallet::new(wallet_handle) + IndySdkWallet::new(wallet_handle) .create_and_store_my_did(None, None) .await?; close_wallet(wallet_handle).await?; diff --git a/aries/aries_vcx/tests/test_pool.rs b/aries/aries_vcx/tests/test_pool.rs index e20f093139..ebc14db90d 100644 --- a/aries/aries_vcx/tests/test_pool.rs +++ b/aries/aries_vcx/tests/test_pool.rs @@ -27,7 +27,7 @@ use aries_vcx_core::{ base_ledger::{AnoncredsLedgerRead, AnoncredsLedgerWrite}, indy::pool::test_utils::get_temp_file_path, }, - wallet::{base_wallet::BaseWallet, indy::wallet::get_verkey_from_wallet}, + wallet::base_wallet::{BaseWallet, DidWallet}, }; use diddoc_legacy::aries::service::AriesService; use serde_json::json; @@ -124,11 +124,11 @@ async fn test_pool_rotate_verkey() -> Result<(), Box> { .await?; rotate_verkey(&setup.wallet, &setup.ledger_write, &did).await?; tokio::time::sleep(Duration::from_millis(1000)).await; - let local_verkey = setup.wallet.key_for_local_did(&did).await?; + let local_verkey = setup.wallet.key_for_did(&did).await?; let ledger_verkey = get_verkey_from_ledger(&setup.ledger_read, &did).await?; assert_ne!(verkey, ledger_verkey); - assert_eq!(local_verkey, ledger_verkey); + assert_eq!(local_verkey.base58(), ledger_verkey); Ok(()) } @@ -173,8 +173,7 @@ async fn test_pool_write_new_endorser_did() -> Result<(), Box> { let setup = SetupPoolDirectory::init().await; let faber = create_test_agent_trustee(setup.genesis_file_path.clone()).await; let acme = create_test_agent(setup.genesis_file_path.clone()).await; - let acme_vk = - get_verkey_from_wallet(acme.wallet.get_wallet_handle(), &acme.institution_did).await?; + let acme_vk = acme.wallet.key_for_did(&acme.institution_did).await?; let attrib_json = json!({ "attrib_name": "foo"}).to_string(); assert!(add_attr( @@ -190,7 +189,7 @@ async fn test_pool_write_new_endorser_did() -> Result<(), Box> { &faber.ledger_write, &faber.institution_did, &acme.institution_did, - &acme_vk, + &acme_vk.base58(), None, ) .await?; diff --git a/aries/aries_vcx/tests/utils/test_agent.rs b/aries/aries_vcx/tests/utils/test_agent.rs index dd69d8692e..876281a446 100644 --- a/aries/aries_vcx/tests/utils/test_agent.rs +++ b/aries/aries_vcx/tests/utils/test_agent.rs @@ -8,7 +8,7 @@ use aries_vcx_core::{ ledger::base_ledger::{ AnoncredsLedgerRead, AnoncredsLedgerWrite, IndyLedgerRead, IndyLedgerWrite, }, - wallet::{base_wallet::BaseWallet, indy::wallet::get_verkey_from_wallet}, + wallet::base_wallet::{BaseWallet, DidWallet}, }; use test_utils::{ constants::TRUSTEE_SEED, @@ -103,15 +103,14 @@ where W: BaseWallet, { let acme = create_test_agent(genesis_file_path.to_string()).await; - let acme_vk = - get_verkey_from_wallet(acme.wallet.get_wallet_handle(), &acme.institution_did).await?; + let acme_vk = acme.wallet.key_for_did(&acme.institution_did).await?; write_endorser_did( &trustee_wallet, &ledger_write, trustee_did, &acme.institution_did, - &acme_vk, + &acme_vk.base58(), None, ) .await?; diff --git a/aries/aries_vcx_core/src/anoncreds/credx_anoncreds.rs b/aries/aries_vcx_core/src/anoncreds/credx_anoncreds.rs index 1b5dbd7ca1..c844a6f41b 100644 --- a/aries/aries_vcx_core/src/anoncreds/credx_anoncreds.rs +++ b/aries/aries_vcx_core/src/anoncreds/credx_anoncreds.rs @@ -26,13 +26,12 @@ use super::base_anoncreds::BaseAnonCreds; use crate::{ errors::error::{AriesVcxCoreError, AriesVcxCoreErrorKind, VcxCoreResult}, utils::{ - async_fn_iterator::AsyncFnIterator, constants::ATTRS, json::{AsTypeOrDeserializationError, TryGetIndex}, }, wallet::{ - base_wallet::{AsyncFnIteratorCollect, BaseWallet}, - structs_io::UnpackMessageOutput, + base_wallet::{record::Record, search_filter::SearchFilter, BaseWallet, RecordWallet}, + entry_tags::EntryTags, }, }; @@ -66,125 +65,43 @@ pub struct RevocationRegistryInfo { struct WalletAdapter(Arc); #[async_trait] -impl BaseWallet for WalletAdapter { - #[cfg(feature = "vdrtools_wallet")] - fn get_wallet_handle(&self) -> indy_api_types::WalletHandle { - self.0.get_wallet_handle() +impl RecordWallet for WalletAdapter { + async fn add_record(&self, record: Record) -> VcxCoreResult<()> { + self.0.add_record(record).await } - async fn create_and_store_my_did( - &self, - seed: Option<&str>, - kdf_method_name: Option<&str>, - ) -> VcxCoreResult<(String, String)> { - self.0.create_and_store_my_did(seed, kdf_method_name).await - } - - async fn key_for_local_did(&self, did: &str) -> VcxCoreResult { - self.0.key_for_local_did(did).await - } - - async fn replace_did_keys_start(&self, target_did: &str) -> VcxCoreResult { - self.0.replace_did_keys_start(target_did).await - } - - async fn replace_did_keys_apply(&self, target_did: &str) -> VcxCoreResult<()> { - self.0.replace_did_keys_apply(target_did).await - } - - async fn add_wallet_record( - &self, - xtype: &str, - id: &str, - value: &str, - tags: Option>, - ) -> VcxCoreResult<()> { - self.0.add_wallet_record(xtype, id, value, tags).await + async fn get_record(&self, category: &str, name: &str) -> VcxCoreResult { + self.0.get_record(category, name).await } - async fn get_wallet_record( + async fn update_record_tags( &self, - xtype: &str, - id: &str, - options: &str, - ) -> VcxCoreResult { - self.0.get_wallet_record(xtype, id, options).await - } - - async fn get_wallet_record_value(&self, xtype: &str, id: &str) -> VcxCoreResult { - self.0.get_wallet_record_value(xtype, id).await - } - - async fn delete_wallet_record(&self, xtype: &str, id: &str) -> VcxCoreResult<()> { - self.0.delete_wallet_record(xtype, id).await - } - - async fn update_wallet_record_value( - &self, - xtype: &str, - id: &str, - value: &str, - ) -> VcxCoreResult<()> { - self.0.update_wallet_record_value(xtype, id, value).await - } - - async fn add_wallet_record_tags( - &self, - xtype: &str, - id: &str, - tags: HashMap, - ) -> VcxCoreResult<()> { - self.0.add_wallet_record_tags(xtype, id, tags).await - } - - async fn update_wallet_record_tags( - &self, - xtype: &str, - id: &str, - tags: HashMap, + category: &str, + name: &str, + new_tags: EntryTags, ) -> VcxCoreResult<()> { - self.0.update_wallet_record_tags(xtype, id, tags).await + self.0.update_record_tags(category, name, new_tags).await } - async fn delete_wallet_record_tags( + async fn update_record_value( &self, - xtype: &str, - id: &str, - tag_names: &str, + category: &str, + name: &str, + new_value: &str, ) -> VcxCoreResult<()> { - self.0.delete_wallet_record_tags(xtype, id, tag_names).await - } - - async fn iterate_wallet_records( - &self, - xtype: &str, - query: &str, - options: &str, - ) -> VcxCoreResult>>> { - self.0.iterate_wallet_records(xtype, query, options).await - } - - // ---- crypto - - async fn sign(&self, my_vk: &str, msg: &[u8]) -> VcxCoreResult> { - self.0.sign(my_vk, msg).await + self.0.update_record_value(category, name, new_value).await } - async fn verify(&self, vk: &str, msg: &[u8], signature: &[u8]) -> VcxCoreResult { - self.0.verify(vk, msg, signature).await + async fn delete_record(&self, category: &str, name: &str) -> VcxCoreResult<()> { + self.0.delete_record(category, name).await } - async fn pack_message( + async fn search_record( &self, - sender_vk: Option<&str>, - receiver_keys: &str, - msg: &[u8], - ) -> VcxCoreResult> { - self.0.pack_message(sender_vk, receiver_keys, msg).await - } - - async fn unpack_message(&self, msg: &[u8]) -> VcxCoreResult { - self.0.unpack_message(msg).await + category: &str, + search_filter: Option, + ) -> VcxCoreResult> { + self.0.search_record(category, search_filter).await } } @@ -200,8 +117,8 @@ impl IndyCredxAnonCreds { where T: DeserializeOwned, { - let str_record = wallet.get_wallet_record_value(category, id).await?; - serde_json::from_str(&str_record).map_err(From::from) + let str_record = wallet.get_record(category, id).await?; + serde_json::from_str(str_record.value()).map_err(From::from) } async fn get_link_secret( @@ -209,14 +126,10 @@ impl IndyCredxAnonCreds { link_secret_id: &str, ) -> VcxCoreResult { let record = wallet - .get_wallet_record(CATEGORY_LINK_SECRET, link_secret_id, "{}") + .get_record(CATEGORY_LINK_SECRET, link_secret_id) .await?; - let record: Value = serde_json::from_str(&record)?; - - let ms_value = (&record).try_get("value")?; - let ms_decimal = ms_value.try_as_str()?; - let ms_bn: BigNumber = BigNumber::from_dec(ms_decimal).map_err(|err| { + let ms_bn: BigNumber = BigNumber::from_dec(record.value()).map_err(|err| { AriesVcxCoreError::from_msg( AriesVcxCoreErrorKind::UrsaError, format!( @@ -235,14 +148,10 @@ impl IndyCredxAnonCreds { credential_id: &str, ) -> VcxCoreResult { let cred_record = wallet - .get_wallet_record(CATEGORY_CREDENTIAL, credential_id, "{}") + .get_record(CATEGORY_CREDENTIAL, credential_id) .await?; - let cred_record: Value = serde_json::from_str(&cred_record)?; - let cred_record_value = (&cred_record).try_get("value")?; - - let cred_json = cred_record_value.try_as_str()?; - let credential: CredxCredential = serde_json::from_str(cred_json)?; + let credential: CredxCredential = serde_json::from_str(cred_record.value())?; Ok(credential) } @@ -251,24 +160,19 @@ impl IndyCredxAnonCreds { wallet: &impl BaseWallet, wql: &str, ) -> VcxCoreResult> { - let mut record_iterator = wallet - .iterate_wallet_records(CATEGORY_CREDENTIAL, wql, "{}") + let records = wallet + .search_record( + CATEGORY_CREDENTIAL, + Some(SearchFilter::JsonFilter(wql.into())), + ) .await?; - let records = record_iterator.collect().await?; let id_cred_tuple_list: VcxCoreResult> = records - .iter() + .into_iter() .map(|record| { - let cred_record: Value = serde_json::from_str(record)?; - - let cred_record_id = (&cred_record).try_get("id")?.try_as_str()?.to_string(); - let cred_record_value = (&cred_record).try_get("value")?; - - let cred_json = cred_record_value.try_as_str()?; - - let credential: CredxCredential = serde_json::from_str(cred_json)?; + let credential: CredxCredential = serde_json::from_str(record.value())?; - Ok((cred_record_id, credential)) + Ok((record.name().into(), credential)) }) .collect(); @@ -428,38 +332,36 @@ impl BaseAnonCreds for IndyCredxAnonCreds { }; let str_rev_reg_info = serde_json::to_string(&rev_reg_info)?; - - wallet - .add_wallet_record( - CATEGORY_REV_REG_INFO, - &rev_reg_id.0, - &str_rev_reg_info, - None, - ) - .await?; + let record = Record::builder() + .name(rev_reg_id.0.clone()) + .category(CATEGORY_REV_REG_INFO.to_string()) + .value(str_rev_reg_info) + .build(); + wallet.add_record(record).await?; let str_rev_reg_def = serde_json::to_string(&rev_reg_def)?; - - wallet - .add_wallet_record(CATEGORY_REV_REG_DEF, &rev_reg_id.0, &str_rev_reg_def, None) - .await?; + let record = Record::builder() + .name(rev_reg_id.0.clone()) + .category(CATEGORY_REV_REG_DEF.to_string()) + .value(str_rev_reg_def.clone()) + .build(); + wallet.add_record(record).await?; let str_rev_reg_def_priv = serde_json::to_string(&rev_reg_def_priv)?; - - wallet - .add_wallet_record( - CATEGORY_REV_REG_DEF_PRIV, - &rev_reg_id.0, - &str_rev_reg_def_priv, - None, - ) - .await?; + let record = Record::builder() + .name(rev_reg_id.0.clone()) + .category(CATEGORY_REV_REG_DEF_PRIV.to_string()) + .value(str_rev_reg_def_priv) + .build(); + wallet.add_record(record).await?; let str_rev_reg = serde_json::to_string(&rev_reg)?; - - wallet - .add_wallet_record(CATEGORY_REV_REG, &rev_reg_id.0, &str_rev_reg, None) - .await?; + let record = Record::builder() + .name(rev_reg_id.0.clone()) + .category(CATEGORY_REV_REG.to_string()) + .value(str_rev_reg.clone()) + .build(); + wallet.add_record(record).await?; Ok((rev_reg_id.0, str_rev_reg_def, str_rev_reg)) } @@ -510,50 +412,46 @@ impl BaseAnonCreds for IndyCredxAnonCreds { )?; let str_cred_def = serde_json::to_string(&cred_def)?; - - // Store stuff in wallet - wallet - .add_wallet_record(CATEGORY_CRED_DEF, &cred_def_id.0, &str_cred_def, None) - .await?; + let record = Record::builder() + .name(cred_def_id.0.clone()) + .category(CATEGORY_CRED_DEF.to_string()) + .value(str_cred_def.clone()) + .build(); + wallet.add_record(record).await?; let str_cred_def_priv = serde_json::to_string(&cred_def_priv)?; - - wallet - .add_wallet_record( - CATEGORY_CRED_DEF_PRIV, - &cred_def_id.0, - &str_cred_def_priv, - None, - ) - .await?; + let record = Record::builder() + .name(cred_def_id.0.clone()) + .category(CATEGORY_CRED_DEF_PRIV.to_string()) + .value(str_cred_def_priv) + .build(); + wallet.add_record(record).await?; let str_cred_key_proof = serde_json::to_string(&cred_key_correctness_proof)?; - - wallet - .add_wallet_record( - CATEGORY_CRED_KEY_CORRECTNESS_PROOF, - &cred_def_id.0, - &str_cred_key_proof, - None, - ) - .await?; - - let store_schema_res = wallet - .add_wallet_record(CATEGORY_CRED_SCHEMA, schema.id(), schema_json, None) - .await; + let record = Record::builder() + .name(cred_def_id.0.clone()) + .category(CATEGORY_CRED_KEY_CORRECTNESS_PROOF.to_string()) + .value(str_cred_key_proof) + .build(); + wallet.add_record(record).await?; + + let record = Record::builder() + .name(schema.id().to_string()) + .category(CATEGORY_CRED_SCHEMA.to_string()) + .value(schema_json.into()) + .build(); + let store_schema_res = wallet.add_record(record).await; if let Err(e) = store_schema_res { warn!("Storing schema {schema_json} failed - {e}. It's possible it is already stored.") } - wallet - .add_wallet_record( - CATEGORY_CRED_MAP_SCHEMA_ID, - &cred_def_id.0, - &schema.id().0, - None, - ) - .await?; + let record = Record::builder() + .name(cred_def_id.0.clone()) + .category(CATEGORY_CRED_MAP_SCHEMA_ID.to_string()) + .value(schema.id().0.clone()) + .build(); + wallet.add_record(record).await?; // Return the ID and the cred def Ok((cred_def_id.0.to_owned(), str_cred_def)) @@ -571,11 +469,11 @@ impl BaseAnonCreds for IndyCredxAnonCreds { Self::get_wallet_record_value(wallet, CATEGORY_CRED_KEY_CORRECTNESS_PROOF, cred_def_id) .await?; - let schema_id = wallet - .get_wallet_record_value(CATEGORY_CRED_MAP_SCHEMA_ID, cred_def_id) + let schema = wallet + .get_record(CATEGORY_CRED_MAP_SCHEMA_ID, cred_def_id) .await?; - let schema_id = SchemaId(schema_id); + let schema_id = SchemaId(schema.value().into()); // If cred_def contains schema ID, why take it as an argument here...? let offer = @@ -687,15 +585,11 @@ impl BaseAnonCreds for IndyCredxAnonCreds { let str_rev_reg_info = serde_json::to_string(&rev_reg_info)?; wallet - .update_wallet_record_value(CATEGORY_REV_REG, &rev_reg_id, str_rev_reg) + .update_record_value(CATEGORY_REV_REG, &rev_reg_id, str_rev_reg) .await?; wallet - .update_wallet_record_value( - CATEGORY_REV_REG_INFO, - &rev_reg_id, - &str_rev_reg_info, - ) + .update_record_value(CATEGORY_REV_REG_INFO, &rev_reg_id, &str_rev_reg_info) .await?; Some(cred_rev_id) @@ -1134,16 +1028,16 @@ impl BaseAnonCreds for IndyCredxAnonCreds { let credential_id = cred_id.map_or(Uuid::new_v4().to_string(), String::from); let record_value = serde_json::to_string(&credential)?; - let tags_json: HashMap = serde_json::from_value(tags)?; + let tags = serde_json::from_value(tags.clone())?; - wallet - .add_wallet_record( - CATEGORY_CREDENTIAL, - &credential_id, - &record_value, - Some(tags_json), - ) - .await?; + let record = Record::builder() + .name(credential_id.clone()) + .category(CATEGORY_CREDENTIAL.into()) + .value(record_value) + .tags(tags) + .build(); + + wallet.add_record(record).await?; Ok(credential_id) } @@ -1154,7 +1048,7 @@ impl BaseAnonCreds for IndyCredxAnonCreds { link_secret_id: &str, ) -> VcxCoreResult { let existing_record = wallet - .get_wallet_record(CATEGORY_LINK_SECRET, link_secret_id, "{}") + .get_record(CATEGORY_LINK_SECRET, link_secret_id) .await .ok(); // ignore error, as we only care about whether it exists or not @@ -1192,9 +1086,13 @@ impl BaseAnonCreds for IndyCredxAnonCreds { ) })?; - wallet - .add_wallet_record(CATEGORY_LINK_SECRET, link_secret_id, &ms_decimal, None) - .await?; + let record = Record::builder() + .name(link_secret_id.into()) + .category(CATEGORY_LINK_SECRET.into()) + .value(ms_decimal) + .build(); + + wallet.add_record(record).await?; return Ok(link_secret_id.to_string()); } @@ -1204,9 +1102,7 @@ impl BaseAnonCreds for IndyCredxAnonCreds { wallet: &impl BaseWallet, cred_id: &str, ) -> VcxCoreResult<()> { - wallet - .delete_wallet_record(CATEGORY_CREDENTIAL, cred_id) - .await + wallet.delete_record(CATEGORY_CREDENTIAL, cred_id).await } async fn issuer_create_schema( @@ -1314,27 +1210,26 @@ impl BaseAnonCreds for IndyCredxAnonCreds { let str_rev_reg_delta = serde_json::to_string(&rev_reg_delta)?; wallet - .update_wallet_record_value(CATEGORY_REV_REG, rev_reg_id, &str_rev_reg) + .update_record_value(CATEGORY_REV_REG, rev_reg_id, &str_rev_reg) .await?; wallet - .update_wallet_record_value(CATEGORY_REV_REG_INFO, rev_reg_id, &str_rev_reg_info) + .update_record_value(CATEGORY_REV_REG_INFO, rev_reg_id, &str_rev_reg_info) .await?; match old_str_rev_reg_delta { Some(_) => { wallet - .update_wallet_record_value( - CATEGORY_REV_REG_DELTA, - rev_reg_id, - &str_rev_reg_delta, - ) + .update_record_value(CATEGORY_REV_REG_DELTA, rev_reg_id, &str_rev_reg_delta) .await? } None => { - wallet - .add_wallet_record(CATEGORY_REV_REG_DELTA, rev_reg_id, &str_rev_reg_delta, None) - .await? + let record = Record::builder() + .name(rev_reg_id.into()) + .category(CATEGORY_REV_REG_DELTA.into()) + .value(str_rev_reg_delta) + .build(); + wallet.add_record(record).await? } } @@ -1385,7 +1280,7 @@ impl BaseAnonCreds for IndyCredxAnonCreds { ) -> VcxCoreResult<()> { if self.get_rev_reg_delta(wallet, rev_reg_id).await?.is_some() { wallet - .delete_wallet_record(CATEGORY_REV_REG_DELTA, rev_reg_id) + .delete_record(CATEGORY_REV_REG_DELTA, rev_reg_id) .await?; } diff --git a/aries/aries_vcx_core/src/ledger/indy_vdr_ledger.rs b/aries/aries_vcx_core/src/ledger/indy_vdr_ledger.rs index bf2216962a..9f1fd675ba 100644 --- a/aries/aries_vcx_core/src/ledger/indy_vdr_ledger.rs +++ b/aries/aries_vcx_core/src/ledger/indy_vdr_ledger.rs @@ -176,7 +176,7 @@ where request: &PreparedRequest, ) -> VcxCoreResult> { let to_sign = request.get_signature_input()?; - let signer_verkey = wallet.key_for_local_did(did).await?; + let signer_verkey = wallet.key_for_did(did).await?; let signature = wallet.sign(&signer_verkey, to_sign.as_bytes()).await?; Ok(signature) } diff --git a/aries/aries_vcx_core/src/lib.rs b/aries/aries_vcx_core/src/lib.rs index 39261cee56..9481dc467a 100644 --- a/aries/aries_vcx_core/src/lib.rs +++ b/aries/aries_vcx_core/src/lib.rs @@ -28,7 +28,6 @@ pub mod global; pub mod ledger; pub mod utils; pub mod wallet; -pub mod wallet2; pub use indy_ledger_response_parser::ResponseParser; pub use indy_vdr::config::PoolConfig; diff --git a/aries/aries_vcx_core/src/wallet/agency_client_wallet.rs b/aries/aries_vcx_core/src/wallet/agency_client_wallet.rs index ed2c2798f3..3b77193c23 100644 --- a/aries/aries_vcx_core/src/wallet/agency_client_wallet.rs +++ b/aries/aries_vcx_core/src/wallet/agency_client_wallet.rs @@ -1,18 +1,22 @@ -use std::{collections::HashMap, sync::Arc}; +use std::sync::Arc; use agency_client::{ errors::error::{AgencyClientError, AgencyClientErrorKind, AgencyClientResult}, wallet::base_agency_client_wallet::BaseAgencyClientWallet, }; use async_trait::async_trait; -#[cfg(feature = "vdrtools_wallet")] -use vdrtools::WalletHandle; - -use super::structs_io::UnpackMessageOutput; +use public_key::{Key, KeyType}; + +use super::{ + base_wallet::{ + did_data::DidData, record::Record, search_filter::SearchFilter, BaseWallet, DidWallet, + RecordWallet, + }, + structs_io::UnpackMessageOutput, +}; use crate::{ errors::error::{AriesVcxCoreError, AriesVcxCoreErrorKind, VcxCoreResult}, - utils::async_fn_iterator::AsyncFnIterator, - wallet::base_wallet::BaseWallet, + wallet::entry_tags::EntryTags, }; #[derive(Debug)] @@ -20,147 +24,112 @@ pub struct AgencyClientWallet { inner: Arc, } -/// Implementation of [BaseWallet] for [AgencyClientWallet] such that a [BaseAgencyClientWallet] -/// can be converted to a [BaseWallet] for packing and unpacking messages, and vice versa. +impl BaseWallet for AgencyClientWallet {} + #[allow(unused_variables)] #[async_trait] -impl BaseWallet for AgencyClientWallet { - async fn create_and_store_my_did( - &self, - seed: Option<&str>, - method_name: Option<&str>, - ) -> VcxCoreResult<(String, String)> { - Err(unimplemented_agency_client_wallet_method( - "create_and_store_my_did", - )) - } - - async fn key_for_local_did(&self, did: &str) -> VcxCoreResult { - Err(unimplemented_agency_client_wallet_method( - "get_verkey_from_wallet", - )) - } - - async fn replace_did_keys_start(&self, target_did: &str) -> VcxCoreResult { - Err(unimplemented_agency_client_wallet_method( - "replace_did_keys_start", - )) +impl RecordWallet for AgencyClientWallet { + async fn add_record(&self, record: Record) -> VcxCoreResult<()> { + Err(unimplemented_agency_client_wallet_method("add_record")) } - async fn replace_did_keys_apply(&self, target_did: &str) -> VcxCoreResult<()> { - Err(unimplemented_agency_client_wallet_method( - "replace_did_key_apply", - )) + async fn get_record(&self, category: &str, name: &str) -> VcxCoreResult { + Err(unimplemented_agency_client_wallet_method("get_record")) } - async fn add_wallet_record( + async fn update_record_tags( &self, - xtype: &str, - id: &str, - value: &str, - tags: Option>, + category: &str, + name: &str, + new_tags: EntryTags, ) -> VcxCoreResult<()> { Err(unimplemented_agency_client_wallet_method( - "add_wallet_record", + "update_record_tags", )) } - async fn get_wallet_record( + async fn update_record_value( &self, - xtype: &str, - id: &str, - options: &str, - ) -> VcxCoreResult { - Err(unimplemented_agency_client_wallet_method( - "get_wallet_record", - )) - } - - async fn get_wallet_record_value(&self, xtype: &str, id: &str) -> VcxCoreResult { + category: &str, + name: &str, + new_value: &str, + ) -> VcxCoreResult<()> { Err(unimplemented_agency_client_wallet_method( - "get_wallet_record_value", + "update_record_value", )) } - async fn delete_wallet_record(&self, xtype: &str, id: &str) -> VcxCoreResult<()> { - Err(unimplemented_agency_client_wallet_method( - "delete_wallet_record", - )) + async fn delete_record(&self, category: &str, name: &str) -> VcxCoreResult<()> { + Err(unimplemented_agency_client_wallet_method("delete_record")) } - async fn update_wallet_record_value( + async fn search_record( &self, - xtype: &str, - id: &str, - value: &str, - ) -> VcxCoreResult<()> { - Err(unimplemented_agency_client_wallet_method( - "update_wallet_record_value", - )) + category: &str, + search_filter: Option, + ) -> VcxCoreResult> { + Err(unimplemented_agency_client_wallet_method("search_record")) } +} - async fn add_wallet_record_tags( +#[async_trait] +#[allow(unused_variables)] +impl DidWallet for AgencyClientWallet { + async fn create_and_store_my_did( &self, - xtype: &str, - id: &str, - tags: HashMap, - ) -> VcxCoreResult<()> { + seed: Option<&str>, + method_name: Option<&str>, + ) -> VcxCoreResult { Err(unimplemented_agency_client_wallet_method( - "add_wallet_record_tags", + "create_and_store_my_did", )) } - async fn delete_wallet_record_tags( - &self, - xtype: &str, - id: &str, - tag_names: &str, - ) -> VcxCoreResult<()> { - Err(unimplemented_agency_client_wallet_method( - "delete_wallet_record_tags", - )) + async fn key_for_did(&self, name: &str) -> VcxCoreResult { + Err(unimplemented_agency_client_wallet_method("key_for_did")) } - async fn update_wallet_record_tags( - &self, - xtype: &str, - id: &str, - tags: HashMap, - ) -> VcxCoreResult<()> { + async fn replace_did_key_start(&self, did: &str, seed: Option<&str>) -> VcxCoreResult { Err(unimplemented_agency_client_wallet_method( - "update_wallet_record_tags", + "replace_did_key_start", )) } - async fn iterate_wallet_records( - &self, - xtype: &str, - query: &str, - options: &str, - ) -> VcxCoreResult>>> { + async fn replace_did_key_apply(&self, did: &str) -> VcxCoreResult<()> { Err(unimplemented_agency_client_wallet_method( - "iterate_wallet_records", + "replace_did_key_apply", )) } - async fn sign(&self, my_vk: &str, msg: &[u8]) -> VcxCoreResult> { + async fn sign(&self, key: &Key, msg: &[u8]) -> VcxCoreResult> { Err(unimplemented_agency_client_wallet_method("sign")) } - async fn verify(&self, vk: &str, msg: &[u8], signature: &[u8]) -> VcxCoreResult { + async fn verify(&self, key: &Key, msg: &[u8], signature: &[u8]) -> VcxCoreResult { Err(unimplemented_agency_client_wallet_method("verify")) } async fn pack_message( &self, - sender_vk: Option<&str>, - receiver_keys: &str, + sender_vk: Option, + receiver_keys: Vec, msg: &[u8], ) -> VcxCoreResult> { - Ok(self + let receiver_list: Vec = + receiver_keys.into_iter().map(|key| key.base58()).collect(); + + let list_json = serde_json::to_string(&receiver_list)?; + + let res = self .inner - .pack_message(sender_vk, receiver_keys, msg) - .await?) + .pack_message( + sender_vk.map(|key| key.base58()).as_deref(), + &list_json, + msg, + ) + .await?; + + Ok(res) } async fn unpack_message(&self, msg: &[u8]) -> VcxCoreResult { @@ -169,11 +138,6 @@ impl BaseWallet for AgencyClientWallet { AriesVcxCoreError::from_msg(AriesVcxCoreErrorKind::ParsingError, err.to_string()) }) } - - #[cfg(feature = "vdrtools_wallet")] - fn get_wallet_handle(&self) -> WalletHandle { - unimplemented!("AgencyClientWallet::get_wallet_handle - this was not expected to be called") - } } pub trait ToBaseWallet { @@ -211,8 +175,38 @@ impl BaseAgencyClientWallet for BaseWalletAgencyClientWallet { receiver_keys: &str, msg: &[u8], ) -> AgencyClientResult> { + let receiver_list = serde_json::from_str::>(receiver_keys).map_err(|e| { + AgencyClientError::from_msg( + AgencyClientErrorKind::UnknownError, + format!("A VCXError occured while calling pack_message: {e:?}"), + ) + })?; + + let keys = receiver_list + .into_iter() + .map(|item| { + Key::from_base58(&item, KeyType::Ed25519).map_err(|e| { + AgencyClientError::from_msg( + AgencyClientErrorKind::NotBase58, + format!("Invalid receiver key: {e:?}"), + ) + }) + }) + .collect::, _>>()?; + + let sender_key = sender_vk + .map(|item| { + Key::from_base58(item, KeyType::Ed25519).map_err(|e| { + AgencyClientError::from_msg( + AgencyClientErrorKind::NotBase58, + format!("Invalid receiver key: {e:?}"), + ) + }) + }) + .transpose()?; + self.inner - .pack_message(sender_vk, receiver_keys, msg) + .pack_message(sender_key, keys, msg) .await .map_err(|e| { AgencyClientError::from_msg( diff --git a/aries/aries_vcx_core/src/wallet/base_wallet.rs b/aries/aries_vcx_core/src/wallet/base_wallet.rs deleted file mode 100644 index 2ee756b77b..0000000000 --- a/aries/aries_vcx_core/src/wallet/base_wallet.rs +++ /dev/null @@ -1,124 +0,0 @@ -use std::collections::HashMap; - -use async_trait::async_trait; - -use super::structs_io::UnpackMessageOutput; -#[cfg(feature = "vdrtools_wallet")] -use crate::WalletHandle; -use crate::{errors::error::VcxCoreResult, utils::async_fn_iterator::AsyncFnIterator}; - -/// Trait defining standard 'wallet' related functionality. The APIs, including -/// input and output types are loosely based off the indy Wallet API: -/// see: -#[async_trait] -pub trait BaseWallet: std::fmt::Debug + Send + Sync { - #[cfg(feature = "vdrtools_wallet")] - fn get_wallet_handle(&self) -> WalletHandle; - - // ----- DIDs - async fn create_and_store_my_did( - &self, - seed: Option<&str>, - kdf_method_name: Option<&str>, - ) -> VcxCoreResult<(String, String)>; - - async fn key_for_local_did(&self, did: &str) -> VcxCoreResult; - - // returns new temp_verkey and remembers it internally - async fn replace_did_keys_start(&self, target_did: &str) -> VcxCoreResult; - - // replaces the `target_did`'s current verkey with the one last generated by - // `replace_did_keys_start` - async fn replace_did_keys_apply(&self, target_did: &str) -> VcxCoreResult<()>; - - // ---- records - - async fn add_wallet_record( - &self, - xtype: &str, - id: &str, - value: &str, - tags: Option>, - ) -> VcxCoreResult<()>; - - async fn get_wallet_record( - &self, - xtype: &str, - id: &str, - options: &str, - ) -> VcxCoreResult; - - async fn get_wallet_record_value(&self, xtype: &str, id: &str) -> VcxCoreResult; - - async fn delete_wallet_record(&self, xtype: &str, id: &str) -> VcxCoreResult<()>; - - async fn update_wallet_record_value( - &self, - xtype: &str, - id: &str, - value: &str, - ) -> VcxCoreResult<()>; - - async fn add_wallet_record_tags( - &self, - xtype: &str, - id: &str, - tags: HashMap, - ) -> VcxCoreResult<()>; - - async fn update_wallet_record_tags( - &self, - xtype: &str, - id: &str, - tags: HashMap, - ) -> VcxCoreResult<()>; - - async fn delete_wallet_record_tags( - &self, - xtype: &str, - id: &str, - tag_names: &str, - ) -> VcxCoreResult<()>; - - async fn iterate_wallet_records( - &self, - xtype: &str, - query: &str, - options: &str, - ) -> VcxCoreResult>>>; - - // ---- crypto - - async fn sign(&self, my_vk: &str, msg: &[u8]) -> VcxCoreResult>; - - async fn verify(&self, vk: &str, msg: &[u8], signature: &[u8]) -> VcxCoreResult; - - async fn pack_message( - &self, - sender_vk: Option<&str>, - receiver_keys: &str, - msg: &[u8], - ) -> VcxCoreResult>; - - async fn unpack_message(&self, msg: &[u8]) -> VcxCoreResult; -} - -#[async_trait] -pub trait AsyncFnIteratorCollect { - type Item; - - async fn collect(&mut self) -> VcxCoreResult>; -} - -#[async_trait] -impl AsyncFnIteratorCollect for Box>> { - type Item = String; - - async fn collect(&mut self) -> VcxCoreResult> { - let mut collection: Vec = vec![]; - while let Some(res) = self.next().await { - collection.push(res?); - } - Ok(collection) - } -} diff --git a/aries/aries_vcx_core/src/wallet/base_wallet/did_data.rs b/aries/aries_vcx_core/src/wallet/base_wallet/did_data.rs new file mode 100644 index 0000000000..f88132403e --- /dev/null +++ b/aries/aries_vcx_core/src/wallet/base_wallet/did_data.rs @@ -0,0 +1,25 @@ +use public_key::Key; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Deserialize, Serialize)] +pub struct DidData { + did: String, + verkey: Key, +} + +impl DidData { + pub fn new(did: &str, verkey: Key) -> Self { + Self { + did: did.into(), + verkey, + } + } + + pub fn did(&self) -> &str { + &self.did + } + + pub fn verkey(&self) -> &Key { + &self.verkey + } +} diff --git a/aries/aries_vcx_core/src/wallet2/mod.rs b/aries/aries_vcx_core/src/wallet/base_wallet/mod.rs similarity index 62% rename from aries/aries_vcx_core/src/wallet2/mod.rs rename to aries/aries_vcx_core/src/wallet/base_wallet/mod.rs index 8f7ada11cf..b3b7ba28a0 100644 --- a/aries/aries_vcx_core/src/wallet2/mod.rs +++ b/aries/aries_vcx_core/src/wallet/base_wallet/mod.rs @@ -1,62 +1,30 @@ use async_trait::async_trait; -#[cfg(feature = "vdrtools_wallet")] -use indy_api_types::domain::wallet::Record as IndyRecord; use public_key::Key; -use serde::{Deserialize, Serialize}; -use typed_builder::TypedBuilder; -use self::entry_tag::EntryTags; -use crate::{errors::error::VcxCoreResult, wallet::structs_io::UnpackMessageOutput}; +use super::entry_tags::EntryTags; +use crate::{ + errors::error::VcxCoreResult, + wallet::{ + base_wallet::{did_data::DidData, record::Record, search_filter::SearchFilter}, + structs_io::UnpackMessageOutput, + }, +}; -#[cfg(feature = "vdrtools_wallet")] -pub mod indy_wallet; +pub mod did_data; +pub mod record; +pub mod search_filter; -pub mod entry_tag; -pub mod utils; - -#[derive(Debug, Clone, TypedBuilder)] -pub struct Record { - category: String, - name: String, - value: String, - #[builder(default)] - tags: EntryTags, -} - -#[cfg(feature = "vdrtools_wallet")] -impl From for Record { - fn from(ir: IndyRecord) -> Self { - Self { - name: ir.id, - category: ir.type_, - value: ir.value, - tags: ir.tags.into(), - } - } -} - -#[derive(Debug, Deserialize, Serialize)] -pub struct DidData { - did: String, - verkey: Key, -} - -pub enum SearchFilter { - JsonFilter(String), -} - -#[async_trait] -pub trait BaseWallet2: RecordWallet + DidWallet {} +pub trait BaseWallet: RecordWallet + DidWallet + Send + Sync + std::fmt::Debug {} #[async_trait] pub trait DidWallet { async fn create_and_store_my_did( &self, seed: Option<&str>, - method_name: Option<&str>, + kdf_method_name: Option<&str>, ) -> VcxCoreResult; - async fn did_key(&self, name: &str) -> VcxCoreResult; + async fn key_for_did(&self, did: &str) -> VcxCoreResult; async fn replace_did_key_start(&self, did: &str, seed: Option<&str>) -> VcxCoreResult; @@ -80,23 +48,23 @@ pub trait DidWallet { pub trait RecordWallet { async fn add_record(&self, record: Record) -> VcxCoreResult<()>; - async fn get_record(&self, name: &str, category: &str) -> VcxCoreResult; + async fn get_record(&self, category: &str, name: &str) -> VcxCoreResult; async fn update_record_tags( &self, - name: &str, category: &str, + name: &str, new_tags: EntryTags, ) -> VcxCoreResult<()>; async fn update_record_value( &self, - name: &str, category: &str, + name: &str, new_value: &str, ) -> VcxCoreResult<()>; - async fn delete_record(&self, name: &str, category: &str) -> VcxCoreResult<()>; + async fn delete_record(&self, category: &str, name: &str) -> VcxCoreResult<()>; async fn search_record( &self, @@ -107,39 +75,31 @@ pub trait RecordWallet { #[cfg(test)] mod tests { - use super::BaseWallet2; + use rand::{distributions::Alphanumeric, Rng}; + + use super::BaseWallet; use crate::{ errors::error::AriesVcxCoreErrorKind, - wallet::indy::IndySdkWallet, - wallet2::{ - entry_tag::{EntryTag, EntryTags}, - utils::random_seed, - DidWallet, Record, RecordWallet, + wallet::{ + base_wallet::{DidWallet, Record, RecordWallet}, + entry_tags::EntryTags, }, }; - async fn build_test_wallet() -> impl BaseWallet2 { - #[cfg(feature = "vdrtools_wallet")] - return dev_setup_indy_wallet().await; + fn random_seed() -> String { + rand::thread_rng() + .sample_iter(Alphanumeric) + .take(32) + .map(char::from) + .collect() } - #[cfg(feature = "vdrtools_wallet")] - async fn dev_setup_indy_wallet() -> IndySdkWallet { - use crate::wallet::indy::{wallet::create_and_open_wallet, WalletConfig}; - - let config_wallet = WalletConfig { - wallet_name: format!("wallet_{}", uuid::Uuid::new_v4()), - wallet_key: "8dvfYSt5d1taSd6yJdpjq4emkwsPDDLYxkNFysFD2cZY".into(), - wallet_key_derivation: "RAW".into(), - wallet_type: None, - storage_config: None, - storage_credentials: None, - rekey: None, - rekey_derivation_method: None, - }; - let wallet_handle = create_and_open_wallet(&config_wallet).await.unwrap(); - - IndySdkWallet::new(wallet_handle) + async fn build_test_wallet() -> impl BaseWallet { + #[cfg(feature = "vdrtools_wallet")] + { + use crate::wallet::indy::tests::dev_setup_indy_wallet; + dev_setup_indy_wallet().await + } } #[tokio::test] @@ -152,9 +112,9 @@ mod tests { .unwrap(); let msg = "sign this".as_bytes(); - let sig = wallet.sign(&did_data.verkey, msg).await.unwrap(); + let sig = wallet.sign(did_data.verkey(), msg).await.unwrap(); - let res = wallet.verify(&did_data.verkey, msg, &sig).await.unwrap(); + let res = wallet.verify(did_data.verkey(), msg, &sig).await.unwrap(); assert!(res); } @@ -167,18 +127,18 @@ mod tests { .await .unwrap(); - let key = wallet.did_key(&did_data.did).await.unwrap(); + let key = wallet.key_for_did(did_data.did()).await.unwrap(); - assert_eq!(did_data.verkey, key); + assert_eq!(did_data.verkey(), &key); let res = wallet - .replace_did_key_start(&did_data.did, Some(&random_seed())) + .replace_did_key_start(did_data.did(), Some(&random_seed())) .await .unwrap(); - wallet.replace_did_key_apply(&did_data.did).await.unwrap(); + wallet.replace_did_key_apply(did_data.did()).await.unwrap(); - let new_key = wallet.did_key(&did_data.did).await.unwrap(); + let new_key = wallet.key_for_did(did_data.did()).await.unwrap(); assert_eq!(res, new_key); } @@ -194,8 +154,8 @@ mod tests { let packed = wallet .pack_message( - Some(sender_data.verkey), - vec![receiver_data.verkey], + Some(sender_data.verkey().clone()), + vec![receiver_data.verkey().clone()], msg.as_bytes(), ) .await @@ -228,9 +188,9 @@ mod tests { wallet.add_record(record1).await.unwrap(); wallet.add_record(record2).await.unwrap(); - let res = wallet.get_record(name, category).await.unwrap(); + let res = wallet.get_record(category, name).await.unwrap(); - assert_eq!(value, res.value); + assert_eq!(value, res.value()); } #[tokio::test] @@ -249,13 +209,13 @@ mod tests { wallet.add_record(record).await.unwrap(); - let res = wallet.get_record(name, category).await.unwrap(); + let res = wallet.get_record(category, name).await.unwrap(); - assert_eq!(value, res.value); + assert_eq!(value, res.value()); - wallet.delete_record(name, category).await.unwrap(); + wallet.delete_record(category, name).await.unwrap(); - let err = wallet.get_record(name, category).await.unwrap_err(); + let err = wallet.get_record(category, name).await.unwrap_err(); assert_eq!(AriesVcxCoreErrorKind::WalletRecordNotFound, err.kind()); } @@ -275,7 +235,6 @@ mod tests { .category(category1.into()) .value(value.into()) .build(); - wallet.add_record(record1).await.unwrap(); let record2 = Record::builder() @@ -283,7 +242,6 @@ mod tests { .category(category1.into()) .value(value.into()) .build(); - wallet.add_record(record2).await.unwrap(); let record3 = Record::builder() @@ -291,7 +249,6 @@ mod tests { .category(category2.into()) .value(value.into()) .build(); - wallet.add_record(record3).await.unwrap(); let res = wallet.search_record(category1, None).await.unwrap(); @@ -307,7 +264,7 @@ mod tests { let category = "my"; let value1 = "xxx"; let value2 = "yyy"; - let tags1: EntryTags = vec![EntryTag::Plaintext("a".into(), "b".into())].into(); + let tags1: EntryTags = vec![("a".into(), "b".into())].into(); let tags2 = EntryTags::default(); let record = Record::builder() @@ -319,17 +276,17 @@ mod tests { wallet.add_record(record.clone()).await.unwrap(); wallet - .update_record_value(name, category, value2) + .update_record_value(category, name, value2) .await .unwrap(); wallet - .update_record_tags(name, category, tags2.clone()) + .update_record_tags(category, name, tags2.clone()) .await .unwrap(); - let res = wallet.get_record(name, category).await.unwrap(); - assert_eq!(value2, res.value); - assert_eq!(tags2, res.tags); + let res = wallet.get_record(category, name).await.unwrap(); + assert_eq!(value2, res.value()); + assert_eq!(&tags2, res.tags()); } #[tokio::test] @@ -340,7 +297,7 @@ mod tests { let category = "my"; let value1 = "xxx"; let value2 = "yyy"; - let tags: EntryTags = vec![EntryTag::Plaintext("a".into(), "b".into())].into(); + let tags: EntryTags = vec![("a".into(), "b".into())].into(); let record = Record::builder() .name(name.into()) @@ -351,13 +308,13 @@ mod tests { wallet.add_record(record.clone()).await.unwrap(); wallet - .update_record_value(name, category, value2) + .update_record_value(category, name, value2) .await .unwrap(); - let res = wallet.get_record(name, category).await.unwrap(); - assert_eq!(value2, res.value); - assert_eq!(tags, res.tags); + let res = wallet.get_record(category, name).await.unwrap(); + assert_eq!(value2, res.value()); + assert_eq!(&tags, res.tags()); } #[tokio::test] @@ -367,8 +324,8 @@ mod tests { let name = "foo"; let category = "my"; let value = "xxx"; - let tags1: EntryTags = vec![EntryTag::Plaintext("a".into(), "b".into())].into(); - let tags2: EntryTags = vec![EntryTag::Plaintext("c".into(), "d".into())].into(); + let tags1: EntryTags = vec![("a".into(), "b".into())].into(); + let tags2: EntryTags = vec![("c".into(), "d".into())].into(); let record = Record::builder() .name(name.into()) @@ -379,12 +336,12 @@ mod tests { wallet.add_record(record.clone()).await.unwrap(); wallet - .update_record_tags(name, category, tags2.clone()) + .update_record_tags(category, name, tags2.clone()) .await .unwrap(); - let res = wallet.get_record(name, category).await.unwrap(); - assert_eq!(value, res.value); - assert_eq!(tags2, res.tags); + let res = wallet.get_record(category, name).await.unwrap(); + assert_eq!(value, res.value()); + assert_eq!(&tags2, res.tags()); } } diff --git a/aries/aries_vcx_core/src/wallet/base_wallet/record.rs b/aries/aries_vcx_core/src/wallet/base_wallet/record.rs new file mode 100644 index 0000000000..6648455c8f --- /dev/null +++ b/aries/aries_vcx_core/src/wallet/base_wallet/record.rs @@ -0,0 +1,30 @@ +use typed_builder::TypedBuilder; + +use crate::wallet::entry_tags::EntryTags; + +#[derive(Debug, Default, Clone, TypedBuilder)] +pub struct Record { + category: String, + name: String, + value: String, + #[builder(default)] + tags: EntryTags, +} + +impl Record { + pub fn value(&self) -> &str { + &self.value + } + + pub fn name(&self) -> &str { + &self.name + } + + pub fn category(&self) -> &str { + &self.category + } + + pub fn tags(&self) -> &EntryTags { + &self.tags + } +} diff --git a/aries/aries_vcx_core/src/wallet/base_wallet/search_filter.rs b/aries/aries_vcx_core/src/wallet/base_wallet/search_filter.rs new file mode 100644 index 0000000000..a8b28360e2 --- /dev/null +++ b/aries/aries_vcx_core/src/wallet/base_wallet/search_filter.rs @@ -0,0 +1,3 @@ +pub enum SearchFilter { + JsonFilter(String), +} diff --git a/aries/aries_vcx_core/src/wallet/entry_tags.rs b/aries/aries_vcx_core/src/wallet/entry_tags.rs new file mode 100644 index 0000000000..ed3f396c1c --- /dev/null +++ b/aries/aries_vcx_core/src/wallet/entry_tags.rs @@ -0,0 +1,150 @@ +use std::fmt; + +use serde::{de::Visitor, ser::SerializeMap, Deserialize, Serialize}; + +pub(crate) type EntryTag = (String, String); + +#[derive(Debug, Default, Clone, PartialEq)] +pub struct EntryTags { + inner: Vec, +} + +impl Serialize for EntryTags { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut map = serializer.serialize_map(Some(self.inner.len()))?; + for tag in self.inner.iter() { + map.serialize_entry(&tag.0, &tag.1)? + } + map.end() + } +} + +struct EntryTagsVisitor; + +impl<'de> Visitor<'de> for EntryTagsVisitor { + type Value = EntryTags; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "a map representing tags") + } + + fn visit_map(self, mut map: A) -> Result + where + A: serde::de::MapAccess<'de>, + { + let mut tags = EntryTags::new(vec![]); + + while let Some(tag) = map.next_entry()? { + tags.add(tag); + } + + Ok(tags) + } +} + +impl<'de> Deserialize<'de> for EntryTags { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + deserializer.deserialize_map(EntryTagsVisitor) + } +} + +impl EntryTags { + pub fn new(inner: Vec) -> Self { + let mut items = inner; + items.sort(); + + Self { inner: items } + } + + pub fn add(&mut self, tag: EntryTag) { + self.inner.push(tag); + self.inner.sort(); + } + + pub fn is_empty(&self) -> bool { + self.inner.is_empty() + } + + pub fn into_inner(self) -> Vec { + self.inner + } + + pub fn merge(&mut self, other: EntryTags) { + self.inner.extend(other.into_inner()); + self.inner.sort(); + } + + pub fn remove(&mut self, tag: EntryTag) { + self.inner.retain(|existing_tag| existing_tag.0 != tag.0); + self.inner.sort(); + } +} + +impl IntoIterator for EntryTags { + type Item = EntryTag; + + type IntoIter = std::vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.inner.into_iter() + } +} + +impl FromIterator for EntryTags { + fn from_iter>(iter: T) -> Self { + let mut tags = Self::default(); + + for item in iter { + tags.add(item); + } + tags + } +} + +impl From> for EntryTags { + fn from(value: Vec) -> Self { + value.into_iter().fold(Self::default(), |mut memo, item| { + memo.add(item); + memo + }) + } +} + +impl From for Vec { + fn from(value: EntryTags) -> Self { + value.inner + } +} + +#[cfg(test)] +mod tests { + use serde_json::json; + + use crate::wallet::entry_tags::EntryTags; + + #[test] + fn test_entry_tags_serialize() { + let tags = EntryTags::new(vec![("~a".into(), "b".into()), ("c".into(), "d".into())]); + + let res = serde_json::to_string(&tags).unwrap(); + + assert_eq!(json!({ "~a": "b", "c": "d" }).to_string(), res); + } + + #[test] + fn test_entry_tags_deserialize() { + let json = json!({"a":"b", "~c":"d"}); + + let tags = EntryTags::new(vec![("a".into(), "b".into()), ("~c".into(), "d".into())]); + + let res = serde_json::from_str(&json.to_string()).unwrap(); + + assert_eq!(tags, res); + } +} diff --git a/aries/aries_vcx_core/src/wallet2/indy_wallet/indy_did_wallet.rs b/aries/aries_vcx_core/src/wallet/indy/indy_did_wallet.rs similarity index 84% rename from aries/aries_vcx_core/src/wallet2/indy_wallet/indy_did_wallet.rs rename to aries/aries_vcx_core/src/wallet/indy/indy_did_wallet.rs index aa73168fdf..b553b2c183 100644 --- a/aries/aries_vcx_core/src/wallet2/indy_wallet/indy_did_wallet.rs +++ b/aries/aries_vcx_core/src/wallet/indy/indy_did_wallet.rs @@ -1,11 +1,14 @@ use async_trait::async_trait; -use public_key::KeyType; +use public_key::{Key, KeyType}; use vdrtools::{DidMethod, DidValue, KeyInfo, Locator, MyDidInfo}; use crate::{ errors::error::{AriesVcxCoreError, AriesVcxCoreErrorKind, VcxCoreResult}, - wallet::{indy::IndySdkWallet, structs_io::UnpackMessageOutput}, - wallet2::{DidData, DidWallet, Key}, + wallet::{ + base_wallet::{did_data::DidData, DidWallet}, + indy::IndySdkWallet, + structs_io::UnpackMessageOutput, + }, }; #[async_trait] @@ -13,29 +16,27 @@ impl DidWallet for IndySdkWallet { async fn create_and_store_my_did( &self, seed: Option<&str>, - method_name: Option<&str>, + did_method_name: Option<&str>, ) -> VcxCoreResult { - let res = Locator::instance() + let (did, vk) = Locator::instance() .did_controller .create_and_store_my_did( self.wallet_handle, MyDidInfo { - method_name: method_name.map(|m| DidMethod(m.into())), + method_name: did_method_name.map(|m| DidMethod(m.into())), seed: seed.map(Into::into), ..MyDidInfo::default() }, ) .await?; - Ok(DidData { - did: res.0, - verkey: Key::from_base58(&res.1, KeyType::Ed25519).map_err(|err| { - AriesVcxCoreError::from_msg(AriesVcxCoreErrorKind::WalletError, err) - })?, - }) + let verkey = Key::from_base58(&vk, KeyType::Ed25519) + .map_err(|err| AriesVcxCoreError::from_msg(AriesVcxCoreErrorKind::WalletError, err))?; + + Ok(DidData::new(&did, verkey)) } - async fn did_key(&self, did: &str) -> VcxCoreResult { + async fn key_for_did(&self, did: &str) -> VcxCoreResult { let res = Locator::instance() .did_controller .key_for_local_did(self.wallet_handle, DidValue(did.into())) diff --git a/aries/aries_vcx_core/src/wallet2/indy_wallet/indy_record_wallet.rs b/aries/aries_vcx_core/src/wallet/indy/indy_record_wallet.rs similarity index 82% rename from aries/aries_vcx_core/src/wallet2/indy_wallet/indy_record_wallet.rs rename to aries/aries_vcx_core/src/wallet/indy/indy_record_wallet.rs index ec106abc9f..d298a852e5 100644 --- a/aries/aries_vcx_core/src/wallet2/indy_wallet/indy_record_wallet.rs +++ b/aries/aries_vcx_core/src/wallet/indy/indy_record_wallet.rs @@ -1,38 +1,41 @@ use async_trait::async_trait; -use indy_api_types::domain::wallet::Record as IndyRecord; +use indy_api_types::domain::wallet::IndyRecord; use serde::Deserialize; use serde_json::Value; use vdrtools::Locator; -use super::{SEARCH_OPTIONS, WALLET_OPTIONS}; +use super::{indy_tags::IndyTags, SEARCH_OPTIONS, WALLET_OPTIONS}; use crate::{ errors::error::{AriesVcxCoreError, VcxCoreResult}, - wallet::indy::IndySdkWallet, - wallet2::{entry_tag::EntryTags, Record, RecordWallet, SearchFilter}, + wallet::{ + base_wallet::{record::Record, search_filter::SearchFilter, RecordWallet}, + entry_tags::EntryTags, + indy::IndySdkWallet, + }, }; #[async_trait] impl RecordWallet for IndySdkWallet { async fn add_record(&self, record: Record) -> VcxCoreResult<()> { - let tags_map = if record.tags.is_empty() { + let tags_map = if record.tags().is_empty() { None } else { - Some(record.tags.into()) + Some(IndyTags::from_entry_tags(record.tags().clone()).into_inner()) }; Ok(Locator::instance() .non_secret_controller .add_record( self.wallet_handle, - record.category, - record.name, - record.value, + record.category().into(), + record.name().into(), + record.value().into(), tags_map, ) .await?) } - async fn get_record(&self, name: &str, category: &str) -> VcxCoreResult { + async fn get_record(&self, category: &str, name: &str) -> VcxCoreResult { let res = Locator::instance() .non_secret_controller .get_record( @@ -50,8 +53,8 @@ impl RecordWallet for IndySdkWallet { async fn update_record_tags( &self, - name: &str, category: &str, + name: &str, new_tags: EntryTags, ) -> VcxCoreResult<()> { Ok(Locator::instance() @@ -60,15 +63,15 @@ impl RecordWallet for IndySdkWallet { self.wallet_handle, category.into(), name.into(), - new_tags.into(), + IndyTags::from_entry_tags(new_tags).into_inner(), ) .await?) } async fn update_record_value( &self, - name: &str, category: &str, + name: &str, new_value: &str, ) -> VcxCoreResult<()> { Ok(Locator::instance() @@ -82,7 +85,7 @@ impl RecordWallet for IndySdkWallet { .await?) } - async fn delete_record(&self, name: &str, category: &str) -> VcxCoreResult<()> { + async fn delete_record(&self, category: &str, name: &str) -> VcxCoreResult<()> { Ok(Locator::instance() .non_secret_controller .delete_record(self.wallet_handle, category.into(), name.into()) diff --git a/aries/aries_vcx_core/src/wallet/indy/indy_tags.rs b/aries/aries_vcx_core/src/wallet/indy/indy_tags.rs new file mode 100644 index 0000000000..f33ae9d489 --- /dev/null +++ b/aries/aries_vcx_core/src/wallet/indy/indy_tags.rs @@ -0,0 +1,29 @@ +use std::collections::HashMap; + +use crate::wallet::entry_tags::{EntryTag, EntryTags}; + +pub(crate) struct IndyTags(HashMap); + +impl IndyTags { + pub fn new(map: HashMap) -> Self { + Self(map) + } + + pub fn into_inner(self) -> HashMap { + self.0 + } + + pub fn from_entry_tags(tags: EntryTags) -> Self { + let mut map = HashMap::new(); + let tags_vec: Vec<_> = tags.into_iter().collect(); + map.extend(tags_vec); + Self(map) + } + + pub fn into_entry_tags(self) -> EntryTags { + let mut items: Vec = self.0.into_iter().collect(); + items.sort(); + + EntryTags::new(items) + } +} diff --git a/aries/aries_vcx_core/src/wallet/indy/indy_wallet.rs b/aries/aries_vcx_core/src/wallet/indy/indy_wallet.rs deleted file mode 100644 index fa9ba6e324..0000000000 --- a/aries/aries_vcx_core/src/wallet/indy/indy_wallet.rs +++ /dev/null @@ -1,167 +0,0 @@ -use std::collections::HashMap; - -use async_trait::async_trait; - -use crate::{ - errors::error::{AriesVcxCoreError, AriesVcxCoreErrorKind, VcxCoreResult}, - utils::async_fn_iterator::AsyncFnIterator, - wallet, - wallet::{ - base_wallet::BaseWallet, - indy::{internal, IndySdkWallet, IndyWalletRecordIterator, WalletRecord}, - structs_io::UnpackMessageOutput, - }, - WalletHandle, -}; - -#[allow(unused_variables)] -#[async_trait] -impl BaseWallet for IndySdkWallet { - async fn create_and_store_my_did( - &self, - seed: Option<&str>, - method_name: Option<&str>, - ) -> VcxCoreResult<(String, String)> { - wallet::indy::wallet::create_and_store_my_did(self.wallet_handle, seed, method_name).await - } - - async fn key_for_local_did(&self, did: &str) -> VcxCoreResult { - wallet::indy::wallet::get_verkey_from_wallet(self.wallet_handle, did).await - } - - async fn replace_did_keys_start(&self, target_did: &str) -> VcxCoreResult { - wallet::indy::wallet::libindy_replace_keys_start(self.wallet_handle, target_did).await - } - - async fn replace_did_keys_apply(&self, target_did: &str) -> VcxCoreResult<()> { - wallet::indy::wallet::libindy_replace_keys_apply(self.wallet_handle, target_did).await - } - - async fn add_wallet_record( - &self, - xtype: &str, - id: &str, - value: &str, - tags: Option>, - ) -> VcxCoreResult<()> { - let res = tags - .map(|x| serde_json::to_string(&x)) - .transpose()? - .to_owned(); - let tags_json = res.as_deref(); - internal::add_wallet_record(self.wallet_handle, xtype, id, value, tags_json).await - } - - async fn get_wallet_record( - &self, - xtype: &str, - id: &str, - options: &str, - ) -> VcxCoreResult { - internal::get_wallet_record(self.wallet_handle, xtype, id, options).await - } - - async fn get_wallet_record_value(&self, xtype: &str, id: &str) -> VcxCoreResult { - let options = r#"{"retrieveType": false, "retrieveValue": true, "retrieveTags": false}"#; - - let str_record = self.get_wallet_record(xtype, id, options).await?; - let wallet_record: WalletRecord = serde_json::from_str(&str_record)?; - wallet_record.value.ok_or_else(|| { - AriesVcxCoreError::from_msg( - AriesVcxCoreErrorKind::WalletRecordNotFound, - "The wallet record does not have a value", - ) - }) - } - - async fn delete_wallet_record(&self, xtype: &str, id: &str) -> VcxCoreResult<()> { - internal::delete_wallet_record(self.wallet_handle, xtype, id).await - } - - async fn update_wallet_record_value( - &self, - xtype: &str, - id: &str, - value: &str, - ) -> VcxCoreResult<()> { - internal::update_wallet_record_value(self.wallet_handle, xtype, id, value).await - } - - async fn update_wallet_record_tags( - &self, - xtype: &str, - id: &str, - tags: HashMap, - ) -> VcxCoreResult<()> { - let tags_json = serde_json::to_string(&tags)?; - internal::update_wallet_record_tags(self.wallet_handle, xtype, id, &tags_json).await - } - - async fn add_wallet_record_tags( - &self, - xtype: &str, - id: &str, - tags: HashMap, - ) -> VcxCoreResult<()> { - let tags_json = serde_json::to_string(&tags)?; - internal::add_wallet_record_tags(self.wallet_handle, xtype, id, &tags_json).await - } - - async fn delete_wallet_record_tags( - &self, - xtype: &str, - id: &str, - tag_names: &str, - ) -> VcxCoreResult<()> { - internal::delete_wallet_record_tags(self.wallet_handle, xtype, id, tag_names).await - } - - async fn iterate_wallet_records( - &self, - xtype: &str, - query: &str, - options: &str, - ) -> VcxCoreResult>>> { - let search = - internal::open_search_wallet(self.wallet_handle, xtype, query, options).await?; - let iter = IndyWalletRecordIterator::new(self.wallet_handle, search); - - Ok(Box::new(iter)) - } - - async fn sign(&self, my_vk: &str, msg: &[u8]) -> VcxCoreResult> { - wallet::indy::signing::vdrtools_sign(self.wallet_handle, my_vk, msg).await - } - - async fn verify(&self, vk: &str, msg: &[u8], signature: &[u8]) -> VcxCoreResult { - wallet::indy::signing::vdrtools_verify(vk, msg, signature).await - } - - async fn pack_message( - &self, - sender_vk: Option<&str>, - receiver_keys: &str, - msg: &[u8], - ) -> VcxCoreResult> { - wallet::indy::signing::vdrtools_pack_message( - self.wallet_handle, - sender_vk, - receiver_keys, - msg, - ) - .await - } - - async fn unpack_message(&self, msg: &[u8]) -> VcxCoreResult { - let unpack_json_bytes = - wallet::indy::signing::vdrtools_unpack_message(self.wallet_handle, msg).await?; - serde_json::from_slice(&unpack_json_bytes[..]).map_err(|err| { - AriesVcxCoreError::from_msg(AriesVcxCoreErrorKind::ParsingError, err.to_string()) - }) - } - - #[cfg(feature = "vdrtools_wallet")] - fn get_wallet_handle(&self) -> WalletHandle { - self.wallet_handle - } -} diff --git a/aries/aries_vcx_core/src/wallet/indy/internal.rs b/aries/aries_vcx_core/src/wallet/indy/internal.rs new file mode 100644 index 0000000000..d75f71db99 --- /dev/null +++ b/aries/aries_vcx_core/src/wallet/indy/internal.rs @@ -0,0 +1,77 @@ +use indy_api_types::SearchHandle; +use vdrtools::{Locator, WalletHandle}; + +use crate::errors::error::VcxCoreResult; + +pub async fn delete_wallet_record( + wallet_handle: WalletHandle, + xtype: &str, + id: &str, +) -> VcxCoreResult<()> { + trace!( + "delete_record >>> xtype: {}, id: {}", + secret!(&xtype), + secret!(&id) + ); + + Locator::instance() + .non_secret_controller + .delete_record(wallet_handle, xtype.into(), id.into()) + .await?; + + Ok(()) +} + +// TODO - FUTURE - revert to pub(crate) after libvcx dependency is fixed +pub async fn open_search_wallet( + wallet_handle: WalletHandle, + xtype: &str, + query: &str, + options: &str, +) -> VcxCoreResult { + trace!( + "open_search >>> xtype: {}, query: {}, options: {}", + secret!(&xtype), + query, + options + ); + + let res = Locator::instance() + .non_secret_controller + .open_search(wallet_handle, xtype.into(), query.into(), options.into()) + .await?; + + Ok(res) +} + +// TODO - FUTURE - revert to pub(crate) after libvcx dependency is fixed +pub async fn fetch_next_records_wallet( + wallet_handle: WalletHandle, + search_handle: SearchHandle, + count: usize, +) -> VcxCoreResult { + trace!( + "fetch_next_records >>> search_handle: {:?}, count: {}", + search_handle, + count + ); + + let res = Locator::instance() + .non_secret_controller + .fetch_search_next_records(wallet_handle, search_handle, count) + .await?; + + Ok(res) +} + +// TODO - FUTURE - revert to pub(crate) after libvcx dependency is fixed +pub async fn close_search_wallet(search_handle: SearchHandle) -> VcxCoreResult<()> { + trace!("close_search >>> search_handle: {:?}", search_handle); + + Locator::instance() + .non_secret_controller + .close_search(search_handle) + .await?; + + Ok(()) +} diff --git a/aries/aries_vcx_core/src/wallet/indy/internal/mod.rs b/aries/aries_vcx_core/src/wallet/indy/internal/mod.rs deleted file mode 100644 index 9736937c29..0000000000 --- a/aries/aries_vcx_core/src/wallet/indy/internal/mod.rs +++ /dev/null @@ -1,220 +0,0 @@ -use vdrtools::{Locator, SearchHandle, WalletHandle}; - -use crate::errors::error::VcxCoreResult; - -pub(crate) async fn add_wallet_record( - wallet_handle: WalletHandle, - xtype: &str, - id: &str, - value: &str, - tags: Option<&str>, -) -> VcxCoreResult<()> { - trace!( - "add_record >>> xtype: {}, id: {}, value: {}, tags: {:?}", - secret!(&xtype), - secret!(&id), - secret!(&value), - secret!(&tags) - ); - - Locator::instance() - .non_secret_controller - .add_record( - wallet_handle, - xtype.into(), - id.into(), - value.into(), - tags.map(serde_json::from_str).transpose()?, - ) - .await?; - - Ok(()) -} - -pub(crate) async fn get_wallet_record( - wallet_handle: WalletHandle, - xtype: &str, - id: &str, - options: &str, -) -> VcxCoreResult { - trace!( - "get_record >>> xtype: {}, id: {}, options: {}", - secret!(&xtype), - secret!(&id), - options - ); - - let res = Locator::instance() - .non_secret_controller - .get_record(wallet_handle, xtype.into(), id.into(), options.into()) - .await?; - - Ok(res) -} - -pub async fn delete_wallet_record( - wallet_handle: WalletHandle, - xtype: &str, - id: &str, -) -> VcxCoreResult<()> { - trace!( - "delete_record >>> xtype: {}, id: {}", - secret!(&xtype), - secret!(&id) - ); - - Locator::instance() - .non_secret_controller - .delete_record(wallet_handle, xtype.into(), id.into()) - .await?; - - Ok(()) -} - -pub(crate) async fn update_wallet_record_value( - wallet_handle: WalletHandle, - xtype: &str, - id: &str, - value: &str, -) -> VcxCoreResult<()> { - trace!( - "update_record_value >>> xtype: {}, id: {}, value: {}", - secret!(&xtype), - secret!(&id), - secret!(&value) - ); - - Locator::instance() - .non_secret_controller - .update_record_value(wallet_handle, xtype.into(), id.into(), value.into()) - .await?; - - Ok(()) -} - -pub(crate) async fn add_wallet_record_tags( - wallet_handle: WalletHandle, - xtype: &str, - id: &str, - tags: &str, -) -> VcxCoreResult<()> { - trace!( - "add_record_tags >>> xtype: {}, id: {}, tags: {:?}", - secret!(&xtype), - secret!(&id), - secret!(&tags) - ); - - Locator::instance() - .non_secret_controller - .add_record_tags( - wallet_handle, - xtype.into(), - id.into(), - serde_json::from_str(tags)?, - ) - .await?; - - Ok(()) -} - -pub(crate) async fn update_wallet_record_tags( - wallet_handle: WalletHandle, - xtype: &str, - id: &str, - tags: &str, -) -> VcxCoreResult<()> { - trace!( - "update_record_tags >>> xtype: {}, id: {}, tags: {}", - secret!(&xtype), - secret!(&id), - secret!(&tags) - ); - - Locator::instance() - .non_secret_controller - .update_record_tags( - wallet_handle, - xtype.into(), - id.into(), - serde_json::from_str(tags)?, - ) - .await?; - - Ok(()) -} - -pub(crate) async fn delete_wallet_record_tags( - wallet_handle: WalletHandle, - xtype: &str, - id: &str, - tag_names: &str, -) -> VcxCoreResult<()> { - trace!( - "delete_record_tags >>> xtype: {}, id: {}, tag_names: {}", - secret!(&xtype), - secret!(&id), - secret!(&tag_names) - ); - - Locator::instance() - .non_secret_controller - .delete_record_tags(wallet_handle, xtype.into(), id.into(), tag_names.into()) - .await?; - - Ok(()) -} - -// TODO - FUTURE - revert to pub(crate) after libvcx dependency is fixed -pub async fn open_search_wallet( - wallet_handle: WalletHandle, - xtype: &str, - query: &str, - options: &str, -) -> VcxCoreResult { - trace!( - "open_search >>> xtype: {}, query: {}, options: {}", - secret!(&xtype), - query, - options - ); - - let res = Locator::instance() - .non_secret_controller - .open_search(wallet_handle, xtype.into(), query.into(), options.into()) - .await?; - - Ok(res) -} - -// TODO - FUTURE - revert to pub(crate) after libvcx dependency is fixed -pub async fn fetch_next_records_wallet( - wallet_handle: WalletHandle, - search_handle: SearchHandle, - count: usize, -) -> VcxCoreResult { - trace!( - "fetch_next_records >>> search_handle: {:?}, count: {}", - search_handle, - count - ); - - let res = Locator::instance() - .non_secret_controller - .fetch_search_next_records(wallet_handle, search_handle, count) - .await?; - - Ok(res) -} - -// TODO - FUTURE - revert to pub(crate) after libvcx dependency is fixed -pub async fn close_search_wallet(search_handle: SearchHandle) -> VcxCoreResult<()> { - trace!("close_search >>> search_handle: {:?}", search_handle); - - Locator::instance() - .non_secret_controller - .close_search(search_handle) - .await?; - - Ok(()) -} diff --git a/aries/aries_vcx_core/src/wallet/indy/mod.rs b/aries/aries_vcx_core/src/wallet/indy/mod.rs index 3bfb69892e..12e861ffb4 100644 --- a/aries/aries_vcx_core/src/wallet/indy/mod.rs +++ b/aries/aries_vcx_core/src/wallet/indy/mod.rs @@ -1,85 +1,29 @@ -use std::thread; - -use async_trait::async_trait; -use futures::executor::block_on; +use indy_api_types::domain::wallet::IndyRecord; use serde::{Deserialize, Serialize}; -use serde_json::Value; use typed_builder::TypedBuilder; -use crate::{ - errors::error::{AriesVcxCoreError, VcxCoreResult}, - utils::{async_fn_iterator::AsyncFnIterator, json::TryGetIndex}, - SearchHandle, WalletHandle, -}; +use self::indy_tags::IndyTags; +use super::base_wallet::{record::Record, BaseWallet}; +use crate::{errors::error::VcxCoreResult, WalletHandle}; -pub mod indy_wallet; +mod indy_did_wallet; +mod indy_record_wallet; +mod indy_tags; pub mod internal; -pub mod signing; pub mod wallet; -pub mod wallet_non_secrets; #[derive(Debug)] pub struct IndySdkWallet { - pub wallet_handle: WalletHandle, + wallet_handle: WalletHandle, } impl IndySdkWallet { pub fn new(wallet_handle: WalletHandle) -> Self { IndySdkWallet { wallet_handle } } -} - -struct IndyWalletRecordIterator { - wallet_handle: WalletHandle, - search_handle: SearchHandle, -} - -impl IndyWalletRecordIterator { - fn new(wallet_handle: WalletHandle, search_handle: SearchHandle) -> Self { - IndyWalletRecordIterator { - wallet_handle, - search_handle, - } - } - - async fn fetch_next_records(&self) -> VcxCoreResult> { - let indy_res_json = - internal::fetch_next_records_wallet(self.wallet_handle, self.search_handle, 1).await?; - - let indy_res: Value = serde_json::from_str(&indy_res_json)?; - - let records = (&indy_res).try_get("records")?; - - let item: Option> = records - .as_array() - .and_then(|arr| arr.first()) - .map(|item| serde_json::to_string(item).map_err(AriesVcxCoreError::from)); - - item.transpose() - } -} - -/// Implementation of a generic [AsyncFnIterator] iterator for indy/vdrtools wallet record -/// iteration. Wraps over the vdrtools record [SearchHandle] functionality -#[async_trait] -impl AsyncFnIterator for IndyWalletRecordIterator { - type Item = VcxCoreResult; - - async fn next(&mut self) -> Option { - let records = self.fetch_next_records().await; - records.transpose() - } -} -impl Drop for IndyWalletRecordIterator { - fn drop(&mut self) { - let search_handle = self.search_handle; - - thread::spawn(move || { - block_on(async { - internal::close_search_wallet(search_handle).await.ok(); - }); - }); + pub fn get_wallet_handle(&self) -> WalletHandle { + self.wallet_handle } } @@ -125,7 +69,7 @@ struct WalletCredentials { } #[derive(Clone, Debug, Serialize, Deserialize)] -pub struct WalletRecord { +pub struct IndyWalletRecord { id: Option, #[serde(rename = "type")] record_type: Option, @@ -133,6 +77,45 @@ pub struct WalletRecord { tags: Option, } +impl IndyWalletRecord { + pub fn from_record(record: Record) -> VcxCoreResult { + let tags = if record.tags().is_empty() { + None + } else { + Some(serde_json::to_string(&record.tags())?) + }; + + Ok(Self { + id: Some(record.name().into()), + record_type: Some(record.category().into()), + value: Some(record.value().into()), + tags, + }) + } +} + +impl From for Record { + fn from(ir: IndyRecord) -> Self { + Self::builder() + .name(ir.id) + .category(ir.type_) + .value(ir.value) + .tags(IndyTags::new(ir.tags).into_entry_tags()) + .build() + } +} + +impl From for IndyRecord { + fn from(record: Record) -> Self { + Self { + id: record.name().into(), + type_: record.category().into(), + value: record.value().into(), + tags: IndyTags::from_entry_tags(record.tags().to_owned()).into_inner(), + } + } +} + #[derive(Clone, Debug, Serialize, Deserialize)] pub struct RestoreWalletConfigs { pub wallet_name: String, @@ -142,3 +125,33 @@ pub struct RestoreWalletConfigs { #[serde(skip_serializing_if = "Option::is_none")] pub wallet_key_derivation: Option, } + +const WALLET_OPTIONS: &str = + r#"{"retrieveType": true, "retrieveValue": true, "retrieveTags": true}"#; + +const SEARCH_OPTIONS: &str = r#"{"retrieveType": true, "retrieveValue": true, "retrieveTags": true, "retrieveRecords": true}"#; + +impl BaseWallet for IndySdkWallet {} + +#[cfg(test)] +pub mod tests { + use super::IndySdkWallet; + + pub async fn dev_setup_indy_wallet() -> IndySdkWallet { + use crate::wallet::indy::{wallet::create_and_open_wallet, WalletConfig}; + + let config_wallet = WalletConfig { + wallet_name: format!("wallet_{}", uuid::Uuid::new_v4()), + wallet_key: "8dvfYSt5d1taSd6yJdpjq4emkwsPDDLYxkNFysFD2cZY".into(), + wallet_key_derivation: "RAW".into(), + wallet_type: None, + storage_config: None, + storage_credentials: None, + rekey: None, + rekey_derivation_method: None, + }; + let wallet_handle = create_and_open_wallet(&config_wallet).await.unwrap(); + + IndySdkWallet::new(wallet_handle) + } +} diff --git a/aries/aries_vcx_core/src/wallet/indy/signing.rs b/aries/aries_vcx_core/src/wallet/indy/signing.rs deleted file mode 100644 index d50c75ea55..0000000000 --- a/aries/aries_vcx_core/src/wallet/indy/signing.rs +++ /dev/null @@ -1,96 +0,0 @@ -use vdrtools::Locator; - -use crate::{ - errors::error::{AriesVcxCoreError, AriesVcxCoreErrorKind, VcxCoreResult}, - WalletHandle, -}; - -pub async fn vdrtools_sign( - wallet_handle: WalletHandle, - my_vk: &str, - msg: &[u8], -) -> VcxCoreResult> { - let res = Locator::instance() - .crypto_controller - .crypto_sign(wallet_handle, my_vk, msg) - .await?; - - Ok(res) -} - -pub async fn vdrtools_verify(vk: &str, msg: &[u8], signature: &[u8]) -> VcxCoreResult { - let res = Locator::instance() - .crypto_controller - .crypto_verify(vk, msg, signature) - .await?; - - Ok(res) -} - -pub async fn vdrtools_pack_message( - wallet_handle: WalletHandle, - sender_vk: Option<&str>, - receiver_keys: &str, - msg: &[u8], -) -> VcxCoreResult> { - // parse json array of keys - let receiver_list = serde_json::from_str::>(receiver_keys) - .map_err(|_| { - AriesVcxCoreError::from_msg( - AriesVcxCoreErrorKind::InvalidJson, - "Invalid RecipientKeys has been passed", - ) - }) - .and_then(|list| { - // break early and error out if no receivers keys are provided - if list.is_empty() { - Err(AriesVcxCoreError::from_msg( - AriesVcxCoreErrorKind::InvalidLibindyParam, - "Empty RecipientKeys has been passed", - )) - } else { - Ok(list) - } - })?; - - let res = Locator::instance() - .crypto_controller - .pack_msg( - msg.into(), - receiver_list, - sender_vk.map(ToOwned::to_owned), - wallet_handle, - ) - .await?; - - Ok(res) -} - -pub async fn vdrtools_unpack_message( - wallet_handle: WalletHandle, - msg: &[u8], -) -> VcxCoreResult> { - let res = Locator::instance() - .crypto_controller - .unpack_msg(serde_json::from_slice(msg)?, wallet_handle) - .await?; - - Ok(res) -} - -pub async fn create_key(wallet_handle: WalletHandle, seed: Option<&str>) -> VcxCoreResult { - use vdrtools::KeyInfo; - - let res = Locator::instance() - .crypto_controller - .create_key( - wallet_handle, - &KeyInfo { - seed: seed.map(ToOwned::to_owned), - crypto_type: None, - }, - ) - .await?; - - Ok(res) -} diff --git a/aries/aries_vcx_core/src/wallet/indy/wallet.rs b/aries/aries_vcx_core/src/wallet/indy/wallet.rs index 1a2da86570..00426d85cf 100644 --- a/aries/aries_vcx_core/src/wallet/indy/wallet.rs +++ b/aries/aries_vcx_core/src/wallet/indy/wallet.rs @@ -3,7 +3,7 @@ use vdrtools::{ domain::wallet::{default_key_derivation_method, KeyDerivationMethod}, errors::IndyErrorKind, }, - DidMethod, DidValue, KeyInfo, Locator, MyDidInfo, WalletHandle, + DidMethod, Locator, MyDidInfo, WalletHandle, }; use crate::{ @@ -232,7 +232,7 @@ pub async fn wallet_configure_issuer( wallet_handle: WalletHandle, key_seed: &str, ) -> VcxCoreResult { - let (institution_did, _institution_verkey) = + let (institution_did, _vk) = create_and_store_my_did(wallet_handle, Some(key_seed), None).await?; Ok(IssuerConfig { institution_did }) @@ -309,39 +309,3 @@ pub async fn create_and_store_my_did( Ok(res) } - -pub async fn libindy_replace_keys_start( - wallet_handle: WalletHandle, - did: &str, -) -> VcxCoreResult { - let res = Locator::instance() - .did_controller - .replace_keys_start(wallet_handle, KeyInfo::default(), DidValue(did.into())) - .await?; - - Ok(res) -} - -pub async fn libindy_replace_keys_apply( - wallet_handle: WalletHandle, - did: &str, -) -> VcxCoreResult<()> { - Locator::instance() - .did_controller - .replace_keys_apply(wallet_handle, DidValue(did.into())) - .await?; - - Ok(()) -} - -pub async fn get_verkey_from_wallet( - wallet_handle: WalletHandle, - did: &str, -) -> VcxCoreResult { - let res = Locator::instance() - .did_controller - .key_for_local_did(wallet_handle, DidValue(did.into())) - .await?; - - Ok(res) -} diff --git a/aries/aries_vcx_core/src/wallet/indy/wallet_non_secrets.rs b/aries/aries_vcx_core/src/wallet/indy/wallet_non_secrets.rs deleted file mode 100644 index 0d55adeaa5..0000000000 --- a/aries/aries_vcx_core/src/wallet/indy/wallet_non_secrets.rs +++ /dev/null @@ -1,133 +0,0 @@ -use serde_json::{self, json}; - -use crate::{ - errors::error::{AriesVcxCoreError, AriesVcxCoreErrorKind, VcxCoreResult}, - wallet::indy::internal::{ - add_wallet_record, delete_wallet_record, get_wallet_record, update_wallet_record_value, - }, - WalletHandle, -}; - -static WALLET_RECORD_TYPE: &str = "cache"; -static RECORD_ID_PREFIX: &str = "rev_reg_delta:"; - -/// Returns stored revocation registry delta record -/// -/// # Arguments -/// `rev_reg_id`: revocation registry id -/// -/// # Returns -/// Revocation registry delta json as a string -/// todo: return VcxResult>, don't swallow errors -pub async fn get_rev_reg_delta(wallet_handle: WalletHandle, rev_reg_id: &str) -> Option { - debug!( - "get_rev_reg_delta >> Getting revocation registry delta for rev_reg_id {}", - rev_reg_id - ); - - let wallet_id = format!("{RECORD_ID_PREFIX}{rev_reg_id}"); - - match get_wallet_record( - wallet_handle, - WALLET_RECORD_TYPE, - &wallet_id, - &json!({"retrieveType": false, "retrieveValue": true, "retrieveTags": false}).to_string(), - ) - .await - { - Ok(json) => match serde_json::from_str(&json).and_then(|x: serde_json::Value| { - serde_json::from_str( - x.get("value") - .unwrap_or(&serde_json::Value::Null) - .as_str() - .unwrap_or(""), - ) - }) { - Ok(cache) => cache, - Err(err) => { - warn!( - "get_rev_reg_delta >> Unable to convert rev_reg_delta cache for rev_reg_id: \ - {}, json: {}, error: {}", - rev_reg_id, json, err - ); - None - } - }, - Err(err) => { - warn!( - "get_rev_reg_delta >> Unable to get rev_reg_delta cache for rev_reg_id: {}, \ - error: {}", - rev_reg_id, err - ); - None - } - } -} - -/// Rewrites or creates revocation registry delta record -/// -/// # Arguments -/// `rev_reg_id`: revocation registry id. -/// `cache`: Cache object. -pub async fn set_rev_reg_delta( - wallet_handle: WalletHandle, - rev_reg_id: &str, - cache: &str, -) -> VcxCoreResult<()> { - debug!( - "set_rev_reg_delta >> Setting store revocation registry delta for revocation registry {} \ - to new value: {}", - rev_reg_id, cache - ); - match serde_json::to_string(cache) { - Ok(json) => { - let wallet_id = format!("{RECORD_ID_PREFIX}{rev_reg_id}"); - match update_wallet_record_value(wallet_handle, WALLET_RECORD_TYPE, &wallet_id, &json) - .await - .or( - add_wallet_record(wallet_handle, WALLET_RECORD_TYPE, &wallet_id, &json, None) - .await, - ) { - Ok(_) => Ok(()), - Err(err) => Err(err), - } - } - Err(_) => Err(AriesVcxCoreError::from_msg( - AriesVcxCoreErrorKind::SerializationError, - format!("Expected cache argument to be valid json. Found instead: {cache}"), - )), - } -} - -/// Clears the stored revocation registry delta record -/// -/// # Arguments -/// `rev_reg_id`: revocation registry id. -/// `cache`: Cache object. -pub async fn clear_rev_reg_delta( - wallet_handle: WalletHandle, - rev_reg_id: &str, -) -> VcxCoreResult { - debug!( - "clear_rev_reg_delta >> Clear revocation registry delta for rev_reg_id {}", - rev_reg_id - ); - if let Some(last_delta) = get_rev_reg_delta(wallet_handle, rev_reg_id).await { - let wallet_id = format!("{RECORD_ID_PREFIX}{rev_reg_id}"); - delete_wallet_record(wallet_handle, WALLET_RECORD_TYPE, &wallet_id).await?; - info!( - "clear_rev_reg_delta >> Cleared stored revocation delta for revocation registry {}, \ - wallet record: ${}", - rev_reg_id, wallet_id - ); - Ok(last_delta) - } else { - Err(AriesVcxCoreError::from_msg( - AriesVcxCoreErrorKind::IOError, - format!( - "Couldn't fetch delta for rev_reg_id {rev_reg_id} before deletion, deletion \ - skipped" - ), - )) - } -} diff --git a/aries/aries_vcx_core/src/wallet/mock_wallet.rs b/aries/aries_vcx_core/src/wallet/mock_wallet.rs index e368d9deac..bf7560bd14 100644 --- a/aries/aries_vcx_core/src/wallet/mock_wallet.rs +++ b/aries/aries_vcx_core/src/wallet/mock_wallet.rs @@ -1,146 +1,114 @@ -use std::collections::HashMap; - use async_trait::async_trait; +use public_key::{Key, KeyType}; -use super::structs_io::UnpackMessageOutput; -#[cfg(feature = "vdrtools_wallet")] -use crate::WalletHandle; +use super::{ + base_wallet::{ + did_data::DidData, record::Record, search_filter::SearchFilter, BaseWallet, DidWallet, + RecordWallet, + }, + structs_io::UnpackMessageOutput, +}; use crate::{ errors::error::{AriesVcxCoreError, AriesVcxCoreErrorKind, VcxCoreResult}, - utils::{ - async_fn_iterator::AsyncFnIterator, - {self}, - }, - wallet::base_wallet::BaseWallet, + utils::{self}, + wallet::entry_tags::EntryTags, }; #[derive(Debug)] pub struct MockWallet; -// NOTE : currently matches the expected results if did_mocks and indy_mocks are enabled -/// Implementation of [BaseAnoncreds] which responds with mock data -#[allow(unused)] -#[async_trait] -impl BaseWallet for MockWallet { - #[cfg(feature = "vdrtools_wallet")] - fn get_wallet_handle(&self) -> WalletHandle { - WalletHandle(1) - } - - async fn create_and_store_my_did( - &self, - seed: Option<&str>, - method_name: Option<&str>, - ) -> VcxCoreResult<(String, String)> { - Ok(( - utils::constants::DID.to_string(), - utils::constants::VERKEY.to_string(), - )) - } - - async fn key_for_local_did(&self, did: &str) -> VcxCoreResult { - Ok(utils::constants::VERKEY.to_string()) - } +impl BaseWallet for MockWallet {} - async fn replace_did_keys_start(&self, target_did: &str) -> VcxCoreResult { - Ok(utils::constants::VERKEY.to_string()) +#[async_trait] +#[allow(unused_variables)] +impl RecordWallet for MockWallet { + async fn add_record(&self, record: Record) -> VcxCoreResult<()> { + Ok(()) } - async fn replace_did_keys_apply(&self, target_did: &str) -> VcxCoreResult<()> { - Ok(()) + async fn get_record(&self, category: &str, name: &str) -> VcxCoreResult { + Ok(Record::builder() + .name("123".into()) + .category("record type".into()) + .value("record value".into()) + .build()) } - async fn add_wallet_record( + async fn update_record_value( &self, - xtype: &str, - id: &str, - value: &str, - tags: Option>, + category: &str, + name: &str, + new_value: &str, ) -> VcxCoreResult<()> { Ok(()) } - async fn get_wallet_record( + async fn update_record_tags( &self, - xtype: &str, - id: &str, - options: &str, - ) -> VcxCoreResult { - Ok(r#"{"id":"123","type":"record type","value":"record value","tags":null}"#.to_string()) - } - - async fn get_wallet_record_value(&self, xtype: &str, id: &str) -> VcxCoreResult { - Ok(r#""record value""#.to_owned()) + category: &str, + name: &str, + new_tags: EntryTags, + ) -> VcxCoreResult<()> { + Ok(()) } - async fn delete_wallet_record(&self, xtype: &str, id: &str) -> VcxCoreResult<()> { + async fn delete_record(&self, category: &str, name: &str) -> VcxCoreResult<()> { Ok(()) } - async fn update_wallet_record_value( + async fn search_record( &self, - xtype: &str, - id: &str, - value: &str, - ) -> VcxCoreResult<()> { - Ok(()) + category: &str, + search_filter: Option, + ) -> VcxCoreResult> { + Err(AriesVcxCoreError::from_msg( + AriesVcxCoreErrorKind::UnimplementedFeature, + "unimplemented mock method: search_record", + )) } +} - async fn add_wallet_record_tags( +#[async_trait] +#[allow(unused_variables)] +impl DidWallet for MockWallet { + async fn create_and_store_my_did( &self, - xtype: &str, - id: &str, - tags: HashMap, - ) -> VcxCoreResult<()> { - Ok(()) + seed: Option<&str>, + method_name: Option<&str>, + ) -> VcxCoreResult { + Ok(DidData::new( + utils::constants::DID, + Key::new(utils::constants::VERKEY.into(), KeyType::Ed25519).unwrap(), + )) } - async fn update_wallet_record_tags( - &self, - xtype: &str, - id: &str, - tags: HashMap, - ) -> VcxCoreResult<()> { - Ok(()) + async fn key_for_did(&self, name: &str) -> VcxCoreResult { + Ok(Key::new(utils::constants::VERKEY.into(), KeyType::Ed25519).unwrap()) } - async fn delete_wallet_record_tags( - &self, - xtype: &str, - id: &str, - tag_names: &str, - ) -> VcxCoreResult<()> { - Ok(()) + async fn replace_did_key_start(&self, did: &str, seed: Option<&str>) -> VcxCoreResult { + Ok(Key::new(utils::constants::VERKEY.into(), KeyType::Ed25519).unwrap()) } - async fn iterate_wallet_records( - &self, - xtype: &str, - query: &str, - options: &str, - ) -> VcxCoreResult>>> { - // not needed yet - Err(AriesVcxCoreError::from_msg( - AriesVcxCoreErrorKind::UnimplementedFeature, - "unimplemented mock method: iterate_wallet_records", - )) + async fn replace_did_key_apply(&self, did: &str) -> VcxCoreResult<()> { + Ok(()) } - async fn sign(&self, my_vk: &str, msg: &[u8]) -> VcxCoreResult> { + async fn sign(&self, key: &Key, msg: &[u8]) -> VcxCoreResult> { Ok(Vec::from(msg)) } - async fn verify(&self, vk: &str, msg: &[u8], signature: &[u8]) -> VcxCoreResult { + async fn verify(&self, key: &Key, msg: &[u8], signature: &[u8]) -> VcxCoreResult { Ok(true) } async fn pack_message( &self, - sender_vk: Option<&str>, - receiver_keys: &str, + sender_vk: Option, + receiver_keys: Vec, msg: &[u8], ) -> VcxCoreResult> { - Ok(msg.to_vec()) + Ok(Vec::from(msg)) } async fn unpack_message(&self, msg: &[u8]) -> VcxCoreResult { diff --git a/aries/aries_vcx_core/src/wallet/mod.rs b/aries/aries_vcx_core/src/wallet/mod.rs index 32ede501ec..d94145b889 100644 --- a/aries/aries_vcx_core/src/wallet/mod.rs +++ b/aries/aries_vcx_core/src/wallet/mod.rs @@ -1,5 +1,6 @@ pub mod agency_client_wallet; pub mod base_wallet; +pub mod entry_tags; #[cfg(feature = "vdrtools_wallet")] pub mod indy; pub mod mock_wallet; diff --git a/aries/aries_vcx_core/src/wallet2/entry_tag.rs b/aries/aries_vcx_core/src/wallet2/entry_tag.rs deleted file mode 100644 index df0682daf4..0000000000 --- a/aries/aries_vcx_core/src/wallet2/entry_tag.rs +++ /dev/null @@ -1,62 +0,0 @@ -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] -pub enum EntryTag { - Encrypted(String, String), - Plaintext(String, String), -} - -#[derive(Debug, Default, Clone, PartialEq)] -pub struct EntryTags { - inner: Vec, -} - -impl EntryTags { - pub fn new(inner: Vec) -> Self { - Self { inner } - } - - pub fn add(&mut self, tag: EntryTag) { - self.inner.push(tag) - } - - pub fn is_empty(&self) -> bool { - self.inner.is_empty() - } -} - -impl IntoIterator for EntryTags { - type Item = EntryTag; - - type IntoIter = std::vec::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - self.inner.into_iter() - } -} - -impl FromIterator for EntryTags { - fn from_iter>(iter: T) -> Self { - let mut tags = Self::default(); - - for item in iter { - tags.add(item); - } - tags - } -} - -impl From> for EntryTags { - fn from(value: Vec) -> Self { - value.into_iter().fold(Self::default(), |mut memo, item| { - memo.add(item); - memo - }) - } -} - -impl From for Vec { - fn from(value: EntryTags) -> Self { - value.inner - } -} diff --git a/aries/aries_vcx_core/src/wallet2/indy_wallet/mod.rs b/aries/aries_vcx_core/src/wallet2/indy_wallet/mod.rs deleted file mode 100644 index d0b8c6d324..0000000000 --- a/aries/aries_vcx_core/src/wallet2/indy_wallet/mod.rs +++ /dev/null @@ -1,62 +0,0 @@ -use std::collections::HashMap; - -use super::{ - entry_tag::{EntryTag, EntryTags}, - BaseWallet2, -}; -use crate::wallet::indy::IndySdkWallet; - -pub mod indy_did_wallet; -pub mod indy_record_wallet; - -const WALLET_OPTIONS: &str = - r#"{"retrieveType": true, "retrieveValue": true, "retrieveTags": true}"#; - -const SEARCH_OPTIONS: &str = r#"{"retrieveType": true, "retrieveValue": true, "retrieveTags": true, "retrieveRecords": true}"#; - -impl BaseWallet2 for IndySdkWallet {} - -impl From for (String, String) { - fn from(value: EntryTag) -> Self { - match value { - EntryTag::Encrypted(key, val) => (key, val), - EntryTag::Plaintext(key, val) => (format!("~{}", key), val), - } - } -} - -impl From<(String, String)> for EntryTag { - fn from(value: (String, String)) -> Self { - if value.0.starts_with('~') { - EntryTag::Plaintext(value.0.trim_start_matches('~').into(), value.1) - } else { - EntryTag::Encrypted(value.0, value.1) - } - } -} - -impl From for HashMap { - fn from(value: EntryTags) -> Self { - let tags: Vec = value.into(); - tags.into_iter().fold(Self::new(), |mut memo, item| { - let (key, value) = item.into(); - - memo.insert(key, value); - memo - }) - } -} - -impl From> for EntryTags { - fn from(value: HashMap) -> Self { - let mut items: Vec = value - .into_iter() - .map(|(key, value)| (key, value)) - .map(From::from) - .collect(); - - items.sort(); - - Self::new(items) - } -} diff --git a/aries/aries_vcx_core/src/wallet2/utils.rs b/aries/aries_vcx_core/src/wallet2/utils.rs deleted file mode 100644 index c39da4485f..0000000000 --- a/aries/aries_vcx_core/src/wallet2/utils.rs +++ /dev/null @@ -1,9 +0,0 @@ -use rand::{distributions::Alphanumeric, Rng}; - -pub fn random_seed() -> String { - rand::thread_rng() - .sample_iter(Alphanumeric) - .take(32) - .map(char::from) - .collect() -} diff --git a/aries/misc/legacy/libvcx_core/Cargo.toml b/aries/misc/legacy/libvcx_core/Cargo.toml index 3295bda016..cfa32e1761 100644 --- a/aries/misc/legacy/libvcx_core/Cargo.toml +++ b/aries/misc/legacy/libvcx_core/Cargo.toml @@ -26,6 +26,7 @@ futures = { version = "0.3", default-features = false } aries_vcx = { path = "../../../aries_vcx", features = ["credx", "vdrtools_wallet"] } aries_vcx_core = { path = "../../../aries_vcx_core" } diddoc_legacy = { path = "../diddoc_legacy" } +public_key = { path = "../../../../did_core/public_key" } thiserror = "1.0.37" uuid = { version = "1.4.1", default-features = false, features = ["v4"] } agency_client = { path = "../agency_client" } diff --git a/aries/misc/legacy/libvcx_core/src/api_vcx/api_global/agency_client.rs b/aries/misc/legacy/libvcx_core/src/api_vcx/api_global/agency_client.rs index 8f4da713bb..fdb05c9dcc 100644 --- a/aries/misc/legacy/libvcx_core/src/api_vcx/api_global/agency_client.rs +++ b/aries/misc/legacy/libvcx_core/src/api_vcx/api_global/agency_client.rs @@ -10,7 +10,7 @@ use aries_vcx::agency_client::{ MessageStatusCode, }; use aries_vcx_core::wallet::{ - agency_client_wallet::ToBaseAgencyClientWallet, base_wallet::BaseWallet, + agency_client_wallet::ToBaseAgencyClientWallet, base_wallet::DidWallet, }; use super::profile::get_main_wallet; @@ -81,12 +81,12 @@ pub async fn provision_cloud_agent( let wallet = get_main_wallet()?; let mut client = get_main_agency_client()?; let seed = agency_config.agent_seed.as_deref(); - let (my_did, my_vk) = wallet.create_and_store_my_did(seed, None).await?; + let did_data = wallet.create_and_store_my_did(seed, None).await?; client .provision_cloud_agent( wallet.to_base_agency_client_wallet(), - &my_did, - &my_vk, + did_data.did(), + &did_data.verkey().base58(), &agency_config.agency_did, &agency_config.agency_verkey, agency_config.agency_endpoint.clone(), diff --git a/aries/misc/legacy/libvcx_core/src/api_vcx/api_global/profile.rs b/aries/misc/legacy/libvcx_core/src/api_vcx/api_global/profile.rs index 428a3dd466..6863338194 100644 --- a/aries/misc/legacy/libvcx_core/src/api_vcx/api_global/profile.rs +++ b/aries/misc/legacy/libvcx_core/src/api_vcx/api_global/profile.rs @@ -5,11 +5,13 @@ use aries_vcx::{ aries_vcx_core::{ anoncreds::base_anoncreds::BaseAnonCreds, ledger::base_ledger::{IndyLedgerRead, IndyLedgerWrite}, - wallet::base_wallet::BaseWallet, }, }; -use aries_vcx_core::ledger::base_ledger::{ - AnoncredsLedgerRead, AnoncredsLedgerWrite, TaaConfigurator, TxnAuthrAgrmtOptions, +use aries_vcx_core::{ + ledger::base_ledger::{ + AnoncredsLedgerRead, AnoncredsLedgerWrite, TaaConfigurator, TxnAuthrAgrmtOptions, + }, + wallet::indy::IndySdkWallet, }; use crate::{ @@ -20,14 +22,14 @@ use crate::{ errors::error::{LibvcxError, LibvcxErrorKind, LibvcxResult}, }; -pub fn try_get_main_wallet() -> LibvcxResult>> { +pub fn try_get_main_wallet() -> LibvcxResult>> { let base_wallet = GLOBAL_BASE_WALLET.read()?; base_wallet.as_ref().cloned().map(Some).ok_or_else(|| { LibvcxError::from_msg(LibvcxErrorKind::NotReady, "Wallet is not initialized") }) } -pub fn get_main_wallet() -> LibvcxResult> { +pub fn get_main_wallet() -> LibvcxResult> { let base_wallet = GLOBAL_BASE_WALLET.read()?; base_wallet.as_ref().cloned().ok_or_else(|| { LibvcxError::from_msg(LibvcxErrorKind::NotReady, "Wallet is not initialized") diff --git a/aries/misc/legacy/libvcx_core/src/api_vcx/api_global/wallet.rs b/aries/misc/legacy/libvcx_core/src/api_vcx/api_global/wallet.rs index c5fad7af17..524bea752b 100644 --- a/aries/misc/legacy/libvcx_core/src/api_vcx/api_global/wallet.rs +++ b/aries/misc/legacy/libvcx_core/src/api_vcx/api_global/wallet.rs @@ -1,14 +1,10 @@ -use std::{ - collections::HashMap, - sync::{Arc, RwLock}, -}; +use std::sync::{Arc, RwLock}; use aries_vcx::{ aries_vcx_core::{ anoncreds::{base_anoncreds::BaseAnonCreds, credx_anoncreds::IndyCredxAnonCreds}, wallet, wallet::{ - base_wallet::BaseWallet, indy::{ internal::{close_search_wallet, fetch_next_records_wallet, open_search_wallet}, wallet::{close_wallet, create_indy_wallet, import, open_wallet}, @@ -21,6 +17,13 @@ use aries_vcx::{ global::settings::DEFAULT_LINK_SECRET_ALIAS, protocols::mediated_connection::pairwise_info::PairwiseInfo, }; +use aries_vcx_core::wallet::{ + base_wallet::{record::Record, DidWallet, RecordWallet}, + entry_tags::EntryTags, + indy::IndyWalletRecord, +}; +use futures::FutureExt; +use public_key::{Key, KeyType}; use crate::{ api_vcx::api_global::profile::{ @@ -113,22 +116,33 @@ pub async fn create_main_wallet(config: &WalletConfig) -> LibvcxResult<()> { pub async fn key_for_local_did(did: &str) -> LibvcxResult { let wallet = get_main_wallet()?; - map_ariesvcx_core_result(wallet.key_for_local_did(did).await) + + map_ariesvcx_core_result(wallet.key_for_did(did).await.map(|key| key.base58())) } pub async fn wallet_sign(vk: &str, data_raw: &[u8]) -> LibvcxResult> { let wallet = get_main_wallet()?; - map_ariesvcx_core_result(wallet.sign(vk, data_raw).await) + + let verkey = Key::from_base58(vk, KeyType::Ed25519)?; + map_ariesvcx_core_result(wallet.sign(&verkey, data_raw).await) } pub async fn wallet_verify(vk: &str, msg: &[u8], signature: &[u8]) -> LibvcxResult { let wallet = get_main_wallet()?; - map_ariesvcx_core_result(wallet.verify(vk, msg, signature).await) + + let verkey = Key::from_base58(vk, KeyType::Ed25519)?; + map_ariesvcx_core_result(wallet.verify(&verkey, msg, signature).await) } pub async fn replace_did_keys_start(did: &str) -> LibvcxResult { let wallet = get_main_wallet()?; - map_ariesvcx_core_result(wallet.replace_did_keys_start(did).await) + + map_ariesvcx_core_result( + wallet + .replace_did_key_start(did, None) + .await + .map(|key| key.base58()), + ) } pub async fn rotate_verkey_apply(did: &str, temp_vk: &str) -> LibvcxResult<()> { @@ -150,8 +164,11 @@ pub async fn wallet_unpack_message(payload: &[u8]) -> LibvcxResult) -> LibvcxResult { let wallet = get_main_wallet()?; - let (pw_did, pw_vk) = wallet.create_and_store_my_did(seed, None).await?; - Ok(PairwiseInfo { pw_did, pw_vk }) + let did_data = wallet.create_and_store_my_did(seed, None).await?; + Ok(PairwiseInfo { + pw_did: did_data.did().into(), + pw_vk: did_data.verkey().base58(), + }) } pub async fn wallet_configure_issuer(enterprise_seed: &str) -> LibvcxResult { @@ -169,8 +186,24 @@ pub async fn wallet_add_wallet_record( option: Option<&str>, ) -> LibvcxResult<()> { let wallet = get_main_wallet()?; - let tags: Option> = option.map(serde_json::from_str).transpose()?; - map_ariesvcx_core_result(wallet.add_wallet_record(type_, id, value, tags).await) + let tags: Option = option.map(serde_json::from_str).transpose()?; + + let record = if let Some(record_tags) = tags { + Record::builder() + .name(id.into()) + .category(type_.into()) + .value(value.into()) + .tags(record_tags) + .build() + } else { + Record::builder() + .name(id.into()) + .category(type_.into()) + .value(value.into()) + .build() + }; + + map_ariesvcx_core_result(wallet.add_record(record).await) } pub async fn wallet_update_wallet_record_value( @@ -179,7 +212,7 @@ pub async fn wallet_update_wallet_record_value( value: &str, ) -> LibvcxResult<()> { let wallet = get_main_wallet()?; - map_ariesvcx_core_result(wallet.update_wallet_record_value(xtype, id, value).await) + map_ariesvcx_core_result(wallet.update_record_value(xtype, id, value).await) } pub async fn wallet_update_wallet_record_tags( @@ -188,8 +221,8 @@ pub async fn wallet_update_wallet_record_tags( tags_json: &str, ) -> LibvcxResult<()> { let wallet = get_main_wallet()?; - let tags: HashMap = serde_json::from_str(tags_json)?; - map_ariesvcx_core_result(wallet.update_wallet_record_tags(xtype, id, tags).await) + let tags = serde_json::from_str(tags_json)?; + map_ariesvcx_core_result(wallet.update_record_tags(xtype, id, tags).await) } pub async fn wallet_add_wallet_record_tags( @@ -198,8 +231,15 @@ pub async fn wallet_add_wallet_record_tags( tags_json: &str, ) -> LibvcxResult<()> { let wallet = get_main_wallet()?; - let tags: HashMap = serde_json::from_str(tags_json)?; - map_ariesvcx_core_result(wallet.add_wallet_record_tags(xtype, id, tags).await) + let record = wallet.get_record(xtype, id).await?; + + let tags = { + let mut tags: EntryTags = serde_json::from_str(tags_json)?; + tags.merge(record.tags().clone()); + tags + }; + + map_ariesvcx_core_result(wallet.update_record_tags(xtype, id, tags).await) } pub async fn wallet_delete_wallet_record_tags( @@ -208,21 +248,40 @@ pub async fn wallet_delete_wallet_record_tags( tags_json: &str, ) -> LibvcxResult<()> { let wallet = get_main_wallet()?; - map_ariesvcx_core_result(wallet.delete_wallet_record_tags(xtype, id, tags_json).await) + let tags: EntryTags = serde_json::from_str(tags_json)?; + + let record = wallet.get_record(xtype, id).await?; + + let mut found_tags = record.tags().clone(); + for key in tags { + found_tags.remove(key); + } + + map_ariesvcx_core_result(wallet.update_record_tags(xtype, id, found_tags).await) } pub async fn wallet_get_wallet_record( xtype: &str, id: &str, - options: &str, + _options: &str, ) -> LibvcxResult { let wallet = get_main_wallet()?; - map_ariesvcx_core_result(wallet.get_wallet_record(xtype, id, options).await) + + map_ariesvcx_result( + wallet + .get_record(xtype, id) + .map(|res| { + let wallet_record = IndyWalletRecord::from_record(res?)?; + + Ok(serde_json::to_string(&wallet_record)?) + }) + .await, + ) } pub async fn wallet_delete_wallet_record(xtype: &str, id: &str) -> LibvcxResult<()> { let wallet = get_main_wallet()?; - map_ariesvcx_core_result(wallet.delete_wallet_record(xtype, id).await) + map_ariesvcx_core_result(wallet.delete_record(xtype, id).await) } pub async fn wallet_open_search_wallet( @@ -285,7 +344,7 @@ pub mod test_utils { aries_vcx_core::wallet::indy::WalletConfig, global::settings::{DEFAULT_WALLET_BACKUP_KEY, DEFAULT_WALLET_KEY, WALLET_KDF_RAW}, }; - use aries_vcx_core::wallet::base_wallet::BaseWallet; + use aries_vcx_core::wallet::base_wallet::{record::Record, DidWallet, RecordWallet}; use crate::{ api_vcx::api_global::{ @@ -323,10 +382,14 @@ pub mod test_utils { let wallet = get_main_wallet().unwrap(); wallet.create_and_store_my_did(None, None).await.unwrap(); let (type_, id, value) = _record(); - wallet - .add_wallet_record(type_, id, value, None) - .await - .unwrap(); + + let new_record = Record::builder() + .name(id.into()) + .category(type_.into()) + .value(value.into()) + .build(); + + wallet.add_record(new_record).await.unwrap(); export_main_wallet(&export_file.path, DEFAULT_WALLET_BACKUP_KEY) .await .unwrap(); @@ -359,7 +422,7 @@ pub mod test_utils { mod tests { use aries_vcx::{ aries_vcx_core::wallet::indy::{ - wallet::delete_wallet, RestoreWalletConfigs, WalletConfig, WalletRecord, + wallet::delete_wallet, IndyWalletRecord, RestoreWalletConfigs, WalletConfig, }, global::settings::{DEFAULT_WALLET_BACKUP_KEY, DEFAULT_WALLET_KEY, WALLET_KDF_RAW}, }; @@ -496,7 +559,7 @@ mod tests { .to_string(); let record = wallet_get_wallet_record(&xtype, &id, &options).await?; - let record: WalletRecord = serde_json::from_str(&record)?; + let record: IndyWalletRecord = serde_json::from_str(&record)?; assert_eq!(record.value.unwrap(), value); Ok(()) } @@ -671,7 +734,7 @@ mod tests { .await .unwrap(); let record = wallet_get_wallet_record(&xtype, &id, "{}").await.unwrap(); - let record: WalletRecord = serde_json::from_str(&record).unwrap(); + let record: IndyWalletRecord = serde_json::from_str(&record).unwrap(); assert_eq!(record.value.unwrap(), new_value); } } diff --git a/aries/misc/legacy/libvcx_core/src/errors/mapping_from_others.rs b/aries/misc/legacy/libvcx_core/src/errors/mapping_from_others.rs index 6f5e3ff7cb..c5c90b1969 100644 --- a/aries/misc/legacy/libvcx_core/src/errors/mapping_from_others.rs +++ b/aries/misc/legacy/libvcx_core/src/errors/mapping_from_others.rs @@ -1,5 +1,7 @@ use std::sync::PoisonError; +use public_key::PublicKeyError; + use crate::errors::error::{LibvcxError, LibvcxErrorKind}; impl From> for LibvcxError { @@ -13,3 +15,9 @@ impl From for LibvcxError { LibvcxError::from_msg(LibvcxErrorKind::InvalidJson, "Invalid json".to_string()) } } + +impl From for LibvcxError { + fn from(value: PublicKeyError) -> Self { + LibvcxError::from_msg(LibvcxErrorKind::InvalidVerkey, value) + } +} diff --git a/aries/misc/legacy/libvdrtools/indy-api-types/src/domain/wallet/mod.rs b/aries/misc/legacy/libvdrtools/indy-api-types/src/domain/wallet/mod.rs index b5a008cefe..7d1fa5271f 100644 --- a/aries/misc/legacy/libvdrtools/indy-api-types/src/domain/wallet/mod.rs +++ b/aries/misc/legacy/libvdrtools/indy-api-types/src/domain/wallet/mod.rs @@ -74,7 +74,7 @@ pub struct KeyConfig { } #[derive(Serialize, Deserialize)] -pub struct Record { +pub struct IndyRecord { // Wallet record type #[serde(rename = "type")] pub type_: String, @@ -86,7 +86,7 @@ pub struct Record { pub tags: HashMap, } -impl fmt::Debug for Record { +impl fmt::Debug for IndyRecord { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Record") .field("type_", &self.type_) diff --git a/aries/misc/legacy/libvdrtools/indy-wallet/src/export_import.rs b/aries/misc/legacy/libvdrtools/indy-wallet/src/export_import.rs index 3dd2eb2e46..a8e646f161 100644 --- a/aries/misc/legacy/libvdrtools/indy-wallet/src/export_import.rs +++ b/aries/misc/legacy/libvdrtools/indy-wallet/src/export_import.rs @@ -7,7 +7,7 @@ use std::{ use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use indy_api_types::{ - domain::wallet::{KeyDerivationMethod, Record}, + domain::wallet::{IndyRecord, KeyDerivationMethod}, errors::prelude::*, }; use indy_utils::crypto::{ @@ -139,7 +139,7 @@ pub(super) async fn export_continue( tags, }) = records.next().await? { - let record = Record { + let record = IndyRecord { type_: type_.ok_or_else(|| { err_msg( IndyErrorKind::InvalidState, @@ -300,7 +300,7 @@ where let mut record = vec![0u8; record_len]; reader.read_exact(&mut record).map_err(_map_io_err)?; - let record: Record = rmp_serde::from_slice(&record).to_indy( + let record: IndyRecord = rmp_serde::from_slice(&record).to_indy( IndyErrorKind::InvalidStructure, "Record is malformed msgpack", )?; diff --git a/aries/misc/legacy/libvdrtools/indy-wallet/src/lib.rs b/aries/misc/legacy/libvdrtools/indy-wallet/src/lib.rs index 8ebda41fe7..84bac326bb 100644 --- a/aries/misc/legacy/libvdrtools/indy-wallet/src/lib.rs +++ b/aries/misc/legacy/libvdrtools/indy-wallet/src/lib.rs @@ -8,7 +8,7 @@ use std::{ }; use indy_api_types::{ - domain::wallet::{CacheConfig, Config, Credentials, ExportConfig, Record, Tags}, + domain::wallet::{CacheConfig, Config, Credentials, ExportConfig, IndyRecord, Tags}, errors::prelude::*, WalletHandle, }; @@ -713,7 +713,7 @@ impl WalletService { &self, old_wh: WalletHandle, new_wh: WalletHandle, - mut migrate_fn: impl FnMut(Record) -> Result, E>, + mut migrate_fn: impl FnMut(IndyRecord) -> Result, E>, ) -> IndyResult where E: std::fmt::Display, @@ -768,7 +768,7 @@ impl WalletService { Some(tags) => tags.clone(), }; - let record = Record { + let record = IndyRecord { type_: unwrapped_type_, id: source_record.id.clone(), value: unwrapped_value, diff --git a/aries/misc/legacy/libvdrtools/src/controllers/wallet.rs b/aries/misc/legacy/libvdrtools/src/controllers/wallet.rs index 980507ad89..11eb3a8404 100644 --- a/aries/misc/legacy/libvdrtools/src/controllers/wallet.rs +++ b/aries/misc/legacy/libvdrtools/src/controllers/wallet.rs @@ -2,7 +2,7 @@ use std::sync::Arc; // use async_std::task::spawn_blocking; use indy_api_types::{ - domain::wallet::{Config, Credentials, ExportConfig, KeyConfig, Record}, + domain::wallet::{Config, Credentials, ExportConfig, IndyRecord, KeyConfig}, errors::prelude::*, WalletHandle, }; @@ -391,7 +391,7 @@ impl WalletController { &self, old_wh: WalletHandle, new_wh: WalletHandle, - migrate_fn: impl FnMut(Record) -> Result, E>, + migrate_fn: impl FnMut(IndyRecord) -> Result, E>, ) -> IndyResult where E: std::fmt::Display, diff --git a/aries/misc/wallet_migrator/src/credx2anoncreds/conv.rs b/aries/misc/wallet_migrator/src/credx2anoncreds/conv.rs index 007995c829..e30267ef93 100644 --- a/aries/misc/wallet_migrator/src/credx2anoncreds/conv.rs +++ b/aries/misc/wallet_migrator/src/credx2anoncreds/conv.rs @@ -1,43 +1,43 @@ -use vdrtools::types::domain::wallet::Record; +use vdrtools::types::domain::wallet::IndyRecord; use crate::error::MigrationResult; -pub fn convert_master_secret(record: Record) -> MigrationResult { +pub fn convert_master_secret(record: IndyRecord) -> MigrationResult { Ok(record) } -pub fn convert_cred(record: Record) -> MigrationResult { +pub fn convert_cred(record: IndyRecord) -> MigrationResult { Ok(record) } -pub fn convert_cred_def(record: Record) -> MigrationResult { +pub fn convert_cred_def(record: IndyRecord) -> MigrationResult { Ok(record) } -pub fn convert_cred_def_priv_key(record: Record) -> MigrationResult { +pub fn convert_cred_def_priv_key(record: IndyRecord) -> MigrationResult { Ok(record) } -pub fn convert_cred_def_correctness_proof(record: Record) -> MigrationResult { +pub fn convert_cred_def_correctness_proof(record: IndyRecord) -> MigrationResult { Ok(record) } -pub fn convert_schema(record: Record) -> MigrationResult { +pub fn convert_schema(record: IndyRecord) -> MigrationResult { Ok(record) } -pub fn convert_rev_reg(record: Record) -> MigrationResult { +pub fn convert_rev_reg(record: IndyRecord) -> MigrationResult { Ok(record) } -pub fn convert_rev_reg_delta(record: Record) -> MigrationResult { +pub fn convert_rev_reg_delta(record: IndyRecord) -> MigrationResult { Ok(record) } -pub fn convert_rev_reg_def(record: Record) -> MigrationResult { +pub fn convert_rev_reg_def(record: IndyRecord) -> MigrationResult { Ok(record) } -pub fn convert_rev_reg_def_priv(record: Record) -> MigrationResult { +pub fn convert_rev_reg_def_priv(record: IndyRecord) -> MigrationResult { Ok(record) } diff --git a/aries/misc/wallet_migrator/src/lib.rs b/aries/misc/wallet_migrator/src/lib.rs index 4f0ded459c..d29b523efe 100644 --- a/aries/misc/wallet_migrator/src/lib.rs +++ b/aries/misc/wallet_migrator/src/lib.rs @@ -6,7 +6,7 @@ use std::fmt::Display; use error::MigrationResult; use log::{error, info}; -pub use vdrtools::types::domain::wallet::Record; +pub use vdrtools::types::domain::wallet::IndyRecord; use vdrtools::{Locator, WalletHandle}; use crate::error::MigrationError; @@ -17,7 +17,7 @@ use crate::error::MigrationError; pub async fn migrate_wallet( src_wallet_handle: WalletHandle, dest_wallet_handle: WalletHandle, - migrate_fn: impl FnMut(Record) -> Result, E>, + migrate_fn: impl FnMut(IndyRecord) -> Result, E>, ) -> MigrationResult<()> where E: Display, diff --git a/aries/misc/wallet_migrator/src/vdrtools2credx/conv.rs b/aries/misc/wallet_migrator/src/vdrtools2credx/conv.rs index 219523ec23..c8256f3661 100644 --- a/aries/misc/wallet_migrator/src/vdrtools2credx/conv.rs +++ b/aries/misc/wallet_migrator/src/vdrtools2credx/conv.rs @@ -4,14 +4,14 @@ use aries_vcx_core::anoncreds::credx_anoncreds::{ CATEGORY_LINK_SECRET, CATEGORY_REV_REG, CATEGORY_REV_REG_DEF, CATEGORY_REV_REG_DEF_PRIV, CATEGORY_REV_REG_DELTA, CATEGORY_REV_REG_INFO, }; -use vdrtools::{types::domain::wallet::Record, IndyError}; +use vdrtools::{types::domain::wallet::IndyRecord, IndyError}; use crate::error::MigrationResult; // The deltas in libvdrtools are prefixed. For absolutely no reason. const REV_REG_DELTA_ID_PREFIX: &str = "rev_reg_delta:"; -pub fn convert_master_secret(mut record: Record) -> MigrationResult { +pub fn convert_master_secret(mut record: IndyRecord) -> MigrationResult { let master_secret: vdrtools::MasterSecret = serde_json::from_str(&record.value)?; record.value = master_secret @@ -26,25 +26,25 @@ pub fn convert_master_secret(mut record: Record) -> MigrationResult { Ok(record) } -pub fn convert_cred(mut record: Record) -> MigrationResult { +pub fn convert_cred(mut record: IndyRecord) -> MigrationResult { record.type_ = CATEGORY_CREDENTIAL.to_owned(); let _: credx::types::Credential = serde_json::from_str(&record.value)?; Ok(record) } -pub fn convert_cred_def(mut record: Record) -> MigrationResult { +pub fn convert_cred_def(mut record: IndyRecord) -> MigrationResult { record.type_ = CATEGORY_CRED_DEF.to_owned(); let _: credx::types::CredentialDefinition = serde_json::from_str(&record.value)?; Ok(record) } -pub fn convert_cred_def_priv_key(mut record: Record) -> MigrationResult { +pub fn convert_cred_def_priv_key(mut record: IndyRecord) -> MigrationResult { record.type_ = CATEGORY_CRED_DEF_PRIV.to_owned(); let _: credx::types::CredentialDefinitionPrivate = serde_json::from_str(&record.value)?; Ok(record) } -pub fn convert_cred_def_correctness_proof(mut record: Record) -> MigrationResult { +pub fn convert_cred_def_correctness_proof(mut record: IndyRecord) -> MigrationResult { record.type_ = CATEGORY_CRED_KEY_CORRECTNESS_PROOF.to_owned(); let old: vdrtools::CredentialDefinitionCorrectnessProof = serde_json::from_str(&record.value)?; let old_value = serde_json::to_string(&old.value)?; @@ -54,13 +54,13 @@ pub fn convert_cred_def_correctness_proof(mut record: Record) -> MigrationResult Ok(record) } -pub fn convert_schema(mut record: Record) -> MigrationResult { +pub fn convert_schema(mut record: IndyRecord) -> MigrationResult { record.type_ = CATEGORY_CRED_SCHEMA.to_owned(); let _: credx::types::Schema = serde_json::from_str(&record.value)?; Ok(record) } -pub fn convert_schema_id(mut record: Record) -> MigrationResult { +pub fn convert_schema_id(mut record: IndyRecord) -> MigrationResult { record.type_ = CATEGORY_CRED_MAP_SCHEMA_ID.to_owned(); // The plain ID is stored as a String, // so not that much to check. @@ -68,13 +68,13 @@ pub fn convert_schema_id(mut record: Record) -> MigrationResult { Ok(record) } -pub fn convert_rev_reg(mut record: Record) -> MigrationResult { +pub fn convert_rev_reg(mut record: IndyRecord) -> MigrationResult { record.type_ = CATEGORY_REV_REG.to_owned(); let _: credx::types::RevocationRegistry = serde_json::from_str(&record.value)?; Ok(record) } -pub fn convert_rev_reg_delta(mut record: Record) -> MigrationResult { +pub fn convert_rev_reg_delta(mut record: IndyRecord) -> MigrationResult { record.type_ = CATEGORY_REV_REG_DELTA.to_owned(); // Shave off the useless prefix, if found. @@ -90,19 +90,19 @@ pub fn convert_rev_reg_delta(mut record: Record) -> MigrationResult { Ok(record) } -pub fn convert_rev_reg_info(mut record: Record) -> MigrationResult { +pub fn convert_rev_reg_info(mut record: IndyRecord) -> MigrationResult { record.type_ = CATEGORY_REV_REG_INFO.to_owned(); let _: RevocationRegistryInfo = serde_json::from_str(&record.value)?; Ok(record) } -pub fn convert_rev_reg_def(mut record: Record) -> MigrationResult { +pub fn convert_rev_reg_def(mut record: IndyRecord) -> MigrationResult { record.type_ = CATEGORY_REV_REG_DEF.to_owned(); let _: credx::types::RevocationRegistryDefinition = serde_json::from_str(&record.value)?; Ok(record) } -pub fn convert_rev_reg_def_priv(mut record: Record) -> MigrationResult { +pub fn convert_rev_reg_def_priv(mut record: IndyRecord) -> MigrationResult { record.type_ = CATEGORY_REV_REG_DEF_PRIV.to_owned(); let _: credx::types::RevocationRegistryDefinitionPrivate = serde_json::from_str(&record.value)?; Ok(record) diff --git a/aries/misc/wallet_migrator/src/vdrtools2credx/mod.rs b/aries/misc/wallet_migrator/src/vdrtools2credx/mod.rs index 54bfc1c302..f6fb140f7b 100644 --- a/aries/misc/wallet_migrator/src/vdrtools2credx/mod.rs +++ b/aries/misc/wallet_migrator/src/vdrtools2credx/mod.rs @@ -1,7 +1,7 @@ pub mod conv; use log::trace; -use vdrtools::types::domain::wallet::Record; +use vdrtools::types::domain::wallet::IndyRecord; use crate::error::MigrationResult; @@ -21,7 +21,7 @@ pub(crate) const INDY_REV_REG_DEF: &str = "Indy::RevocationRegistryDefinition"; pub(crate) const INDY_REV_REG_DEF_PRIV: &str = "Indy::RevocationRegistryDefinitionPrivate"; /// Contains the logic for record mapping and migration. -pub fn migrate_any_record(record: Record) -> MigrationResult> { +pub fn migrate_any_record(record: IndyRecord) -> MigrationResult> { trace!("Migrating wallet record {record:?}"); let record = match record.type_.as_str() { @@ -384,7 +384,7 @@ mod tests { .await .unwrap(); - let record: Record = serde_json::from_str(&record_str).unwrap(); + let record: IndyRecord = serde_json::from_str(&record_str).unwrap(); record.value } diff --git a/aries/wrappers/uniffi-aries-vcx/core/src/core/unpack_message.rs b/aries/wrappers/uniffi-aries-vcx/core/src/core/unpack_message.rs index e001c9e622..f78f1529aa 100644 --- a/aries/wrappers/uniffi-aries-vcx/core/src/core/unpack_message.rs +++ b/aries/wrappers/uniffi-aries-vcx/core/src/core/unpack_message.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use aries_vcx::aries_vcx_core::wallet::{base_wallet::BaseWallet, structs_io::UnpackMessageOutput}; +use aries_vcx::aries_vcx_core::wallet::{base_wallet::DidWallet, structs_io::UnpackMessageOutput}; use super::profile::ProfileHolder; use crate::{errors::error::VcxUniFFIResult, runtime::block_on};