1pub mod did;
35pub mod did_web;
36pub mod key_management;
37pub mod kms;
38pub mod proof;
39pub mod rdf_integration;
40pub mod revocation;
41#[cfg(feature = "bbs-plus")]
42pub mod signatures;
43pub mod signed_graph;
44pub mod url;
45pub mod vc;
46#[cfg(feature = "zkp")]
47pub mod zkp;
48
49pub mod document_versioning;
51
52pub mod credential_exchange;
54
55pub mod key_agreement;
57
58pub mod presentation_builder;
60
61pub mod vc_verifier;
63
64pub mod vc_presenter;
66
67pub mod trust_chain;
69
70pub mod authentication;
72
73pub mod presentation_request;
75
76pub mod did_resolver;
78
79pub mod identity_registry;
81
82pub mod credential_schema;
84
85pub mod key_manager;
87
88pub mod proof_purpose;
90
91use chrono::{DateTime, Utc};
92use serde::{Deserialize, Serialize};
93use thiserror::Error;
94
95#[cfg(feature = "did-ethr")]
97pub use did::methods::{DidEthr, DidEthrMethod, EthNetwork};
98#[cfg(feature = "did-ion")]
99pub use did::methods::{
100 DidIon, DidIonMethod, IonCreateOperation, IonDocument, IonKeyDescriptor, IonKeyPurpose,
101 IonOperationType, IonService,
102};
103pub use did::{ChainNamespace, Did, DidDocument, DidPkh, DidPkhMethod, DidResolver};
104pub use key_management::{
105 generate_rotation_key, KeyExpiry, KeyRotation, KeyRotationManager, KeyRotationReason,
106 KeyRotationRecord, KeyRotationRegistry, Keystore, LifecycleKeyRotationRecord,
107 VerificationKey as ManagedVerificationKey,
108};
109pub use kms::{
110 create_mock_kms, KeyUsage, KmsAlgorithm, KmsBackend, KmsDidSigner, KmsKeyMetadata, KmsProvider,
111 MockAwsKms, MockAzureKms, MockGcpKms,
112};
113pub use proof::{
114 jws::{
115 attach_jws_proof, extract_jws_proof, sign_document, verify_document, CompactJws,
116 JsonWebSignature2020, JwsAlgorithm, JwsHeader, JwsSigner, JwsVerifier,
117 },
118 Proof, ProofPurpose, ProofType,
119};
120pub use revocation::{
121 BloomFilter, CredentialStatus, RevocationEntry, RevocationList2020, RevocationRegistry,
122 RevocationRegistry2020, RevocationStatus, StatusList2021, StatusList2021Inner,
123 StatusListCredential, StatusPurpose, MIN_LIST_SIZE,
124};
125#[cfg(feature = "bbs-plus")]
126pub use signatures::{
127 BbsKeyPair, BbsPlusSignature, BbsProof, BbsProofRequest, EcdsaJwsSigner, EcdsaJwsVerifier,
128 Ed25519JwsSigner, Ed25519JwsVerifier, Es256Signer, Es256Verifier,
129 JwsAlgorithm as SignaturesJwsAlgorithm, JwsHeader as SignaturesJwsHeader, JwsPayload,
130 JwsSignature, JwsSignatureHeader, JwsSigner as SignaturesJwsSigner, JwsSignerTrait,
131 JwsVerifier as SignaturesJwsVerifier, JwsVerifierTrait, MockJwsSigner, MockJwsVerifier,
132 P256KeyPair, Rs256Signer, Rs256Verifier, RsaKeyPair,
133};
134pub use signed_graph::SignedGraph;
135pub use url::{DereferencedResource, DidDereferencer, DidUrl};
136pub use vc::{
137 CredentialIssuer, CredentialSubject, CredentialVerifier, VerifiableCredential,
138 VerifiablePresentation,
139};
140#[cfg(feature = "zkp")]
141pub use zkp::{
142 prove_selective, verify_selective, AttributeCommitment, CredentialAttribute,
143 DisclosurePresentation, PedersenParams, PedersenSelectiveDisclosureProof, SchnorrProof,
144 SelectiveDisclosureCredential, SelectiveDisclosureProof, SelectiveDisclosureRequest,
145 ZkpProofRequest,
146};
147
148#[derive(Error, Debug)]
150pub enum DidError {
151 #[error("Invalid DID format: {0}")]
152 InvalidFormat(String),
153
154 #[error("Unsupported DID method: {0}")]
155 UnsupportedMethod(String),
156
157 #[error("Resolution failed: {0}")]
158 ResolutionFailed(String),
159
160 #[error("Verification failed: {0}")]
161 VerificationFailed(String),
162
163 #[error("Signing failed: {0}")]
164 SigningFailed(String),
165
166 #[error("Key not found: {0}")]
167 KeyNotFound(String),
168
169 #[error("Invalid key: {0}")]
170 InvalidKey(String),
171
172 #[error("Credential expired")]
173 CredentialExpired,
174
175 #[error("Invalid proof: {0}")]
176 InvalidProof(String),
177
178 #[error("Canonicalization failed: {0}")]
179 CanonicalizationFailed(String),
180
181 #[error("Serialization error: {0}")]
182 SerializationError(String),
183
184 #[error("Network error: {0}")]
185 NetworkError(String),
186
187 #[error("Internal error: {0}")]
188 InternalError(String),
189}
190
191pub type DidResult<T> = Result<T, DidError>;
192
193#[derive(Debug, Clone, Serialize, Deserialize)]
195#[serde(rename_all = "camelCase")]
196pub struct VerificationMethod {
197 pub id: String,
199 #[serde(rename = "type")]
201 pub method_type: String,
202 pub controller: String,
204 #[serde(skip_serializing_if = "Option::is_none")]
206 pub public_key_multibase: Option<String>,
207 #[serde(skip_serializing_if = "Option::is_none")]
209 pub public_key_jwk: Option<serde_json::Value>,
210 #[serde(skip_serializing_if = "Option::is_none")]
212 pub blockchain_account_id: Option<String>,
213}
214
215impl VerificationMethod {
216 pub fn ed25519(id: &str, controller: &str, public_key: &[u8]) -> Self {
218 let multibase = format!("z{}", bs58::encode(public_key).into_string());
220
221 Self {
222 id: id.to_string(),
223 method_type: "Ed25519VerificationKey2020".to_string(),
224 controller: controller.to_string(),
225 public_key_multibase: Some(multibase),
226 public_key_jwk: None,
227 blockchain_account_id: None,
228 }
229 }
230
231 pub fn blockchain(
235 id: &str,
236 controller: &str,
237 method_type: &str,
238 blockchain_account_id: &str,
239 ) -> Self {
240 Self {
241 id: id.to_string(),
242 method_type: method_type.to_string(),
243 controller: controller.to_string(),
244 public_key_multibase: None,
245 public_key_jwk: None,
246 blockchain_account_id: Some(blockchain_account_id.to_string()),
247 }
248 }
249
250 pub fn jwk(id: &str, controller: &str, method_type: &str, jwk: serde_json::Value) -> Self {
252 Self {
253 id: id.to_string(),
254 method_type: method_type.to_string(),
255 controller: controller.to_string(),
256 public_key_multibase: None,
257 public_key_jwk: Some(jwk),
258 blockchain_account_id: None,
259 }
260 }
261
262 pub fn get_public_key_bytes(&self) -> DidResult<Vec<u8>> {
264 if let Some(ref multibase) = self.public_key_multibase {
265 if let Some(stripped) = multibase.strip_prefix('z') {
267 bs58::decode(stripped)
268 .into_vec()
269 .map_err(|e| DidError::InvalidKey(e.to_string()))
270 } else {
271 Err(DidError::InvalidKey("Unknown multibase prefix".to_string()))
272 }
273 } else if self.blockchain_account_id.is_some() {
274 Err(DidError::InvalidKey(
275 "Blockchain account verification methods do not expose raw public keys".to_string(),
276 ))
277 } else {
278 Err(DidError::InvalidKey("No public key available".to_string()))
279 }
280 }
281}
282
283#[derive(Debug, Clone, Serialize, Deserialize)]
285#[serde(rename_all = "camelCase")]
286pub struct Service {
287 pub id: String,
289 #[serde(rename = "type")]
291 pub service_type: String,
292 pub service_endpoint: String,
294}
295
296#[derive(Debug, Clone, Serialize, Deserialize)]
298pub struct VerificationResult {
299 pub valid: bool,
301 pub issuer: Option<String>,
303 pub verified_at: DateTime<Utc>,
305 pub error: Option<String>,
307 pub checks: Vec<VerificationCheck>,
309}
310
311#[derive(Debug, Clone, Serialize, Deserialize)]
313pub struct VerificationCheck {
314 pub name: String,
316 pub passed: bool,
318 pub details: Option<String>,
320}
321
322impl VerificationResult {
323 pub fn success(issuer: &str) -> Self {
324 Self {
325 valid: true,
326 issuer: Some(issuer.to_string()),
327 verified_at: Utc::now(),
328 error: None,
329 checks: vec![],
330 }
331 }
332
333 pub fn failure(error: &str) -> Self {
334 Self {
335 valid: false,
336 issuer: None,
337 verified_at: Utc::now(),
338 error: Some(error.to_string()),
339 checks: vec![],
340 }
341 }
342
343 pub fn with_check(mut self, name: &str, passed: bool, details: Option<&str>) -> Self {
344 self.checks.push(VerificationCheck {
345 name: name.to_string(),
346 passed,
347 details: details.map(String::from),
348 });
349 self
350 }
351}
352
353#[cfg(test)]
354mod tests {
355 use super::*;
356
357 #[test]
358 fn test_verification_method_ed25519() {
359 let public_key = vec![
360 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
361 25, 26, 27, 28, 29, 30, 31, 32,
362 ];
363
364 let vm = VerificationMethod::ed25519("did:key:z123#key-1", "did:key:z123", &public_key);
365
366 assert_eq!(vm.method_type, "Ed25519VerificationKey2020");
367 assert!(vm.public_key_multibase.is_some());
368
369 let recovered = vm.get_public_key_bytes().unwrap();
370 assert_eq!(recovered, public_key);
371 }
372
373 #[test]
374 fn test_verification_result() {
375 let result = VerificationResult::success("did:key:z123")
376 .with_check("signature", true, None)
377 .with_check("expiration", true, Some("Not expired"));
378
379 assert!(result.valid);
380 assert_eq!(result.checks.len(), 2);
381 }
382}