trust_tasks_didcomm/handler.rs
1//! [`DidcommHandler`] — the framework's [`TransportHandler`] for DIDComm
2//! v2.1.
3//!
4//! Constructed per-exchange (one per inbound message on the consumer
5//! side; once per peer on the producer side). The handler reports the
6//! locally-controlled DID as `recipient` and the DIDComm-verified peer
7//! DID as `issuer`, then lets the framework's default
8//! [`TransportHandler::resolve_parties`] apply SPEC.md §4.8.1
9//! precedence unchanged.
10
11use trust_tasks_rs::{TransportContext, TransportHandler};
12
13/// Stable identifier for the DIDComm binding, per SPEC.md §9.2.
14///
15/// `bindings/didcomm/0.2` §1. The binding identifier moved with the minor;
16/// the envelope `type` ([`ENVELOPE_TYPE`](crate::ENVELOPE_TYPE)) deliberately
17/// did not, so a 0.1 and a 0.2 implementation stay mutually intelligible on
18/// the wire (binding §7.1).
19pub const BINDING_URI: &str = "https://trusttasks.org/binding/didcomm/0.2";
20
21/// A [`TransportHandler`] for one DIDComm v2.1 exchange.
22///
23/// `local` is the DID this party controls. `peer` is the
24/// authcrypt-verified sender DID on the consumer side, or the configured
25/// remote DID on the producer side.
26///
27/// Both fields are `Option<String>` so a caller can model a party it has
28/// not established. The consumer path in [`unpack_trust_task`](crate::unpack_trust_task)
29/// never leaves either side `None`: binding §2/§4 admit only authcrypt, which
30/// always yields both a verified sender and the DID it was sealed to. A
31/// handler built with `peer = None` makes the framework fall back entirely to
32/// the document's in-band `proof`, so construct one only where that is what
33/// you mean.
34#[derive(Debug, Clone)]
35pub struct DidcommHandler {
36 local: Option<String>,
37 peer: Option<String>,
38}
39
40impl DidcommHandler {
41 /// Construct a handler. Either side may be `None`.
42 pub fn new(local: impl Into<Option<String>>, peer: impl Into<Option<String>>) -> Self {
43 Self {
44 local: local.into(),
45 peer: peer.into(),
46 }
47 }
48
49 /// The local party's DID, if set.
50 pub fn local(&self) -> Option<&str> {
51 self.local.as_deref()
52 }
53
54 /// The verified peer DID, if set.
55 pub fn peer(&self) -> Option<&str> {
56 self.peer.as_deref()
57 }
58}
59
60impl TransportHandler for DidcommHandler {
61 fn binding_uri(&self) -> &str {
62 BINDING_URI
63 }
64
65 fn derive_parties(&self) -> TransportContext {
66 TransportContext {
67 issuer: self.peer.clone(),
68 recipient: self.local.clone(),
69 }
70 }
71}