Skip to content

Commit

Permalink
feat: add new Wallet trait, implement for indy wallet
Browse files Browse the repository at this point in the history
Signed-off-by: Ondrej Prazak <ondrej.prazak@absa.africa>
  • Loading branch information
Ondrej Prazak committed Jan 12, 2024
1 parent 41ea29f commit c2d7e0e
Show file tree
Hide file tree
Showing 16 changed files with 794 additions and 1 deletion.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions aries/aries_vcx/src/errors/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ pub enum AriesVcxErrorKind {
#[error("Could not parse a value")]
ParsingError,

#[error("Unexpected wallet error")]
WalletError,

// A2A
#[error("Invalid HTTP response.")]
InvalidHttpResponse,
Expand Down
1 change: 1 addition & 0 deletions aries/aries_vcx/src/errors/mapping_others.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ impl From<AriesVcxCoreError> for AriesVcxError {
AriesVcxErrorKind::DuplicationMasterSecret
}
AriesVcxCoreErrorKind::DuplicationDid => AriesVcxErrorKind::DuplicationDid,
AriesVcxCoreErrorKind::WalletError => AriesVcxErrorKind::WalletError,
AriesVcxCoreErrorKind::LoggingError => AriesVcxErrorKind::LoggingError,
AriesVcxCoreErrorKind::EncodeError => AriesVcxErrorKind::EncodeError,
AriesVcxCoreErrorKind::UnknownError => AriesVcxErrorKind::UnknownError,
Expand Down
1 change: 1 addition & 0 deletions aries/aries_vcx_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ tokio = { version = "1.20" }
indy-vdr-proxy-client = { git = "https://github.com/hyperledger/indy-vdr.git", rev = "c143268", optional = true }
indy-ledger-response-parser = { path = "../misc/indy_ledger_response_parser" }
lru = { version = "0.12.0" }
public_key = { path = "../../did_core/public_key"}

[dev-dependencies]
tokio = { version = "1.20", features = ["rt", "macros", "rt-multi-thread"] }
3 changes: 3 additions & 0 deletions aries/aries_vcx_core/src/errors/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ pub enum AriesVcxCoreErrorKind {
#[error("Attempted to add a DID to wallet when that DID already exists in wallet")]
DuplicationDid,

#[error("Unexpected wallet error")]
WalletError,

// Logger
#[error("Logging Error")]
LoggingError,
Expand Down
1 change: 1 addition & 0 deletions aries/aries_vcx_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ 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;
Expand Down
107 changes: 107 additions & 0 deletions aries/aries_vcx_core/src/wallet2/entry_tag.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
use std::collections::HashMap;

use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub enum EntryTag {
Encrypted(String, String),
Plaintext(String, String),
}

#[cfg(feature = "vdrtools_wallet")]
impl From<EntryTag> for (String, String) {
fn from(value: EntryTag) -> Self {
match value {
EntryTag::Encrypted(key, val) => (key, val),
EntryTag::Plaintext(key, val) => (format!("~{}", key), val),
}
}
}

#[cfg(feature = "vdrtools_wallet")]
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)
}
}
}

#[derive(Debug, Default, Clone, PartialEq)]
pub struct EntryTags {
inner: Vec<EntryTag>,
}

impl EntryTags {
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<Self::Item>;

fn into_iter(self) -> Self::IntoIter {
self.inner.into_iter()
}
}

impl FromIterator<EntryTag> for EntryTags {
fn from_iter<T: IntoIterator<Item = EntryTag>>(iter: T) -> Self {
let mut tags = Self::default();

for item in iter {
tags.add(item);
}
tags
}
}

impl From<Vec<EntryTag>> for EntryTags {
fn from(value: Vec<EntryTag>) -> Self {
value.into_iter().fold(Self::default(), |mut memo, item| {
memo.add(item);
memo
})
}
}

impl From<EntryTags> for Vec<EntryTag> {
fn from(value: EntryTags) -> Self {
value.inner
}
}

