1pub mod did;
35pub mod key_management;
36pub mod proof;
37pub mod rdf_integration;
38pub mod signed_graph;
39pub mod vc;
40
41use chrono::{DateTime, Utc};
42use serde::{Deserialize, Serialize};
43use thiserror::Error;
44
45pub use did::{Did, DidDocument, DidResolver};
47pub use key_management::Keystore;
48pub use proof::{Proof, ProofPurpose, ProofType};
49pub use signed_graph::SignedGraph;
50pub use vc::{
51 CredentialIssuer, CredentialSubject, CredentialVerifier, VerifiableCredential,
52 VerifiablePresentation,
53};
54
55#[derive(Error, Debug)]
57pub enum DidError {
58 #[error("Invalid DID format: {0}")]
59 InvalidFormat(String),
60
61 #[error("Unsupported DID method: {0}")]
62 UnsupportedMethod(String),
63
64 #[error("Resolution failed: {0}")]
65 ResolutionFailed(String),
66
67 #[error("Verification failed: {0}")]
68 VerificationFailed(String),
69
70 #[error("Signing failed: {0}")]
71 SigningFailed(String),
72
73 #[error("Key not found: {0}")]
74 KeyNotFound(String),
75
76 #[error("Invalid key: {0}")]
77 InvalidKey(String),
78
79 #[error("Credential expired")]
80 CredentialExpired,
81
82 #[error("Invalid proof: {0}")]
83 InvalidProof(String),
84
85 #[error("Canonicalization failed: {0}")]
86 CanonicalizationFailed(String),
87
88 #[error("Serialization error: {0}")]
89 SerializationError(String),
90
91 #[error("Network error: {0}")]
92 NetworkError(String),
93
94 #[error("Internal error: {0}")]
95 InternalError(String),
96}
97
98pub type DidResult<T> = Result<T, DidError>;
99
100#[derive(Debug, Clone, Serialize, Deserialize)]
102#[serde(rename_all = "camelCase")]
103pub struct VerificationMethod {
104 pub id: String,
106 #[serde(rename = "type")]
108 pub method_type: String,
109 pub controller: String,
111 #[serde(skip_serializing_if = "Option::is_none")]
113 pub public_key_multibase: Option<String>,
114 #[serde(skip_serializing_if = "Option::is_none")]
116 pub public_key_jwk: Option<serde_json::Value>,
117}
118
119impl VerificationMethod {
120 pub fn ed25519(id: &str, controller: &str, public_key: &[u8]) -> Self {
122 let multibase = format!("z{}", bs58::encode(public_key).into_string());
124
125 Self {
126 id: id.to_string(),
127 method_type: "Ed25519VerificationKey2020".to_string(),
128 controller: controller.to_string(),
129 public_key_multibase: Some(multibase),
130 public_key_jwk: None,
131 }
132 }
133
134 pub fn get_public_key_bytes(&self) -> DidResult<Vec<u8>> {
136 if let Some(ref multibase) = self.public_key_multibase {
137 if let Some(stripped) = multibase.strip_prefix('z') {
139 bs58::decode(stripped)
140 .into_vec()
141 .map_err(|e| DidError::InvalidKey(e.to_string()))
142 } else {
143 Err(DidError::InvalidKey("Unknown multibase prefix".to_string()))
144 }
145 } else {
146 Err(DidError::InvalidKey("No public key available".to_string()))
147 }
148 }
149}
150
151#[derive(Debug, Clone, Serialize, Deserialize)]
153#[serde(rename_all = "camelCase")]
154pub struct Service {
155 pub id: String,
157 #[serde(rename = "type")]
159 pub service_type: String,
160 pub service_endpoint: String,
162}
163
164#[derive(Debug, Clone, Serialize, Deserialize)]
166pub struct VerificationResult {
167 pub valid: bool,
169 pub issuer: Option<String>,
171 pub verified_at: DateTime<Utc>,
173 pub error: Option<String>,
175 pub checks: Vec<VerificationCheck>,
177}
178
179#[derive(Debug, Clone, Serialize, Deserialize)]
181pub struct VerificationCheck {
182 pub name: String,
184 pub passed: bool,
186 pub details: Option<String>,
188}
189
190impl VerificationResult {
191 pub fn success(issuer: &str) -> Self {
192 Self {
193 valid: true,
194 issuer: Some(issuer.to_string()),
195 verified_at: Utc::now(),
196 error: None,
197 checks: vec![],
198 }
199 }
200
201 pub fn failure(error: &str) -> Self {
202 Self {
203 valid: false,
204 issuer: None,
205 verified_at: Utc::now(),
206 error: Some(error.to_string()),
207 checks: vec![],
208 }
209 }
210
211 pub fn with_check(mut self, name: &str, passed: bool, details: Option<&str>) -> Self {
212 self.checks.push(VerificationCheck {
213 name: name.to_string(),
214 passed,
215 details: details.map(String::from),
216 });
217 self
218 }
219}
220
221#[cfg(test)]
222mod tests {
223 use super::*;
224
225 #[test]
226 fn test_verification_method_ed25519() {
227 let public_key = vec![
228 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
229 25, 26, 27, 28, 29, 30, 31, 32,
230 ];
231
232 let vm = VerificationMethod::ed25519("did:key:z123#key-1", "did:key:z123", &public_key);
233
234 assert_eq!(vm.method_type, "Ed25519VerificationKey2020");
235 assert!(vm.public_key_multibase.is_some());
236
237 let recovered = vm.get_public_key_bytes().unwrap();
238 assert_eq!(recovered, public_key);
239 }
240
241 #[test]
242 fn test_verification_result() {
243 let result = VerificationResult::success("did:key:z123")
244 .with_check("signature", true, None)
245 .with_check("expiration", true, Some("Not expired"));
246
247 assert!(result.valid);
248 assert_eq!(result.checks.len(), 2);
249 }
250}