Skip to main content

ma_did/
identity.rs

1use crate::{Did, Document, EncryptionKey, Result, SigningKey, VerificationMethod};
2
3/// A generated DID identity with keys and a signed document.
4///
5/// Private keys are hex-encoded for storage. Use [`SigningKey::from_private_key_bytes`]
6/// and [`EncryptionKey::from_private_key_bytes`] to reconstruct key objects.
7#[derive(Debug, Clone)]
8pub struct GeneratedIdentity {
9    pub subject_url: Did,
10    pub document: Document,
11    pub signing_private_key_hex: String,
12    pub encryption_private_key_hex: String,
13}
14
15/// Generate a base DID identity with keys and a signed document.
16///
17/// No `ma` extension fields are set — those are application-specific.
18///
19/// # Examples
20///
21/// ```
22/// use ma_did::generate_identity;
23///
24/// let id = generate_identity(
25///     "k51qzi5uqu5dj9807pbuod1pplf0vxh8m4lfy3ewl9qbm2s8dsf9ugdf9gedhr"
26/// ).unwrap();
27///
28/// // Document is signed and valid
29/// id.document.verify().unwrap();
30/// id.document.validate().unwrap();
31///
32/// // Private keys available for storage
33/// assert!(!id.signing_private_key_hex.is_empty());
34/// assert!(!id.encryption_private_key_hex.is_empty());
35/// ```
36pub fn generate_identity(ipns: &str) -> Result<GeneratedIdentity> {
37    let subject_url = Did::new_url(ipns, None::<String>)?;
38    let sign_url = Did::new_url(ipns, None::<String>)?;
39    let enc_url = Did::new_url(ipns, None::<String>)?;
40
41    let signing_key = SigningKey::generate(sign_url)?;
42    let encryption_key = EncryptionKey::generate(enc_url)?;
43
44    let mut document = Document::new(&subject_url, &subject_url);
45
46    let assertion_vm = VerificationMethod::new(
47        subject_url.base_id(),
48        subject_url.base_id(),
49        signing_key.key_type.clone(),
50        signing_key.did.fragment.as_deref().unwrap_or_default(),
51        signing_key.public_key_multibase.clone(),
52    )?;
53
54    let key_agreement_vm = VerificationMethod::new(
55        subject_url.base_id(),
56        subject_url.base_id(),
57        encryption_key.key_type.clone(),
58        encryption_key.did.fragment.as_deref().unwrap_or_default(),
59        encryption_key.public_key_multibase.clone(),
60    )?;
61
62    let assertion_vm_id = assertion_vm.id.clone();
63    document.add_verification_method(assertion_vm.clone())?;
64    document.add_verification_method(key_agreement_vm.clone())?;
65    document.assertion_method = vec![assertion_vm_id];
66    document.key_agreement = vec![key_agreement_vm.id.clone()];
67    document.sign(&signing_key, &assertion_vm)?;
68
69    Ok(GeneratedIdentity {
70        subject_url,
71        document,
72        signing_private_key_hex: hex::encode(signing_key.private_key_bytes()),
73        encryption_private_key_hex: hex::encode(encryption_key.private_key_bytes()),
74    })
75}