#[cfg(feature = "vdrtools_wallet")]
impl From<EntryTags> for HashMap<String, String> {
fn from(value: EntryTags) -> Self {
let tags: Vec<EntryTag> = value.into();
tags.into_iter().fold(Self::new(), |mut memo, item| {
let (key, value) = item.into();

memo.insert(key, value);
memo
})
}
}

#[cfg(feature = "vdrtools_wallet")]
impl From<HashMap<String, String>> for EntryTags {
fn from(value: HashMap<String, String>) -> Self {
Self {
inner: value
.into_iter()
.map(|(key, value)| (key, value))
.map(From::from)
.collect(),
}
}
}
120 changes: 120 additions & 0 deletions aries/aries_vcx_core/src/wallet2/indy_wallet/indy_did_wallet.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
use async_trait::async_trait;
use public_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},
};

#[async_trait]
impl DidWallet for IndySdkWallet {
async fn create_and_store_my_did(
&self,
seed: Option<&str>,
method_name: Option<&str>,
) -> VcxCoreResult<DidData> {
let res = Locator::instance()
.did_controller
.create_and_store_my_did(
self.wallet_handle,
MyDidInfo {
method_name: 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)
})?,
})
}

async fn did_key(&self, did: &str) -> VcxCoreResult<Key> {
let res = Locator::instance()
.did_controller
.key_for_local_did(self.wallet_handle, DidValue(did.into()))
.await?;

Key::from_base58(&res, KeyType::Ed25519)
.map_err(|err| AriesVcxCoreError::from_msg(AriesVcxCoreErrorKind::WalletError, err))
}

async fn replace_did_key_start(&self, did: &str, seed: Option<&str>) -> VcxCoreResult<Key> {
let key_info = KeyInfo {
seed: seed.map(Into::into),
..Default::default()
};

let key_string = Locator::instance()
.did_controller
.replace_keys_start(self.wallet_handle, key_info, DidValue(did.into()))
.await?;

let key = Key::from_base58(&key_string, KeyType::Ed25519)
.map_err(|err| AriesVcxCoreError::from_msg(AriesVcxCoreErrorKind::WalletError, err))?;

Ok(key)
}

async fn replace_did_key_apply(&self, did: &str) -> VcxCoreResult<()> {
Ok(Locator::instance()
.did_controller
.replace_keys_apply(self.wallet_handle, DidValue(did.into()))
.await?)
}

async fn sign(&self, key: &Key, msg: &[u8]) -> VcxCoreResult<Vec<u8>> {
Locator::instance()
.crypto_controller
.crypto_sign(self.wallet_handle, &key.base58(), msg)
.await
.map_err(From::from)
}

async fn verify(&self, key: &Key, msg: &[u8], signature: &[u8]) -> VcxCoreResult<bool> {
Locator::instance()
.crypto_controller
.crypto_verify(&key.base58(), msg, signature)
.await
.map_err(From::from)
}

async fn pack_message(
&self,
sender_vk: Option<Key>,
receiver_keys: Vec<Key>,
msg: &[u8],
) -> VcxCoreResult<Vec<u8>> {
let receiver_keys_str = receiver_keys.into_iter().map(|key| key.base58()).collect();

Ok(Locator::instance()
.crypto_controller
.pack_msg(
msg.into(),
receiver_keys_str,
sender_vk.map(|key| key.base58()),
self.wallet_handle,
)
.await?)
}

async fn unpack_message(&self, msg: &[u8]) -> VcxCoreResult<UnpackMessageOutput> {
let unpacked_bytes = Locator::instance()
.crypto_controller
.unpack_msg(serde_json::from_slice(msg)?, self.wallet_handle)
.await?;

let res: UnpackMessageOutput =
serde_json::from_slice(&unpacked_bytes[..]).map_err(|err| {
AriesVcxCoreError::from_msg(AriesVcxCoreErrorKind::ParsingError, err.to_string())
})?;

Ok(res)
}
}
Loading

0 comments on commit c2d7e0e

Please sign in to comment.