Skip to main content

co_identity/types/
identity.rs

1// SPDX-License-Identifier: AGPL-3.0-only
2// Copyright (C) 2026 1io BRANDGUARDIAN GmbH
3
4use crate::DidCommPublicContext;
5use co_primitives::Network;
6use std::{collections::BTreeSet, fmt::Debug, sync::Arc};
7
8/// Identity representation.
9pub trait Identity {
10	/// The identities identifier (who; DID).
11	fn identity(&self) -> &str;
12
13	/// Public key of the identity if it need to be referenced with the message.
14	fn public_key(&self) -> Option<Vec<u8>>;
15
16	/// Verify signature with this identity.
17	fn verify(&self, signature: &[u8], data: &[u8], public_key: Option<&[u8]>) -> bool;
18
19	/// Public DIDComm context.
20	fn didcomm_public(&self) -> Option<DidCommPublicContext>;
21
22	/// Get Networks where we can (possibly) reach the identity.
23	fn networks(&self) -> BTreeSet<Network>;
24
25	fn try_didcomm_public(&self) -> Result<DidCommPublicContext, anyhow::Error> {
26		self.didcomm_public()
27			.ok_or(anyhow::anyhow!("unsupported identity: no public didcomm context: {}", self.identity()))
28	}
29
30	fn boxed_public(self) -> IdentityBox
31	where
32		Self: Sized + Clone + Send + Sync + 'static,
33	{
34		IdentityBox::new(self)
35	}
36}
37
38/// Dynamic Identity.
39#[derive(Clone)]
40pub struct IdentityBox {
41	identity: Arc<dyn Identity + Send + Sync + 'static>,
42}
43impl IdentityBox {
44	pub fn new<I: Identity + Send + Sync + 'static>(identity: I) -> Self {
45		Self { identity: Arc::new(identity) }
46	}
47}
48impl Debug for IdentityBox {
49	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50		f.debug_struct("Identity").field("did", &self.identity.identity()).finish()
51	}
52}
53impl Identity for IdentityBox {
54	fn identity(&self) -> &str {
55		self.identity.identity()
56	}
57
58	fn public_key(&self) -> Option<Vec<u8>> {
59		self.identity.public_key()
60	}
61
62	fn verify(&self, signature: &[u8], data: &[u8], public_key: Option<&[u8]>) -> bool {
63		self.identity.verify(signature, data, public_key)
64	}
65
66	fn didcomm_public(&self) -> Option<DidCommPublicContext> {
67		self.identity.didcomm_public()
68	}
69
70	fn networks(&self) -> BTreeSet<co_primitives::Network> {
71		self.identity.networks()
72	}
73}