use std::sync::Arc;
use affinidi_messaging_didcomm_service::{
DIDCommServiceError, MESSAGE_PICKUP_STATUS_TYPE, MessagePolicy, RequestLogging, Router,
TRUST_PING_TYPE, handler_fn, ignore_handler, trust_ping_handler,
};
use tokio::sync::RwLock;
use tracing::debug;
use affinidi_did_resolver_cache_sdk::DIDCacheClient;
use crate::config::AppConfig;
use crate::didcomm_bridge::DIDCommBridge;
use crate::keys::seed_store::SeedStore;
use crate::server::AppState;
use crate::store::KeyspaceHandle;
use super::handlers;
#[cfg(feature = "tee")]
use vta_sdk::protocols::attestation_management;
#[cfg(feature = "webvh")]
use vta_sdk::protocols::did_management;
#[cfg(feature = "webvh")]
use vta_sdk::protocols::protocol_management;
#[cfg(feature = "webvh")]
use vta_sdk::protocols::provision_integration_management;
use vta_sdk::protocols::{
self, acl_management, audit_management, context_management, credential_exchange,
key_management, seed_management, vta_management,
};
#[derive(Clone)]
pub struct VtaState {
pub keys_ks: KeyspaceHandle,
pub acl_ks: KeyspaceHandle,
pub contexts_ks: KeyspaceHandle,
pub did_templates_ks: KeyspaceHandle,
pub audit_ks: KeyspaceHandle,
pub imported_ks: KeyspaceHandle,
pub service_state_ks: KeyspaceHandle,
#[cfg(feature = "webvh")]
pub webvh_ks: KeyspaceHandle,
pub sealed_nonces_ks: KeyspaceHandle,
#[cfg(feature = "webvh")]
pub drains_ks: KeyspaceHandle,
#[cfg(feature = "webvh")]
pub snapshot_ks: KeyspaceHandle,
#[cfg(feature = "webvh")]
pub mediator_registry: Arc<crate::messaging::registry::MediatorListenerRegistry>,
#[cfg(feature = "webvh")]
pub drain_sweeper: Arc<crate::messaging::drain_sweeper::DrainSweeper>,
#[cfg(feature = "webvh")]
pub webvh_auth_locks: crate::operations::did_webvh::WebvhAuthLocks,
pub telemetry: vti_common::telemetry::SharedTelemetrySink,
pub seed_store: Arc<dyn SeedStore>,
pub config: Arc<RwLock<AppConfig>>,
pub did_resolver: Option<DIDCacheClient>,
pub didcomm_bridge: Arc<DIDCommBridge>,
#[cfg(feature = "didcomm")]
pub secrets_resolver: Option<Arc<affinidi_tdk::secrets_resolver::ThreadedSecretsResolver>>,
#[cfg(feature = "didcomm")]
pub signing_vm_id: Option<String>,
#[cfg(feature = "didcomm")]
pub ka_vm_id: Option<String>,
#[cfg(feature = "tee")]
pub tee_state: Option<crate::tee::TeeState>,
pub restart_tx: tokio::sync::watch::Sender<bool>,
}
#[cfg(feature = "webvh")]
impl From<&VtaState> for crate::operations::provision_integration::ProvisionIntegrationDeps {
fn from(state: &VtaState) -> Self {
Self {
keys_ks: state.keys_ks.clone(),
acl_ks: state.acl_ks.clone(),
audit_ks: state.audit_ks.clone(),
contexts_ks: state.contexts_ks.clone(),
did_templates_ks: state.did_templates_ks.clone(),
imported_ks: state.imported_ks.clone(),
webvh_ks: state.webvh_ks.clone(),
sealed_nonces_ks: state.sealed_nonces_ks.clone(),
seed_store: state.seed_store.clone(),
config: state.config.clone(),
did_resolver: state.did_resolver.clone(),
didcomm_bridge: state.didcomm_bridge.clone(),
}
}
}
impl From<&AppState> for VtaState {
fn from(state: &AppState) -> Self {
Self {
keys_ks: state.keys_ks.clone(),
acl_ks: state.acl_ks.clone(),
contexts_ks: state.contexts_ks.clone(),
did_templates_ks: state.did_templates_ks.clone(),
audit_ks: state.audit_ks.clone(),
imported_ks: state.imported_ks.clone(),
service_state_ks: state.service_state_ks.clone(),
#[cfg(feature = "webvh")]
webvh_ks: state.webvh_ks.clone(),
sealed_nonces_ks: state.sealed_nonces_ks.clone(),
#[cfg(feature = "webvh")]
drains_ks: state.drains_ks.clone(),
#[cfg(feature = "webvh")]
snapshot_ks: state.snapshot_ks.clone(),
#[cfg(feature = "webvh")]
mediator_registry: Arc::clone(&state.mediator_registry),
#[cfg(feature = "webvh")]
drain_sweeper: Arc::clone(&state.drain_sweeper),
#[cfg(feature = "webvh")]
webvh_auth_locks: state.webvh_auth_locks.clone(),
telemetry: Arc::clone(&state.telemetry),
seed_store: state.seed_store.clone(),
config: Arc::clone(&state.config),
did_resolver: state.did_resolver.clone(),
didcomm_bridge: Arc::clone(&state.didcomm_bridge),
#[cfg(feature = "didcomm")]
secrets_resolver: state.secrets_resolver.clone(),
#[cfg(feature = "didcomm")]
signing_vm_id: state.signing_vm_id.clone(),
#[cfg(feature = "didcomm")]
ka_vm_id: state.ka_vm_id.clone(),
#[cfg(feature = "tee")]
tee_state: state.tee.as_ref().map(|tc| tc.state.clone()),
restart_tx: state.restart_tx.clone(),
}
}
}
pub struct BridgeHandler {
inner: Router,
bridge: Arc<DIDCommBridge>,
}
#[async_trait::async_trait]
impl affinidi_messaging_didcomm_service::DIDCommHandler for BridgeHandler {
async fn handle(
&self,
ctx: affinidi_messaging_didcomm_service::HandlerContext,
message: affinidi_messaging_didcomm::Message,
meta: affinidi_messaging_didcomm::UnpackMetadata,
) -> Result<Option<affinidi_messaging_didcomm_service::DIDCommResponse>, DIDCommServiceError>
{
if self.bridge.try_complete(&message) {
return Ok(None);
}
if message.thid.is_some() {
debug!(
msg_type = %message.typ,
thid = message.thid.as_deref().unwrap_or(""),
from = message.from.as_deref().unwrap_or("unknown"),
"unmatched response — no pending request for thread (stale message)"
);
}
self.inner.handle(ctx, message, meta).await
}
}
pub fn build_handler(
state: Arc<VtaState>,
app_state: AppState,
bridge: Arc<DIDCommBridge>,
) -> Result<BridgeHandler, DIDCommServiceError> {
let mut router = Router::new()
.extension(state)
.extension(app_state)
.route(TRUST_PING_TYPE, handler_fn(trust_ping_handler))?
.route(MESSAGE_PICKUP_STATUS_TYPE, handler_fn(ignore_handler))?
.route(
handlers::TRUST_TASK_ENVELOPE_TYPE,
handler_fn(handlers::handle_trust_task),
)?
.route(
key_management::CREATE_KEY,
handler_fn(handlers::handle_create_key),
)?
.route(
key_management::GET_KEY,
handler_fn(handlers::handle_get_key),
)?
.route(
key_management::LIST_KEYS,
handler_fn(handlers::handle_list_keys),
)?
.route(
key_management::RENAME_KEY,
handler_fn(handlers::handle_rename_key),
)?
.route(
key_management::REVOKE_KEY,
handler_fn(handlers::handle_revoke_key),
)?
.route(
key_management::GET_KEY_SECRET,
handler_fn(handlers::handle_get_key_secret),
)?
.route(
key_management::SIGN_REQUEST,
handler_fn(handlers::handle_sign_request),
)?
.route(
seed_management::LIST_SEEDS,
handler_fn(handlers::handle_list_seeds),
)?
.route(
seed_management::ROTATE_SEED,
handler_fn(handlers::handle_rotate_seed),
)?
.route(
context_management::CREATE_CONTEXT,
handler_fn(handlers::handle_create_context),
)?
.route(
context_management::GET_CONTEXT,
handler_fn(handlers::handle_get_context),
)?
.route(
context_management::LIST_CONTEXTS,
handler_fn(handlers::handle_list_contexts),
)?
.route(
context_management::UPDATE_CONTEXT,
handler_fn(handlers::handle_update_context),
)?
.route(
context_management::UPDATE_CONTEXT_DID,
handler_fn(handlers::handle_update_context_did),
)?
.route(
context_management::PREVIEW_DELETE_CONTEXT,
handler_fn(handlers::handle_preview_delete_context),
)?
.route(
context_management::DELETE_CONTEXT,
handler_fn(handlers::handle_delete_context),
)?
.route(
acl_management::CREATE_ACL,
handler_fn(handlers::handle_create_acl),
)?
.route(
acl_management::GET_ACL,
handler_fn(handlers::handle_get_acl),
)?
.route(
acl_management::LIST_ACL,
handler_fn(handlers::handle_list_acl),
)?
.route(
acl_management::UPDATE_ACL,
handler_fn(handlers::handle_update_acl),
)?
.route(
acl_management::DELETE_ACL,
handler_fn(handlers::handle_delete_acl),
)?
.route(
acl_management::SWAP_ACL,
handler_fn(handlers::handle_swap_acl),
)?
.route(
acl_management::ACL_SWAP_KEY,
handler_fn(handlers::handle_swap_acl),
)?
.route(
audit_management::LIST_LOGS,
handler_fn(handlers::handle_list_logs),
)?
.route(
audit_management::GET_RETENTION,
handler_fn(handlers::handle_get_retention),
)?
.route(
audit_management::UPDATE_RETENTION,
handler_fn(handlers::handle_update_retention),
)?
.route(
vta_management::GET_CONFIG,
handler_fn(handlers::handle_get_config),
)?
.route(
vta_management::UPDATE_CONFIG,
handler_fn(handlers::handle_update_config),
)?
.route(
protocols::PROBLEM_REPORT_TYPE,
handler_fn(handlers::handle_problem_report),
)?
.route(
vta_management::RESTART,
handler_fn(handlers::handle_restart),
)?
.route(
protocols::backup_management::EXPORT_BACKUP,
handler_fn(handlers::handle_backup_export),
)?
.route(
protocols::backup_management::IMPORT_BACKUP,
handler_fn(handlers::handle_backup_import),
)?
.route(
credential_exchange::ISSUE,
handler_fn(handlers::handle_credential_issue),
)?
.route(
credential_exchange::QUERY,
handler_fn(handlers::handle_credential_query),
)?
.route(
credential_exchange::OFFER,
handler_fn(handlers::handle_credential_offer),
)?;
#[cfg(feature = "webvh")]
{
router = router
.route(
did_management::CREATE_DID_WEBVH,
handler_fn(handlers::handle_create_did_webvh),
)?
.route(
did_management::GET_DID_WEBVH,
handler_fn(handlers::handle_get_did_webvh),
)?
.route(
did_management::GET_DID_WEBVH_LOG,
handler_fn(handlers::handle_get_did_webvh_log),
)?
.route(
did_management::LIST_DIDS_WEBVH,
handler_fn(handlers::handle_list_dids_webvh),
)?
.route(
did_management::DELETE_DID_WEBVH,
handler_fn(handlers::handle_delete_did_webvh),
)?
.route(
did_management::ADD_WEBVH_SERVER,
handler_fn(handlers::handle_add_webvh_server),
)?
.route(
did_management::LIST_WEBVH_SERVERS,
handler_fn(handlers::handle_list_webvh_servers),
)?
.route(
did_management::LIST_WEBVH_SERVER_DOMAINS,
handler_fn(handlers::handle_list_webvh_server_domains),
)?
.route(
did_management::UPDATE_WEBVH_SERVER,
handler_fn(handlers::handle_update_webvh_server),
)?
.route(
did_management::REMOVE_WEBVH_SERVER,
handler_fn(handlers::handle_remove_webvh_server),
)?
.route(
did_management::UPDATE_DID_WEBVH,
handler_fn(handlers::handle_update_did_webvh),
)?
.route(
did_management::ROTATE_DID_WEBVH_KEYS,
handler_fn(handlers::handle_rotate_did_webvh_keys),
)?
.route(
did_management::REGISTER_DID_WITH_SERVER,
handler_fn(handlers::handle_register_did_with_server),
)?;
router = router
.route(
protocol_management::DISABLE_DIDCOMM,
handler_fn(super::handlers_protocol::handle_disable_didcomm),
)?
.route(
protocol_management::ENABLE_REST,
handler_fn(super::handlers_protocol::handle_enable_rest),
)?
.route(
protocol_management::UPDATE_REST,
handler_fn(super::handlers_protocol::handle_update_rest),
)?
.route(
protocol_management::DISABLE_REST,
handler_fn(super::handlers_protocol::handle_disable_rest),
)?
.route(
protocol_management::ROLLBACK_REST,
handler_fn(super::handlers_protocol::handle_rollback_rest),
)?
.route(
protocol_management::UPDATE_DIDCOMM,
handler_fn(super::handlers_protocol::handle_update_didcomm),
)?
.route(
protocol_management::ROLLBACK_DIDCOMM,
handler_fn(super::handlers_protocol::handle_rollback_didcomm),
)?
.route(
protocol_management::LIST_SERVICES,
handler_fn(super::handlers_protocol::handle_list_services),
)?
.route(
protocol_management::LIST_DRAIN,
handler_fn(super::handlers_protocol::handle_list_drain),
)?
.route(
protocol_management::DRAIN_CANCEL,
handler_fn(super::handlers_protocol::handle_drain_cancel),
)?
.route(
protocol_management::MEDIATOR_REPORT,
handler_fn(super::handlers_protocol::handle_mediator_report),
)?;
}
#[cfg(feature = "webvh")]
{
router = router
.route(
provision_integration_management::CANONICAL_PROVISION_INTEGRATION,
handler_fn(handlers::handle_provision_integration),
)?
.route(
provision_integration_management::CANONICAL_PROVISION_INTEGRATION_0_2,
handler_fn(handlers::handle_provision_integration),
)?;
}
router = router
.route(
handlers::STEP_UP_APPROVE_REQUEST_TYPE,
handler_fn(handlers::handle_step_up_approve),
)?
.route(
handlers::STEP_UP_APPROVE_REQUEST_CANONICAL,
handler_fn(handlers::handle_step_up_approve),
)?;
#[cfg(feature = "tee")]
{
router = router
.route(
attestation_management::GET_TEE_STATUS,
handler_fn(handlers::handle_tee_status),
)?
.route(
attestation_management::REQUEST_ATTESTATION,
handler_fn(handlers::handle_request_attestation),
)?;
}
router = router.route(
protocols::discovery::DISCOVER_CAPABILITIES,
handler_fn(handlers::handle_discover_capabilities),
)?;
router = router
.fallback(handler_fn(handlers::handle_unknown))
.layer(
MessagePolicy::new()
.require_encrypted(true)
.require_authenticated(true)
.allow_anonymous_sender(false),
)
.layer(RequestLogging);
Ok(BridgeHandler {
inner: router,
bridge,
})
}