use super::helper::{
get_did_document_from_body,
get_did_exchange_message,
get_exchange_info_from_message,
DidExchangeBaseMessage,
DidExchangeOptions,
DidExchangeType,
};
use crate::{
get_from_to_from_message,
keypair::{get_com_keypair, get_key_agreement_key, save_com_keypair},
protocols::{
did_exchange::datatypes::{State, UserType},
did_exchange::did_exchange::{get_current_state, save_didexchange, save_state},
protocol::{generate_step_output, StepResult}
},
};
pub fn send_response(options: &str, message: &str) -> StepResult {
let parsed_message: DidExchangeBaseMessage = serde_json::from_str(message)?;
let options: DidExchangeOptions = serde_json::from_str(options)?;
let exchange_info = get_from_to_from_message(&parsed_message.base_message)?;
let encoded_keypair = get_com_keypair(&exchange_info.from, &exchange_info.to)?;
let metadata = serde_json::to_string(&encoded_keypair)?;
let pub_key_bytes = hex::decode(encoded_keypair.pub_key)?;
let pub_key_base58_string = &bs58::encode(pub_key_bytes).into_string();
let (request_message, ..) = get_did_exchange_message(
DidExchangeType::Response,
&exchange_info.from,
&encoded_keypair.key_agreement_key,
&encoded_keypair.target_key_agreement_key,
&options.service_endpoint.unwrap_or_else(|| "".to_string()),
pub_key_base58_string,
&parsed_message,
)?;
let thid = parsed_message.thid.ok_or("Thread id can't be empty")?;
let current_state: State = get_current_state(&thid, &UserType::Invitee)?.parse()?;
match current_state {
State::ReceiveRequest => {
save_state(&thid, &State::SendResponse, &UserType::Invitee)?
}
_ => {
return Err(Box::from(format!(
"Error while processing step: State from {} to {} not allowed",
current_state,
State::SendResponse
)))
}
};
save_didexchange(
&exchange_info.from,
&exchange_info.to,
&thid,
&serde_json::to_string(&request_message)?,
&State::SendResponse,
)?;
generate_step_output(&serde_json::to_string(&request_message)?, &metadata)
}
pub fn receive_response(_options: &str, message: &str) -> StepResult {
let parsed_message: DidExchangeBaseMessage = serde_json::from_str(message)?;
let did_document = get_did_document_from_body(message)?;
let exchange_info = get_exchange_info_from_message(&parsed_message.base_message, did_document)?;
let encoded_keypair = get_key_agreement_key(&exchange_info.to)?;
let enhanced_encoded_keypair = save_com_keypair(
&exchange_info.to,
&exchange_info.from,
&exchange_info.to,
&exchange_info.did_id,
&encoded_keypair.pub_key,
&encoded_keypair.secret_key,
Some(exchange_info.pub_key_hex.to_owned()),
Some(exchange_info.service_endpoint.to_owned()),
)?;
if exchange_info.from != exchange_info.did_id {
save_com_keypair(
&exchange_info.to,
&exchange_info.from,
&exchange_info.to,
&exchange_info.did_id,
&encoded_keypair.pub_key,
&encoded_keypair.secret_key,
Some(exchange_info.pub_key_hex),
Some(exchange_info.service_endpoint),
)?;
}
let metadata = serde_json::to_string(&enhanced_encoded_keypair)?;
let thid = parsed_message.thid.ok_or("Thread id can't be empty")?;
let current_state: State = get_current_state(&thid, &UserType::Inviter)?.parse()?;
match current_state {
State::SendRequest => {
save_state(&thid, &State::ReceiveResponse, &UserType::Inviter)?
}
_ => {
return Err(Box::from(format!(
"Error while processing step: State from {} to {} not allowed",
current_state,
State::ReceiveResponse
)))
}
};
save_didexchange(
&exchange_info.from,
&exchange_info.to,
&thid,
&serde_json::to_string(&enhanced_encoded_keypair)?,
&State::ReceiveResponse,
)?;
generate_step_output(message, &metadata)
}