use serde_json::Value;
use super::VtaClient;
use crate::error::VtaError;
use crate::protocols::persona::{
ContactDocument, LocalProfileEntry, PersonaAttributeDeleteBody, PersonaAttributeListBody,
PersonaAttributePutBody, PersonaBindingGetBody, PersonaBindingListBody, PersonaBindingSetBody,
PersonaContactDeleteBody, PersonaContactGetBody, PersonaContactListBody, PersonaContactPutBody,
PersonaCorrelationAnalyzeBody, PersonaDisclosureHistoryBody, PersonaDisclosurePresentBody,
PersonaDisclosurePreviewBody, PersonaLocalBindingSetBody, PersonaLocalProfileDeleteBody,
PersonaLocalProfileGetBody, PersonaLocalProfileListBody, PersonaLocalProfilePutBody,
PersonaProfileDeleteBody, PersonaProfileGetBody, PersonaProfileListBody, PersonaProfilePutBody,
PersonaRenderersListBody, ProfileEntry, Provenance, ValueType,
};
use crate::trust_tasks;
const PERSONA_TT_TIMEOUT: u64 = 30;
fn body(value: impl serde::Serialize) -> Result<Value, VtaError> {
serde_json::to_value(value)
.map_err(|e| VtaError::Validation(format!("encode persona payload: {e}")))
}
impl VtaClient {
#[allow(clippy::too_many_arguments)]
pub async fn persona_attribute_put(
&self,
claim_type: &str,
value: Value,
value_type: ValueType,
provenance: Provenance,
label: Option<&str>,
attribute_id: Option<&str>,
expected_version: Option<u64>,
) -> Result<Value, VtaError> {
let payload = body(PersonaAttributePutBody {
claim_type: claim_type.to_string(),
value,
value_type,
provenance,
label: label.map(str::to_string),
attribute_id: attribute_id.map(str::to_string),
expected_version,
ext: None,
})?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_ATTRIBUTE_PUT_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
pub async fn persona_attribute_list(
&self,
type_prefix: Option<&str>,
include_values: bool,
include_sensitive: bool,
include_stale: Option<bool>,
limit: Option<std::num::NonZeroU64>,
cursor: Option<&str>,
) -> Result<Value, VtaError> {
let payload = body(PersonaAttributeListBody {
type_prefix: type_prefix.map(str::to_string),
include_values: include_values.then_some(true),
include_sensitive: include_sensitive.then_some(true),
include_stale,
limit,
cursor: cursor.map(str::to_string),
ext: None,
})?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_ATTRIBUTE_LIST_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
pub async fn persona_attribute_delete(
&self,
attribute_id: &str,
cascade: bool,
expected_version: Option<u64>,
) -> Result<Value, VtaError> {
let payload = body(PersonaAttributeDeleteBody {
attribute_id: attribute_id.to_string(),
cascade: cascade.then_some(true),
expected_version,
ext: None,
})?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_ATTRIBUTE_DELETE_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
pub async fn persona_profile_put(
&self,
name: &str,
entries: Vec<ProfileEntry>,
credential_refs: Vec<String>,
profile_id: Option<&str>,
expected_version: Option<u64>,
) -> Result<Value, VtaError> {
let payload = body(PersonaProfilePutBody {
name: name.to_string(),
entries,
credential_refs,
profile_id: profile_id.map(str::to_string),
expected_version,
ext: None,
})?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_PROFILE_PUT_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
pub async fn persona_profile_get(
&self,
profile_id: &str,
resolve: bool,
) -> Result<Value, VtaError> {
let payload = body(PersonaProfileGetBody {
profile_id: profile_id.to_string(),
resolve: resolve.then_some(true),
ext: None,
})?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_PROFILE_GET_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
pub async fn persona_profile_list(
&self,
limit: Option<std::num::NonZeroU64>,
cursor: Option<&str>,
) -> Result<Value, VtaError> {
let payload = body(PersonaProfileListBody {
limit,
cursor: cursor.map(str::to_string),
ext: None,
})?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_PROFILE_LIST_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
pub async fn persona_profile_delete(
&self,
profile_id: &str,
unbind: bool,
expected_version: Option<u64>,
) -> Result<Value, VtaError> {
let payload = body(PersonaProfileDeleteBody {
profile_id: profile_id.to_string(),
unbind: unbind.then_some(true),
expected_version,
ext: None,
})?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_PROFILE_DELETE_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
pub async fn persona_binding_set(
&self,
context_id: &str,
persona_did: &str,
profile_id: Option<&str>,
public_entries: Vec<String>,
expected_version: Option<u64>,
) -> Result<Value, VtaError> {
let payload = body(PersonaBindingSetBody {
context_id: context_id.to_string(),
persona_did: persona_did.to_string(),
profile_id: profile_id.map(str::to_string),
public_entries,
expected_version,
ext: None,
})?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_BINDING_SET_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
pub async fn persona_binding_get(
&self,
context_id: &str,
persona_did: &str,
) -> Result<Value, VtaError> {
let payload = body(PersonaBindingGetBody {
context_id: context_id.to_string(),
persona_did: persona_did.to_string(),
ext: None,
})?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_BINDING_GET_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
pub async fn persona_binding_list(
&self,
context_id: &str,
limit: Option<std::num::NonZeroU64>,
cursor: Option<&str>,
) -> Result<Value, VtaError> {
let payload = body(PersonaBindingListBody {
context_id: context_id.to_string(),
limit,
cursor: cursor.map(str::to_string),
ext: None,
})?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_BINDING_LIST_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
pub async fn persona_contact_put(
&self,
context_id: &str,
subject_did: &str,
known_by_persona: &str,
document: ContactDocument,
credential_refs: Vec<String>,
notes: Option<&str>,
) -> Result<Value, VtaError> {
let payload = body(PersonaContactPutBody {
context_id: context_id.to_string(),
subject_did: subject_did.to_string(),
known_by_persona: known_by_persona.to_string(),
document,
credential_refs,
notes: notes.map(str::to_string),
ext: None,
})?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_CONTACT_PUT_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
pub async fn persona_contact_get(
&self,
context_id: &str,
contact_id: &str,
rev: Option<std::num::NonZeroU64>,
include_history: bool,
) -> Result<Value, VtaError> {
let payload = body(PersonaContactGetBody {
context_id: context_id.to_string(),
contact_id: contact_id.to_string(),
rev,
include_history: include_history.then_some(true),
ext: None,
})?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_CONTACT_GET_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
pub async fn persona_contact_list(
&self,
context_id: &str,
known_by_persona: Option<&str>,
changed_since: Option<&str>,
limit: Option<std::num::NonZeroU64>,
cursor: Option<&str>,
) -> Result<Value, VtaError> {
let payload = body(PersonaContactListBody {
context_id: context_id.to_string(),
known_by_persona: known_by_persona.map(str::to_string),
changed_since: changed_since.map(str::to_string),
limit,
cursor: cursor.map(str::to_string),
ext: None,
})?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_CONTACT_LIST_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
pub async fn persona_contact_delete(
&self,
context_id: &str,
contact_id: &str,
) -> Result<Value, VtaError> {
let payload = body(PersonaContactDeleteBody {
context_id: context_id.to_string(),
contact_id: contact_id.to_string(),
ext: None,
})?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_CONTACT_DELETE_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
pub async fn persona_disclosure_preview(
&self,
context_id: &str,
persona_did: &str,
verifier_did: &str,
requested_claims: Vec<String>,
purpose: Option<&str>,
renderer: Option<&str>,
) -> Result<Value, VtaError> {
let payload = body(PersonaDisclosurePreviewBody {
context_id: context_id.to_string(),
persona_did: persona_did.to_string(),
verifier_did: verifier_did.to_string(),
requested_claims,
purpose: purpose.map(str::to_string),
renderer: renderer.map(str::to_string),
ext: None,
})?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_DISCLOSURE_PREVIEW_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
pub async fn persona_disclosure_present(
&self,
context_id: &str,
preview_id: &str,
challenge: Option<&str>,
mint: Option<Value>,
) -> Result<Value, VtaError> {
let payload = body(PersonaDisclosurePresentBody {
context_id: context_id.to_string(),
preview_id: preview_id.to_string(),
challenge: challenge.map(str::to_string),
mint,
ext: None,
})?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_DISCLOSURE_PRESENT_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
pub async fn persona_disclosure_history(
&self,
context_id: Option<&str>,
verifier_did: Option<&str>,
attribute_type: Option<&str>,
since: Option<&str>,
limit: Option<std::num::NonZeroU64>,
cursor: Option<&str>,
) -> Result<Value, VtaError> {
let payload = body(PersonaDisclosureHistoryBody {
context_id: context_id.map(str::to_string),
verifier_did: verifier_did.map(str::to_string),
attribute_type: attribute_type.map(str::to_string),
since: since.map(str::to_string),
limit,
cursor: cursor.map(str::to_string),
ext: None,
})?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_DISCLOSURE_HISTORY_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
pub async fn persona_correlation_analyze(
&self,
attribute_id: Option<&str>,
profile_id: Option<&str>,
candidate: Option<Value>,
) -> Result<Value, VtaError> {
let payload = body(PersonaCorrelationAnalyzeBody {
attribute_id: attribute_id.map(str::to_string),
profile_id: profile_id.map(str::to_string),
candidate,
ext: None,
})?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_CORRELATION_ANALYZE_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
pub async fn persona_renderers_list(&self) -> Result<Value, VtaError> {
let payload = body(PersonaRenderersListBody { ext: None })?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_RENDERERS_LIST_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
pub async fn persona_local_profile_put(
&self,
context_id: &str,
name: &str,
entries: Vec<LocalProfileEntry>,
profile_id: Option<&str>,
expected_version: Option<u64>,
) -> Result<Value, VtaError> {
let payload = body(PersonaLocalProfilePutBody {
context_id: context_id.to_string(),
name: name.to_string(),
entries,
profile_id: profile_id.map(str::to_string),
expected_version,
ext: None,
})?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_LOCAL_PROFILE_PUT_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
pub async fn persona_local_profile_get(
&self,
context_id: &str,
profile_id: &str,
) -> Result<Value, VtaError> {
let payload = body(PersonaLocalProfileGetBody {
context_id: context_id.to_string(),
profile_id: profile_id.to_string(),
ext: None,
})?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_LOCAL_PROFILE_GET_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
pub async fn persona_local_profile_list(
&self,
context_id: &str,
limit: Option<std::num::NonZeroU64>,
cursor: Option<&str>,
) -> Result<Value, VtaError> {
let payload = body(PersonaLocalProfileListBody {
context_id: context_id.to_string(),
limit,
cursor: cursor.map(str::to_string),
ext: None,
})?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_LOCAL_PROFILE_LIST_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
pub async fn persona_local_profile_delete(
&self,
context_id: &str,
profile_id: &str,
unbind: bool,
) -> Result<Value, VtaError> {
let payload = body(PersonaLocalProfileDeleteBody {
context_id: context_id.to_string(),
profile_id: profile_id.to_string(),
unbind: unbind.then_some(true),
ext: None,
})?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_LOCAL_PROFILE_DELETE_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
pub async fn persona_local_binding_set(
&self,
context_id: &str,
persona_did: &str,
profile_id: Option<&str>,
expected_version: Option<u64>,
) -> Result<Value, VtaError> {
let payload = body(PersonaLocalBindingSetBody {
context_id: context_id.to_string(),
persona_did: persona_did.to_string(),
profile_id: profile_id.map(str::to_string),
expected_version,
ext: None,
})?;
self.dispatch_trust_task(
trust_tasks::TASK_PERSONA_LOCAL_BINDING_SET_1_0,
payload,
PERSONA_TT_TIMEOUT,
)
.await
}
}